KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > blandware > atleap > webapp > taglib > core > menu > PrepareMenuTag


1 /*
2  * Copyright 2004 Blandware (http://www.blandware.com)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package com.blandware.atleap.webapp.taglib.core.menu;
17
18 import com.blandware.atleap.common.Constants;
19 import com.blandware.atleap.model.core.Page;
20 import com.blandware.atleap.service.core.PageManager;
21 import com.blandware.atleap.webapp.exception.MenuUtilException;
22 import com.blandware.atleap.webapp.menu.MenuComponent;
23 import com.blandware.atleap.webapp.struts.ContentTilesRequestProcessor;
24 import com.blandware.atleap.webapp.util.core.CacheUtil;
25 import com.blandware.atleap.webapp.util.core.MenuUtil;
26 import com.blandware.atleap.webapp.util.core.WebappUtil;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.struts.Globals;
30 import org.apache.struts.taglib.TagUtils;
31 import org.apache.struts.tiles.ComponentDefinition;
32 import org.apache.struts.tiles.TilesUtil;
33 import org.springframework.context.ApplicationContext;
34 import org.springframework.web.context.support.WebApplicationContextUtils;
35
36 import javax.servlet.ServletContext JavaDoc;
37 import javax.servlet.http.HttpServletRequest JavaDoc;
38 import javax.servlet.http.HttpServletResponse JavaDoc;
39 import javax.servlet.jsp.JspException JavaDoc;
40 import javax.servlet.jsp.JspTagException JavaDoc;
41 import javax.servlet.jsp.PageContext JavaDoc;
42 import javax.servlet.jsp.tagext.SimpleTagSupport JavaDoc;
43 import java.net.MalformedURLException JavaDoc;
44 import java.util.Locale JavaDoc;
45
46 /**
47  * <p>Replacement of DisplayMenuTag. Can get menu items from persistent storage.</p>
48  * <p>
49  * Allowed attributes are:
50  * <ul>
51  * <li>
52  * <b>name</b> - required - name of menu component that needs to be obtained.
53  * If <b>var</b> is not specified, this will be used instead of it too.
54  * </li>
55  * <li>
56  * <b>definition</b> - name of definition for which to obtain menu items. By
57  * default it is definition of currently processed page.
58  * </li>
59  * <li>
60  * <b>uri</b> - URI of page for which to obtain menu items. By default it is URI
61  * of currently processed page.
62  * </li>
63  * <li>
64  * <b>locale</b> - locale to use. By default it will be taken from session
65  * </li>
66  * <li>
67  * <b>addLocaleSuffix</b> - whether to add locale suffixes to menu locations.
68  * Default is "true".
69  * </li>
70  * <li>
71  * <b>var</b> - name of variable that will accept loaded menu component. If not
72  * specified, <b>name</b> will be used.
73  * </li>
74  * <li>
75  * <b>scope</b> - scope of variable to save loaded menu component
76  * </li>
77  * </ul>
78  * </p>
79  * <p><a HREF="PrepareMenuTag.java.htm"><i>View Source</i></a></p>
80  *
81  * @author Andrey Grebnev <a HREF="mailto:andrey.grebnev@blandware.com">&lt;andrey.grebnev@blandware.com&gt;</a>
82  * @author Sergey Zubtcovskii <a HREF="mailto:sergey.zubtcovskii@blandware.com">&lt;sergey.zubtcovskii@blandware.com&gt;</a>
83  * @version $Revision: 1.10 $ $Date: 2005/10/12 13:35:02 $
84  * @jsp.tag name="prepareMenu"
85  * body-content="empty"
86  */

