001/*
002 *  Copyright 2014 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.cms.parameters;
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.excalibur.source.SourceResolver;
024import org.apache.excalibur.source.impl.FileSource;
025
026import org.ametys.cms.file.FileHelper;
027import org.ametys.core.right.RightManager.RightResult;
028import org.ametys.core.ui.Callable;
029import org.ametys.core.ui.StaticClientSideElement;
030import org.ametys.core.user.UserIdentity;
031
032/**
033 * Component for operations on parameters files and folders
034 */
035public class ParametersClientSideElement extends StaticClientSideElement
036{
037    private static final String _ROOT_PARAMETERS_DIRECTORY_URI = "context://WEB-INF/param";
038    
039    private FileHelper _fileHelper;
040    private SourceResolver _srcResolver;
041    
042    @Override
043    public void service(ServiceManager serviceManager) throws ServiceException
044    {
045        super.service(serviceManager);
046        _fileHelper = (FileHelper) serviceManager.lookup(FileHelper.ROLE);
047        _srcResolver = (org.apache.excalibur.source.SourceResolver) serviceManager.lookup(org.apache.excalibur.source.SourceResolver.ROLE);        
048    }
049
050    /**
051     * Saves parameters file.
052     * @param relPath the relative file's path from parameters files root directory
053     * @param text the UTF-8 file content to save
054     * @return The result map
055     * @throws IOException If an error occurred while saving 
056     */
057    @Callable
058    public Map<String, Object> saveParameters(String relPath, String text) throws IOException 
059    {
060        String fileURI = _ROOT_PARAMETERS_DIRECTORY_URI + (relPath.length() > 0 ? "/" + relPath : "");
061        return _fileHelper.saveFile(fileURI, text);
062    }
063    
064    /**
065     * Add a new folder
066     * @param parentRelPath the relative parent file's path from parameters files root directory
067     * @param name The name of folder to create
068     * @return a map containing the name of the created folder, its path and the path of its parent
069     * @throws IOException If an error occurred while creating folder
070     */
071    @Callable
072    public Map<String, Object> addFolder(String parentRelPath, String name) throws IOException 
073    {
074        // Check user can access this feature
075        _checkUserRight("CMS_Rights_EditParameterFile", "/cms");
076        
077        FileSource rootDir = (FileSource) _srcResolver.resolveURI(_ROOT_PARAMETERS_DIRECTORY_URI);
078        
079        String parentURI = _ROOT_PARAMETERS_DIRECTORY_URI + (parentRelPath.length() > 0 ? "/" + parentRelPath : "");
080        
081        Map<String, Object> result = _fileHelper.addFolder(parentURI, name, true);
082        
083        if (result.containsKey("uri"))
084        {
085            String folderUri = (String) result.get("uri");
086            String path = folderUri.substring(rootDir.getURI().length());
087            result.put("path", path.endsWith("/") ? path.substring(0, path.length() - 1) : path);
088            result.put("parentPath", parentRelPath.endsWith("/") ? parentRelPath.substring(0, parentRelPath.length() - 1) : parentRelPath);
089        }
090
091        return result;
092    }
093    
094    /**
095    * Remove a folder or a file
096    * @param relPath the relative file's path from parameters files root directory
097    * @return the result map
098    * @throws IOException If an error occurs while removing the folder
099    */
100    @Callable
101    public Map<String, Object> deleteFile(String relPath) throws IOException
102    {
103        // Check user can access this feature
104        _checkUserRight("CMS_Rights_EditParameterFile", "/cms");
105       
106        String fileUri = _ROOT_PARAMETERS_DIRECTORY_URI + (relPath.length() > 0 ? "/" + relPath : "");
107        return _fileHelper.deleteFile(fileUri);
108    }
109    
110    /**
111    * Rename a file or a folder 
112    * @param relPath the relative file's path from parameters files root directory
113    * @param name the new name of the file/folder
114    * @return the result map
115    * @throws IOException if an error occurs while renaming the file/folder
116    */
117    @Callable
118    public Map<String, Object> renameFile (String relPath, String name) throws IOException 
119    {
120        // Check user can access this feature
121        _checkUserRight ("CMS_Rights_EditParameterFile", "/cms"); 
122        
123        FileSource rootDir = (FileSource) _srcResolver.resolveURI(_ROOT_PARAMETERS_DIRECTORY_URI);
124        
125        String fileUri = _ROOT_PARAMETERS_DIRECTORY_URI + (relPath.length() > 0 ? "/" + relPath : "");
126        Map<String, Object> result = _fileHelper.renameFile(fileUri, name);
127        
128        if (result.containsKey("uri"))
129        {
130            String newURI = (String) result.get("uri");
131            String path = newURI.substring(rootDir.getURI().length());
132            result.put("path", path);
133        }
134        return result;
135    }
136    
137    /**
138    * Check if a file with same name already exist
139    * @param parentRelPath the path where the file will be added
140    * @param name the name of the file 
141    * @return result the server's response in JSON
142    * @throws Exception if an error occurred
143    */
144    @Callable
145    public boolean fileExists(String parentRelPath, String name) throws Exception
146    {
147        String parentUri = _ROOT_PARAMETERS_DIRECTORY_URI + (parentRelPath.length() > 0 ? "/" + parentRelPath : "");
148        return _fileHelper.hasChild(parentUri, name);
149    }
150    
151    /**
152     * Check if the user right to access the feature
153     * @param rightId The right id
154     * @param context The right context
155     * @throws IllegalStateException if the user has no right
156     */
157    protected void _checkUserRight (String rightId, String context) throws IllegalStateException
158    {
159        UserIdentity user = _currentUserProvider.getUser();
160        if (_rightManager.hasRight(user, rightId, context) != RightResult.RIGHT_ALLOW)
161        {
162            getLogger().error("User '" + user + "' tried to access a privileged feature without convenient right. Should have right '" + rightId + "' on context '" + context + "'");
163            throw new IllegalStateException("You have no right to access this feature.");
164        }
165    }
166    
167}