001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.gwt;
029
030import org.opencms.file.types.CmsResourceTypeUnknownFile;
031import org.opencms.gwt.shared.CmsGwtConstants;
032import org.opencms.main.CmsEvent;
033import org.opencms.main.I_CmsEventListener;
034import org.opencms.main.OpenCms;
035import org.opencms.workplace.CmsWorkplace;
036import org.opencms.workplace.explorer.CmsExplorerTypeSettings;
037import org.opencms.workplace.explorer.CmsIconRule;
038
039import java.util.Map;
040
041/**
042 * Utility class to generate the resource icon CSS.<p>
043 *
044 * @since 8.0.0
045 */
046public final class CmsIconUtil extends org.opencms.gwt.shared.CmsIconUtil implements I_CmsEventListener {
047
048    /**
049     * Inner helper class for building the CSS rules.<p>
050     */
051    public static class CssBuilder {
052
053        /** The buffer into which the CSS is written. */
054        private StringBuffer m_buffer = new StringBuffer(1024);
055
056        /**
057         * Builds the CSS for all resource types.<p>
058         *
059         * @return a string containing the CSS rules for all resource types
060         */
061        public String buildResourceIconCss() {
062
063            m_buffer.append(buildUnknownIconCss());
064            for (CmsExplorerTypeSettings type : OpenCms.getWorkplaceManager().getExplorerTypeSettings()) {
065                addCssForType(type);
066            }
067            addPseudoTypes();
068            addResourceNotFoundIconRule();
069            return m_buffer.toString();
070        }
071
072        /**
073         * Builds the CSS for the icon for unknown resource types.<p>
074         *
075         * @return the CSS for unknown resource type icons
076         */
077        public String buildUnknownIconCss() {
078
079            String unknown = getIconUri(
080                OpenCms.getWorkplaceManager().getExplorerTypeSetting(
081                    CmsResourceTypeUnknownFile.getStaticTypeName()).getBigIconIfAvailable());
082            String template = "div.%1$s { background: transparent scroll 50%% 50%% no-repeat url(\"%2$s\");} ";
083
084            return String.format(template, TYPE_ICON_CLASS, unknown);
085        }
086
087        /**
088         * Writes the CSS for a single icon rule to a buffer.<p>
089         *
090         * @param typeName the name of the resource type
091         * @param rule the icon rule
092         */
093        private void addCssForIconRule(String typeName, CmsIconRule rule) {
094
095            String extension = rule.getExtension();
096            if (rule.getBigIcon() != null) {
097                CmsIconCssRuleBuilder cssBig = new CmsIconCssRuleBuilder();
098                cssBig.addSelectorForSubType(typeName, extension, false);
099                cssBig.setImageUri(getIconUri(rule.getBigIcon()));
100                cssBig.writeCss(m_buffer);
101
102                CmsIconCssRuleBuilder cssSmall = new CmsIconCssRuleBuilder();
103                cssSmall.addSelectorForSubType(typeName, extension, true);
104                cssSmall.setImageUri(getIconUri(rule.getIcon()));
105                cssSmall.writeCss(m_buffer);
106
107            } else {
108                CmsIconCssRuleBuilder css = new CmsIconCssRuleBuilder();
109                css.addSelectorForSubType(typeName, extension, false);
110                css.addSelectorForSubType(typeName, extension, true);
111                css.setImageUri(getIconUri(rule.getIcon()));
112                css.writeCss(m_buffer);
113
114            }
115        }
116
117        /**
118         * Helper method for appending the CSS for a single resource type to a buffer.<p>
119         *
120         * @param explorerType the explorer type for which the CSS should be generated
121         */
122        private void addCssForType(CmsExplorerTypeSettings explorerType) {
123
124            String typeName = explorerType.getName();
125            if (explorerType.getBigIcon() != null) {
126                CmsIconCssRuleBuilder css = new CmsIconCssRuleBuilder();
127                css.setImageUri(getIconUri(explorerType.getBigIcon()));
128                css.addSelectorForType(typeName, false);
129                css.writeCss(m_buffer);
130
131                CmsIconCssRuleBuilder cssSmall = new CmsIconCssRuleBuilder();
132                cssSmall.setImageUri(getIconUri(explorerType.getIcon()));
133                cssSmall.addSelectorForType(typeName, true);
134                cssSmall.writeCss(m_buffer);
135            } else if (explorerType.getOriginalIcon() != null) {
136                CmsIconCssRuleBuilder css = new CmsIconCssRuleBuilder();
137                css.setImageUri(getIconUri(explorerType.getIcon()));
138                css.addSelectorForType(typeName, true);
139                css.addSelectorForType(typeName, false);
140                css.writeCss(m_buffer);
141            } else {
142                CmsIconCssRuleBuilder css = new CmsIconCssRuleBuilder();
143                css.setImageUri(getIconUri(CmsExplorerTypeSettings.DEFAULT_BIG_ICON));
144                css.addSelectorForType(typeName, false);
145                css.writeCss(m_buffer);
146
147                CmsIconCssRuleBuilder cssSmall = new CmsIconCssRuleBuilder();
148                cssSmall.setImageUri(getIconUri(CmsExplorerTypeSettings.DEFAULT_NORMAL_ICON));
149                cssSmall.addSelectorForType(typeName, true);
150                cssSmall.writeCss(m_buffer);
151            }
152
153            Map<String, CmsIconRule> iconRules = explorerType.getIconRules();
154            for (Map.Entry<String, CmsIconRule> entry : iconRules.entrySet()) {
155                CmsIconRule rule = entry.getValue();
156                addCssForIconRule(typeName, rule);
157            }
158        }
159
160        /**
161         * Adds icon rule for pseudo resource types.<p>
162         */
163        private void addPseudoTypes() {
164
165            CmsExplorerTypeSettings navlevel = new CmsExplorerTypeSettings();
166            navlevel.setName(CmsGwtConstants.TYPE_NAVLEVEL);
167            navlevel.setIcon(ICON_NAV_LEVEL_SMALL);
168            navlevel.setBigIcon(ICON_NAV_LEVEL_BIG);
169            addCssForType(navlevel);
170            CmsExplorerTypeSettings modelgroupReuse = new CmsExplorerTypeSettings();
171            modelgroupReuse.setName(CmsGwtConstants.TYPE_MODELGROUP_REUSE);
172            modelgroupReuse.setIcon(ICON_MODEL_GROUP_REUSE_SMALL);
173            modelgroupReuse.setBigIcon(ICON_MODEL_GROUP_REUSE_BIG);
174            addCssForType(modelgroupReuse);
175            CmsExplorerTypeSettings modelgroupPage = new CmsExplorerTypeSettings();
176            modelgroupPage.setName(CmsGwtConstants.TYPE_MODELGROUP_PAGE);
177            modelgroupPage.setIcon(ICON_MODEL_GROUP_SMALL);
178            modelgroupPage.setBigIcon(ICON_MODEL_GROUP_BIG);
179            addCssForType(modelgroupPage);
180        }
181
182        /**
183         * Adds an icon rule for resource not found.<p>
184         */
185        private void addResourceNotFoundIconRule() {
186
187            CmsIconCssRuleBuilder cssBig = new CmsIconCssRuleBuilder();
188            cssBig.addSelectorForType(TYPE_RESOURCE_NOT_FOUND, false);
189            cssBig.setImageUri(getIconUri(NOT_FOUND_ICON_BIG));
190            cssBig.writeCss(m_buffer);
191
192            CmsIconCssRuleBuilder cssSmall = new CmsIconCssRuleBuilder();
193            cssSmall.addSelectorForType(TYPE_RESOURCE_NOT_FOUND, true);
194            cssSmall.setImageUri(getIconUri(NOT_FOUND_ICON_SMALL));
195            cssSmall.writeCss(m_buffer);
196        }
197
198        /**
199         * Converts an icon file name to a full icon URI.<p>
200         *
201         * @param icon the file name of the icon
202         *
203         * @return the full icon uri
204         */
205        private String getIconUri(String icon) {
206
207            return CmsWorkplace.getResourceUri(CmsWorkplace.RES_PATH_FILETYPES + icon);
208        }
209
210    }
211
212    /** Pseudo type icon. */
213    public static final String ICON_MODEL_GROUP_BIG = "modelpage_groups_big.png";
214
215    /** Pseudo type icon. */
216    public static final String ICON_MODEL_GROUP_REUSE_BIG = "modelgroup_reuse_big.png";
217
218    /** Pseudo type icon. */
219    public static final String ICON_MODEL_GROUP_REUSE_SMALL = "modelgroup_reuse.png";
220
221    /** Pseudo type icon. */
222    public static final String ICON_MODEL_GROUP_SMALL = "modelpage_groups.png";
223
224    /** Pseudo type icon. */
225    public static final String ICON_NAV_LEVEL_BIG = "navlevel_big.png";
226
227    /** Pseudo type icon. */
228    public static final String ICON_NAV_LEVEL_SMALL = "navlevel.png";
229
230    /** The big resource not found icon name. */
231    public static final String NOT_FOUND_ICON_BIG = "resourceNotFoundBig.png";
232
233    /** The small resource not found icon name. */
234    public static final String NOT_FOUND_ICON_SMALL = "resourceNotFoundSmall.png";
235
236    /** The cached CSS. */
237    private static String m_cachedCss;
238
239    /** Flag indicating the 'clear caches' event listener has been registered. */
240    private static boolean m_listenerRegistered;
241
242    /**
243     * Constructor.<p>
244     */
245    private CmsIconUtil() {
246
247    }
248
249    /**
250     * Builds the CSS for all resource types.<p>
251     *
252     * @return a string containing the CSS rules for all resource types
253     */
254    public static String buildResourceIconCss() {
255
256        if (!m_listenerRegistered) {
257            registerListener();
258        }
259        if (m_cachedCss == null) {
260            rebuildCss();
261        }
262        return m_cachedCss;
263    }
264
265    /**
266     * Rebuilds the icon CSS.<p>
267     */
268    private static synchronized void rebuildCss() {
269
270        if (m_cachedCss == null) {
271            CssBuilder builder = new CssBuilder();
272            m_cachedCss = builder.buildResourceIconCss();
273        }
274    }
275
276    /**
277     * Registers the 'clear caches' event listener.<p>
278     */
279    private static synchronized void registerListener() {
280
281        if (!m_listenerRegistered) {
282            OpenCms.getEventManager().addCmsEventListener(
283                new CmsIconUtil(),
284                new int[] {I_CmsEventListener.EVENT_CLEAR_CACHES});
285            m_listenerRegistered = true;
286        }
287    }
288
289    /**
290     * @see org.opencms.main.I_CmsEventListener#cmsEvent(org.opencms.main.CmsEvent)
291     */
292    public void cmsEvent(CmsEvent event) {
293
294        m_cachedCss = null;
295    }
296
297}