Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
IntrospectionConfiguration |
|
| 1.0909090909090908;1.091 |
1 | /* |
|
2 | * Copyright 2004 The Apache Software Foundation. |
|
3 | * |
|
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 | * you may not use this file except in compliance with the License. |
|
6 | * You may obtain a copy of the License at |
|
7 | * |
|
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 | * |
|
10 | * Unless required by applicable law or agreed to in writing, software |
|
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 | * See the License for the specific language governing permissions and |
|
14 | * limitations under the License. |
|
15 | */ |
|
16 | ||
17 | package org.apache.commons.betwixt; |
|
18 | ||
19 | import org.apache.commons.betwixt.strategy.ClassNormalizer; |
|
20 | import org.apache.commons.betwixt.strategy.CollectiveTypeStrategy; |
|
21 | import org.apache.commons.betwixt.strategy.DefaultNameMapper; |
|
22 | import org.apache.commons.betwixt.strategy.DefaultPluralStemmer; |
|
23 | import org.apache.commons.betwixt.strategy.MappingDerivationStrategy; |
|
24 | import org.apache.commons.betwixt.strategy.NameMapper; |
|
25 | import org.apache.commons.betwixt.strategy.NamespacePrefixMapper; |
|
26 | import org.apache.commons.betwixt.strategy.PluralStemmer; |
|
27 | import org.apache.commons.betwixt.strategy.PropertySuppressionStrategy; |
|
28 | import org.apache.commons.betwixt.strategy.SimpleTypeMapper; |
|
29 | import org.apache.commons.betwixt.strategy.StandardSimpleTypeMapper; |
|
30 | import org.apache.commons.betwixt.strategy.TypeBindingStrategy; |
|
31 | import org.apache.commons.logging.Log; |
|
32 | import org.apache.commons.logging.LogFactory; |
|
33 | ||
34 | /** |
|
35 | * <p>Stores introspection phase binding configuration.</p> |
|
36 | * <p> |
|
37 | * There are two phase in Betwixt's processing. |
|
38 | * The first phase is the introspection of the bean. |
|
39 | * Strutural configuration settings effect this phase. |
|
40 | * The second phase comes when Betwixt dynamically uses reflection |
|
41 | * to execute the mapping. |
|
42 | * This object stores configuration settings pertaining to the first phase. |
|
43 | * </p> |
|
44 | * <p> |
|
45 | * These common settings have been collected into one class so that they can |
|
46 | * be more easily shared not only between the objects that execute the introspection |
|
47 | * but also (by a user) between different <code>XMLIntrospector</code>s. |
|
48 | * </p> |
|
49 | * @author <a href='http://jakarta.apache.org/'>Apache Commons Team</a> |
|
50 | * @version $Revision: 397648 $ |
|
51 | */ |
|
52 | 7396 | public class IntrospectionConfiguration { |
53 | ||
54 | /** should attributes or elements be used for primitive types */ |
|
55 | 3698 | private boolean attributesForPrimitives = false; |
56 | ||
57 | 2208 | /** should we wrap collections in an extra element? */ |
58 | 3698 | private boolean wrapCollectionsInElement = true; |
59 | ||
60 | 1104 | /** Should the existing bean info search path for java.reflect.Introspector be used? */ |
61 | 3698 | private boolean useBeanInfoSearchPath = false; |
62 | ||
63 | 1104 | /** Should existing BeanInfo classes be used at all for java.reflect.Introspector */ |
64 | 3698 | private boolean ignoreAllBeanInfo = false; |
65 | ||
66 | 1104 | // pluggable strategies |
67 | /** The strategy used to detect matching singular and plural properties */ |
|
68 | private PluralStemmer pluralStemmer; |
|
69 | 1104 | |
70 | /** The strategy used to convert bean type names into element names */ |
|
71 | private NameMapper elementNameMapper; |
|
72 | ||
73 | /** Strategy normalizes the Class of the Object before introspection */ |
|
74 | 3698 | private ClassNormalizer classNormalizer = new ClassNormalizer(); |
75 | ||
76 | /** Log for introspection messages */ |
|
77 | 3698 | private Log introspectionLog = LogFactory.getLog(XMLIntrospector.class); |
78 | ||
79 | 1104 | /** |
80 | * The strategy used to convert bean type names into attribute names |
|
81 | * It will default to the normal nameMapper. |
|
82 | 1104 | */ |
83 | private NameMapper attributeNameMapper; |
|
84 | ||
85 | /** Prefix naming strategy */ |
|
86 | 3698 | private NamespacePrefixMapper prefixMapper = new NamespacePrefixMapper(); |
87 | /** Mapping strategy for simple types */ |
|
88 | 3698 | private SimpleTypeMapper simpleTypeMapper = new StandardSimpleTypeMapper(); |
89 | /** Binding strategy for Java type */ |
|
90 | 3698 | private TypeBindingStrategy typeBindingStrategy = TypeBindingStrategy.DEFAULT; |
91 | 1104 | /** Strategy used for determining which types are collective */ |
92 | 3698 | private CollectiveTypeStrategy collectiveTypeStrategy = CollectiveTypeStrategy.DEFAULT; |
93 | 1104 | |
94 | /** |
|
95 | 1104 | * Strategy used to determine whether the bind or introspection time type is to be used to |
96 | * determine the mapping. |
|
97 | 1104 | */ |
98 | 3698 | private MappingDerivationStrategy mappingDerivationStrategy = MappingDerivationStrategy.DEFAULT; |
99 | ||
100 | /** |
|
101 | * Strategy used to determine which properties should be ignored |
|
102 | */ |
|
103 | 4802 | private PropertySuppressionStrategy propertySuppressionStrategy = PropertySuppressionStrategy.DEFAULT; |
104 | ||
105 | /** |
|
106 | * Gets the <code>ClassNormalizer</code> strategy. |
|
107 | * This is used to determine the Class to be introspected |
|
108 | 1104 | * (the normalized Class). |
109 | * |
|
110 | * @return the <code>ClassNormalizer</code> used to determine the Class to be introspected |
|
111 | * for a given Object. |
|
112 | */ |
|
113 | public ClassNormalizer getClassNormalizer() { |
|
114 | 7248 | return classNormalizer; |
115 | } |
|
116 | ||
117 | /** |
|
118 | * Sets the <code>ClassNormalizer</code> strategy. |
|
119 | 2169 | * This is used to determine the Class to be introspected |
120 | * (the normalized Class). |
|
121 | * |
|
122 | * @param classNormalizer the <code>ClassNormalizer</code> to be used to determine |
|
123 | * the Class to be introspected for a given Object. |
|
124 | */ |
|
125 | public void setClassNormalizer(ClassNormalizer classNormalizer) { |
|
126 | 30 | this.classNormalizer = classNormalizer; |
127 | 30 | } |
128 | ||
129 | /** |
|
130 | * Should attributes (or elements) be used for primitive types. |
|
131 | 9 | * @return true if primitive types will be mapped to attributes in the introspection |
132 | 9 | */ |
133 | public boolean isAttributesForPrimitives() { |
|
134 | 7570 | return attributesForPrimitives; |
135 | } |
|
136 | ||
137 | /** |
|
138 | * Set whether attributes (or elements) should be used for primitive types. |
|
139 | 2271 | * @param attributesForPrimitives pass trus to map primitives to attributes, |
140 | * pass false to map primitives to elements |
|
141 | */ |
|
142 | public void setAttributesForPrimitives(boolean attributesForPrimitives) { |
|
143 | 4930 | this.attributesForPrimitives = attributesForPrimitives; |
144 | 4930 | } |
145 | ||
146 | /** |
|
147 | * Should collections be wrapped in an extra element? |
|
148 | 1479 | * |
149 | 1479 | * @return whether we should we wrap collections in an extra element? |
150 | */ |
|
151 | public boolean isWrapCollectionsInElement() { |
|
152 | 1730 | return wrapCollectionsInElement; |
153 | } |
|
154 | ||
155 | /** |
|
156 | * Sets whether we should we wrap collections in an extra element. |
|
157 | 519 | * |
158 | * @param wrapCollectionsInElement pass true if collections should be wrapped in a |
|
159 | * parent element |
|
160 | */ |
|
161 | public void setWrapCollectionsInElement(boolean wrapCollectionsInElement) { |
|
162 | 820 | this.wrapCollectionsInElement = wrapCollectionsInElement; |
163 | 820 | } |
164 | ||
165 | /** |
|
166 | * Get singular and plural matching strategy. |
|
167 | 246 | * |
168 | 246 | * @return the strategy used to detect matching singular and plural properties |
169 | */ |
|
170 | public PluralStemmer getPluralStemmer() { |
|
171 | 2016 | if ( pluralStemmer == null ) { |
172 | 1288 | pluralStemmer = createPluralStemmer(); |
173 | } |
|
174 | 2016 | return pluralStemmer; |
175 | } |
|
176 | 594 | |
177 | 381 | /** |
178 | * Sets the strategy used to detect matching singular and plural properties |
|
179 | 594 | * |
180 | * @param pluralStemmer the PluralStemmer used to match singular and plural |
|
181 | */ |
|
182 | public void setPluralStemmer(PluralStemmer pluralStemmer) { |
|
183 | 20 | this.pluralStemmer = pluralStemmer; |
184 | 20 | } |
185 | ||
186 | /** |
|
187 | * Gets the name mapping strategy used to convert bean names into elements. |
|
188 | 6 | * |
189 | 6 | * @return the strategy used to convert bean type names into element |
190 | * names. If no element mapper is currently defined then a default one is created. |
|
191 | */ |
|
192 | public NameMapper getElementNameMapper() { |
|
193 | 15164 | if ( elementNameMapper == null ) { |
194 | 1858 | elementNameMapper = createNameMapper(); |
195 | } |
|
196 | 15164 | return elementNameMapper; |
197 | } |
|
198 | 4542 | |
199 | 552 | /** |
200 | * Sets the strategy used to convert bean type names into element names |
|
201 | 4542 | * @param nameMapper the NameMapper to use for the conversion |
202 | */ |
|
203 | public void setElementNameMapper(NameMapper nameMapper) { |
|
204 | 480 | this.elementNameMapper = nameMapper; |
205 | 480 | } |
206 | ||
207 | /** |
|
208 | * Gets the name mapping strategy used to convert bean names into attributes. |
|
209 | 144 | * |
210 | 144 | * @return the strategy used to convert bean type names into attribute |
211 | * names. If no attributeNamemapper is known, it will default to the ElementNameMapper |
|
212 | */ |
|
213 | public NameMapper getAttributeNameMapper() { |
|
214 | 2220 | if (attributeNameMapper == null) { |
215 | 470 | attributeNameMapper = createNameMapper(); |
216 | } |
|
217 | 2220 | return attributeNameMapper; |
218 | } |
|
219 | 666 | |
220 | 141 | |
221 | /** |
|
222 | 666 | * Sets the strategy used to convert bean type names into attribute names |
223 | * @param nameMapper the NameMapper to use for the convertion |
|
224 | */ |
|
225 | public void setAttributeNameMapper(NameMapper nameMapper) { |
|
226 | 200 | this.attributeNameMapper = nameMapper; |
227 | 200 | } |
228 | ||
229 | /** |
|
230 | * <p>Should the original <code>java.reflect.Introspector</code> bean info search path be used?</p> |
|
231 | 60 | * <p> |
232 | 60 | * Default is false. |
233 | * </p> |
|
234 | * |
|
235 | * @return boolean if the beanInfoSearchPath should be used. |
|
236 | */ |
|
237 | public boolean useBeanInfoSearchPath() { |
|
238 | 33460 | return useBeanInfoSearchPath; |
239 | } |
|
240 | ||
241 | /** |
|
242 | * Specifies if you want to use the beanInfoSearchPath |
|
243 | 9966 | * @see java.beans.Introspector for more details |
244 | * @param useBeanInfoSearchPath |
|
245 | */ |
|
246 | public void setUseBeanInfoSearchPath(boolean useBeanInfoSearchPath) { |
|
247 | 0 | this.useBeanInfoSearchPath = useBeanInfoSearchPath; |
248 | 0 | } |
249 | ||
250 | /** |
|
251 | * <p>Should existing BeanInfo classes be ignored by <code>java.reflect.Introspector</code>.</p> |
|
252 | 0 | * <p> |
253 | 0 | * Default is false. |
254 | * </p> |
|
255 | * |
|
256 | * @return boolean if the BeanInfo classes should be used. |
|
257 | */ |
|
258 | public boolean ignoreAllBeanInfo() { |
|
259 | 12764 | return ignoreAllBeanInfo; |
260 | } |
|
261 | ||
262 | /** |
|
263 | * Specifies if you want to ignore existing BeanInfo classes at all for introspection |
|
264 | 3822 | * @see java.beans.Introspector for more details |
265 | * @param ignoreAllBeanInfo set to true to ignore all BeanInfo classes |
|
266 | */ |
|
267 | public void setIgnoreAllBeanInfo(boolean ignoreAllBeanInfo) { |
|
268 | 20 | this.ignoreAllBeanInfo = ignoreAllBeanInfo; |
269 | 20 | } |
270 | ||
271 | ||
272 | /** |
|
273 | 6 | * A Factory method to lazily create a new strategy |
274 | 6 | * to detect matching singular and plural properties. |
275 | * |
|
276 | * @return new defualt PluralStemmer implementation |
|
277 | */ |
|
278 | protected PluralStemmer createPluralStemmer() { |
|
279 | 1288 | return new DefaultPluralStemmer(); |
280 | } |
|
281 | ||
282 | /** |
|
283 | * A Factory method to lazily create a strategy |
|
284 | 381 | * used to convert bean type names into element names. |
285 | * |
|
286 | * @return new default NameMapper implementation |
|
287 | */ |
|
288 | protected NameMapper createNameMapper() { |
|
289 | 2328 | return new DefaultNameMapper(); |
290 | } |
|
291 | ||
292 | /** |
|
293 | * Gets the common Log used for introspection. |
|
294 | 693 | * It is more convenient to use a single Log |
295 | * that can be easily configured. |
|
296 | * @return Log, not null |
|
297 | */ |
|
298 | public Log getIntrospectionLog() { |
|
299 | 95794 | return introspectionLog; |
300 | } |
|
301 | ||
302 | /** |
|
303 | * Sets the common Log used by introspection. |
|
304 | 28569 | * It is more convenient to use a single Log |
305 | * that can be easily configured. |
|
306 | * @param log Log, not null |
|
307 | */ |
|
308 | public void setIntrospectionLog(Log log) { |
|
309 | 0 | introspectionLog = log; |
310 | 0 | } |
311 | ||
312 | ||
313 | /** |
|
314 | 0 | * Gets the <code>NamespacePrefixMapper</code> used to convert namespace URIs |
315 | 0 | * into prefixes. |
316 | * @return NamespacePrefixMapper, not null |
|
317 | */ |
|
318 | public NamespacePrefixMapper getPrefixMapper() { |
|
319 | 2100 | return prefixMapper; |
320 | } |
|
321 | ||
322 | /** |
|
323 | * Sets the <code>NamespacePrefixMapper</code> used to convert namespave URIs |
|
324 | 630 | * into prefixes. |
325 | * @param mapper NamespacePrefixMapper, not null |
|
326 | */ |
|
327 | public void setPrefixMapper(NamespacePrefixMapper mapper) { |
|
328 | 0 | prefixMapper = mapper; |
329 | 0 | } |
330 | ||
331 | ||
332 | /** |
|
333 | 0 | * Gets the simple type binding strategy. |
334 | 0 | * @return SimpleTypeMapper, not null |
335 | */ |
|
336 | public SimpleTypeMapper getSimpleTypeMapper() { |
|
337 | 7720 | return simpleTypeMapper; |
338 | } |
|
339 | ||
340 | /** |
|
341 | * Sets the simple type binding strategy. |
|
342 | 2316 | * @param mapper SimpleTypeMapper, not null |
343 | */ |
|
344 | public void setSimpleTypeMapper(SimpleTypeMapper mapper) { |
|
345 | 30 | simpleTypeMapper = mapper; |
346 | 30 | } |
347 | ||
348 | /** |
|
349 | * Gets the <code>TypeBindingStrategy</code> to be used |
|
350 | 9 | * to determine the binding for Java types. |
351 | 9 | * @return the <code>TypeBindingStrategy</code> to be used, |
352 | * not null |
|
353 | */ |
|
354 | public TypeBindingStrategy getTypeBindingStrategy() { |
|
355 | 20074 | return typeBindingStrategy; |
356 | } |
|
357 | ||
358 | /** |
|
359 | * Sets the <code>TypeBindingStrategy</code> to be used |
|
360 | 6015 | * to determine the binding for Java types. |
361 | * @param typeBindingStrategy the <code>TypeBindingStrategy</code> to be used, |
|
362 | * not null |
|
363 | */ |
|
364 | public void setTypeBindingStrategy(TypeBindingStrategy typeBindingStrategy) { |
|
365 | 0 | this.typeBindingStrategy = typeBindingStrategy; |
366 | 0 | } |
367 | ||
368 | ||
369 | /** |
|
370 | 0 | * Gets the <code>MappingDerivationStrategy</code> |
371 | 0 | * used to determine whether the bind or introspection time |
372 | * type should determine the mapping. |
|
373 | * @since 0.7 |
|
374 | * @return <code>MappingDerivationStrategy</code>, not null |
|
375 | */ |
|
376 | public MappingDerivationStrategy getMappingDerivationStrategy() { |
|
377 | 16412 | return mappingDerivationStrategy; |
378 | } |
|
379 | /** |
|
380 | * Sets the <code>MappingDerivationStrategy</code> |
|
381 | * used to determine whether the bind or introspection time |
|
382 | 4911 | * type should determine the mapping. |
383 | * @since 0.7 |
|
384 | * @param mappingDerivationStrategy <code>MappingDerivationStrategy</code>, not null |
|
385 | */ |
|
386 | public void setMappingDerivationStrategy( |
|
387 | MappingDerivationStrategy mappingDerivationStrategy) { |
|
388 | 90 | this.mappingDerivationStrategy = mappingDerivationStrategy; |
389 | 90 | } |
390 | ||
391 | /** |
|
392 | * Gets the strategy which determines the properties to be ignored. |
|
393 | 27 | * @since 0.7 |
394 | 27 | * @return the <code>PropertySuppressionStrategy</code> to be used for introspection, not null |
395 | */ |
|
396 | public PropertySuppressionStrategy getPropertySuppressionStrategy() { |
|
397 | 14662 | return propertySuppressionStrategy; |
398 | } |
|
399 | ||
400 | /** |
|
401 | * Sets the strategy which determines the properties to be ignored. |
|
402 | 4386 | * @since 0.7 |
403 | * @param propertySuppressionStrategy the <code>PropertySuppressionStrategy</code> to be used for introspection, not null |
|
404 | */ |
|
405 | public void setPropertySuppressionStrategy( |
|
406 | PropertySuppressionStrategy propertySuppressionStrategy) { |
|
407 | 30 | this.propertySuppressionStrategy = propertySuppressionStrategy; |
408 | 30 | } |
409 | ||
410 | /** |
|
411 | * Gets the strategy used to determine which types are collective. |
|
412 | 9 | * @return <code>CollectiveTypeStrategy</code>, not null |
413 | 9 | */ |
414 | public CollectiveTypeStrategy getCollectiveTypeStrategy() { |
|
415 | 17048 | return collectiveTypeStrategy; |
416 | } |
|
417 | ||
418 | /** |
|
419 | * Sets the strategy used to determine which types are collective. |
|
420 | 5100 | * @param collectiveTypeStrategy <code>CollectiveTypeStrategy</code>, not null |
421 | */ |
|
422 | public void setCollectiveTypeStrategy( |
|
423 | CollectiveTypeStrategy collectiveTypeStrategy) { |
|
424 | 0 | this.collectiveTypeStrategy = collectiveTypeStrategy; |
425 | 0 | } |
426 | ||
427 | /** |
|
428 | * Is this a loop type class? |
|
429 | 0 | * @since 0.7 |
430 | 0 | * @param type is this <code>Class</code> a loop type? |
431 | * @return true if the type is a loop type, or if type is null |
|
432 | */ |
|
433 | public boolean isLoopType(Class type) { |
|
434 | 17048 | return getCollectiveTypeStrategy().isCollective(type); |
435 | } |
|
436 | } |