1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.morph.lang.languages;
17
18 import java.util.Locale;
19
20 import net.sf.composite.util.ObjectUtils;
21 import net.sf.morph.Defaults;
22 import net.sf.morph.lang.DecoratedLanguage;
23 import net.sf.morph.lang.LanguageException;
24 import net.sf.morph.transform.Converter;
25 import net.sf.morph.transform.TransformationException;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29
30 /**
31 * A convenient base class for Languages that takes care of exception
32 * handling and logging. Also exposes the
33 * {@link net.sf.morph.lang.DecoratedLanguage} interface while only requiring
34 * subclasses to implement the methods in {@link net.sf.morph.lang.Language}.
35 *
36 * @author Matt Sgarlata
37 * @since Nov 28, 2004
38 */
39 public abstract class BaseLanguage implements DecoratedLanguage {
40
41 private Converter converter;
42 private String languageName;
43
44 private transient Log log;
45
46 /**
47 * Create a new BaseLanguage.
48 */
49 public BaseLanguage() {
50 super();
51 establishLog(null);
52 }
53
54 /**
55 * Implement <code>isProperty(expression)</code>.
56 * @param expression
57 * @return boolean
58 * @throws Exception
59 */
60 protected abstract boolean isPropertyImpl(String expression) throws Exception;
61
62 /**
63 * Implement <code>getType(target, expression)</code>.
64 * @param target bean
65 * @param expression to read
66 * @return Class
67 * @throws Exception
68 */
69 protected abstract Class getTypeImpl(Object target, String expression)
70 throws Exception;
71
72 /**
73 * Implement <code>get(target, expression)</code>.
74 * @param target bean
75 * @param expression to get
76 * @return Object
77 * @throws Exception
78 */
79 protected abstract Object getImpl(Object target, String expression) throws Exception;
80
81 /**
82 * Implement <code>set(target, expression, value)</code>.
83 * @param target bean
84 * @param expression to set
85 * @param value to set
86 * @throws Exception
87 */
88 protected abstract void setImpl(Object target, String expression, Object value)
89 throws Exception;
90
91 /**
92 * {@inheritDoc}
93 */
94 public final boolean isProperty(String expression) throws LanguageException {
95 try {
96 boolean isProperty = isPropertyImpl(expression);
97
98 if (log.isTraceEnabled()) {
99 log.trace("Expression '"
100 + expression
101 + "' denotes a"
102 + (isProperty ? " simple property of an object"
103 : "n expression that involves traversal of an object graph"));
104 }
105 return isProperty;
106 }
107 catch (LanguageException e) {
108 throw e;
109 }
110 catch (Exception e) {
111 throw new LanguageException("Could not determine if expression '"
112 + expression + "' references a nested property", e);
113 }
114 }
115
116 /**
117 * {@inheritDoc}
118 */
119 public final Class getType(Object target, String expression) throws LanguageException {
120 if (target == null) {
121 throw new LanguageException("The target object cannot be null");
122 }
123 if (log.isTraceEnabled()) {
124 log.trace("Retrieving type of '" + expression + "' from target "
125 + ObjectUtils.getObjectDescription(target));
126 }
127 try {
128 Class type = getTypeImpl(target, expression);
129 return type == null ? Object.class : type;
130 }
131 catch (LanguageException e) {
132 throw e;
133 }
134 catch (Exception e) {
135 throw new LanguageException("Could not retrieve type of '"
136 + expression + "' from target "
137 + ObjectUtils.getObjectDescription(target), e);
138 }
139 }
140
141 /**
142 * {@inheritDoc}
143 */
144 public final Object get(Object target, String expression) throws LanguageException {
145 if (target == null) {
146 throw new LanguageException("The target object cannot be null");
147 }
148 if (log.isTraceEnabled()) {
149 log.trace("Retrieving '" + expression + "' from target "
150 + ObjectUtils.getObjectDescription(target));
151 }
152 try {
153 return getImpl(target, expression);
154 }
155 catch (LanguageException e) {
156 throw e;
157 }
158 catch (Exception e) {
159 throw new LanguageException("Could not retrieve '" + expression
160 + "' from target "
161 + ObjectUtils.getObjectDescription(target), e);
162 }
163 }
164
165 /**
166 * {@inheritDoc}
167 */
168 public final void set(Object target, String expression, Object value)
169 throws LanguageException {
170 set(target, expression, value, null);
171 }
172
173 /**
174 * {@inheritDoc}
175 */
176 public final Object get(Object target, String expression, Class destinationClass)
177 throws LanguageException, TransformationException {
178 return get(target, expression, destinationClass, null);
179 }
180
181 /**
182 * {@inheritDoc}
183 */
184 public final Object get(Object target, String expression, Class destinationClass,
185 Locale locale) throws LanguageException, TransformationException {
186 Object object = get(target, expression);
187 return getConverter().convert(destinationClass, object, locale);
188 }
189
190 /**
191 * {@inheritDoc}
192 */
193 public final Object get(Object target, String expression, Locale locale,
194 Class destinationClass) throws LanguageException, TransformationException {
195 return get(target, expression, destinationClass, locale);
196 }
197
198 /**
199 * {@inheritDoc}
200 */
201 public void set(Object target, String expression, Object value, Locale locale)
202 throws LanguageException, TransformationException {
203
204 if (target == null) {
205 throw new LanguageException("The target object cannot be null");
206 }
207 if (log.isTraceEnabled()) {
208 log.trace("Setting '" + expression + "' to "
209 + ObjectUtils.getObjectDescription(value) + " on target "
210 + ObjectUtils.getObjectDescription(target));
211 }
212
213 Class type = getType(target, expression);
214 Object converted = type.isInstance(value) ? value : getConverter()
215 .convert(type, value, locale);
216
217 try {
218 setImpl(target, expression, converted);
219 }
220 catch (LanguageException e) {
221 throw e;
222 }
223 catch (Exception e) {
224 throw new LanguageException("Could not set '" + expression
225 + "' to " + ObjectUtils.getObjectDescription(value)
226 + " on target " + ObjectUtils.getObjectDescription(target),
227 e);
228 }
229 }
230
231 /**
232 * Get the Converter.
233 * @return Converter
234 */
235 public Converter getConverter() {
236 if (converter == null) {
237 setConverter(Defaults.createConverter());
238 }
239 return converter;
240 }
241
242 /**
243 * Set the Converter.
244 * @param converter to set
245 */
246 public void setConverter(Converter converter) {
247 this.converter = converter;
248 }
249
250 /**
251 * Get the languageName.
252 * @return String
253 */
254 public String getLanguageName() {
255 return languageName;
256 }
257
258 /**
259 * Set the languageName.
260 * @param languageName the String to set
261 */
262 public void setLanguageName(String languageName) {
263 if (ObjectUtils.equals(languageName, this.languageName)) {
264 return;
265 }
266 this.languageName = languageName;
267 establishLog(languageName);
268 }
269
270 private void establishLog(String name) {
271 log = name == null ? LogFactory.getLog(getClass()) : LogFactory.getLog(name);
272 }
273
274 /**
275 * {@inheritDoc}
276 */
277 public String toString() {
278 String name = getLanguageName();
279 return name == null ? super.toString() : name;
280 }
281 }