Created
September 27, 2012 11:32
Custom tag used to get static final class fields in JSP (based on Jakarta 'unstandard' custom tag library API)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2005 The Apache Software Foundation. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.github.xaerxess; | |
import java.lang.reflect.Field; | |
import java.lang.reflect.Modifier; | |
import java.util.HashMap; | |
import java.util.Map; | |
import org.springframework.util.ClassUtils; | |
/** | |
* Utility class for working with Class instances. | |
*/ | |
final class ClassReflectionUtils { | |
/** | |
* Private constructor to prevent instantiation of this class. | |
*/ | |
private ClassReflectionUtils() { | |
} | |
/** | |
* Creates and returns a map of the names of public static final constants to | |
* their values, for the specified class. | |
* | |
* @param className The fully qualified name of the class for which the | |
* constants should be determined | |
* | |
* @return {@code Map<String, Object>} from constant names to values | |
* @throws ClassNotFoundException | |
* @throws IllegalAccessException | |
* @throws IllegalArgumentException | |
*/ | |
public static Map<String, Object> getClassConstants(final String className) | |
throws ClassNotFoundException, IllegalArgumentException, | |
IllegalAccessException { | |
final Map<String, Object> constants = new HashMap<String, Object>(); | |
final Class<?> clazz = ClassUtils.forName(className, | |
ClassUtils.getDefaultClassLoader()); | |
for (final Field field : clazz.getFields()) { | |
final int modifiers = field.getModifiers(); | |
if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) | |
&& Modifier.isFinal(modifiers)) { | |
// null as argument because it's ignored when field is static | |
final Object value = field.get(null); | |
if (value != null) { | |
constants.put(field.getName(), value); | |
} | |
} | |
} | |
return constants; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> | |
<tag> | |
<name>useConstants</name> | |
<tag-class>com.github.xaerxess.UseConstantsTag</tag-class> | |
<body-content>empty</body-content> | |
<display-name>useConstants</display-name> | |
<description> | |
Exposes all of the public constants in a class as a map stored in | |
a scoped attribute. The scope may be specified, but defaults to page | |
scope. | |
</description> | |
<variable> | |
<name-from-attribute>var</name-from-attribute> | |
<variable-class>java.lang.Object</variable-class> | |
<declare>true</declare> | |
<scope>AT_BEGIN</scope> | |
<description>The name of the attribute into which the map will be stored.</description> | |
</variable> | |
<attribute> | |
<name>var</name> | |
<required>yes</required> | |
<rtexprvalue>no</rtexprvalue> | |
<description>Name of the scoped attribute into which the map will be stored.</description> | |
</attribute> | |
<attribute> | |
<name>className</name> | |
<required>yes</required> | |
<rtexprvalue>no</rtexprvalue> | |
<description>Fully qualified name of the class from which constants will be extracted.</description> | |
</attribute> | |
<attribute> | |
<name>scope</name> | |
<required>no</required> | |
<rtexprvalue>no</rtexprvalue> | |
<description>Scope into which to store the map. Default is page scope.</description> | |
</attribute> | |
<example> | |
To expose all of the constants in the Integer class: | |
<![CDATA[<un:useConstants var="const" className="java.lang.Integer" />]]> | |
</example> | |
</tag> | |
</taglib> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2005 The Apache Software Foundation. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.github.xaerxess; | |
import java.util.Map; | |
import javax.servlet.jsp.JspException; | |
import javax.servlet.jsp.JspTagException; | |
import javax.servlet.jsp.tagext.TagSupport; | |
import org.springframework.util.Assert; | |
import org.springframework.web.util.TagUtils; | |
/** | |
* Tag that exposes all of the public constants in a class as a map stored in | |
* a scoped attribute. The scope may be specified, but defaults to page scope. | |
* <p/> | |
* Based on abandoned project taglibs-unstandard, specifically | |
* {@code org.apache.taglibs.unstandard.UseConstantsTag}. Uses Spring's TagUtils | |
* and ClassUtils instead of utils bundled in taglibs-unstandard, plus it | |
* supports generics. | |
* | |
* @see http://jakarta.apache.org/taglibs/unstandard | |
*/ | |
public class UseConstantsTag extends TagSupport { | |
private static final long serialVersionUID = 1L; | |
/** | |
* The fully qualified name of the Java class for which constants are to be | |
* exposed. | |
*/ | |
private String className; | |
/** | |
* The scope in which the exposed map will be stored. | |
*/ | |
private String scope = TagUtils.SCOPE_PAGE; | |
/** | |
* The name of the scoped attribute in which the constants will be stored. | |
*/ | |
private String var; | |
/** | |
* Construct an instance of this class. | |
*/ | |
public UseConstantsTag() { | |
} | |
/** | |
* Retrieve the name of the class for which constants are to be exposed. | |
* | |
* @return The fully qualified class name. | |
*/ | |
public String getClassName() { | |
return className; | |
} | |
/** | |
* Set the name of the class for which constants are to be exposed. | |
* | |
* @param className The fully qualified class name. | |
*/ | |
public void setClassName(final String className) { | |
this.className = className; | |
} | |
/** | |
* Retrieve the scope in which the exposed map will be stored. | |
* | |
* @return The name of the scope. | |
*/ | |
public String getScope() { | |
return scope; | |
} | |
/** | |
* Set the scope in which the exposed map will be stored. | |
* | |
* @param scope The name of the scope. | |
*/ | |
public void setScope(final String scope) { | |
Assert.notNull(scope, "Scope cannot be null"); | |
this.scope = scope; | |
} | |
/** | |
* Retrieve the variable name in which the exposed map will be stored. | |
* | |
* @return The name of the variable. | |
*/ | |
public String getVar() { | |
return var; | |
} | |
/** | |
* Set the variable name in which the exposed map will be stored. | |
* | |
* @param var The name of the variable. | |
*/ | |
public void setVar(final String var) { | |
this.var = var; | |
} | |
/** | |
* Expose the constants for a class as a scoped attribute. | |
* | |
* @return A constant that identifies what the container should do next. | |
* | |
* @throws JspException if a fatal error occurs. | |
*/ | |
@Override | |
public int doStartTag() throws JspException { | |
if (className != null && var != null) { | |
Map<String, Object> constants; | |
try { | |
constants = ClassReflectionUtils.getClassConstants(className); | |
} catch (final ClassNotFoundException e) { | |
throw new JspTagException("Class not found: " + className, e); | |
} catch (final IllegalArgumentException e) { | |
throw new JspTagException("Illegal argument: " + className, e); | |
} catch (final IllegalAccessException e) { | |
throw new JspTagException("Illegal access: " + className, e); | |
} | |
if (!constants.isEmpty()) { | |
pageContext.setAttribute(var, constants, TagUtils.getScope(scope)); | |
} | |
} | |
return SKIP_BODY; | |
} | |
/** | |
* Free up any resources being used by this tag handler. | |
*/ | |
@Override | |
public void release() { | |
super.release(); | |
className = null; | |
scope = null; | |
var = null; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment