org.dozer.loader.xml.XMLParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dozer Show documentation
Show all versions of dozer Show documentation
Dozer is a powerful Java Bean to Java Bean mapper that recursively copies data from one object to another
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dozer.loader.xml;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.dozer.classmap.MappingDirection;
import org.dozer.classmap.MappingFileData;
import org.dozer.classmap.RelationshipType;
import org.dozer.config.BeanContainer;
import org.dozer.loader.DozerBuilder;
import org.dozer.loader.MappingsSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Internal class that parses a raw custom xml mapping file into ClassMap objects.
*
* Only intended for internal use.
*
* @author garsombke.franz
* @author johnsen.knut-erik
* @author dmitry.buzdin
*/
public class XMLParser implements MappingsSource {
private static final Logger log = LoggerFactory.getLogger(XMLParser.class);
// Common Elements/Attributes
private static final String WILDCARD = "wildcard";
private static final String TRIM_STRINGS = "trim-strings";
private static final String BEAN_FACTORY = "bean-factory";
private static final String DATE_FORMAT = "date-format";
private static final String RELATIONSHIP_TYPE = "relationship-type";
private static final String REMOVE_ORPHANS = "remove-orphans";
// Parsing Elements
private static final String CONFIGURATION_ELEMENT = "configuration";
private static final String STOP_ON_ERRORS_ELEMENT = "stop-on-errors";
private static final String CUSTOM_CONVERTERS_ELEMENT = "custom-converters";
private static final String COPY_BY_REFERENCES_ELEMENT = "copy-by-references";
private static final String COPY_BY_REFERENCE = "copy-by-reference";
private static final String CONVERTER_ELEMENT = "converter";
private static final String CLASS_A_ELEMENT = "class-a";
private static final String CLASS_B_ELEMENT = "class-b";
private static final String MAPPING_ELEMENT = "mapping";
private static final String FIELD_ELEMENT = "field";
private static final String FIELD_EXCLUDE_ELEMENT = "field-exclude";
private static final String A_ELEMENT = "a";
private static final String B_ELEMENT = "b";
private static final String SRC_TYPE_HINT_ELEMENT = "a-hint";
private static final String DEST_TYPE_HINT_ELEMENT = "b-hint";
private static final String SRC_TYPE_DEEP_INDEX_HINT_ELEMENT = "a-deep-index-hint";
private static final String DEST_TYPE_DEEP_INDEX_HINT_ELEMENT = "b-deep-index-hint";
private static final String ALLOWED_EXCEPTIONS_ELEMENT = "allowed-exceptions";
private static final String ALLOWED_EXCEPTION_ELEMENT = "exception";
private static final String VARIABLES_ELEMENT = "variables";
private static final String VARIABLE_ELEMENT = "variable";
// Parsing Attributes
private static final String TYPE_ATTRIBUTE = "type";
private static final String NAME_ATTRIBUTE = "name";
private static final String COPY_BY_REFERENCE_ATTRIBUTE = "copy-by-reference";
private static final String THE_SET_METHOD_ATTRIBUTE = "set-method";
private static final String THE_GET_METHOD_ATTRIBUTE = "get-method";
private static final String STOP_ON_ERRORS_ATTRIBUTE = "stop-on-errors";
private static final String MAPID_ATTRIBUTE = "map-id";
private static final String MAP_SET_METHOD_ATTRIBUTE = "map-set-method";
private static final String MAP_GET_METHOD_ATTRIBUTE = "map-get-method";
private static final String KEY_ATTRIBUTE = "key";
private static final String FACTORY_BEANID_ATTRIBUTE = "factory-bean-id";
private static final String IS_ACCESSIBLE_ATTRIBUTE = "is-accessible";
private static final String CREATE_METHOD_ATTRIBUTE = "create-method";
private static final String MAP_NULL_ATTRIBUTE = "map-null";
private static final String MAP_EMPTY_STRING_ATTRIBUTE = "map-empty-string";
private static final String CUSTOM_CONVERTER_ATTRIBUTE = "custom-converter";
private static final String CUSTOM_CONVERTER_ID_ATTRIBUTE = "custom-converter-id";
private static final String CUSTOM_CONVERTER_PARAM_ATTRIBUTE = "custom-converter-param";
private final Document document;
private final ElementReader elementReader;
/**
* @param document Xml document containing valid mappings definition
*/
public XMLParser(Document document) {
this.document = document;
this.elementReader = BeanContainer.getInstance().getElementReader();
}
private String getAttribute(Element element, String attribute) {
return elementReader.getAttribute(element, attribute);
}
private String getNodeValue(Element element) {
return elementReader.getNodeValue(element);
}
private void debugElement(Element element) {
log.debug("config name: {}",element.getNodeName());
log.debug(" value: {}", element.getFirstChild().getNodeValue());
}
/**
* Builds object representation of mappings based on content of Xml document
*
* @return mapping container
*/
public MappingFileData load() {
DozerBuilder builder = new DozerBuilder();
Element theRoot = document.getDocumentElement();
NodeList nl = theRoot.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
log.debug("name: {}", ele.getNodeName());
if (CONFIGURATION_ELEMENT.equals(ele.getNodeName())) {
parseConfiguration(ele, builder);
} else if (MAPPING_ELEMENT.equals(ele.getNodeName())) {
parseMapping(ele, builder);
}
}
}
return builder.build();
}
private void parseMapping(Element ele, DozerBuilder builder) {
DozerBuilder.MappingBuilder definitionBuilder = builder.mapping();
if (StringUtils.isNotEmpty(getAttribute(ele, DATE_FORMAT))) {
definitionBuilder.dateFormat(getAttribute(ele, DATE_FORMAT));
}
if (StringUtils.isNotEmpty(getAttribute(ele, MAP_NULL_ATTRIBUTE))) {
definitionBuilder.mapNull(BooleanUtils.toBoolean(getAttribute(ele, MAP_NULL_ATTRIBUTE)));
}
if (StringUtils.isNotEmpty(getAttribute(ele, MAP_EMPTY_STRING_ATTRIBUTE))) {
definitionBuilder.mapEmptyString(BooleanUtils.toBoolean(getAttribute(ele, MAP_EMPTY_STRING_ATTRIBUTE)));
}
if (StringUtils.isNotEmpty(getAttribute(ele, BEAN_FACTORY))) {
definitionBuilder.beanFactory(getAttribute(ele, BEAN_FACTORY));
}
if (StringUtils.isNotEmpty(getAttribute(ele, RELATIONSHIP_TYPE))) {
String relationshipTypeValue = getAttribute(ele, RELATIONSHIP_TYPE);
RelationshipType relationshipType = RelationshipType.valueOf(relationshipTypeValue);
definitionBuilder.relationshipType(relationshipType);
}
if (StringUtils.isNotEmpty(getAttribute(ele, WILDCARD))) {
definitionBuilder.wildcard(Boolean.valueOf(getAttribute(ele, WILDCARD)));
}
if (StringUtils.isNotEmpty(getAttribute(ele, TRIM_STRINGS))) {
definitionBuilder.trimStrings(Boolean.valueOf(getAttribute(ele, TRIM_STRINGS)));
}
if (StringUtils.isNotEmpty(getAttribute(ele, STOP_ON_ERRORS_ATTRIBUTE))) {
definitionBuilder.stopOnErrors(Boolean.valueOf(getAttribute(ele, STOP_ON_ERRORS_ATTRIBUTE)));
}
if (StringUtils.isNotEmpty(getAttribute(ele, MAPID_ATTRIBUTE))) {
definitionBuilder.mapId(getAttribute(ele, MAPID_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(ele, TYPE_ATTRIBUTE))) {
String mappingDirection = getAttribute(ele, TYPE_ATTRIBUTE);
MappingDirection direction = MappingDirection.valueOf(mappingDirection);
definitionBuilder.type(direction);
}
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element element = (Element) node;
debugElement(element);
if (CLASS_A_ELEMENT.equals(element.getNodeName())) {
String typeName = getNodeValue(element);
DozerBuilder.ClassDefinitionBuilder classBuilder = definitionBuilder.classA(typeName);
parseClass(element, classBuilder);
}
if (CLASS_B_ELEMENT.equals(element.getNodeName())) {
String typeName = getNodeValue(element);
DozerBuilder.ClassDefinitionBuilder classBuilder = definitionBuilder.classB(typeName);
parseClass(element, classBuilder);
}
if (FIELD_ELEMENT.equals(element.getNodeName())) {
parseGenericFieldMap(element, definitionBuilder);
} else if (FIELD_EXCLUDE_ELEMENT.equals(element.getNodeName())) {
parseFieldExcludeMap(element, definitionBuilder);
}
}
}
}
private void parseClass(Element element, DozerBuilder.ClassDefinitionBuilder classBuilder) {
if (StringUtils.isNotEmpty(getAttribute(element, MAP_GET_METHOD_ATTRIBUTE))) {
classBuilder.mapGetMethod(getAttribute(element, MAP_GET_METHOD_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(element, MAP_SET_METHOD_ATTRIBUTE))) {
classBuilder.mapSetMethod(getAttribute(element, MAP_SET_METHOD_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(element, BEAN_FACTORY))) {
classBuilder.beanFactory(getAttribute(element, BEAN_FACTORY));
}
if (StringUtils.isNotEmpty(getAttribute(element, FACTORY_BEANID_ATTRIBUTE))) {
classBuilder.factoryBeanId(getAttribute(element, FACTORY_BEANID_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(element, CREATE_METHOD_ATTRIBUTE))) {
classBuilder.createMethod(getAttribute(element, CREATE_METHOD_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(element, MAP_NULL_ATTRIBUTE))) {
classBuilder.mapNull(Boolean.valueOf(getAttribute(element, MAP_NULL_ATTRIBUTE)));
}
if (StringUtils.isNotEmpty(getAttribute(element, MAP_EMPTY_STRING_ATTRIBUTE))) {
classBuilder.mapEmptyString(Boolean.valueOf(getAttribute(element, MAP_EMPTY_STRING_ATTRIBUTE)));
}
if (StringUtils.isNotEmpty(getAttribute(element, IS_ACCESSIBLE_ATTRIBUTE))) {
classBuilder.isAccessible(Boolean.valueOf(getAttribute(element, IS_ACCESSIBLE_ATTRIBUTE)));
}
}
private void parseFieldExcludeMap(Element ele, DozerBuilder.MappingBuilder definitionBuilder) {
DozerBuilder.FieldExclusionBuilder fieldMapBuilder = definitionBuilder.fieldExclude();
if (StringUtils.isNotEmpty(getAttribute(ele, TYPE_ATTRIBUTE))) {
String mappingDirection = getAttribute(ele, TYPE_ATTRIBUTE);
MappingDirection direction = MappingDirection.valueOf(mappingDirection);
fieldMapBuilder.type(direction);
}
NodeList nodeList = ele.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node instanceof Element) {
Element element = (Element) node;
debugElement(element);
parseFieldElements(element, fieldMapBuilder);
}
}
}
private void parseFieldElements(Element element, DozerBuilder.FieldBuider fieldMapBuilder) {
if (A_ELEMENT.equals(element.getNodeName())) {
String name = getNodeValue(element);
String type = getAttribute(element, TYPE_ATTRIBUTE);
DozerBuilder.FieldDefinitionBuilder fieldBuilder = fieldMapBuilder.a(name, type);
parseField(element, fieldBuilder);
}
if (B_ELEMENT.equals(element.getNodeName())) {
String name = getNodeValue(element);
String type = getAttribute(element, TYPE_ATTRIBUTE);
DozerBuilder.FieldDefinitionBuilder fieldBuilder = fieldMapBuilder.b(name, type);
parseField(element, fieldBuilder);
}
}
private void parseGenericFieldMap(Element ele, DozerBuilder.MappingBuilder definitionBuilder) {
DozerBuilder.FieldMappingBuilder fieldMapBuilder = determineFieldMap(definitionBuilder, ele);
if (StringUtils.isNotEmpty(getAttribute(ele, COPY_BY_REFERENCE_ATTRIBUTE))) {
fieldMapBuilder.copyByReference(BooleanUtils.toBoolean(getAttribute(ele, COPY_BY_REFERENCE_ATTRIBUTE)));
}
if (StringUtils.isNotEmpty(getAttribute(ele, MAPID_ATTRIBUTE))) {
fieldMapBuilder.mapId(getAttribute(ele, MAPID_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(ele, TYPE_ATTRIBUTE))) {
String mappingDirection = getAttribute(ele, TYPE_ATTRIBUTE);
MappingDirection direction = MappingDirection.valueOf(mappingDirection);
fieldMapBuilder.type(direction);
}
if (StringUtils.isNotEmpty(getAttribute(ele, CUSTOM_CONVERTER_ATTRIBUTE))) {
fieldMapBuilder.customConverter(getAttribute(ele, CUSTOM_CONVERTER_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(ele, CUSTOM_CONVERTER_ID_ATTRIBUTE))) {
fieldMapBuilder.customConverterId(getAttribute(ele, CUSTOM_CONVERTER_ID_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(ele, CUSTOM_CONVERTER_PARAM_ATTRIBUTE))) {
fieldMapBuilder.customConverterParam(getAttribute(ele, CUSTOM_CONVERTER_PARAM_ATTRIBUTE));
}
parseFieldMap(ele, fieldMapBuilder);
}
private DozerBuilder.FieldMappingBuilder determineFieldMap(DozerBuilder.MappingBuilder definitionBuilder, Element ele) {
DozerBuilder.FieldMappingBuilder fieldMapBuilder = definitionBuilder.field();
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element element = (Element) node;
if (A_ELEMENT.equals(element.getNodeName())) {
String name = getNodeValue(element);
String type = getAttribute(element, TYPE_ATTRIBUTE);
DozerBuilder.FieldDefinitionBuilder builder = fieldMapBuilder.a(name, type);
parseField(element, builder);
}
if (B_ELEMENT.equals(element.getNodeName())) {
String name = getNodeValue(element);
String type = getAttribute(element, TYPE_ATTRIBUTE);
DozerBuilder.FieldDefinitionBuilder builder = fieldMapBuilder.b(name, type);
parseField(element, builder);
}
}
}
return fieldMapBuilder;
}
private void parseFieldMap(Element ele, DozerBuilder.FieldMappingBuilder fieldMapBuilder) {
setRelationshipType(ele, fieldMapBuilder);
if (StringUtils.isNotEmpty(getAttribute(ele, REMOVE_ORPHANS))) {
fieldMapBuilder.removeOrphans(BooleanUtils.toBoolean(getAttribute(ele, REMOVE_ORPHANS)));
}
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element element = (Element) node;
debugElement(element);
parseFieldElements(element, fieldMapBuilder);
if (SRC_TYPE_HINT_ELEMENT.equals(element.getNodeName())) {
String hint = getNodeValue(element);
fieldMapBuilder.srcHintContainer(hint);
}
if (DEST_TYPE_HINT_ELEMENT.equals(element.getNodeName())) {
String hint = getNodeValue(element);
fieldMapBuilder.destHintContainer(hint);
}
if (SRC_TYPE_DEEP_INDEX_HINT_ELEMENT.equals(element.getNodeName())) {
String hint = getNodeValue(element);
fieldMapBuilder.srcDeepIndexHintContainer(hint);
}
if (DEST_TYPE_DEEP_INDEX_HINT_ELEMENT.equals(element.getNodeName())) {
String hint = getNodeValue(element);
fieldMapBuilder.destDeepIndexHintContainer(hint);
}
}
}
}
private void setRelationshipType(Element ele, DozerBuilder.FieldMappingBuilder definitionBuilder) {
RelationshipType relationshipType = null;
if (StringUtils.isNotEmpty(getAttribute(ele, RELATIONSHIP_TYPE))) {
String relationshipTypeValue = getAttribute(ele, RELATIONSHIP_TYPE);
relationshipType = RelationshipType.valueOf(relationshipTypeValue);
}
definitionBuilder.relationshipType(relationshipType);
}
private void parseField(Element ele, DozerBuilder.FieldDefinitionBuilder fieldBuilder) {
if (StringUtils.isNotEmpty(getAttribute(ele, DATE_FORMAT))) {
fieldBuilder.dateFormat(getAttribute(ele, DATE_FORMAT));
}
if (StringUtils.isNotEmpty(getAttribute(ele, THE_GET_METHOD_ATTRIBUTE))) {
fieldBuilder.theGetMethod(getAttribute(ele, THE_GET_METHOD_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(ele, THE_SET_METHOD_ATTRIBUTE))) {
fieldBuilder.theSetMethod(getAttribute(ele, THE_SET_METHOD_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(ele, MAP_GET_METHOD_ATTRIBUTE))) {
fieldBuilder.mapGetMethod(getAttribute(ele, MAP_GET_METHOD_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(ele, MAP_SET_METHOD_ATTRIBUTE))) {
fieldBuilder.mapSetMethod(getAttribute(ele, MAP_SET_METHOD_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(ele, KEY_ATTRIBUTE))) {
fieldBuilder.key(getAttribute(ele, KEY_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(ele, CREATE_METHOD_ATTRIBUTE))) {
fieldBuilder.createMethod(getAttribute(ele, CREATE_METHOD_ATTRIBUTE));
}
if (StringUtils.isNotEmpty(getAttribute(ele, IS_ACCESSIBLE_ATTRIBUTE))) {
fieldBuilder.accessible(BooleanUtils.toBoolean(getAttribute(ele, IS_ACCESSIBLE_ATTRIBUTE)));
}
}
private void parseConfiguration(Element ele, DozerBuilder builder) {
DozerBuilder.ConfigurationBuilder configBuilder = builder.configuration();
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element element = (Element) node;
debugElement(element);
final String nodeValue = getNodeValue(element);
if (STOP_ON_ERRORS_ELEMENT.equals(element.getNodeName())) {
configBuilder.stopOnErrors(Boolean.valueOf(nodeValue));
} else if (DATE_FORMAT.equals(element.getNodeName())) {
configBuilder.dateFormat(nodeValue);
} else if (WILDCARD.equals(element.getNodeName())) {
configBuilder.wildcard(Boolean.valueOf(nodeValue));
} else if (TRIM_STRINGS.equals(element.getNodeName())) {
configBuilder.trimStrings(Boolean.valueOf(nodeValue));
} else if (RELATIONSHIP_TYPE.equals(element.getNodeName())) {
RelationshipType relationshipType = RelationshipType.valueOf(nodeValue);
configBuilder.relationshipType(relationshipType);
} else if (BEAN_FACTORY.equals(element.getNodeName())) {
configBuilder.beanFactory(nodeValue);
} else if (CUSTOM_CONVERTERS_ELEMENT.equals(element.getNodeName())) {
parseCustomConverters(element, configBuilder);
} else if (COPY_BY_REFERENCES_ELEMENT.equals(element.getNodeName())) {
parseCopyByReferences(element, configBuilder);
} else if (ALLOWED_EXCEPTIONS_ELEMENT.equals(element.getNodeName())) {
parseAllowedExceptions(element, configBuilder);
} else if (VARIABLES_ELEMENT.equals(element.getNodeName())) {
parseVariables(element);
}
}
}
}
private void parseVariables(Element element) {
NodeList nl = element.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
debugElement(ele);
if (VARIABLE_ELEMENT.equals(ele.getNodeName())) {
ELEngine engine = BeanContainer.getInstance().getElEngine();
if (engine != null) {
String name = getAttribute(ele, NAME_ATTRIBUTE);
String value = getNodeValue(ele);
engine.setVariable(name, value);
}
}
}
}
}
private void parseCustomConverters(Element ele, DozerBuilder.ConfigurationBuilder config) {
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element element = (Element) node;
debugElement(element);
if (CONVERTER_ELEMENT.equals(element.getNodeName())) {
String converterType = getAttribute(element, TYPE_ATTRIBUTE);
DozerBuilder.CustomConverterBuilder customConverterBuilder = config.customConverter(converterType);
NodeList list = element.getChildNodes();
for (int x = 0; x < list.getLength(); x++) {
Node node1 = list.item(x);
if (node1 instanceof Element) {
Element element1 = (Element) node1;
if (CLASS_A_ELEMENT.equals(element1.getNodeName())) {
customConverterBuilder.classA(getNodeValue(element1));
} else if (CLASS_B_ELEMENT.equals(element1.getNodeName())) {
customConverterBuilder.classB(getNodeValue(element1));
}
}
}
}
}
}
}
private void parseCopyByReferences(Element ele, DozerBuilder.ConfigurationBuilder config) {
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element element = (Element) node;
debugElement(element);
if (COPY_BY_REFERENCE.equals(element.getNodeName())) {
String typeMask = getNodeValue(element);
config.copyByReference(typeMask);
}
}
}
}
private void parseAllowedExceptions(Element ele, DozerBuilder.ConfigurationBuilder config) {
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element element = (Element) node;
debugElement(element);
if (ALLOWED_EXCEPTION_ELEMENT.equals(element.getNodeName())) {
String exceptionType = getNodeValue(element);
config.allowedException(exceptionType);
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy