001: package org.apache.velocity.tools.view;
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 java.lang.reflect.InvocationTargetException;
023: import java.lang.reflect.Method;
024: import java.util.HashMap;
025: import java.util.Map;
026: import org.apache.commons.logging.Log;
027: import org.apache.commons.logging.LogFactory;
028:
029: /**
030: * ToolInfo implementation for view tools. New instances
031: * are returned for every call to getInstance(obj), and tools
032: * that have an init(Object) method are initialized with the
033: * given object before being returned. And tools that have a
034: * configure(Map) method will be configured before being returned
035: * if there are parameters specified for the tool.
036: *
037: * @author Nathan Bubna
038: * @author <a href="mailto:henning@schmiedehausen.org">Henning P. Schmiedehausen</a>
039: * @version $Id: ViewToolInfo.java 479724 2006-11-27 18:49:37Z nbubna $
040: */
041: public class ViewToolInfo implements ToolInfo {
042: protected static final Log LOG = LogFactory
043: .getLog(ViewToolInfo.class);
044:
045: private String key;
046: private Class clazz;
047: private Map parameters;
048: private Method init = null;
049: private Method configure = null;
050:
051: public ViewToolInfo() {
052: }
053:
054: //TODO: if classloading becomes needed elsewhere, move this to a utils class
055: /**
056: * Return the <code>Class</code> object for the specified fully qualified
057: * class name, from this web application's class loader. If no
058: * class loader is set for the current thread, then the class loader
059: * that loaded this class will be used.
060: *
061: * @param name Fully qualified class name to be loaded
062: * @return Class object
063: * @exception ClassNotFoundException if the class cannot be found
064: * @since VelocityTools 1.1
065: */
066: protected Class getApplicationClass(String name)
067: throws ClassNotFoundException {
068: ClassLoader loader = Thread.currentThread()
069: .getContextClassLoader();
070: if (loader == null) {
071: loader = ViewToolInfo.class.getClassLoader();
072: }
073: return loader.loadClass(name);
074: }
075:
076: /*********************** Mutators *************************/
077:
078: public void setKey(String key) {
079: this .key = key;
080: }
081:
082: /**
083: * If an instance of the tool cannot be created from
084: * the classname passed to this method, it will throw an exception.
085: *
086: * @param classname the fully qualified java.lang.Class name of the tool
087: */
088: public void setClassname(String classname) throws Exception {
089: if (classname != null && classname.length() != 0) {
090: this .clazz = getApplicationClass(classname);
091: // create an instance to make sure we can
092: Object instance = clazz.newInstance();
093: try {
094: // try to get an init(Object) method
095: this .init = clazz.getMethod("init",
096: new Class[] { Object.class });
097: } catch (NoSuchMethodException nsme) {
098: // ignore
099: }
100: try {
101: // check for a configure(Map) method
102: this .configure = clazz.getMethod("configure",
103: new Class[] { Map.class });
104: } catch (NoSuchMethodException nsme) {
105: // ignore
106: }
107: } else {
108: this .clazz = null;
109: }
110: }
111:
112: /**
113: * Set parameter map for this tool.
114: *
115: * @since VelocityTools 1.1
116: */
117: public void setParameters(Map parameters) {
118: this .parameters = parameters;
119: }
120:
121: /**
122: * Set/add new parameter for this tool.
123: *
124: * @since VelocityTools 1.1
125: */
126: public void setParameter(String name, String value) {
127: if (parameters == null) {
128: parameters = new HashMap();
129: }
130: parameters.put(name, value);
131: }
132:
133: /*********************** Accessors *************************/
134:
135: public String getKey() {
136: return key;
137: }
138:
139: public String getClassname() {
140: return clazz != null ? clazz.getName() : null;
141: }
142:
143: /**
144: * Get parameters for this tool.
145: * @since VelocityTools 1.1
146: */
147: public Map getParameters() {
148: return parameters;
149: }
150:
151: /**
152: * Returns a new instance of the tool. If the tool
153: * has an init(Object) method, the new instance
154: * will be initialized using the given data. If parameters
155: * have been specified and the tool has a configure(Map)
156: * method, the tool will be passed the parameters also.
157: */
158: public Object getInstance(Object initData) {
159: if (clazz == null) {
160: LOG.error("Tool " + this .key + " has no Class definition!");
161: return null;
162: }
163:
164: /* Get the tool instance */
165: Object tool = null;
166: try {
167: tool = clazz.newInstance();
168: }
169: /* we shouldn't get exceptions here because we already
170: * got an instance of this class during setClassname().
171: * but to be safe, let's catch the declared ones and give
172: * notice of them, and let other exceptions slip by. */
173: catch (IllegalAccessException e) {
174: LOG.error("Exception while instantiating instance of \""
175: + getClassname() + "\"", e);
176: } catch (InstantiationException e) {
177: LOG.error("Exception while instantiating instance of \""
178: + getClassname() + "\"", e);
179: }
180:
181: /* if the tool is configurable and we have parameters... */
182: if (configure != null && parameters != null) {
183: try {
184: // call the configure method on the instance
185: configure.invoke(tool, new Object[] { parameters });
186: } catch (IllegalAccessException iae) {
187: LOG.error("Exception when calling configure(Map) on "
188: + tool, iae);
189: } catch (InvocationTargetException ite) {
190: LOG.error("Exception when calling configure(Map) on "
191: + tool, ite);
192: }
193: }
194:
195: /* if the tool is initializable... */
196: if (init != null) {
197: try {
198: // call the init method on the instance
199: init.invoke(tool, new Object[] { initData });
200: } catch (IllegalAccessException iae) {
201: LOG.error("Exception when calling init(Object) on "
202: + tool, iae);
203: } catch (InvocationTargetException ite) {
204: LOG.error("Exception when calling init(Object) on "
205: + tool, ite);
206: }
207: }
208: return tool;
209: }
210:
211: }
|