87 public class PrepareMenuTag extends SimpleTagSupport JavaDoc {
88
89     protected transient final Log log = LogFactory.getLog(PrepareMenuTag.class);
90
91     protected ApplicationContext applicationCtx = null;
92
93     /**
94      * Definition name in database. By default it is definition of current processed page
95      */

96     protected String JavaDoc definition = null;
97
98     /**
99      * URI of the page in database. By default it is URI of currently processed page
100      */

101     protected String JavaDoc uri = null;
102
103     /**
104      * Locale to use. By default it will be taken from session
105      */

106     protected String JavaDoc locale = null;
107
108     /**
109      * Holds value of property name.
110      */

111     protected String JavaDoc name;
112
113     /**
114      * Name of variable to use instead of value specified in <code>name</code> attribute to save prepared menu component
115      */

116     protected String JavaDoc var;
117
118     /**
119      * Scope to export menu in
120      */

121     protected String JavaDoc scope;
122
123     /**
124      * Whether or not to add locale suffixes to menu locations
125      */

126     protected Boolean JavaDoc addLocaleSuffix = Boolean.TRUE;
127
128     /**
129      * Returns name of menu item
130      *
131      * @return name of menu item
132      * @jsp.attribute required="true"
133      * rtexprvalue="true"
134      * type="java.lang.String"
135      * description="The name of menu item"
136      */

137     public String JavaDoc getName() {
138         return this.name;
139     }
140
141     /**
142      * Sets name of menu item
143      *
144      * @param name New value of property name.
145      */

146     public void setName(String JavaDoc name) {
147         this.name = name;
148     }
149
150     /**
151      * Returns URI for which menu items will be loaded
152      *
153      * @return URI for which menu items will be loaded
154      * @jsp.attribute required="false"
155      * rtexprvalue="true"
156      * type="java.lang.String"
157      * description="URI of the page in database. By default it is URI of currently processed page"
158      */

159     public String JavaDoc getUri() {
160         return uri;
161     }
162
163     /**
164      * Sets URI for which menu items will be loaded
165      *
166      * @param uri URI for which menu items will be loaded
167      */

168     public void setUri(String JavaDoc uri) {
169         this.uri = uri;
170     }
171
172     /**
173      * Returns name of definition for which menu items will be loaded
174      *
175      * @return name of definition for which menu items will be loaded
176      * @jsp.attribute required="false"
177      * rtexprvalue="true"
178      * type="java.lang.String"
179      * description="Definition name in persistence storage. By default it is definition of currently processed page"
180      */

181     public String JavaDoc getDefinition() {
182         return definition;
183     }
184
185     /**
186      * Sets name of definition for which menu items will be loaded
187      *
188      * @param definition name of definition for which menu items will be loaded
189      */

190     public void setDefinition(String JavaDoc definition) {
191         this.definition = definition;
192     }
193
194     /**
195      * Returns locale that will be used when loading menu items
196      *
197      * @return locale
198      * @jsp.attribute required="false"
199      * rtexprvalue="true"
200      * type="java.lang.Boolean"
201      * description="Locale to use. By default it will be taken from session"
202      */

203     public String JavaDoc getLocale() {
204         return locale;
205     }
206
207     /**
208      * Sets locale that will be used when loading menu items
209      *
210      * @param locale locale to set
211      */

212     public void setLocale(String JavaDoc locale) {
213         this.locale = locale;
214     }
215
216     /**
217      * Returns name of variable that will accept loaded menu
218      *
219      * @return variable name
220      * @jsp.attribute required="false"
221      * rtexprvalue="true"
222      * type="java.lang.String"
223      * description="Name of variable to use instead of value specified in 'name' attribute to save prepared menu component"
224      */

225     public String JavaDoc getVar() {
226         return var;
227     }
228
229     /**
230      * Sets name of variable that will accept loaded menu
231      *
232      * @param var name of variable to set
233      */

234     public void setVar(String JavaDoc var) {
235         this.var = var;
236     }
237
238     /**
239      * Returns scope of variable that will accept loaded menu
240      *
241      * @return variable scope
242      * @jsp.attribute required="false"
243      * rtexprvalue="true"
244      * type="java.lang.String"
245      * description="Scope to export variable to"
246      */

247     public String JavaDoc getScope() {
248         return scope;
249     }
250
251     /**
252      * Sets scope of variable that will accept loaded menu
253      *
254      * @param scope variable scope to set
255      */

256     public void setScope(String JavaDoc scope) {
257         this.scope = scope;
258     }
259
260     /**
261      * Returns whether or not to add locale suffix to locations
262      *
263      * @return whether to add locale suffix to locations
264      * @jsp.attribute required="false"
265      * rtexprvalue="true"
266      * type="java.lang.Boolean"
267      * description="Whether or not to add locale suffixes to menu locations"
268      */

269     public Boolean JavaDoc getAddLocaleSuffix() {
270         return addLocaleSuffix;
271     }
272
273     /**
274      * Sets whether to add locale suffix to locations
275      *
276      * @param addLocaleSuffix whether to add locale suffix to locations
277      */

278     public void setAddLocaleSuffix(Boolean JavaDoc addLocaleSuffix) {
279         this.addLocaleSuffix = addLocaleSuffix;
280     }
281
282     /**
283      * Processes tag
284      *
285      * @throws JspException thrown if some error occured
286      */

287     public void doTag() throws JspException JavaDoc {
288
289         PageContext JavaDoc pageContext = (PageContext JavaDoc) getJspContext();
290
291         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) pageContext.getRequest();
292         ServletContext JavaDoc servletContext = request.getSession().getServletContext();
293
294         applicationCtx = WebApplicationContextUtils.getRequiredWebApplicationContext(pageContext.getServletContext());
295
296         if ( addLocaleSuffix == null ) {
297             addLocaleSuffix = Boolean.TRUE;
298         }
299
300         //get locale
301
if ( locale == null ) {
302             Locale JavaDoc l = (Locale JavaDoc) pageContext.getAttribute(Globals.LOCALE_KEY, PageContext.SESSION_SCOPE);
303             if ( l != null ) {
304                 locale = l.getLanguage();
305             }
306         }
307         if ( locale == null ) {
308             locale = Locale.getDefault().getLanguage();
309         }
310
311         // get definition
312
TagUtils tagUtils = TagUtils.getInstance();
313         if ( definition != null ) {
314             ComponentDefinition tmpDef = null;
315             try {
316                 tmpDef = TilesUtil.getDefinition(definition, request, servletContext);
317             } catch ( Exception JavaDoc ex ) {
318                 //do nothing
319
}
320             if ( tmpDef == null ) {
321                 String JavaDoc errorMessage = "Specified definition '" + definition + "' was not found";
322                 if ( log.isErrorEnabled() ) {
323                     log.error(errorMessage);
324                 }
325                 JspTagException JavaDoc e = new JspTagException JavaDoc(errorMessage);
326                 tagUtils.saveException(pageContext, e);
327                 throw e;
328             }
329         } else {
330             definition = (String JavaDoc) pageContext.getAttribute(ContentTilesRequestProcessor.DEFINITION_NAME, PageContext.REQUEST_SCOPE);
331         }
332         if ( definition == null ) {
333             String JavaDoc errorMessage = "DEFINITION_NAME attribute was not found in request. This can be used only on pages processed by action using tile definition.";
334             if ( log.isErrorEnabled() ) {
335                 log.error(errorMessage);
336             }
337             JspTagException JavaDoc e = new JspTagException JavaDoc(errorMessage);
338             tagUtils.saveException(pageContext, e);
339             throw e;
340         }
341
342         //get uri
343
if ( uri != null ) {
344             PageManager pageManager = (PageManager) applicationCtx.getBean(Constants.PAGE_MANAGER_BEAN);
345             Page page = pageManager.findPageByUri(uri);
346             if ( page == null ) {
347                 String JavaDoc errorMessage = "Specified page uri '" + uri + "' was not found";
348                 if ( log.isErrorEnabled() ) {
349                     log.error(errorMessage);
350                 }
351                 JspTagException JavaDoc e = new JspTagException JavaDoc(errorMessage);
352                 tagUtils.saveException(pageContext, e);
353                 throw e;
354             }
355         } else {
356             uri = (String JavaDoc) pageContext.getAttribute(ContentTilesRequestProcessor.PROCESSED_URI, PageContext.REQUEST_SCOPE);
357         }
358         if ( uri == null ) {
359             String JavaDoc errorMessage = "PROCESSED_URI attribute was not found in request. This can be used only on pages processed by action using tile definition.";
360             if ( log.isErrorEnabled() ) {
361                 log.error(errorMessage);
362             }
363             JspTagException JavaDoc e = new JspTagException JavaDoc(errorMessage);
364             tagUtils.saveException(pageContext, e);
365             throw e;
366         }
367
368         CacheUtil cacheUtil = CacheUtil.getInstance(request);
369
370         MenuComponent menu = null;
371
372         if ( log.isDebugEnabled() ) {
373             log.debug("Try to get from cache: menuName=" + getName() + " locale=" + locale + " definition=" + definition + " uri=" + uri);
374         }
375         menu = cacheUtil.getMenuFromCache(getName(), locale, definition, uri);
376         if ( menu == null ) {
377             if ( log.isDebugEnabled() ) {
378                 log.debug("Trying to get from database");
379             }
380             MenuUtil menuUtil = new MenuUtil((HttpServletRequest JavaDoc) pageContext.getRequest());
381             try {
382                 menu = menuUtil.getMenuComponent(getName(), locale, definition, uri, true);
383                 if ( menu != null ) {
384                     cacheUtil.putMenuInCache(menu, getName(), locale, definition, uri);
385                 }
386             } catch ( MenuUtilException e ) {
387                 throw new JspTagException JavaDoc(e);
388             }
389         }
390
391         if ( menu != null ) {
392             try {
393
394                 // set the location value to use
395
// the context relative page attribute
396
// if specified in the menu
397
try {
398                     setPageLocation(menu);
399                 } catch ( MalformedURLException JavaDoc m ) {
400                     if ( log.isErrorEnabled() ) {
401                         log.error("Incorrect action or forward: " + m.getMessage());
402                         log.error("Menu '" + menu.getName() + "' location set to #");
403                     }
404                     menu.setLocation("#");
405                 }
406
407                 String JavaDoc attr = new String JavaDoc(name);
408
409                 if ( var != null ) {
410                     attr = new String JavaDoc(var);
411                 }
412
413                 int varScope = PageContext.PAGE_SCOPE;
414                 if ( scope != null ) {
415                     varScope = tagUtils.getScope(scope);
416                 }
417
418                 pageContext.setAttribute(attr, menu, varScope);
419
420             } catch ( Exception JavaDoc ex ) {
421                 if ( log.isErrorEnabled() ) {
422                     log.error(ex);
423                 }
424                 tagUtils.saveException(pageContext, ex);
425                 throw new JspException JavaDoc(ex);
426             }
427         } else {
428
429             // if menu is null, perhaps it was not found, or it is invisible on current layer. So, do nothing,
430
// just post the message to log
431

432             if ( log.isInfoEnabled() ) {
433                 log.info("Menu '" + getName() + "' either does not exist, or it is invisible on current layer. Skipping...");
434             }
435         }
436     }
437
438     /**
439      * Sets the value for the menu location to the
440      * appropriate value if location is null. If location
441      * is null, and the page attribute exists, it's value
442      * will be set to the the value for page prepended with
443      * the context path of the application.
444      * <p/>
445      * If the page is null, and the forward attribute exists,
446      * it's value will be looked up in struts-config.xml.
447      *
448      * @param menu The menu component to set the location for.
449      */

