1 /**
2 * Licensed under the Artistic License; you may not use this file
3 * except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://displaytag.sourceforge.net/license.html
7 *
8 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
9 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 */
12 package org.displaytag.decorator;
13
14 import javax.servlet.jsp.PageContext;
15
16 import org.apache.commons.lang.StringUtils;
17 import org.displaytag.exception.DecoratorException;
18 import org.displaytag.exception.DecoratorInstantiationException;
19 import org.displaytag.properties.MediaTypeEnum;
20 import org.displaytag.util.ReflectHelper;
21
22
23 /**
24 * Factory for TableDecorator or ColumnDecorator object.
25 * @author Fabrizio Giustina
26 * @version $Id$
27 */
28 public class DefaultDecoratorFactory implements DecoratorFactory
29 {
30
31 /**
32 * <p>
33 * If the user has specified a decorator, then this method takes care of creating the decorator (and checking to
34 * make sure it is a subclass of the TableDecorator object). If there are any problems loading the decorator then
35 * this will throw a DecoratorInstantiationException which will get propagated up to the page.
36 * </p>
37 * <p>
38 * Two different methods for loading a decorator are handled by this factory:
39 * </p>
40 * <ul>
41 * <li>First of all, an object with key <code>decoratorName</code> is searched in the page/request/session/scope</li>
42 * <li>If not found, assume <code>decoratorName</code> is the class name of the decorator and load it using
43 * reflection</li>
44 * </ul>
45 * @param decoratorName String full decorator class name
46 * @return instance of TableDecorator
47 * @throws DecoratorInstantiationException if unable to load specified TableDecorator
48 */
49 public TableDecorator loadTableDecorator(PageContext pageContext, String decoratorName)
50 throws DecoratorInstantiationException
51 {
52 if (StringUtils.isBlank(decoratorName))
53 {
54 return null;
55 }
56
57 // first check: is decoratorName an object in page/request/session/application scope?
58 Object decorator = pageContext.findAttribute(decoratorName);
59
60 // second check: if a decorator was not found assume decoratorName is the class name and load it using
61 // reflection
62 if (decorator == null)
63 {
64 try
65 {
66 decorator = ReflectHelper.classForName(decoratorName).newInstance();
67 }
68 catch (ClassNotFoundException e)
69 {
70 throw new DecoratorInstantiationException(DefaultDecoratorFactory.class, decoratorName, e);
71 }
72 catch (InstantiationException e)
73 {
74 throw new DecoratorInstantiationException(DefaultDecoratorFactory.class, decoratorName, e);
75 }
76 catch (IllegalAccessException e)
77 {
78 throw new DecoratorInstantiationException(DefaultDecoratorFactory.class, decoratorName, e);
79 }
80 }
81
82 if (decorator instanceof TableDecorator)
83 {
84 return (TableDecorator) decorator;
85 }
86 else
87 {
88 throw new DecoratorInstantiationException(
89 DefaultDecoratorFactory.class,
90 decoratorName,
91 new ClassCastException(decorator.getClass().getName()));
92 }
93
94 }
95
96 /**
97 * <p>
98 * If the user has specified a column decorator, then this method takes care of creating the decorator (and checking
99 * to make sure it is a subclass of the DisplaytagColumnDecorator object). If there are any problems loading the
100 * decorator then this will throw a DecoratorInstantiationException which will get propagated up to the page.
101 * </p>
102 * <p>
103 * Two different methods for loading a decorator are handled by this factory:
104 * </p>
105 * <ul>
106 * <li>First of all, an object with key <code>decoratorName</code> is searched in the page/request/session/scope</li>
107 * <li>If not found, assume <code>decoratorName</code> is the class name of the decorator and load it using
108 * reflection</li>
109 * </ul>
110 * @param decoratorName String full decorator class name
111 * @return instance of DisplaytagColumnDecorator
112 * @throws DecoratorInstantiationException if unable to load ColumnDecorator
113 */
114 public DisplaytagColumnDecorator loadColumnDecorator(PageContext pageContext, String decoratorName)
115 throws DecoratorInstantiationException
116 {
117 if (StringUtils.isBlank(decoratorName))
118 {
119 return null;
120 }
121
122 // first check: is decoratorName an object in page/request/session/application scope?
123 Object decorator = pageContext.findAttribute(decoratorName);
124
125 // second check: if a decorator was not found assume decoratorName is the class name and load it using
126 // reflection
127 if (decorator == null)
128 {
129 try
130 {
131 decorator = ReflectHelper.classForName(decoratorName).newInstance();
132 }
133 catch (ClassNotFoundException e)
134 {
135 throw new DecoratorInstantiationException(DefaultDecoratorFactory.class, decoratorName, e);
136 }
137 catch (InstantiationException e)
138 {
139 throw new DecoratorInstantiationException(DefaultDecoratorFactory.class, decoratorName, e);
140 }
141 catch (IllegalAccessException e)
142 {
143 throw new DecoratorInstantiationException(DefaultDecoratorFactory.class, decoratorName, e);
144 }
145 }
146
147 if (decorator instanceof DisplaytagColumnDecorator)
148 {
149 return (DisplaytagColumnDecorator) decorator;
150 }
151 else if (decorator instanceof ColumnDecorator)
152 {
153 return new DeprecatedDecoratorWrapper((ColumnDecorator) decorator);
154 }
155 else
156 {
157 throw new DecoratorInstantiationException(
158 DefaultDecoratorFactory.class,
159 decoratorName,
160 new ClassCastException(decorator.getClass().getName()));
161 }
162 }
163
164 /**
165 * Wrapper class for handling decorators implementing the deprecated ColumnDecorator interface as 1.1
166 * <code>DisplaytagColumnDecorator</code>s.
167 */
168 private static class DeprecatedDecoratorWrapper implements DisplaytagColumnDecorator
169 {
170
171 /**
172 * Wrapped 1.0 decorator.
173 */
174 private ColumnDecorator decorator;
175
176 /**
177 * Instantiates a new wrapper for old decorators.
178 * @param decorator ColumnDecorator instance
179 */
180 public DeprecatedDecoratorWrapper(ColumnDecorator decorator)
181 {
182 this.decorator = decorator;
183 }
184
185 /**
186 * @see org.displaytag.decorator.DisplaytagColumnDecorator#decorate(Object, PageContext, MediaTypeEnum)
187 * @deprecated
188 */
189 public Object decorate(Object columnValue, PageContext pageContext, MediaTypeEnum media)
190 throws DecoratorException
191 {
192 return decorator.decorate(columnValue);
193 }
194
195 }
196 }