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.skin;
017
018import java.io.File;
019import java.util.ArrayList;
020import java.util.HashMap;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024
025import org.apache.avalon.framework.component.Component;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.avalon.framework.service.Serviceable;
029import org.apache.commons.io.FileUtils;
030
031import org.ametys.core.right.RightManager;
032import org.ametys.core.right.RightManager.RightResult;
033import org.ametys.core.ui.Callable;
034import org.ametys.core.user.CurrentUserProvider;
035import org.ametys.core.user.UserIdentity;
036import org.ametys.plugins.skincommons.SkinEditionHelper;
037import org.ametys.plugins.skincommons.SkinLockManager;
038import org.ametys.runtime.i18n.I18nizableText;
039import org.ametys.web.repository.site.Site;
040import org.ametys.web.repository.site.SiteManager;
041import org.ametys.web.skin.Skin;
042import org.ametys.web.skin.SkinsManager;
043
044/**
045 * DAO for files and folders inside a skin directory
046 */
047public class SkinDAO implements Serviceable, Component
048{
049    /** The Avalon role */
050    public static final String ROLE = SkinDAO.class.getName();
051    
052    /** Constant for skin editor tool id */
053    public static final String SKIN_EDITOR_TOOL_ID = "uitool-skineditor";
054    
055    private static final String __WORK_MODE = "work";
056    private static final String __PROD_MODE = "prod";
057    
058    /** The lock manager */
059    protected SkinLockManager _lockManager;
060    /** The skin edition helper */
061    protected SkinEditionHelper _skinHelper;
062
063    private SkinsManager _skinManager;
064
065    private CurrentUserProvider _userProvider;
066
067    private RightManager _rightManager;
068
069    private SiteManager _siteManager;
070    
071    @Override
072    public void service(ServiceManager manager) throws ServiceException
073    {
074        _skinHelper = (SkinEditionHelper) manager.lookup(SkinEditionHelper.ROLE);
075        _lockManager = (SkinLockManager) manager.lookup(SkinLockManager.ROLE);
076        _skinManager = (SkinsManager) manager.lookup(SkinsManager.ROLE);
077        _userProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE);
078        _rightManager = (RightManager) manager.lookup(RightManager.ROLE);
079        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
080    }
081    
082    /**
083     * Get the list of skins available for a site
084     * @param siteName The site name
085     * @return the list of skins
086     */
087    @Callable
088    public List<Object> getSkinsList(String siteName) 
089    {
090        List<Object> skinsList = new ArrayList<>();
091        
092        Site site = _siteManager.getSite(siteName);
093        String currentSkinId = site.getSkinId();
094        
095        UserIdentity user = _userProvider.getUser();
096        if (_rightManager.hasRight(user, "Plugins_SkinEditor_EditAllSkin", "/cms") == RightResult.RIGHT_ALLOW)
097        {
098            Set<String> skins = _skinManager.getSkins();
099            for (String id : skins)
100            {
101                Skin skin = _skinManager.getSkin(id);
102                skinsList.add(_skin2JsonObject(skin, id.equals(currentSkinId)));
103            }
104            
105        }
106        else if (_rightManager.hasRight(user, "Plugins_SkinEditor_EditCurrentSkin", "/cms") == RightResult.RIGHT_ALLOW)
107        {
108            Skin skin = _skinManager.getSkin(currentSkinId);
109            skinsList.add(_skin2JsonObject(skin, true));
110        }
111        
112        return skinsList;
113    }
114    
115    private Map<String, Object> _skin2JsonObject (Skin skin, boolean current)
116    {
117        Map<String, Object> jsonObject = new HashMap<>();
118        
119        I18nizableText label = skin.getLabel();
120        String icon = skin.getLargeImage();
121        
122        jsonObject.put("id", skin.getId());
123        jsonObject.put("current", current);
124        jsonObject.put("label", label);
125        jsonObject.put("icon", icon);
126        
127        return jsonObject;
128    }
129    
130    /**
131     * Open a skin for editing
132     * @param skinId the skin id
133     * @param mode the edition mode
134     * @param unlinkModel True to remove any existing change
135     * @return the skin id
136     * @throws Exception if an error occurs during the skin opening process
137     */
138    @Callable
139    public String openSkin(String skinId, String mode, boolean unlinkModel) throws Exception
140    {
141        File tempDir = _skinHelper.getTempDirectory(skinId);
142        File workDir = _skinHelper.getWorkDirectory(skinId);
143        File skinDir = _skinHelper.getSkinDirectory(skinId);
144        
145        if (unlinkModel)
146        {
147            unlinkModel (skinDir);
148            unlinkModel(workDir);
149            unlinkModel(tempDir);
150        }
151        
152        if (__PROD_MODE.equals(mode) || __WORK_MODE.equals(mode))
153        {
154            // Delete temp directory if exists
155            if (tempDir.exists())
156            {
157                _skinHelper.deleteQuicklyDirectory(tempDir);
158            }
159            
160            if (__PROD_MODE.equals(mode))
161            {
162                // Delete work directory if exists
163                if (workDir.exists())
164                {
165                    _skinHelper.deleteQuicklyDirectory(workDir);
166                }
167                
168                // Copy from skin
169                FileUtils.copyDirectory(skinDir, workDir);
170            }
171                    
172            // Copy work in temp
173            FileUtils.copyDirectory(workDir, tempDir);
174            
175            // Create .lock file
176            _lockManager.updateLockFile(tempDir, SKIN_EDITOR_TOOL_ID);
177        }
178        else
179        {
180            // Update .lock file
181            _lockManager.updateLockFile(tempDir, SKIN_EDITOR_TOOL_ID);
182        }
183        
184        return skinId;
185    }
186    
187    /**
188     * Unlink model
189     * @param skinDir The skin directory
190     */
191    protected void unlinkModel (File skinDir)
192    {
193        File modelFile = new File (skinDir, "model.xml");
194        File bakFile = new File (skinDir, "model.xml.bak");
195        
196        if (bakFile.exists())
197        {
198            // Delete old bak file if exists
199            bakFile.delete();
200        }
201        
202        if (modelFile.exists())
203        {
204            modelFile.renameTo(bakFile);
205        }
206    }
207}