450     protected void setPageLocation(MenuComponent menu)
451             throws MalformedURLException JavaDoc, JspException JavaDoc {
452
453         PageContext JavaDoc pageContext = (PageContext JavaDoc) getJspContext();
454         HttpServletRequest JavaDoc request =
455                 (HttpServletRequest JavaDoc) pageContext.getRequest();
456         setLocation(menu);
457         String JavaDoc url = menu.getLocation();
458
459         // Check if there are parameters on the value
460
if ( (url != null) && (url.indexOf("${") > -1) ) {
461             String JavaDoc queryString = null;
462
463             if ( url.indexOf("?") > -1 ) {
464                 queryString = url.substring(url.indexOf("?") + 1);
465                 url = url.substring(0, url.indexOf(queryString));
466             }
467
468             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
469
470             // variable is in the URL
471
if ( queryString != null ) {
472                 sb = parseString(queryString, request);
473                 menu.setUrl(url + sb.toString());
474             } else {
475                 // parse the URL, rather than the queryString
476
sb = parseString(url, request);
477                 menu.setUrl(sb.toString());
478             }
479         } else {
480             menu.setUrl(url);
481         }
482
483         // do all contained menus
484
MenuComponent[] subMenus = menu.getMenuComponents();
485
486         if ( subMenus.length > 0 ) {
487             for ( int i = 0; i < subMenus.length; i++ ) {
488                 setPageLocation(subMenus[i]);
489             }
490         }
491     }
492
493     protected void setLocation(MenuComponent menu) throws MalformedURLException JavaDoc {
494
495         PageContext JavaDoc pageContext = (PageContext JavaDoc) getJspContext();
496         HttpServletRequest JavaDoc request = (HttpServletRequest JavaDoc) pageContext.getRequest();
497         HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc) pageContext.getResponse();
498
499         // if the location attribute is null,
500
// then set it with a context relative page
501
// attribute if it exists
502
if ( menu.getLocation() == null ) {
503             try {
504                 if ( menu.getAnchor() != null ) {
505                     // are we sure we'll get an HttpServletRequest?
506
menu.setLocation(request.getContextPath() +
507                             getAnchor(menu.getAnchor()));
508                 } else if ( menu.getForward() != null ) {
509                     String JavaDoc forward = WebappUtil.computeURL(null, menu.getForward(), null, null, null, request, response, true, false, addLocaleSuffix.booleanValue());
510                     menu.setLocation(forward);
511                 } else if ( menu.getAction() != null ) {
512                     // generate Struts Action URL,
513
// this will append Context Path (if any),
514
// Servlet Mapping (path mapping or extension mapping)
515
// Module Prefix (if any) & Session ID (if any)
516
String JavaDoc action = WebappUtil.computeURL(menu.getAction(), null, null, null, null, request, response, true, false, addLocaleSuffix.booleanValue());
517                     menu.setLocation(action);
518                 }
519             } catch ( NoClassDefFoundError JavaDoc e ) {
520                 if ( menu.getForward() != null ) {
521                     throw new MalformedURLException JavaDoc("forward '" + menu.getForward() + "' invalid - no struts.jar");
522                 } else if ( menu.getAction() != null ) {
523                     throw new MalformedURLException JavaDoc("action '" + menu.getAction() + "' invalid - no struts.jar");
524                 }
525             }
526         } else if ( addLocaleSuffix.booleanValue() && !menu.getExternalLocation().booleanValue() ) {
527             // add locale suffix, if requested
528
String JavaDoc href = menu.getLocation();
529             if ( !WebappUtil.isAbsoluteURL(href) && !href.startsWith("/") ) {
530                 href = WebappUtil.computeURL(null, null, "/" + href, null, null, request, response, true, false);
531                 menu.setLocation(href);
532             }
533         }
534     }
535
536     /**
537      * Returns the value with page prepended with a "/"
538      * if it is not already.
539      *
540      * @param page The value for the page.
541      */

542     protected String JavaDoc getAnchor(String JavaDoc page) {
543         if ( page.startsWith("/") ) {
544             return page;
545         } else {
546             page = "/" + page;
547         }
548
549         return page;
550     }
551
552     private StringBuffer JavaDoc parseString(String JavaDoc str, HttpServletRequest JavaDoc request) {
553
554         PageContext JavaDoc pageContext = (PageContext JavaDoc) getJspContext();
555
556         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
557
558         while ( str.indexOf("${") >= 0 ) {
559             sb.append(str.substring(0, str.indexOf("${")));
560
561             String JavaDoc variable =
562                     str.substring(str.indexOf("${") + 2, str.indexOf("}"));
563             String JavaDoc value = (String JavaDoc) pageContext.findAttribute(variable);
564
565             if ( value == null ) {
566                 // look for it as a request parameter
567
value = request.getParameter(variable);
568             }
569
570             // is value still null?!
571
if ( value == null ) {
572                 log.warn("Value for '" + variable +
573                         "' not found in pageContext or as a request parameter");
574             }
575
576             sb.append(value);
577             str = str.substring(str.indexOf("}") + 1, str.length());
578         }
579
580         return sb.append(str);
581     }
582 }
583
Popular Tags