001/* 002 * Copyright 2017 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.extraction.edition; 017 018import java.io.File; 019import java.io.IOException; 020import java.io.OutputStream; 021import java.nio.file.Files; 022import java.nio.file.Paths; 023import java.util.LinkedHashMap; 024import java.util.Map; 025import java.util.Properties; 026 027import javax.xml.transform.OutputKeys; 028import javax.xml.transform.TransformerFactory; 029import javax.xml.transform.sax.SAXTransformerFactory; 030import javax.xml.transform.sax.TransformerHandler; 031import javax.xml.transform.stream.StreamResult; 032 033import org.apache.avalon.framework.service.ServiceException; 034import org.apache.avalon.framework.service.ServiceManager; 035import org.apache.cocoon.xml.XMLUtils; 036import org.apache.excalibur.source.Source; 037import org.apache.excalibur.source.SourceResolver; 038import org.apache.excalibur.source.impl.FileSource; 039import org.apache.xml.serializer.OutputPropertiesFactory; 040 041import org.ametys.core.ui.Callable; 042import org.ametys.core.ui.StaticClientSideElement; 043import org.ametys.plugins.extraction.ExtractionConstants; 044 045/** 046 * This client site element manages a button to create an extraction definition file 047 */ 048public class EditExtractionClientSideElement extends StaticClientSideElement 049{ 050 /** The Avalon role name */ 051 public static final String ROLE = EditExtractionClientSideElement.class.getName(); 052 053 private SourceResolver _sourceResolver; 054 055 @Override 056 public void service(ServiceManager serviceManager) throws ServiceException 057 { 058 super.service(serviceManager); 059 _sourceResolver = (SourceResolver) serviceManager.lookup(SourceResolver.ROLE); 060 } 061 062 /** 063 * Creates an extraction definition file. 064 * @param definitionFileName The extraction definition name 065 * @return Map containing success boolean and error codes if one occurs 066 * @throws Exception if an error occurs 067 */ 068 @Callable (right = "Extraction_Rights_EditExtraction") 069 public Map<String, Object> createExtraction(String definitionFileName) throws Exception 070 { 071 Map<String, Object> response = new LinkedHashMap<>(); 072 073 // Create extraction definitions directory 074 Source definitionsSrc = _sourceResolver.resolveURI(ExtractionConstants.DEFINITIONS_DIR); 075 File definitionsDir = ((FileSource) definitionsSrc).getFile(); 076 definitionsDir.mkdirs(); 077 078 String definitionFilePath = ExtractionConstants.DEFINITIONS_DIR + definitionFileName; 079 Source definitionSrc = _sourceResolver.resolveURI(definitionFilePath); 080 File definitionFile = ((FileSource) definitionSrc).getFile(); 081 082 if (definitionFile.exists()) 083 { 084 if (getLogger().isErrorEnabled()) 085 { 086 getLogger().error("A definition file already exists with name '" + definitionFileName + "'"); 087 } 088 response.put("success", false); 089 response.put("error", "already-exists"); 090 return response; 091 } 092 093 try (OutputStream os = Files.newOutputStream(Paths.get(definitionFile.getAbsolutePath()))) 094 { 095 // Create a transformer for saving sax into a file 096 TransformerHandler handler = ((SAXTransformerFactory) TransformerFactory.newInstance()).newTransformerHandler(); 097 098 StreamResult result = new StreamResult(os); 099 handler.setResult(result); 100 101 // create the format of result 102 Properties format = new Properties(); 103 format.put(OutputKeys.METHOD, "xml"); 104 format.put(OutputKeys.INDENT, "yes"); 105 format.put(OutputKeys.ENCODING, "UTF-8"); 106 format.put(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "4"); 107 handler.getTransformer().setOutputProperties(format); 108 109 // sax skeleton 110 handler.startDocument(); 111 XMLUtils.createElement(handler, "extraction"); 112 handler.endDocument(); 113 } 114 catch (Exception e) 115 { 116 if (getLogger().isErrorEnabled()) 117 { 118 getLogger().error("Error when trying to create the extraction definition file '" + definitionFileName + "'", e); 119 } 120 response.put("success", false); 121 response.put("error", "other-error"); 122 return response; 123 } 124 125 response.put("success", true); 126 return response; 127 } 128 129 /** 130 * Renames an extraction definition file. 131 * @param definitionOldFileName The extraction definition old file name 132 * @param definitionNewFileName The extraction definition new file name 133 * @return Map containing success boolean and error codes if one occurs 134 * @throws Exception if an error occurs 135 */ 136 @Callable (right = "Extraction_Rights_EditExtraction") 137 public Map<String, Object> renameExtraction(String definitionOldFileName, String definitionNewFileName) throws Exception 138 { 139 Map<String, Object> response = new LinkedHashMap<>(); 140 141 String oldFilePath = ExtractionConstants.DEFINITIONS_DIR + definitionOldFileName; 142 Source oldSrc = _sourceResolver.resolveURI(oldFilePath); 143 File oldFile = ((FileSource) oldSrc).getFile(); 144 145 if (!oldFile.exists()) 146 { 147 if (getLogger().isErrorEnabled()) 148 { 149 getLogger().error("Error while renaming '" + definitionOldFileName + "': this definition file doesn't exist."); 150 } 151 response.put("success", false); 152 response.put("error", "unexisting"); 153 return response; 154 } 155 156 String newFilePath = ExtractionConstants.DEFINITIONS_DIR + definitionNewFileName; 157 Source newSrc = _sourceResolver.resolveURI(newFilePath); 158 File newFile = ((FileSource) newSrc).getFile(); 159 160 if (newFile.exists()) 161 { 162 if (getLogger().isErrorEnabled()) 163 { 164 getLogger().error("Error while renaming to '" + definitionNewFileName + "': a definition file with this name already exists."); 165 } 166 response.put("success", false); 167 response.put("error", "already-exists"); 168 return response; 169 } 170 171 // Copy old file in the new one 172 try 173 { 174 Files.copy(oldFile.toPath(), newFile.toPath()); 175 } 176 catch (IOException e) 177 { 178 if (getLogger().isErrorEnabled()) 179 { 180 getLogger().error("Error while copying old definition file '" + definitionOldFileName + "' in the new one.", e); 181 } 182 response.put("success", false); 183 response.put("error", "other-error"); 184 return response; 185 } 186 187 try 188 { 189 Files.deleteIfExists(oldFile.toPath()); 190 } 191 catch (IOException e) 192 { 193 if (getLogger().isErrorEnabled()) 194 { 195 getLogger().error("Error while deleting old definition file '" + definitionOldFileName + "'.", e); 196 } 197 response.put("success", false); 198 response.put("error", "other-error"); 199 return response; 200 } 201 202 response.put("success", true); 203 return response; 204 } 205 206 /** 207 * Deletes an extraction definition file. 208 * @param definitionFileName The extraction definition file to delete 209 * @return <code>true</code> if extraction deletion succeed, <code>false</code> otherwise 210 * @throws Exception if an error occurs 211 */ 212 @Callable (right = "Extraction_Rights_EditExtraction") 213 public boolean deleteExtraction(String definitionFileName) throws Exception 214 { 215 String filePath = ExtractionConstants.DEFINITIONS_DIR + definitionFileName; 216 Source source = _sourceResolver.resolveURI(filePath); 217 File file = ((FileSource) source).getFile(); 218 219 if (!file.exists()) 220 { 221 throw new IllegalArgumentException("Error while deleting '" + definitionFileName + "': this definition file doesn't exist."); 222 } 223 224 try 225 { 226 Files.deleteIfExists(file.toPath()); 227 } 228 catch (IOException e) 229 { 230 if (getLogger().isErrorEnabled()) 231 { 232 getLogger().error("Error while deleting definition file '" + definitionFileName + "'.", e); 233 } 234 throw e; 235 } 236 237 return true; 238 } 239 240}