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