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