View Javadoc
1   /*******************************************************************************
2    *   Gisgraphy Project 
3    * 
4    *   This library is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU Lesser General Public
6    *   License as published by the Free Software Foundation; either
7    *   version 2.1 of the License, or (at your option) any later version.
8    * 
9    *   This library is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   *   Lesser General Public License for more details.
13   * 
14   *   You should have received a copy of the GNU Lesser General Public
15   *   License along with this library; if not, write to the Free Software
16   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
17   * 
18   *  Copyright 2008  Gisgraphy project 
19   *  David Masclet <davidmasclet@gisgraphy.com>
20   *  
21   *  
22   *******************************************************************************/
23  package com.gisgraphy.webapp.taglib;
24  
25  import java.lang.reflect.AccessibleObject;
26  import java.lang.reflect.Field;
27  import java.util.HashMap;
28  import java.util.Map;
29  
30  import javax.servlet.jsp.JspException;
31  import javax.servlet.jsp.PageContext;
32  import javax.servlet.jsp.tagext.TagSupport;
33  
34  import org.apache.commons.logging.Log;
35  import org.apache.commons.logging.LogFactory;
36  
37  import com.gisgraphy.Constants;
38  
39  /**
40   * <p>
41   * This class is designed to put all the public variables in a class to a
42   * specified scope - designed for exposing a Constants class to Tag Libraries.
43   * </p>
44   * <p>
45   * It is designed to be used as follows:
46   * 
47   * <pre>
48   * &lt;tag:constants /&gt;
49   * </pre>
50   * 
51   * </p>
52   * <p>
53   * Optional values are "className" (fully qualified) and "scope".
54   * </p>
55   * <p>
56   * <a href="BaseAction.java.html"><i>View Source</i></a>
57   * </p>
58   * 
59   * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
60   */
61  public class ConstantsTag extends TagSupport {
62      private static final long serialVersionUID = 3258417209566116146L;
63  
64      private final Log log = LogFactory.getLog(ConstantsTag.class);
65  
66      /**
67       * The class to expose the variables from.
68       */
69      private String clazz = Constants.class.getName();
70  
71      /**
72       * The scope to be put the variable in.
73       */
74      protected String scope;
75  
76      /**
77       * The single variable to expose.
78       */
79      protected String var;
80  
81      /**
82       * Main method that does processing and exposes Constants in specified scope
83       * 
84       * @return int
85       * @throws JspException
86       *                 if processing fails
87       */
88      @Override
89      public int doStartTag() throws JspException {
90  	// Using reflection, get the available field names in the class
91  	Class<?> c = null;
92  	int toScope = PageContext.PAGE_SCOPE;
93  
94  	if (scope != null) {
95  	    toScope = getScope(scope);
96  	}
97  
98  	try {
99  	    c = Class.forName(clazz);
100 	} catch (ClassNotFoundException cnf) {
101 	    log.error("ClassNotFound - maybe a typo?");
102 	    throw new JspException(cnf.getMessage());
103 	}
104 
105 	try {
106 	    // if var is null, expose all variables
107 	    if (var == null) {
108 		Field[] fields = c.getDeclaredFields();
109 
110 		AccessibleObject.setAccessible(fields, true);
111 
112 		for (Field field : fields) {
113 		    pageContext.setAttribute(field.getName(), field.get(this),
114 			    toScope);
115 		}
116 	    } else {
117 		try {
118 		    Object value = c.getField(var).get(this);
119 		    pageContext.setAttribute(c.getField(var).getName(), value,
120 			    toScope);
121 		} catch (NoSuchFieldException nsf) {
122 		    log.error(nsf.getMessage());
123 		    throw new JspException(nsf);
124 		}
125 	    }
126 	} catch (IllegalAccessException iae) {
127 	    log.error("Illegal Access Exception - maybe a classloader issue?");
128 	    throw new JspException(iae);
129 	}
130 
131 	// Continue processing this page
132 	return (SKIP_BODY);
133     }
134 
135     public void setClassName(String clazz) {
136 	this.clazz = clazz;
137     }
138 
139     public String getClassName() {
140 	return this.clazz;
141     }
142 
143     public void setScope(String scope) {
144 	this.scope = scope;
145     }
146 
147     public String getScope() {
148 	return (this.scope);
149     }
150 
151     public void setVar(String var) {
152 	this.var = var;
153     }
154 
155     public String getVar() {
156 	return (this.var);
157     }
158 
159     /**
160      * Release all allocated resources.
161      */
162     @Override
163     public void release() {
164 	super.release();
165 	clazz = null;
166 	scope = Constants.class.getName();
167     }
168 
169     /**
170      * Maps lowercase JSP scope names to their PageContext integer constant
171      * values.
172      */
173     private static final Map<String, Integer> SCOPES = new HashMap<String, Integer>();
174 
175     /**
176      * Initialize the scope names map and the encode variable
177      */
178     static {
179 	SCOPES.put("page", PageContext.PAGE_SCOPE);
180 	SCOPES.put("request", PageContext.REQUEST_SCOPE);
181 	SCOPES.put("session", PageContext.SESSION_SCOPE);
182 	SCOPES.put("application", PageContext.APPLICATION_SCOPE);
183     }
184 
185     /**
186      * Converts the scope name into its corresponding PageContext constant
187      * value.
188      * 
189      * @param scopeName
190      *                Can be "page", "request", "session", or "application" in
191      *                any case.
192      * @return The constant representing the scope (ie.
193      *         PageContext.REQUEST_SCOPE).
194      * @throws JspException
195      *                 if the scopeName is not a valid name.
196      */
197     public int getScope(String scopeName) throws JspException {
198 	Integer scope = SCOPES.get(scopeName.toLowerCase());
199 
200 	if (scope == null) {
201 	    throw new JspException("Scope '" + scopeName
202 		    + "' not a valid option");
203 	}
204 
205 	return scope;
206     }
207 }