001/*
002 *  Copyright 2011 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.skinfactory.parameters;
017
018import java.io.IOException;
019import java.nio.file.Files;
020import java.nio.file.Path;
021import java.util.HashMap;
022import java.util.List;
023import java.util.Map;
024import java.util.stream.Stream;
025
026import org.apache.cocoon.xml.AttributesImpl;
027import org.apache.cocoon.xml.XMLUtils;
028import org.xml.sax.ContentHandler;
029import org.xml.sax.SAXException;
030
031import org.ametys.core.util.path.PathUtils;
032import org.ametys.runtime.i18n.I18nizableText;
033import org.ametys.skinfactory.filefilter.FileFilter;
034import org.ametys.web.skin.SkinModel;
035
036/**
037 * Implementation of {@link AbstractSkinParameter} for a variant
038 */
039public class VariantParameter extends AbstractSkinParameter
040{
041    private String _iconGlyph;
042    private String _iconSmall;
043    private String _iconLarge;
044    private List<Variant> _variants;
045    
046    
047    /**
048     * Constructor
049     * @param id the unique id
050     * @param label the label
051     * @param description the description
052     * @param variants the list of values for this variant
053     */
054    public VariantParameter(String id, I18nizableText label, I18nizableText description, List<Variant> variants)
055    {
056        super(id, label, description);
057        _variants = variants;
058    }
059    
060    /**
061     * Constructor
062     * @param id the unique id
063     * @param label the label
064     * @param description the description
065     * @param iconGlyph The CSS classe for icon, to use instead of small and large icon
066     * @param iconSmall The small icon
067     * @param iconLarge The large icon
068     * @param variants the list of values for this variant
069     */
070    public VariantParameter(String id, I18nizableText label, I18nizableText description, String iconGlyph, String iconSmall, String iconLarge, List<Variant> variants)
071    {
072        super(id, label, description);
073        _iconGlyph = iconGlyph;
074        _iconSmall = iconSmall;
075        _iconLarge = iconLarge;
076        _variants = variants;
077    }
078    
079    @Override
080    public SkinParameterType getType()
081    {
082        return SkinParameterType.VARIANT;
083    }
084    /**
085     * Get the variants
086     * @return The variants
087     */
088    public List<Variant> getVariants()
089    {
090        return _variants;
091    }
092    
093    /**
094     * Set the CSS icon
095     * @param iconGlyph the CSS icon
096     */
097    public void setIconGlyph(String iconGlyph)
098    {
099        _iconGlyph = iconGlyph;
100    }
101    
102    /**
103     * Get the CSS icon
104     * @return The CSS icon
105     */
106    public String getIconGlyph ()
107    {
108        return _iconGlyph;
109    }
110    
111    /**
112     * Set the small icon relative path
113     * @param iconSmall the small icon
114     */
115    public void setIconSmall(String iconSmall)
116    {
117        _iconSmall = iconSmall;
118    }
119    
120    /**
121     * Get the small icon
122     * @return The small icon
123     */
124    public String getIconSmall ()
125    {
126        return _iconSmall;
127    }
128    
129    /**
130     * Set the large icon relative path
131     * @param iconLarge the large icon
132     */
133    public void setIconLarge(String iconLarge)
134    {
135        _iconLarge = iconLarge;
136    }
137    
138    /**
139     * Get the large icon
140     * @return The large icon
141     */
142    public String getIconLarge ()
143    {
144        return _iconLarge;
145    }
146    
147    @Override
148    public void apply(Path tempDir, Path modelDir, Object value, String lang) throws SkinParameterException
149    {
150        Path variantFile = modelDir.resolve("model/variants/" + this._id);
151        Path srcFile = variantFile.resolve((String) value);
152        
153        try
154        {
155            // Copy variant files recursively excluding CVS and .svn directories
156            PathUtils.copyDirectory(srcFile, tempDir, FileFilter.getModelVariantFilter((String) value, srcFile), false);
157        }
158        catch (IOException e)
159        {
160            throw new SkinParameterException ("Unable to apply variant parameter '" + getId() + "'", e);
161        }
162    }
163
164    @Override
165    public void toSAX(ContentHandler contentHandler, String modelName) throws SAXException
166    {
167        AttributesImpl attrs = new AttributesImpl();
168        attrs.addCDATAAttribute("id", getId());
169        attrs.addCDATAAttribute("type", SkinParameterType.VARIANT.name().toLowerCase());
170        
171        XMLUtils.startElement(contentHandler, "parameter", attrs);
172        
173        getLabel().toSAX(contentHandler, "label");
174        getDescription().toSAX(contentHandler, "description");
175        
176        if (getIconGlyph() != null)
177        {
178            XMLUtils.createElement(contentHandler, "iconGlyph", getIconGlyph());
179        }
180        
181        if (getIconSmall() != null)
182        {
183            XMLUtils.createElement(contentHandler, "iconSmall", "/plugins/skinfactory/" + modelName + "/_thumbnail/16/16/model/variants/" + this._id + "/" + getIconSmall());
184        }
185        else
186        {
187            XMLUtils.createElement(contentHandler, "iconSmall", "/plugins/skinfactory/resources/img/variant_default_16.png");
188        }
189        
190        if (getIconLarge() != null)
191        {
192            XMLUtils.createElement(contentHandler, "iconLarge", "/plugins/skinfactory/" + modelName + "/_thumbnail/32/32/model/variants/" + this._id + "/" + getIconLarge());
193        }
194        else
195        {
196            XMLUtils.createElement(contentHandler, "iconLarge", "/plugins/skinfactory/resources/img/variant_default_32.png");
197        }
198        
199        XMLUtils.endElement(contentHandler, "parameter");
200        
201    }
202
203    @Override
204    public Map<String, Object> toJson(String modelName)
205    {
206        Map<String, Object> jsonObject = new HashMap<>();
207        
208        jsonObject.put("id", getId());
209        jsonObject.put("type", SkinParameterType.VARIANT.name().toLowerCase());
210        
211        jsonObject.put("label", getLabel());
212        jsonObject.put("description", getDescription());
213        
214        if (getIconGlyph() != null)
215        {
216            jsonObject.put("iconGlyph", getIconGlyph());
217        }
218        
219        if (getIconSmall() != null)
220        {
221            jsonObject.put("iconSmall", "/plugins/skinfactory/" + modelName + "/_thumbnail/16/16/model/variants/" + this._id + "/" + getIconSmall());
222        }
223        else
224        {
225            jsonObject.put("iconSmall", "/plugins/skinfactory/resources/img/variant_default_16.png");
226        }
227        
228        if (getIconLarge() != null)
229        {
230            jsonObject.put("iconLarge", "/plugins/skinfactory/" + modelName + "/_thumbnail/32/32/model/variants/" + this._id + "/" + getIconLarge());
231        }
232        else
233        {
234            jsonObject.put("iconLarge", "/plugins/skinfactory/resources/img/variant_default_32.png");
235        }
236        
237        return jsonObject;
238    }
239    
240    @Override
241    public String getDefaultValue(SkinModel model)
242    {
243        try
244        {
245            Path variantFile = model.getPath().resolve("model/variants/" + this._id);
246            try (Stream<Path> files = Files.list(variantFile))
247            {
248                return files
249                        .filter(FileFilter.getSkinDirectoryFilter())
250                        .findFirst()
251                        .map(f -> f.getFileName().toString())
252                        .orElse(null);
253            }
254            
255        }
256        catch (IOException e)
257        {
258            throw new RuntimeException("Cannot get default value for variant " + this._id + " of model " + model.getId(), e);
259        }
260    }
261    
262    @Override
263    public String getDefaultValue(SkinModel model, String lang)
264    {
265        return getDefaultValue(model);
266    }
267}