1 16 package net.sf.dozer.util.mapping.util; 17 18 import java.io.IOException ; 19 import java.io.InputStream ; 20 21 import javax.xml.parsers.DocumentBuilder ; 22 import javax.xml.parsers.DocumentBuilderFactory ; 23 import javax.xml.parsers.ParserConfigurationException ; 24 25 import net.sf.dozer.util.mapping.converters.CustomConverterContainer; 26 import net.sf.dozer.util.mapping.converters.CustomConverterDescription; 27 import net.sf.dozer.util.mapping.fieldmap.AllowedExceptionContainer; 28 import net.sf.dozer.util.mapping.fieldmap.ClassMap; 29 import net.sf.dozer.util.mapping.fieldmap.Configuration; 30 import net.sf.dozer.util.mapping.fieldmap.CopyByReference; 31 import net.sf.dozer.util.mapping.fieldmap.CopyByReferenceContainer; 32 import net.sf.dozer.util.mapping.fieldmap.DozerClass; 33 import net.sf.dozer.util.mapping.fieldmap.ExcludeFieldMap; 34 import net.sf.dozer.util.mapping.fieldmap.Field; 35 import net.sf.dozer.util.mapping.fieldmap.FieldMap; 36 import net.sf.dozer.util.mapping.fieldmap.GenericFieldMap; 37 import net.sf.dozer.util.mapping.fieldmap.Hint; 38 import net.sf.dozer.util.mapping.fieldmap.Mappings; 39 40 import org.apache.commons.lang.BooleanUtils; 41 import org.apache.commons.lang.StringUtils; 42 import org.apache.commons.logging.Log; 43 import org.apache.commons.logging.LogFactory; 44 import org.w3c.dom.Document ; 45 import org.w3c.dom.Element ; 46 import org.w3c.dom.Node ; 47 import org.w3c.dom.NodeList ; 48 import org.xml.sax.Attributes ; 49 import org.xml.sax.SAXException ; 50 import org.xml.sax.SAXParseException ; 51 import org.xml.sax.helpers.DefaultHandler ; 52 53 56 public class XMLParser extends MapperConstants { 57 58 private static final Log log = LogFactory.getLog(XMLParser.class); 59 60 private final Mappings mappings = new Mappings(); 61 62 public Mappings parse(InputStream inputSource) throws SAXException , ParserConfigurationException , IOException , 63 ClassNotFoundException { 64 DocumentBuilderFactory factory = createDocumentBuilderFactory(); 65 DocumentBuilder builder = createDocumentBuilder(factory); 66 Document document = builder.parse(inputSource); 67 Element theRoot = document.getDocumentElement(); 68 NodeList nl = theRoot.getChildNodes(); 69 for (int i = 0; i < nl.getLength(); i++) { 70 Node node = nl.item(i); 71 if (node instanceof Element ) { 72 Element ele = (Element ) node; 73 log.info("name: " + ele.getNodeName()); 74 if (CONFIGURATION_ELEMENT.equals(ele.getNodeName())) { 75 parseConfiguration(ele); 76 } else if (MAPPING_ELEMENT.equals(ele.getNodeName())) { 77 parseMapping(ele); 78 } 79 } 80 } 81 return mappings; 82 } 83 84 private void parseMapping(Element ele) throws ClassNotFoundException { 85 ClassMap classMap = new ClassMap(); 86 mappings.getMapping().add(classMap); 87 if (StringUtils.isNotEmpty(ele.getAttribute(DATE_FORMAT_ATTRIBUTE))) { 88 classMap.setDateFormat(ele.getAttribute(DATE_FORMAT_ATTRIBUTE)); 89 } 90 if (StringUtils.isNotEmpty(ele.getAttribute(MAP_NULL_ATTRIBUTE))) { 91 classMap.setMapNull(BooleanUtils.toBoolean(ele.getAttribute(MAP_NULL_ATTRIBUTE))); 92 } 93 if (StringUtils.isNotEmpty(ele.getAttribute(MAP_EMPTY_STRING_ATTRIBUTE))) { 94 classMap.setMapEmptyString(BooleanUtils.toBoolean(ele.getAttribute(MAP_EMPTY_STRING_ATTRIBUTE))); 95 } 96 if (StringUtils.isNotEmpty(ele.getAttribute(BEAN_FACTORY_ATTRIBUTE))) { 97 classMap.setBeanFactory(ele.getAttribute(BEAN_FACTORY_ATTRIBUTE)); 98 } 99 if (StringUtils.isNotEmpty(ele.getAttribute(WILDCARD_ATTRIBUTE))) { 100 classMap.setWildcard(BooleanUtils.toBoolean(ele.getAttribute(WILDCARD_ATTRIBUTE))); 101 } 102 if (StringUtils.isNotEmpty(ele.getAttribute(STOP_ON_ERRORS_ATTRIBUTE))) { 103 classMap.setStopOnErrors(BooleanUtils.toBoolean(ele.getAttribute(STOP_ON_ERRORS_ATTRIBUTE))); 104 } 105 if (StringUtils.isNotEmpty(ele.getAttribute(MAPID_ATTRIBUTE))) { 106 classMap.setMapId(ele.getAttribute(MAPID_ATTRIBUTE)); 107 } 108 if (StringUtils.isNotEmpty(ele.getAttribute(TYPE_ATTRIBUTE))) { 109 classMap.setType(ele.getAttribute(TYPE_ATTRIBUTE)); 110 } 111 if (StringUtils.isNotEmpty(ele.getAttribute(IS_ACCESSIBLE_ATTRIBUTE))) { 112 classMap.setAccessible(BooleanUtils.toBoolean(ele.getAttribute(IS_ACCESSIBLE_ATTRIBUTE))); 113 } 114 NodeList nl = ele.getChildNodes(); 115 for (int i = 0; i < nl.getLength(); i++) { 116 Node node = nl.item(i); 117 if (node instanceof Element ) { 118 Element element = (Element ) node; 119 log.info("config name: " + element.getNodeName()); 120 log.info(" value: " + element.getFirstChild().getNodeValue()); 121 if (CLASS_A_ELEMENT.equals(element.getNodeName())) { 122 DozerClass source = new DozerClass(); 123 source.setName(element.getFirstChild().getNodeValue().trim()); 124 if (StringUtils.isNotEmpty(element.getAttribute(MAP_GET_METHOD_ATTRIBUTE))) { 125 source.setMapGetMethod(element.getAttribute(MAP_GET_METHOD_ATTRIBUTE)); 126 } 127 if (StringUtils.isNotEmpty(element.getAttribute(MAP_SET_METHOD_ATTRIBUTE))) { 128 source.setMapSetMethod(element.getAttribute(MAP_SET_METHOD_ATTRIBUTE)); 129 } 130 if (StringUtils.isNotEmpty(element.getAttribute(BEAN_FACTORY_ATTRIBUTE))) { 131 source.setBeanFactory(element.getAttribute(BEAN_FACTORY_ATTRIBUTE)); 132 } 133 if (StringUtils.isNotEmpty(element.getAttribute(FACTORY_BEANID_ATTRIBUTE))) { 134 source.setFactoryBeanId(element.getAttribute(FACTORY_BEANID_ATTRIBUTE)); 135 } 136 if (StringUtils.isNotEmpty(element.getAttribute(CREATE_METHOD_ATTRIBUTE))) { 137 source.setCreateMethod(element.getAttribute(CREATE_METHOD_ATTRIBUTE)); 138 } 139 if (StringUtils.isNotEmpty(element.getAttribute(MAP_NULL_ATTRIBUTE))) { 140 source.setMapNull(Boolean.valueOf(element.getAttribute(MAP_NULL_ATTRIBUTE))); 141 } 142 if (StringUtils.isNotEmpty(element.getAttribute(MAP_EMPTY_STRING_ATTRIBUTE))) { 143 source.setMapEmptyString(Boolean.valueOf(element.getAttribute(MAP_EMPTY_STRING_ATTRIBUTE))); 144 } 145 classMap.setSourceClass(source); 146 } 147 if (CLASS_B_ELEMENT.equals(element.getNodeName())) { 148 DozerClass dest = new DozerClass(); 149 dest.setName(element.getFirstChild().getNodeValue().trim()); 150 if (StringUtils.isNotEmpty(element.getAttribute(MAP_GET_METHOD_ATTRIBUTE))) { 151 dest.setMapGetMethod(element.getAttribute(MAP_GET_METHOD_ATTRIBUTE)); 152 } 153 if (StringUtils.isNotEmpty(element.getAttribute(MAP_SET_METHOD_ATTRIBUTE))) { 154 dest.setMapSetMethod(element.getAttribute(MAP_SET_METHOD_ATTRIBUTE)); 155 } 156 if (StringUtils.isNotEmpty(element.getAttribute(BEAN_FACTORY_ATTRIBUTE))) { 157 dest.setBeanFactory(element.getAttribute(BEAN_FACTORY_ATTRIBUTE)); 158 } 159 if (StringUtils.isNotEmpty(element.getAttribute(FACTORY_BEANID_ATTRIBUTE))) { 160 dest.setFactoryBeanId(element.getAttribute(FACTORY_BEANID_ATTRIBUTE)); 161 } 162 if (StringUtils.isNotEmpty(element.getAttribute(CREATE_METHOD_ATTRIBUTE))) { 163 dest.setCreateMethod(element.getAttribute(CREATE_METHOD_ATTRIBUTE)); 164 } 165 if (StringUtils.isNotEmpty(element.getAttribute(MAP_NULL_ATTRIBUTE))) { 166 dest.setMapNull(Boolean.valueOf(element.getAttribute(MAP_NULL_ATTRIBUTE))); 167 } 168 if (StringUtils.isNotEmpty(element.getAttribute(MAP_EMPTY_STRING_ATTRIBUTE))) { 169 dest.setMapEmptyString(Boolean.valueOf(element.getAttribute(MAP_EMPTY_STRING_ATTRIBUTE))); 170 } 171 classMap.setDestClass(dest); 172 } 173 if (FIELD_ELEMENT.equals(element.getNodeName())) { 174 parseGenericFieldMap(element, classMap); 175 } else if (FIELD_EXCLUDE_ELEMENT.equals(element.getNodeName())) { 176 parseFieldExcludeMap(element, classMap); 177 } 178 } 179 } 180 } 181 182 private void parseFieldExcludeMap(Element ele, ClassMap classMap) { 183 ExcludeFieldMap efm = new ExcludeFieldMap(); 184 if (StringUtils.isNotEmpty(ele.getAttribute(TYPE_ATTRIBUTE))) { 185 efm.setType(ele.getAttribute(TYPE_ATTRIBUTE)); 186 } 187 classMap.addFieldMapping(efm); 188 NodeList nl = ele.getChildNodes(); 189 for (int i = 0; i < nl.getLength(); i++) { 190 Node node = nl.item(i); 191 if (node instanceof Element ) { 192 Element element = (Element ) node; 193 log.info("config name: " + element.getNodeName()); 194 log.info(" value: " + element.getFirstChild().getNodeValue()); 195 parseFieldElements(element, efm); 196 } 197 } 198 } 199 200 private void parseFieldElements(Element element, FieldMap fieldMap) { 201 if (A_ELEMENT.equals(element.getNodeName())) { 202 fieldMap.setSourceField(parseField(element)); 203 } 204 if (B_ELEMENT.equals(element.getNodeName())) { 205 fieldMap.setDestField(parseField(element)); 206 } 207 } 208 209 private void parseGenericFieldMap(Element ele, ClassMap classMap) { 210 GenericFieldMap gfm = new GenericFieldMap(); 211 classMap.addFieldMapping(gfm); 212 if (StringUtils.isNotEmpty(ele.getAttribute(COPY_BY_REFERENCE_ATTRIBUTE))) { 213 gfm.setCopyByReference(BooleanUtils.toBoolean(ele.getAttribute(COPY_BY_REFERENCE_ATTRIBUTE))); 214 } 215 if (StringUtils.isNotEmpty(ele.getAttribute(MAPID_ATTRIBUTE))) { 216 gfm.setMapId(ele.getAttribute(MAPID_ATTRIBUTE)); 217 } 218 if (StringUtils.isNotEmpty(ele.getAttribute(TYPE_ATTRIBUTE))) { 219 gfm.setType(ele.getAttribute(TYPE_ATTRIBUTE)); 220 } 221 if (StringUtils.isNotEmpty(ele.getAttribute(CUSTOM_CONVERTER_ATTRIBUTE))) { 222 gfm.setCustomConverter(ele.getAttribute(CUSTOM_CONVERTER_ATTRIBUTE)); 223 } 224 225 226 parseFieldMap(ele, gfm); 227 } 228 229 private void parseFieldMap(Element ele, GenericFieldMap fieldMap) { 230 if (StringUtils.isNotEmpty(ele.getAttribute(RELATIONSHIP_TYPE_ATTRIBUTE))) { 231 fieldMap.setRelationshipType(ele.getAttribute(RELATIONSHIP_TYPE_ATTRIBUTE)); 232 } 233 NodeList nl = ele.getChildNodes(); 234 for (int i = 0; i < nl.getLength(); i++) { 235 Node node = nl.item(i); 236 if (node instanceof Element ) { 237 Element element = (Element ) node; 238 log.info("config name: " + element.getNodeName()); 239 log.info(" value: " + element.getFirstChild().getNodeValue()); 240 parseFieldElements(element, fieldMap); 241 if (SOURCE_TYPE_HINT_ELEMENT.equals(element.getNodeName())) { 242 Hint sourceHint = new Hint(); 243 sourceHint.setHintName(element.getFirstChild().getNodeValue().trim()); 244 fieldMap.setSourceTypeHint(sourceHint); 245 } 246 if (DESTINATION_TYPE_HINT_ELEMENT.equals(element.getNodeName())) { 247 Hint destHint = new Hint(); 248 destHint.setHintName(element.getFirstChild().getNodeValue().trim()); 249 fieldMap.setDestinationTypeHint(destHint); 250 } 251 } 252 } 253 } 254 255 private boolean isIndexed(String fieldName) { 256 return (fieldName != null) && (fieldName.matches(".+\\[\\d+\\]")); 257 } 258 259 private String getFieldNameOfIndexedField(String fieldName) { 260 return fieldName == null ? null : fieldName.replaceAll("\\[\\d+\\]", ""); 261 } 262 263 private int getIndexOfIndexedField(String fieldName) { 264 return Integer.parseInt(fieldName.replaceAll(".*\\[", "").replaceAll("\\]", "")); 265 } 266 267 private Field parseField(Element ele) { 268 Field rvalue = null; 269 String type = null; 270 String fieldName; 271 String name = (ele.getFirstChild().getNodeValue().trim()); 272 if (isIndexed(name)) { 273 fieldName = getFieldNameOfIndexedField(name); 274 } else { 275 fieldName = name; 276 } 277 if (StringUtils.isNotEmpty(ele.getAttribute(TYPE_ATTRIBUTE))) { 278 type = ele.getAttribute(TYPE_ATTRIBUTE); 279 } 280 rvalue = new Field(fieldName, type); 281 if (isIndexed(name)) { 282 rvalue.setIndexed(true); 283 rvalue.setIndex(getIndexOfIndexedField(name)); 284 } 285 if (StringUtils.isNotEmpty(ele.getAttribute(DATE_FORMAT_ATTRIBUTE))) { 286 rvalue.setDateFormat(ele.getAttribute(DATE_FORMAT_ATTRIBUTE)); 287 } 288 if (StringUtils.isNotEmpty(ele.getAttribute(THE_GET_METHOD_ATTRIBUTE))) { 289 rvalue.setTheGetMethod(ele.getAttribute(THE_GET_METHOD_ATTRIBUTE)); 290 } 291 if (StringUtils.isNotEmpty(ele.getAttribute(THE_SET_METHOD_ATTRIBUTE))) { 292 rvalue.setTheSetMethod(ele.getAttribute(THE_SET_METHOD_ATTRIBUTE)); 293 } 294 if (StringUtils.isNotEmpty(ele.getAttribute(MAP_GET_METHOD_ATTRIBUTE))) { 295 rvalue.setMapGetMethod(ele.getAttribute(MAP_GET_METHOD_ATTRIBUTE)); 296 } 297 if (StringUtils.isNotEmpty(ele.getAttribute(MAP_SET_METHOD_ATTRIBUTE))) { 298 rvalue.setMapSetMethod(ele.getAttribute(MAP_SET_METHOD_ATTRIBUTE)); 299 } 300 if (StringUtils.isNotEmpty(ele.getAttribute(KEY_ATTRIBUTE))) { 301 rvalue.setKey(ele.getAttribute(KEY_ATTRIBUTE)); 302 } 303 if (StringUtils.isNotEmpty(ele.getAttribute(CREATE_METHOD_ATTRIBUTE))) { 304 rvalue.setCreateMethod(ele.getAttribute(CREATE_METHOD_ATTRIBUTE)); 305 } 306 if (StringUtils.isNotEmpty(ele.getAttribute(IS_ACCESSIBLE_ATTRIBUTE))) { 307 rvalue.setAccessible(BooleanUtils.toBoolean(ele.getAttribute(IS_ACCESSIBLE_ATTRIBUTE))); 308 } 309 return rvalue; 310 } 311 312 private void parseConfiguration(Element ele) throws ClassNotFoundException { 313 Configuration config = new Configuration(); 314 mappings.setConfiguration(config); 315 NodeList nl = ele.getChildNodes(); 316 for (int i = 0; i < nl.getLength(); i++) { 317 Node node = nl.item(i); 318 if (node instanceof Element ) { 319 Element element = (Element ) node; 320 log.info("config name: " + element.getNodeName()); 321 log.info(" value: " + element.getFirstChild().getNodeValue()); 322 if (STOP_ON_ERRORS_ELEMENT.equals(element.getNodeName())) { 323 config.setStopOnErrors(BooleanUtils.toBoolean(element.getFirstChild().getNodeValue().trim())); 324 } else if (DATE_FORMAT_ELEMENT.equals(element.getNodeName())) { 325 config.setDateFormat(element.getFirstChild().getNodeValue().trim()); 326 } else if (WILDCARD_ELEMENT.equals(element.getNodeName())) { 327 config.setWildcard(BooleanUtils.toBoolean(element.getFirstChild().getNodeValue().trim())); 328 } else if (BEAN_FACTORY_ELEMENT.equals(element.getNodeName())) { 329 config.setBeanFactory(element.getFirstChild().getNodeValue().trim()); 330 } else if (IS_ACCESSIBLE_ELEMENT.equals(element.getNodeName())) { 331 config.setAccessible(BooleanUtils.toBoolean(element.getFirstChild().getNodeValue().trim())); 332 } else if (CUSTOM_CONVERTERS_ELEMENT.equals(element.getNodeName())) { 333 parseCustomConverters(element, config); 334 } else if (COPY_BY_REFERENCES_ELEMENT.equals(element.getNodeName())) { 335 parseCopyByReferences(element, config); 336 } else if (ALLOWED_EXCEPTIONS_ELEMENT.equals(element.getNodeName())) { 337 parseAllowedExceptions(element, config); 338 } 339 } 340 } 341 } 342 343 private void parseCustomConverters(Element ele, Configuration config) throws ClassNotFoundException { 344 CustomConverterContainer container = new CustomConverterContainer(); 345 config.setCustomConverters(container); 346 NodeList nl = ele.getChildNodes(); 347 for (int i = 0; i < nl.getLength(); i++) { 348 Node node = nl.item(i); 349 if (node instanceof Element ) { 350 Element element = (Element ) node; 351 log.info("config name: " + element.getNodeName()); 352 log.info(" value: " + element.getFirstChild().getNodeValue()); 353 if (CONVERTER_ELEMENT.equals(element.getNodeName())) { 354 CustomConverterDescription customConverter = new CustomConverterDescription(); 355 container.addConverter(customConverter); 356 customConverter.setType(Thread.currentThread().getContextClassLoader().loadClass(element.getAttribute(TYPE_ATTRIBUTE))); 357 NodeList list = element.getChildNodes(); 358 for (int x = 0; x < list.getLength(); x++) { 359 Node node1 = list.item(x); 360 if (node1 instanceof Element ) { 361 Element element1 = (Element ) node1; 362 if (CLASS_A_ELEMENT.equals(element1.getNodeName())) { 363 customConverter.setClassA(Thread.currentThread().getContextClassLoader().loadClass(element1.getFirstChild().getNodeValue().trim())); 364 } else if (CLASS_B_ELEMENT.equals(element1.getNodeName())) { 365 customConverter.setClassB(Thread.currentThread().getContextClassLoader().loadClass(element1.getFirstChild().getNodeValue().trim())); 366 } 367 } 368 } 369 } 370 } 371 } 372 } 373 374 private void parseCopyByReferences(Element ele, Configuration config) { 375 CopyByReferenceContainer container = new CopyByReferenceContainer(); 376 config.setCopyByReferences(container); 377 NodeList nl = ele.getChildNodes(); 378 for (int i = 0; i < nl.getLength(); i++) { 379 Node node = nl.item(i); 380 if (node instanceof Element ) { 381 Element element = (Element ) node; 382 log.info("config name: " + element.getNodeName()); 383 log.info(" value: " + element.getFirstChild().getNodeValue()); 384 if (COPY_BY_REFERENCE_ELEMENT.equals(element.getNodeName())) { 385 CopyByReference cbr = new CopyByReference(); 386 container.getCopyByReferences().add(cbr); 387 cbr.setReferenceName(element.getFirstChild().getNodeValue().trim()); 388 } 389 } 390 } 391 } 392 private void parseAllowedExceptions(Element ele, Configuration config) { 393 AllowedExceptionContainer container = new AllowedExceptionContainer(); 394 config.setAllowedExceptions(container); 395 NodeList nl = ele.getChildNodes(); 396 for (int i = 0; i < nl.getLength(); i++) { 397 Node node = nl.item(i); 398 if (node instanceof Element ) { 399 Element element = (Element ) node; 400 log.info("config name: " + element.getNodeName()); 401 log.info(" value: " + element.getFirstChild().getNodeValue()); 402 if (ALLOWED_EXCEPTION_ELEMENT.equals(element.getNodeName())) { 403 try { 404 Class ex = Class.forName(element.getFirstChild().getNodeValue()); 405 if (!RuntimeException .class.isAssignableFrom(ex)) { 406 throw new ClassNotFoundException (); 407 } 408 container.getExceptions().add(ex); 409 } catch (ClassNotFoundException e) { 410 log.error("Class not found or does not extend RuntimeException: " + element.getFirstChild().getNodeValue()); 411 } 412 } 413 } 414 } 415 } 416 417 425 protected DocumentBuilderFactory createDocumentBuilderFactory() throws ParserConfigurationException { 426 427 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 428 factory.setValidating(true); 429 factory.setNamespaceAware(false); 430 factory.setIgnoringElementContentWhitespace(true); 431 return factory; 432 } 433 434 444 protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory) throws ParserConfigurationException { 445 446 DocumentBuilder docBuilder = factory.newDocumentBuilder(); 447 docBuilder.setErrorHandler(new DozerDefaultHandler()); 448 docBuilder.setEntityResolver(new DozerResolver()); 449 return docBuilder; 450 } 451 452 class DozerDefaultHandler extends DefaultHandler { 453 private final Log log = LogFactory.getLog(DozerDefaultHandler.class); 454 455 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { 456 log.info("tag: " + qName); 457 } 458 459 public void warning(SAXParseException e) throws SAXException { 460 throw new SAXException (getMessage("Warning", e)); 462 } 463 464 public void error(SAXParseException e) throws SAXException { 465 throw new SAXException (getMessage("Error", e)); 466 } 467 468 public void fatalError(SAXParseException e) throws SAXException { 469 throw new SAXException (getMessage("Fatal Error", e)); 470 } 471 472 private String getMessage(String level, SAXParseException e) { 473 return ("Parsing " + level + "\n" + "Line: " + e.getLineNumber() + "\n" + "URI: " + e.getSystemId() + "\n" 474 + "Message: " + e.getMessage()); 475 } 476 } 477 } 478 | Popular Tags |