001/*
002 *  Copyright 2010 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.skineditor.resources;
017
018import java.io.IOException;
019import java.nio.file.Path;
020import java.util.Map;
021
022import org.apache.avalon.framework.component.Component;
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.avalon.framework.service.Serviceable;
026import org.apache.excalibur.source.SourceResolver;
027import org.apache.excalibur.source.impl.FileSource;
028
029import org.ametys.core.file.FileHelper;
030import org.ametys.core.ui.Callable;
031import org.ametys.plugins.skincommons.SkinEditionHelper;
032import org.ametys.plugins.skincommons.SkinLockManager;
033
034/**
035 * DAO for files and folders inside a skin directory
036 */
037public class SkinResourceDAO implements Serviceable, Component
038{
039    /** Constant for skin editor tool id */
040    public static final String SKIN_EDITOR_TOOL_ID = "uitool-skineditor";
041    
042    /** The lock manager */
043    protected SkinLockManager _lockManager;
044    /** The skin edition helper */
045    protected SkinEditionHelper _skinHelper;
046    /** The file helper */
047    protected FileHelper _fileHelper;
048    /** The source resolver */
049    protected SourceResolver _srcResolver;
050
051    @Override
052    public void service(ServiceManager manager) throws ServiceException
053    {
054        _skinHelper = (SkinEditionHelper) manager.lookup(SkinEditionHelper.ROLE);
055        _fileHelper = (FileHelper) manager.lookup(FileHelper.ROLE);
056        _lockManager = (SkinLockManager) manager.lookup(SkinLockManager.ROLE);
057        _srcResolver = (org.apache.excalibur.source.SourceResolver) manager.lookup(org.apache.excalibur.source.SourceResolver.ROLE);
058    }
059    
060    /**
061     * Saves the text in file
062     * @param skinName The name of the skin containing the resource
063     * @param relPath the relative path of file under the skin directory
064     * @param text the file content to save
065     * @return The result map
066     * @throws IOException If an error occurred while saving 
067     */
068    @Callable
069    public Map<String, Object> save(String skinName, String relPath, String text) throws IOException 
070    {
071        String tempDirURI = _skinHelper.getTempDirectoryURI(skinName);
072        
073        String fileURI = tempDirURI + (relPath.length() > 0 ? "/" + relPath : "");
074        
075        Map<String, Object> result = _fileHelper.saveFile(fileURI, text);
076        
077        if (result.containsKey("isI18n"))
078        {
079            _skinHelper.invalidateTempSkinCatalogues(skinName);
080        }
081        
082        Path tempDir = _skinHelper.getTempDirectory(skinName);
083        // Update lock
084        _lockManager.updateLockFile(tempDir, SKIN_EDITOR_TOOL_ID);
085        
086        return result;
087    }
088    
089    /**
090     * checks if the resource already exists in the parent
091     * @param skinName The name of the skin containing the resource
092     * @param parentRelPath The parent path
093     * @param fileName the file name to check
094     * @return true if the file exists
095     * @throws IOException if something goes wrong while trying to retrieve a file
096     */
097    @Callable
098    public boolean checkSourceExists(String skinName, String parentRelPath, String fileName) throws IOException
099    {
100        String tempDirURI = _skinHelper.getTempDirectoryURI(skinName);
101        String parentFileURI = tempDirURI + (parentRelPath.length() > 0 ? "/" + parentRelPath : "");
102        
103        return _fileHelper.hasChild(parentFileURI, fileName);
104    }
105    
106    /**
107     * Copy a file or directory
108     * @param skinName the name of the current skin
109     * @param srcPath the path of the source file or directory
110     * @param parentTargetPath the new path for the source file or directory
111     * @return a map of data
112     * @throws IOException if something went wrong during the source copy processing
113     */
114    @Callable
115    public Map<String, Object> copySource(String skinName, String srcPath, String parentTargetPath) throws IOException
116    {
117        String tempDirURI = _skinHelper.getTempDirectoryURI(skinName);
118        
119        String srcFileURI = tempDirURI + (srcPath.length() > 0 ? "/" + srcPath : "");
120        String parentTargetURI = tempDirURI + (parentTargetPath.length() > 0 ? "/" + parentTargetPath : "");
121        
122        Map<String, Object> result = _fileHelper.copySource(srcFileURI, parentTargetURI);
123        
124        // Update lock
125        FileSource rootDir = (FileSource) _srcResolver.resolveURI(tempDirURI);
126        _lockManager.updateLockFile(rootDir.getFile().toPath(), SKIN_EDITOR_TOOL_ID);
127        
128        if (result.containsKey("uri"))
129        {
130            String folderUri = (String) result.get("uri");
131            String path = folderUri.substring(rootDir.getURI().length());
132            result.put("path", path.endsWith("/") ? path.substring(0, path.length() - 1) : path);
133            result.put("skinName", skinName);
134        }
135        
136        return result;
137    }
138    
139    /**
140     * Create a folder
141     * @param skinName the name of the current skin
142     * @param parentRelPath the path of the parent containing the folder
143     * @param originalName the name of the new folder
144     * @param renameIfExists if true, will generate a valid name if "originalName" already exists.
145     * @return a map of data
146     * @throws IOException if an error occurs while manipulating files
147     */
148    @Callable
149    public Map addFolder(String skinName, String parentRelPath, String originalName, boolean renameIfExists) throws IOException
150    {
151        String tempDirURI = _skinHelper.getTempDirectoryURI(skinName);
152        String parentURI = tempDirURI + (parentRelPath.length() > 0 ? "/" + parentRelPath : "");
153        
154        Map<String, Object> result = _fileHelper.addFolder(parentURI, originalName, renameIfExists);
155        
156        // Update lock
157        FileSource rootDir = (FileSource) _srcResolver.resolveURI(tempDirURI);
158        _lockManager.updateLockFile(rootDir.getFile().toPath(), SKIN_EDITOR_TOOL_ID);
159       
160        if (result.containsKey("uri"))
161        {
162            String folderUri = (String) result.get("uri");
163            String path = folderUri.substring(rootDir.getURI().length());
164            result.put("path", path.endsWith("/") ? path.substring(0, path.length() - 1) : path);
165            result.put("parentPath", parentRelPath.endsWith("/") ? parentRelPath.substring(0, parentRelPath.length() - 1) : parentRelPath);
166            result.put("skinName", skinName);
167        }
168        
169        return result;
170    }
171
172
173    /**
174     * Delete a file or a directory
175     * @param skinName the name of the current skin
176     * @param relPath the path of the file or directory
177     * @return a map of data
178     * @throws IOException if an error occurs while manipulating files
179     */
180    @Callable
181    public Map deleteFile(String skinName, String relPath) throws IOException
182    {
183        String tempDirURI = _skinHelper.getTempDirectoryURI(skinName);
184        String fileURI = tempDirURI + (relPath.length() > 0 ? "/" + relPath : "");
185        
186        Map result = _fileHelper.deleteFile(fileURI);
187        
188        // Update lock
189        Path tempDir = _skinHelper.getTempDirectory(skinName);
190        _lockManager.updateLockFile(tempDir, SKIN_EDITOR_TOOL_ID);
191        
192        return result;
193    }
194    
195    /**
196     * Move a file or a directory
197     * @param skinName the name of current skin
198     * @param srcPath the path of the file or directory
199     * @param targetPath the targeted path
200     * @return a map of data
201     * @throws IOException if something goes wrong during the source moving process
202     */
203    @Callable
204    public Map<String, Object> moveSource(String skinName, String srcPath, String targetPath) throws IOException
205    {
206        String tempDirURI = _skinHelper.getTempDirectoryURI(skinName);
207        
208        String srcFileURI = tempDirURI + (srcPath.length() > 0 ? "/" + srcPath : "");
209        String parentTargetURI = tempDirURI + (targetPath.length() > 0 ? "/" + targetPath : "");
210        
211        Map<String, Object> result = _fileHelper.moveSource(srcFileURI, parentTargetURI);
212        
213        // Update lock
214        FileSource rootDir = (FileSource) _srcResolver.resolveURI(tempDirURI);
215        _lockManager.updateLockFile(rootDir.getFile().toPath(), SKIN_EDITOR_TOOL_ID);
216
217        if (result.containsKey("uri"))
218        {
219            String folderUri = (String) result.get("uri");
220            String path = folderUri.substring(rootDir.getURI().length());
221            result.put("path", path.endsWith("/") ? path.substring(0, path.length() - 1) : path);
222            result.put("skinName", skinName);
223        }
224        
225        return result;
226    }
227    
228    /**
229     * Rename a file or a directory
230     * @param skinName the current skin name
231     * @param relPath the path of the file
232     * @param name the new name
233     * @return a map of data
234     * @throws IOException if something goes wrong when renaming the source
235     */
236    @Callable
237    public Map renameSource(String skinName, String relPath, String name) throws IOException
238    {
239        String tempDirURI = _skinHelper.getTempDirectoryURI(skinName);
240        String fileURI = tempDirURI + (relPath.length() > 0 ? "/" + relPath : "");
241        
242        Map<String, Object> result = _fileHelper.renameFile(fileURI, name);
243        
244        // Update lock
245        FileSource rootDir = null;
246        try
247        {
248            rootDir = (FileSource) _srcResolver.resolveURI(tempDirURI);
249            _lockManager.updateLockFile(rootDir.getFile().toPath(), SKIN_EDITOR_TOOL_ID);
250        }
251        finally
252        {
253            _srcResolver.release(rootDir);
254        }
255        
256        if (result.containsKey("uri"))
257        {
258            String newURI = (String) result.get("uri");
259            String path = newURI.substring(rootDir.getURI().length());
260            result.put("path", path);
261            result.put("name", name);
262            result.put("skinName", skinName);
263        }
264        
265        return result;
266    }
267}