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            CmsExplorerTypeSettings navlevel = new CmsExplorerTypeSettings();
068            navlevel.setName(CmsGwtConstants.TYPE_NAVLEVEL);
069            navlevel.setIcon("navlevel.png");
070            addCssForType(navlevel);
071            addResourceNotFoundIconRule();
072            return m_buffer.toString();
073        }
074
075        /**
076         * Builds the CSS for the icon for unknown resource types.<p>
077         * 
078         * @return the CSS for unknown resource type icons
079         */
080        public String buildUnknownIconCss() {
081
082            String unknown = getIconUri(OpenCms.getWorkplaceManager().getExplorerTypeSetting(
083                CmsResourceTypeUnknownFile.getStaticTypeName()).getBigIconIfAvailable());
084            String template = "div.%1$s { background: transparent scroll 50%% 50%% no-repeat url(\"%2$s\");} ";
085
086            return String.format(template, TYPE_ICON_CLASS, unknown);
087        }
088
089        /**
090         * Writes the CSS for a single icon rule to a buffer.<p>
091         * 
092         * @param typeName the name of the resource type 
093         * @param rule the icon rule 
094         */
095        private void addCssForIconRule(String typeName, CmsIconRule rule) {
096
097            String extension = rule.getExtension();
098            if (rule.getBigIcon() != null) {
099                CmsIconCssRuleBuilder cssBig = new CmsIconCssRuleBuilder();
100                cssBig.addSelectorForSubType(typeName, extension, false);
101                cssBig.setImageUri(getIconUri(rule.getBigIcon()));
102                cssBig.writeCss(m_buffer);
103
104                CmsIconCssRuleBuilder cssSmall = new CmsIconCssRuleBuilder();
105                cssSmall.addSelectorForSubType(typeName, extension, true);
106                cssSmall.setImageUri(getIconUri(rule.getIcon()));
107                cssSmall.writeCss(m_buffer);
108
109            } else {
110                CmsIconCssRuleBuilder css = new CmsIconCssRuleBuilder();
111                css.addSelectorForSubType(typeName, extension, false);
112                css.addSelectorForSubType(typeName, extension, true);
113                css.setImageUri(getIconUri(rule.getIcon()));
114                css.writeCss(m_buffer);
115
116            }
117        }
118
119        /**
120         * Helper method for appending the CSS for a single resource type to a buffer.<p>
121         * 
122         * @param explorerType the explorer type for which the CSS should be generated 
123         */
124        private void addCssForType(CmsExplorerTypeSettings explorerType) {
125
126            String typeName = explorerType.getName();
127            if (explorerType.getBigIcon() != null) {
128                CmsIconCssRuleBuilder css = new CmsIconCssRuleBuilder();
129                css.setImageUri(getIconUri(explorerType.getBigIcon()));
130                css.addSelectorForType(typeName, false);
131                css.writeCss(m_buffer);
132
133                CmsIconCssRuleBuilder cssSmall = new CmsIconCssRuleBuilder();
134                cssSmall.setImageUri(getIconUri(explorerType.getIcon()));
135                cssSmall.addSelectorForType(typeName, true);
136                cssSmall.writeCss(m_buffer);
137            } else if (explorerType.getOriginalIcon() != null) {
138                CmsIconCssRuleBuilder css = new CmsIconCssRuleBuilder();
139                css.setImageUri(getIconUri(explorerType.getIcon()));
140                css.addSelectorForType(typeName, true);
141                css.addSelectorForType(typeName, false);
142                css.writeCss(m_buffer);
143            } else {
144                CmsIconCssRuleBuilder css = new CmsIconCssRuleBuilder();
145                css.setImageUri(getIconUri(CmsExplorerTypeSettings.DEFAULT_BIG_ICON));
146                css.addSelectorForType(typeName, false);
147                css.writeCss(m_buffer);
148
149                CmsIconCssRuleBuilder cssSmall = new CmsIconCssRuleBuilder();
150                cssSmall.setImageUri(getIconUri(CmsExplorerTypeSettings.DEFAULT_NORMAL_ICON));
151                cssSmall.addSelectorForType(typeName, true);
152                cssSmall.writeCss(m_buffer);
153            }
154
155            Map<String, CmsIconRule> iconRules = explorerType.getIconRules();
156            for (Map.Entry<String, CmsIconRule> entry : iconRules.entrySet()) {
157                CmsIconRule rule = entry.getValue();
158                addCssForIconRule(typeName, rule);
159            }
160        }
161
162        /**
163         * Adds an icon rule for resource not found.<p>
164         */
165        private void addResourceNotFoundIconRule() {
166
167            CmsIconCssRuleBuilder cssBig = new CmsIconCssRuleBuilder();
168            cssBig.addSelectorForType(TYPE_RESOURCE_NOT_FOUND, false);
169            cssBig.setImageUri(getIconUri(NOT_FOUND_ICON_BIG));
170            cssBig.writeCss(m_buffer);
171
172            CmsIconCssRuleBuilder cssSmall = new CmsIconCssRuleBuilder();
173            cssSmall.addSelectorForType(TYPE_RESOURCE_NOT_FOUND, true);
174            cssSmall.setImageUri(getIconUri(NOT_FOUND_ICON_SMALL));
175            cssSmall.writeCss(m_buffer);
176        }
177
178        /**
179         * Converts an icon file name to a full icon URI.<p>
180         * 
181         * @param icon the file name of the icon
182         * 
183         * @return the full icon uri 
184         */
185        private String getIconUri(String icon) {
186
187            return CmsWorkplace.getResourceUri(CmsWorkplace.RES_PATH_FILETYPES + icon);
188        }
189
190    }
191
192    /** The big resource not found icon name. */
193    public static final String NOT_FOUND_ICON_BIG = "resourceNotFoundBig.png";
194
195    /** The small resource not found icon name. */
196    public static final String NOT_FOUND_ICON_SMALL = "resourceNotFoundSmall.png";
197
198    /** The cached CSS. */
199    private static String m_cachedCss;
200
201    /** Flag indicating the 'clear caches' event listener has been registered. */
202    private static boolean m_listenerRegistered;
203
204    /**
205     * Constructor.<p>
206     */
207    private CmsIconUtil() {
208
209    }
210
211    /**
212     * Builds the CSS for all resource types.<p>
213     * 
214     * @return a string containing the CSS rules for all resource types 
215     */
216    public static String buildResourceIconCss() {
217
218        if (!m_listenerRegistered) {
219            registerListener();
220        }
221        if (m_cachedCss == null) {
222            rebuildCss();
223        }
224        return m_cachedCss;
225    }
226
227    /**
228     * Rebuilds the icon CSS.<p>
229     */
230    private static synchronized void rebuildCss() {
231
232        if (m_cachedCss == null) {
233            CssBuilder builder = new CssBuilder();
234            m_cachedCss = builder.buildResourceIconCss();
235        }
236    }
237
238    /**
239     * Registers the 'clear caches' event listener.<p>
240     */
241    private static synchronized void registerListener() {
242
243        if (!m_listenerRegistered) {
244            OpenCms.getEventManager().addCmsEventListener(
245                new CmsIconUtil(),
246                new int[] {I_CmsEventListener.EVENT_CLEAR_CACHES});
247            m_listenerRegistered = true;
248        }
249    }
250
251    /**
252     * @see org.opencms.main.I_CmsEventListener#cmsEvent(org.opencms.main.CmsEvent)
253     */
254    public void cmsEvent(CmsEvent event) {
255
256        m_cachedCss = null;
257    }
258
259}