View Javadoc

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.DefaultNameMapper;
21  import org.apache.commons.betwixt.strategy.DefaultPluralStemmer;
22  import org.apache.commons.betwixt.strategy.NameMapper;
23  import org.apache.commons.betwixt.strategy.NamespacePrefixMapper;
24  import org.apache.commons.betwixt.strategy.PluralStemmer;
25  import org.apache.commons.betwixt.strategy.SimpleTypeMapper;
26  import org.apache.commons.betwixt.strategy.StandardSimpleTypeMapper;
27  import org.apache.commons.betwixt.strategy.TypeBindingStrategy;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  
31  /***
32   * <p>Stores introspection phase binding configuration.</p>
33   * <p>
34   * There are two phase in Betwixt's processing. 
35   * The first phase is the introspection of the bean. 
36   * Strutural configuration settings effect this phase. 
37   * The second phase comes when Betwixt dynamically uses reflection 
38   * to execute the mapping. 
39   * This object stores configuration settings pertaining to the first phase.
40   * </p>
41   * <p>
42   * These common settings have been collected into one class so that they can  
43   * be more easily shared not only between the objects that execute the introspection
44   * but also (by a user) between different <code>XMLIntrospector</code>s.
45   * </p>
46   * @author <a href='http://jakarta.apache.org/'>Apache Commons Team</a>
47   * @version $Revision: 1.3 $
48   */
49  public class IntrospectionConfiguration {
50  
51      /*** should attributes or elements be used for primitive types */
52      private boolean attributesForPrimitives = false;
53      
54      /*** should we wrap collections in an extra element? */
55      private boolean wrapCollectionsInElement = true;
56  
57      /*** Should the existing bean info search path for java.reflect.Introspector be used? */
58      private boolean useBeanInfoSearchPath = false;
59  
60      // pluggable strategies        
61      /*** The strategy used to detect matching singular and plural properties */
62      private PluralStemmer pluralStemmer;
63      
64      /*** The strategy used to convert bean type names into element names */
65      private NameMapper elementNameMapper;
66  
67      /*** Strategy normalizes the Class of the Object before introspection */
68      private ClassNormalizer classNormalizer = new ClassNormalizer(); 
69      
70      /*** Log for introspection messages */
71      private Log introspectionLog = LogFactory.getLog(XMLIntrospector.class);
72  
73      /***
74       * The strategy used to convert bean type names into attribute names
75       * It will default to the normal nameMapper.
76       */
77      private NameMapper attributeNameMapper;
78  
79      /*** Prefix naming strategy */
80      private NamespacePrefixMapper prefixMapper = new NamespacePrefixMapper();
81      /*** Mapping strategy for simple types */
82      private SimpleTypeMapper simpleTypeMapper = new StandardSimpleTypeMapper();
83      /*** Binding strategy for Java type */
84      private TypeBindingStrategy typeBindingStrategy = TypeBindingStrategy.DEFAULT;
85      
86      /***
87        * Gets the <code>ClassNormalizer</code> strategy.
88        * This is used to determine the Class to be introspected
89        * (the normalized Class). 
90        *
91        * @return the <code>ClassNormalizer</code> used to determine the Class to be introspected
92        * for a given Object.
93        */
94      public ClassNormalizer getClassNormalizer() {
95          return classNormalizer;
96      }
97      
98      /***
99        * Sets the <code>ClassNormalizer</code> strategy.
100       * This is used to determine the Class to be introspected
101       * (the normalized Class). 
102       *
103       * @param classNormalizer the <code>ClassNormalizer</code> to be used to determine 
104       * the Class to be introspected for a given Object.
105       */    
106     public void setClassNormalizer(ClassNormalizer classNormalizer) {
107         this.classNormalizer = classNormalizer;
108     }
109 
110     /*** 
111       * Should attributes (or elements) be used for primitive types.
112       * @return true if primitive types will be mapped to attributes in the introspection
113       */
114     public boolean isAttributesForPrimitives() {
115         return attributesForPrimitives;
116     }
117 
118     /*** 
119       * Set whether attributes (or elements) should be used for primitive types. 
120       * @param attributesForPrimitives pass trus to map primitives to attributes,
121       *        pass false to map primitives to elements
122       */
123     public void setAttributesForPrimitives(boolean attributesForPrimitives) {
124         this.attributesForPrimitives = attributesForPrimitives;
125     }
126     
127     /***
128      * Should collections be wrapped in an extra element?
129      * 
130      * @return whether we should we wrap collections in an extra element? 
131      */
132     public boolean isWrapCollectionsInElement() {
133         return wrapCollectionsInElement;
134     }
135 
136     /*** 
137      * Sets whether we should we wrap collections in an extra element.
138      *
139      * @param wrapCollectionsInElement pass true if collections should be wrapped in a
140      *        parent element
141      */
142     public void setWrapCollectionsInElement(boolean wrapCollectionsInElement) {
143         this.wrapCollectionsInElement = wrapCollectionsInElement;
144     }    
145 
146     /*** 
147      * Get singular and plural matching strategy.
148      *
149      * @return the strategy used to detect matching singular and plural properties 
150      */
151     public PluralStemmer getPluralStemmer() {
152         if ( pluralStemmer == null ) {
153             pluralStemmer = createPluralStemmer();
154         }
155         return pluralStemmer;
156     }
157     
158     /*** 
159      * Sets the strategy used to detect matching singular and plural properties 
160      *
161      * @param pluralStemmer the PluralStemmer used to match singular and plural
162      */
163     public void setPluralStemmer(PluralStemmer pluralStemmer) {
164         this.pluralStemmer = pluralStemmer;
165     }
166     
167     /***
168      * Gets the name mapping strategy used to convert bean names into elements.
169      *
170      * @return the strategy used to convert bean type names into element 
171      * names. If no element mapper is currently defined then a default one is created.
172      */
173     public NameMapper getElementNameMapper() {
174         if ( elementNameMapper == null ) {
175             elementNameMapper = createNameMapper();
176          }
177         return elementNameMapper;
178     }
179      
180     /***
181      * Sets the strategy used to convert bean type names into element names
182      * @param nameMapper the NameMapper to use for the conversion
183      */
184     public void setElementNameMapper(NameMapper nameMapper) {
185         this.elementNameMapper = nameMapper;
186     }
187     
188     /***
189      * Gets the name mapping strategy used to convert bean names into attributes.
190      *
191      * @return the strategy used to convert bean type names into attribute
192      * names. If no attributeNamemapper is known, it will default to the ElementNameMapper
193      */
194     public NameMapper getAttributeNameMapper() {
195         if (attributeNameMapper == null) {
196             attributeNameMapper = createNameMapper();
197         }
198         return attributeNameMapper;
199      }
200 
201 
202     /***
203      * Sets the strategy used to convert bean type names into attribute names
204      * @param nameMapper the NameMapper to use for the convertion
205      */
206     public void setAttributeNameMapper(NameMapper nameMapper) {
207         this.attributeNameMapper = nameMapper;
208     }
209     
210     /***
211      * Should the original <code>java.reflect.Introspector</code> bean info search path be used?
212      * By default it will be false.
213      * 
214      * @return boolean if the beanInfoSearchPath should be used.
215      */
216     public boolean useBeanInfoSearchPath() {
217         return useBeanInfoSearchPath;
218     }
219 
220     /***
221      * Specifies if you want to use the beanInfoSearchPath 
222      * @see java.beans.Introspector for more details
223      * @param useBeanInfoSearchPath 
224      */
225     public void setUseBeanInfoSearchPath(boolean useBeanInfoSearchPath) {
226         this.useBeanInfoSearchPath = useBeanInfoSearchPath;
227     }
228     
229     /*** 
230      * A Factory method to lazily create a new strategy 
231      * to detect matching singular and plural properties.
232      *
233      * @return new defualt PluralStemmer implementation
234      */
235     protected PluralStemmer createPluralStemmer() {
236         return new DefaultPluralStemmer();
237     }
238     
239     /*** 
240      * A Factory method to lazily create a strategy 
241      * used to convert bean type names into element names.
242      *
243      * @return new default NameMapper implementation
244      */
245     protected NameMapper createNameMapper() {
246         return new DefaultNameMapper();
247     }
248     
249     /***
250      * Gets the common Log used for introspection.
251      * It is more convenient to use a single Log
252      * that can be easily configured.
253      * @return Log, not null
254      */
255     public Log getIntrospectionLog() {
256         return introspectionLog;
257     }
258 
259     /***
260      * Sets the common Log used by introspection.
261      * It is more convenient to use a single Log
262      * that can be easily configured.
263      * @param log Log, not null
264      */
265     public void setIntrospectionLog(Log log) {
266         introspectionLog = log;
267     }
268 
269     
270     /***
271      * Gets the <code>NamespacePrefixMapper</code> used to convert namespace URIs 
272      * into prefixes.
273      * @return NamespacePrefixMapper, not null
274      */
275     public NamespacePrefixMapper getPrefixMapper() {
276         return prefixMapper;
277     }
278 
279     /***
280      * Sets the <code>NamespacePrefixMapper</code> used to convert namespave URIs
281      * into prefixes.
282      * @param mapper NamespacePrefixMapper, not null
283      */
284     public void setPrefixMapper(NamespacePrefixMapper mapper) {
285         prefixMapper = mapper;
286     }
287     
288     
289     /***
290      * Gets the simple type binding strategy.
291      * @return SimpleTypeMapper, not null
292      */
293     public SimpleTypeMapper getSimpleTypeMapper() {
294         return simpleTypeMapper;
295     }
296 
297     /***
298      * Sets the simple type binding strategy.
299      * @param mapper SimpleTypeMapper, not null
300      */
301     public void setSimpleTypeMapper(SimpleTypeMapper mapper) {
302         simpleTypeMapper = mapper;
303     }
304 
305     /***
306      * Gets the <code>TypeBindingStrategy</code> to be used
307      * to determine the binding for Java types.
308      * @return the <code>TypeBindingStrategy</code> to be used, 
309      * not null
310      */
311     public TypeBindingStrategy getTypeBindingStrategy() {
312         return typeBindingStrategy;
313     }
314     
315     /***
316      * Sets the <code>TypeBindingStrategy</code> to be used
317      * to determine the binding for Java types.
318      * @param typeBindingStrategy the <code>TypeBindingStrategy</code> to be used,
319      * not null
320      */
321     public void setTypeBindingStrategy(TypeBindingStrategy typeBindingStrategy) {
322         this.typeBindingStrategy = typeBindingStrategy;
323     }
324 }