001    package org.apache.turbine.services.pull.tools;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.commons.logging.Log;
023    import org.apache.commons.logging.LogFactory;
024    import org.apache.turbine.om.security.User;
025    import org.apache.turbine.pipeline.PipelineData;
026    import org.apache.turbine.services.pull.ApplicationTool;
027    import org.apache.turbine.services.ui.TurbineUI;
028    import org.apache.turbine.services.ui.UIService;
029    import org.apache.turbine.util.RunData;
030    import org.apache.turbine.util.ServerData;
031    
032    /**
033     * Manages all UI elements for a Turbine Application. Any UI element can be
034     * accessed in any template using the $ui handle (assuming you use the default
035     * PullService configuration). So, for example, you could access the background
036     * color for your pages by using $ui.bgcolor
037     * <p>
038     * This implementation provides a single level of inheritance in that if a
039     * property does not exist in a non-default skin, the value from the default
040     * skin will be used. By only requiring values different to those stored in
041     * the default skin to appear in the non-default skins the amount of memory
042     * consumed in cases where the UserManager instance is used at a non-global
043     * scope will potentially be reduced due to the fact that a shared instance of
044     * the default skin properties can be used. Note that this inheritance only
045     * applies to property values - it does not apply to any images or stylesheets
046     * that may form part of your skins.
047     * <p>
048     * This is an application pull tool for the template system. You should not
049     * use it in a normal application!  Within Java code you should use TurbineUI.
050     * <p>
051     *
052     * This is an application pull tool for the template system. You should
053     * <strong>only</strong> use it in a normal application to set the skin
054     * attribute for a user (setSkin(User user, String skin)) and to initialize it
055     * for the user, otherwise use TurbineUI is probably the way to go.
056     *
057     * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
058     * @author <a href="mailto:james_coltman@majorband.co.uk">James Coltman</a>
059     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
060     * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
061     * @version $Id$
062     * @see UIService
063     */
064    public class UITool implements ApplicationTool
065    {
066        /** Logging */
067        private static Log log = LogFactory.getLog(UITool.class);
068    
069        /**
070         * Attribute name of skinName value in User's temp hashmap.
071         */
072        public static final String SKIN_ATTRIBUTE = UITool.class.getName()+ ".skin";
073    
074        /**
075         * The actual skin being used for the webapp.
076         */
077        private String skinName;
078    
079        /**
080         * Refresh the tool.
081         */
082        public void refresh()
083        {
084            TurbineUI.refresh(getSkin());
085            log.debug("UITool refreshed for skin: " + getSkin());
086        }
087    
088        /**
089         * Provide access to the list of available skin names.
090         *
091         * @return the available skin names.
092         */
093        public String[] getSkinNames()
094        {
095            return TurbineUI.getSkinNames();
096        }
097    
098        /**
099         * Get the name of the default skin name for the web application from the
100         * TurbineResources.properties file. If the property is not present the
101         * name of the default skin will be returned.  Note that the web application
102         * skin name may be something other than default, in which case its
103         * properties will default to the skin with the name "default".
104         *
105         * @return the name of the default skin for the web application.
106         */
107        public String getWebappSkinName()
108        {
109            return TurbineUI.getWebappSkinName();
110        }
111    
112        /**
113         * Retrieve a skin property.  If the property is not defined in the current
114         * skin the value for the default skin will be provided.  If the current
115         * skin does not exist then the skin configured for the webapp will be used.
116         * If the webapp skin does not exist the default skin will be used.  If the
117         * default skin does not exist then <code>null</code> will be returned.
118         *
119         * @param key the key to retrieve from the skin.
120         * @return the value of the property for the named skin (defaulting to the
121         * default skin), the webapp skin, the default skin or <code>null</code>,
122         * depending on whether or not the property or skins exist.
123         */
124        public String get(String key)
125        {
126            return TurbineUI.get(getSkin(), key);
127        }
128    
129        /**
130         * Retrieve the skin name.
131         */
132        public String getSkin()
133        {
134            return skinName;
135        }
136    
137        /**
138         * Set the skin name to the skin from the TurbineResources.properties file.
139         * If the property is not present use the "default" skin.
140         */
141        public void setSkin()
142        {
143            skinName = TurbineUI.getWebappSkinName();
144        }
145    
146        /**
147         * Set the skin name to the specified skin.
148         *
149         * @param skinName the skin name to use.
150         */
151        public void setSkin(String skinName)
152        {
153            this.skinName = skinName;
154        }
155    
156        /**
157         * Set the skin name when the tool is configured to be loaded on a
158         * per-request basis. By default it calls getSkin to return the skin
159         * specified in TurbineResources.properties. Developers can write a subclass
160         * of UITool that overrides this method to determine the skin to use based
161         * on information held in the request.
162         *
163         * @param data a RunData instance
164         */
165        protected void setSkin(RunData data)
166        {
167            setSkin();
168        }
169    
170        /**
171         * Set the skin name when the tool is configured to be loaded on a
172         * per-session basis. If the user's temp hashmap contains a value in the
173         * attribute specified by the String constant SKIN_ATTRIBUTE then that is
174         * returned. Otherwise it calls getSkin to return the skin specified in
175         * TurbineResources.properties.
176         *
177         * @param user a User instance
178         */
179        protected void setSkin(User user)
180        {
181            if (user.getTemp(SKIN_ATTRIBUTE) == null)
182            {
183                setSkin();
184            }
185            else
186            {
187                setSkin((String) user.getTemp(SKIN_ATTRIBUTE));
188            }
189        }
190    
191        /**
192         * Set the skin name in the user's temp hashmap for the current session.
193         *
194         * @param user a User instance
195         * @param skin the skin name for the session
196         */
197        public static void setSkin(User user, String skin)
198        {
199            user.setTemp(SKIN_ATTRIBUTE, skin);
200        }
201    
202        /**
203         * Retrieve the URL for an image that is part of the skin. The images are
204         * stored in the WEBAPP/resources/ui/skins/[SKIN]/images directory.
205         *
206         * <p>Use this if for some reason your server name, server scheme, or server
207         * port change on a per request basis. I'm not sure if this would happen in
208         * a load balanced situation. I think in most cases the image(String image)
209         * method would probably be enough, but I'm not absolutely positive.
210         *
211         * @param imageId the id of the image whose URL will be generated.
212         * @param data the RunDate to use as the source of the ServerData to use as
213         * the basis for the URL.
214         */
215        public String image(String imageId, RunData data)
216        {
217            return image(imageId, data.getServerData());
218        }
219    
220        /**
221         * Retrieve the URL for an image that is part of the skin. The images are
222         * stored in the WEBAPP/resources/ui/skins/[SKIN]/images directory.
223         *
224         * <p>Use this if for some reason your server name, server scheme, or server
225         * port change on a per request basis. I'm not sure if this would happen in
226         * a load balanced situation. I think in most cases the image(String image)
227         * method would probably be enough, but I'm not absolutely positive.
228         *
229         * @param imageId the id of the image whose URL will be generated.
230         * @param serverData the serverData to use as the basis for the URL.
231         */
232        public String image(String imageId, ServerData serverData)
233        {
234            return TurbineUI.image(getSkin(), imageId, serverData);
235        }
236    
237        /**
238         * Retrieve the URL for an image that is part of the skin. The images are
239         * stored in the WEBAPP/resources/ui/skins/[SKIN]/images directory.
240         *
241         * @param imageId the id of the image whose URL will be generated.
242         */
243        public String image(String imageId)
244        {
245            return TurbineUI.image(getSkin(), imageId);
246        }
247    
248        /**
249         * Retrieve the URL for the style sheet that is part of the skin. The style
250         * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory with the
251         * filename skin.css
252         *
253         * <p>Use this if for some reason your server name, server scheme, or server
254         * port change on a per request basis. I'm not sure if this would happen in
255         * a load balanced situation. I think in most cases the style() method would
256         * probably be enough, but I'm not absolutely positive.
257         *
258         * @param data the RunDate to use as the source of the ServerData to use as
259         * the basis for the URL.
260         */
261        public String getStylecss(RunData data)
262        {
263            return getStylecss(data.getServerData());
264        }
265    
266        /**
267         * Retrieve the URL for the style sheet that is part of the skin. The style
268         * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory with the
269         * filename skin.css
270         *
271         * <p>Use this if for some reason your server name, server scheme, or server
272         * port change on a per request basis. I'm not sure if this would happen in
273         * a load balanced situation. I think in most cases the style() method would
274         * probably be enough, but I'm not absolutely positive.
275         *
276         * @param serverData the serverData to use as the basis for the URL.
277         */
278        public String getStylecss(ServerData serverData)
279        {
280            return TurbineUI.getStylecss(getSkin(), serverData);
281        }
282    
283        /**
284         * Retrieve the URL for the style sheet that is part of the skin. The style
285         * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory with the
286         * filename skin.css
287         */
288        public String getStylecss()
289        {
290            return TurbineUI.getStylecss(getSkin());
291        }
292    
293        /**
294         * Retrieve the URL for a given script that is part of the skin. The script
295         * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory.
296         *
297         * <p>Use this if for some reason your server name, server scheme, or server
298         * port change on a per request basis. I'm not sure if this would happen in
299         * a load balanced situation. I think in most cases the image(String image)
300         * method would probably be enough, but I'm not absolutely positive.
301         *
302         * @param filename the name of the script file whose URL will be generated.
303         * @param data the RunDate to use as the source of the ServerData to use as
304         * the basis for the URL.
305         */
306        public String getScript(String filename, RunData data)
307        {
308            return getScript(filename, data.getServerData());
309        }
310    
311        /**
312         * Retrieve the URL for a given script that is part of the skin. The script
313         * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory.
314         *
315         * <p>Use this if for some reason your server name, server scheme, or server
316         * port change on a per request basis. I'm not sure if this would happen in
317         * a load balanced situation. I think in most cases the image(String image)
318         * method would probably be enough, but I'm not absolutely positive.
319         *
320         * @param filename the name of the script file whose URL will be generated.
321         * @param serverData the serverData to use as the basis for the URL.
322         */
323        public String getScript(String filename, ServerData serverData)
324        {
325            return TurbineUI.getScript(getSkin(), filename, serverData);
326        }
327    
328        /**
329         * Retrieve the URL for a given script that is part of the skin. The script
330         * is stored in the WEBAPP/resources/ui/skins/[SKIN] directory.
331         *
332         * @param filename the name of the script file whose URL will be generated.
333         */
334        public String getScript(String filename)
335        {
336            return TurbineUI.getScript(getSkin(), filename);
337        }
338    
339        /**
340         * Initialize the UITool object.
341         *
342         * @param data This is null, RunData or User depending upon specified tool
343         * scope.
344         */
345        public void init(Object data)
346        {
347            if (data == null)
348            {
349                log.debug("UITool scope is global");
350                setSkin();
351            }
352            else if (data instanceof RunData)
353            {
354                log.debug("UITool scope is request");
355                setSkin((RunData) data);
356            }
357            else if (data instanceof PipelineData)
358            {
359                PipelineData pipelineData = (PipelineData) data;
360                RunData runData = (RunData)pipelineData;
361                log.debug("UITool scope is request");
362                setSkin(runData);
363            }
364            else if (data instanceof User)
365            {
366                log.debug("UITool scope is session");
367                setSkin((User) data);
368            }
369        }
370    
371    }