001/*
002 *  Copyright 2019 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.IOException;
019import java.util.Map;
020
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023import org.apache.commons.lang3.StringUtils;
024import org.apache.excalibur.source.SourceResolver;
025import org.apache.excalibur.source.impl.FileSource;
026
027import org.ametys.core.file.FileHelper;
028import org.ametys.core.ui.Callable;
029import org.ametys.core.ui.StaticClientSideElement;
030import org.ametys.plugins.extraction.ExtractionConstants;
031import org.ametys.plugins.extraction.ExtractionRightAssignmentContext;
032import org.ametys.plugins.extraction.execution.ExtractionDAO;
033
034/**
035 * Component for operations on extraction folders
036 */
037public class FoldersClientSideElement extends StaticClientSideElement
038{
039    private FileHelper _fileHelper;
040    private SourceResolver _srcResolver;
041    private ExtractionDAO _extractionDAO;
042    
043    @Override
044    public void service(ServiceManager serviceManager) throws ServiceException
045    {
046        super.service(serviceManager);
047        _fileHelper = (FileHelper) serviceManager.lookup(FileHelper.ROLE);
048        _srcResolver = (org.apache.excalibur.source.SourceResolver) serviceManager.lookup(org.apache.excalibur.source.SourceResolver.ROLE);        
049        _extractionDAO = (ExtractionDAO) serviceManager.lookup(ExtractionDAO.ROLE);
050    }
051
052    /**
053     * Add a new folder
054     * @param parentRelPath the relative parent file's path from parameters files root directory
055     * @param name The name of folder to create
056     * @return a map containing the name of the created folder, its path and the path of its parent
057     * @throws IOException If an error occurred while creating folder
058     */
059    @Callable (right = ExtractionConstants.MODIFY_EXTRACTION_RIGHT_ID)
060    public Map<String, Object> addFolder(String parentRelPath, String name) throws IOException 
061    {
062        String nonNullParentRelPath = StringUtils.defaultString(parentRelPath);
063        
064        FileSource rootDir = (FileSource) _srcResolver.resolveURI(ExtractionConstants.DEFINITIONS_DIR);
065        if (!rootDir.exists())
066        {
067            rootDir.getFile().mkdirs();
068        }
069        
070        String parentURI = ExtractionConstants.DEFINITIONS_DIR + (StringUtils.isNotEmpty(nonNullParentRelPath) ? "/" + nonNullParentRelPath : "");
071        
072        Map<String, Object> result = _fileHelper.addFolder(parentURI, name, true);
073        
074        if (result.containsKey("uri"))
075        {
076            String folderUri = (String) result.get("uri");
077            String path = folderUri.substring(rootDir.getURI().length());
078            result.put("path", path.endsWith("/") ? path.substring(0, path.length() - 1) : path);
079            result.put("parentPath", nonNullParentRelPath.endsWith("/") ? nonNullParentRelPath.substring(0, nonNullParentRelPath.length() - 1) : nonNullParentRelPath);
080        }
081
082        return result;
083    }
084    
085    /**
086    * Remove a folder or a file
087    * @param relPath the relative file's path from parameters files root directory
088    * @return the result map
089    * @throws IOException If an error occurs while removing the folder
090    */
091    @Callable (right = ExtractionConstants.MODIFY_EXTRACTION_RIGHT_ID)
092    public Map<String, Object> deleteFile(String relPath) throws IOException
093    {
094        String fileUri = ExtractionConstants.DEFINITIONS_DIR + (relPath.length() > 0 ? "/" + relPath : "");
095        String context = ExtractionRightAssignmentContext.ROOT_CONTEXT_PREFIX + "/" + relPath;
096        FileSource folderToDelete = (FileSource) _srcResolver.resolveURI(fileUri);
097        _extractionDAO.deleteRightsRecursively(context, folderToDelete);
098        return _fileHelper.deleteFile(fileUri);
099    }
100    
101    /**
102    * Rename a file or a folder 
103    * @param relPath the relative file's path from parameters files root directory
104    * @param name the new name of the file/folder
105    * @return the result map
106    * @throws IOException if an error occurs while renaming the file/folder
107    */
108    @Callable (right = ExtractionConstants.MODIFY_EXTRACTION_RIGHT_ID)
109    public Map<String, Object> renameFile(String relPath, String name) throws IOException 
110    {
111        FileSource rootDir = (FileSource) _srcResolver.resolveURI(ExtractionConstants.DEFINITIONS_DIR);
112        
113        String fileUri = ExtractionConstants.DEFINITIONS_DIR + (relPath.length() > 0 ? "/" + relPath : "");
114
115        FileSource file = (FileSource) _srcResolver.resolveURI(fileUri);
116        
117        String relativeParentPath = StringUtils.removeEnd(relPath, file.getName());
118        String relativeNewFilePath = relativeParentPath + name;
119        String sourceContext = ExtractionRightAssignmentContext.ROOT_CONTEXT_PREFIX + "/" + relPath;
120        String targetContext = ExtractionRightAssignmentContext.ROOT_CONTEXT_PREFIX + "/" + relativeNewFilePath;
121        
122        _extractionDAO.copyRightsRecursively(sourceContext, targetContext, file);
123
124        Map<String, Object> result = _fileHelper.renameFile(fileUri, name);
125
126        if ((boolean) result.get("success"))
127        {
128            FileSource newFile = (FileSource) _srcResolver.resolveURI((String) result.get("uri"));
129            _extractionDAO.deleteRightsRecursively(sourceContext, newFile);
130        }
131        else
132        {
133            _extractionDAO.deleteRightsRecursively(targetContext, file);
134        }
135        
136        if (result.containsKey("uri"))
137        {
138            String newURI = (String) result.get("uri");
139            String path = newURI.substring(rootDir.getURI().length());
140            result.put("path", path);
141        }
142        return result;
143    }
144}