001/*
002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Anahide Tchertchian
016 */
017package org.nuxeo.theme.styling.service.descriptors;
018
019import java.io.Serializable;
020import java.util.ArrayList;
021import java.util.List;
022
023import org.apache.commons.lang.builder.EqualsBuilder;
024import org.nuxeo.common.xmap.annotation.XNode;
025import org.nuxeo.common.xmap.annotation.XNodeList;
026import org.nuxeo.common.xmap.annotation.XObject;
027
028/**
029 * A flavor represents the set of information that can be used to switch the theme styling on a given page.
030 * <p>
031 * It holds presets that can be referenced in CSS files, as well as logo information. It can extend another flavor, in
032 * case it will its logo and presets. The name and label are not inherited.
033 * <p>
034 * At registration, presets and log information are merged of a previous contribution with the same name already held
035 * that kind of information. When emptying the list of presets.
036 *
037 * @since 5.5
038 */
039@XObject("flavor")
040public class FlavorDescriptor implements Serializable {
041
042    private static final long serialVersionUID = 1L;
043
044    @XNode("@name")
045    String name;
046
047    @XNode("label")
048    String label;
049
050    @XNode("@extends")
051    String extendsFlavor;
052
053    @XNode("logo")
054    LogoDescriptor logo;
055
056    @XNode("palettePreview")
057    PalettePreview palettePreview;
058
059    /**
060     * @since 7.4
061     */
062    @XNode("sass@append")
063    boolean appendSass;
064
065    @XNode("presetsList@append")
066    boolean appendPresets;
067
068    /**
069     * @since 7.4
070     */
071    @XNodeList(value = "sass/import", type = ArrayList.class, componentType = SassImport.class)
072    List<SassImport> sassImports;
073
074    @XNodeList(value = "presetsList/presets", type = ArrayList.class, componentType = FlavorPresets.class)
075    List<FlavorPresets> presets;
076
077    /**
078     * @since 7.4
079     */
080    @XNodeList(value = "links/icon", type = ArrayList.class, componentType = IconDescriptor.class)
081    List<IconDescriptor> favicons;
082
083    @Override
084    public FlavorDescriptor clone() {
085        FlavorDescriptor clone = new FlavorDescriptor();
086        clone.setName(getName());
087        clone.setLabel(getLabel());
088        LogoDescriptor logo = getLogo();
089        if (logo != null) {
090            clone.setLogo(logo.clone());
091        }
092        PalettePreview pp = getPalettePreview();
093        if (pp != null) {
094            clone.setPalettePreview(pp.clone());
095        }
096        clone.setExtendsFlavor(getExtendsFlavor());
097        clone.setAppendPresets(getAppendPresets());
098        List<FlavorPresets> presets = getPresets();
099        if (presets != null) {
100            List<FlavorPresets> newPresets = new ArrayList<FlavorPresets>();
101            for (FlavorPresets item : presets) {
102                newPresets.add(item.clone());
103            }
104            clone.setPresets(newPresets);
105        }
106        clone.setAppendSass(getAppendSass());
107        List<SassImport> sassVariables = getSassImports();
108        if (sassVariables != null) {
109            List<SassImport> cSassVariables = new ArrayList<SassImport>();
110            for (SassImport var : sassVariables) {
111                cSassVariables.add(var.clone());
112            }
113            clone.setSassImports(cSassVariables);
114        }
115        List<IconDescriptor> favicons = getFavicons();
116        if (favicons != null) {
117            List<IconDescriptor> icons = new ArrayList<IconDescriptor>();
118            for (IconDescriptor icon : favicons) {
119                icons.add(icon.clone());
120            }
121            clone.setFavicons(icons);
122        }
123        return clone;
124    }
125
126    @Override
127    public boolean equals(Object obj) {
128        if (!(obj instanceof FlavorDescriptor)) {
129            return false;
130        }
131        if (obj == this) {
132            return true;
133        }
134        FlavorDescriptor f = (FlavorDescriptor) obj;
135        return new EqualsBuilder().append(name, f.name).append(label, f.label).append(extendsFlavor,
136                f.extendsFlavor).append(logo, f.logo).append(palettePreview, f.palettePreview).append(appendPresets,
137                        f.appendPresets).append(presets, f.presets).append(appendSass, f.appendSass).append(sassImports,
138                                f.sassImports).append(favicons, f.favicons).isEquals();
139    }
140
141    public boolean getAppendPresets() {
142        return appendPresets;
143    }
144
145    /**
146     * @since 7.4
147     */
148    public boolean getAppendSass() {
149        return appendSass;
150    }
151
152    public String getExtendsFlavor() {
153        return extendsFlavor;
154    }
155
156    /**
157     * @since 7.4
158     */
159    public List<IconDescriptor> getFavicons() {
160        return favicons;
161    }
162
163    public String getLabel() {
164        return label;
165    }
166
167    public LogoDescriptor getLogo() {
168        return logo;
169    }
170
171    public String getName() {
172        return name;
173    }
174
175    public PalettePreview getPalettePreview() {
176        return palettePreview;
177    }
178
179    public List<FlavorPresets> getPresets() {
180        return presets;
181    }
182
183    /**
184     * @since 7.4
185     */
186    public List<SassImport> getSassImports() {
187        return sassImports;
188    }
189
190    @Override
191    public int hashCode() {
192        final int prime = 31;
193        int result = 1;
194        result = prime * result + (appendPresets ? 1231 : 1237);
195        result = prime * result + (appendSass ? 1231 : 1237);
196        result = prime * result + ((extendsFlavor == null) ? 0 : extendsFlavor.hashCode());
197        result = prime * result + ((favicons == null) ? 0 : favicons.hashCode());
198        result = prime * result + ((label == null) ? 0 : label.hashCode());
199        result = prime * result + ((logo == null) ? 0 : logo.hashCode());
200        result = prime * result + ((name == null) ? 0 : name.hashCode());
201        result = prime * result + ((palettePreview == null) ? 0 : palettePreview.hashCode());
202        result = prime * result + ((presets == null) ? 0 : presets.hashCode());
203        result = prime * result + ((sassImports == null) ? 0 : sassImports.hashCode());
204        return result;
205    }
206
207    public void merge(FlavorDescriptor src) {
208        String newExtend = src.getExtendsFlavor();
209        if (newExtend != null) {
210            setExtendsFlavor(newExtend);
211        }
212        String newLabel = src.getLabel();
213        if (newLabel != null) {
214            setLabel(newLabel);
215        }
216        LogoDescriptor logo = src.getLogo();
217        if (logo != null) {
218            LogoDescriptor newLogo = getLogo();
219            if (newLogo == null) {
220                newLogo = logo.clone();
221            } else {
222                // merge logo info
223                if (logo.getHeight() != null) {
224                    newLogo.setHeight(logo.getHeight());
225                }
226                if (logo.getWidth() != null) {
227                    newLogo.setWidth(logo.getWidth());
228                }
229                if (logo.getTitle() != null) {
230                    newLogo.setTitle(logo.getTitle());
231                }
232                if (logo.getPath() != null) {
233                    newLogo.setPath(logo.getPath());
234                }
235            }
236            setLogo(newLogo);
237        }
238        PalettePreview pp = src.getPalettePreview();
239        if (pp != null) {
240            setPalettePreview(pp);
241        }
242
243        List<FlavorPresets> newPresets = src.getPresets();
244        if (newPresets != null) {
245            List<FlavorPresets> merged = new ArrayList<FlavorPresets>();
246            merged.addAll(newPresets);
247            boolean keepOld = src.getAppendPresets() || (newPresets.isEmpty() && !src.getAppendPresets());
248            if (keepOld) {
249                // add back old contributions
250                List<FlavorPresets> oldPresets = getPresets();
251                if (oldPresets != null) {
252                    merged.addAll(0, oldPresets);
253                }
254            }
255            setPresets(merged);
256        }
257
258        List<SassImport> newSassImports = src.getSassImports();
259        if (newSassImports != null) {
260            List<SassImport> merged = new ArrayList<SassImport>();
261            merged.addAll(newSassImports);
262            boolean keepOld = src.getAppendSass() || (newSassImports.isEmpty() && !src.getAppendSass());
263            if (keepOld) {
264                // add back old contributions
265                List<SassImport> oldSassImports = getSassImports();
266                if (oldSassImports != null) {
267                    merged.addAll(0, oldSassImports);
268                }
269            }
270            setSassImports(merged);
271        }
272
273        List<IconDescriptor> newFavicons = src.getFavicons();
274        if (newFavicons != null && !newFavicons.isEmpty()) {
275            setFavicons(newFavicons);
276        }
277
278    }
279
280    public void setAppendPresets(boolean appendPresets) {
281        this.appendPresets = appendPresets;
282    }
283
284    /**
285     * @since 7.4
286     */
287    public void setAppendSass(boolean appendSass) {
288        this.appendSass = appendSass;
289    }
290
291    public void setExtendsFlavor(String extendsFlavor) {
292        this.extendsFlavor = extendsFlavor;
293    }
294
295    /**
296     * @since 7.4
297     */
298    public void setFavicons(List<IconDescriptor> favicons) {
299        this.favicons = favicons;
300    }
301
302    public void setLabel(String label) {
303        this.label = label;
304    }
305
306    public void setLogo(LogoDescriptor logo) {
307        this.logo = logo;
308    }
309
310    public void setName(String name) {
311        this.name = name;
312    }
313
314    public void setPalettePreview(PalettePreview palettePreview) {
315        this.palettePreview = palettePreview;
316    }
317
318    public void setPresets(List<FlavorPresets> presets) {
319        this.presets = presets;
320    }
321
322    /**
323     * @since 7.4
324     */
325    public void setSassImports(List<SassImport> sassImports) {
326        this.sassImports = sassImports;
327    }
328
329}