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