/* * Copyright (c) 2015 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.io.appschema.model; import static eu.esdihumboldt.hale.io.appschema.AppSchemaIO.APP_SCHEMA_NAMESPACE; import static eu.esdihumboldt.hale.io.appschema.AppSchemaIO.APP_SCHEMA_PREFIX; import static eu.esdihumboldt.hale.io.appschema.AppSchemaIO.getFirstElementByTagName; import static eu.esdihumboldt.hale.io.appschema.writer.AppSchemaMappingUtils.propertyTypeFromDOM; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import eu.esdihumboldt.hale.common.align.io.impl.DOMEntityDefinitionHelper; import eu.esdihumboldt.hale.common.align.io.impl.internal.generated.PropertyType; import eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition; import eu.esdihumboldt.hale.common.core.io.ComplexValueType; import eu.esdihumboldt.hale.common.schema.model.TypeIndex; /** * Complex value for {@link FeatureChaining} configuration. * * <p> * Since feature chaining configuration is supposed to be serialized to XML and * stored in the project file, and since {@link PropertyEntityDefinition} * objects can't be deserialized at project loading (entity definitions can't be * resolved before a {@link TypeIndex} is created), the * {@link #fromDOM(Element, Void)} method deserializes them to their JAXB * counterpart, {@link PropertyType}, leaving the entity resolution task to * downstream code. * </p> * * @author Stefano Costa, GeoSolutions */ public class FeatureChainingComplexType implements ComplexValueType<FeatureChaining, Void> { /** * @see eu.esdihumboldt.hale.common.core.io.ComplexValueType#fromDOM(org.w3c.dom.Element, * java.lang.Object) */ @Override public FeatureChaining fromDOM(Element fragment, Void context) { FeatureChaining value = new FeatureChaining(); if (fragment != null) { NodeList joinElList = fragment.getElementsByTagNameNS(APP_SCHEMA_NAMESPACE, "join"); for (int i = 0; i < joinElList.getLength(); i++) { Element joinEl = (Element) joinElList.item(i); JoinConfiguration joinConf = new JoinConfiguration(); joinConf.setJoinCellId(joinEl.getAttribute("id")); value.joins.put(joinConf.joinCellId, joinConf); NodeList chainElList = joinEl.getElementsByTagName("chain"); for (int j = 0; j < chainElList.getLength(); j++) { Element chainEl = (Element) chainElList.item(j); ChainConfiguration chainConf = new ChainConfiguration(); chainConf.setChainIndex(Integer.valueOf(chainEl.getAttribute("index"))); chainConf.setPrevChainIndex(Integer.valueOf(chainEl .getAttribute("prevChainIndex"))); Element nestedTypeTargetEl = getFirstElementByTagName(chainEl, "property", "http://www.esdi-humboldt.eu/hale/alignment"); // I can't resolve the property entity definition here, // 'cause I've no target schema index available to perform // the resolution: I'll do it later, during the export PropertyType propertyType = propertyTypeFromDOM(nestedTypeTargetEl); chainConf.setJaxbNestedTypeTarget(propertyType); Element mappingNameEl = getFirstElementByTagName(chainEl, "mapping"); if (mappingNameEl != null) { String mappingName = mappingNameEl.getAttribute("name"); chainConf.setMappingName(mappingName); } joinConf.chains.put(chainConf.chainIndex, chainConf); } } } return value; } /** * @see eu.esdihumboldt.hale.common.core.io.ComplexValueType#toDOM(java.lang.Object) */ @Override public Element toDOM(FeatureChaining value) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); try { DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.newDocument(); Element featureChainingEl = doc .createElementNS(APP_SCHEMA_NAMESPACE, "FeatureChaining"); featureChainingEl.setPrefix(APP_SCHEMA_PREFIX); if (value != null && value.joins != null) { for (JoinConfiguration joinConf : value.joins.values()) { Element joinEl = doc.createElementNS(APP_SCHEMA_NAMESPACE, "join"); joinEl.setAttribute("id", joinConf.getJoinCellId()); featureChainingEl.appendChild(joinEl); if (joinConf.chains != null) { for (ChainConfiguration chainConf : joinConf.chains.values()) { Element chainEl = doc.createElementNS(APP_SCHEMA_NAMESPACE, "chain"); chainEl.setAttribute("index", Integer.toString(chainConf.getChainIndex())); chainEl.setAttribute("prevChainIndex", Integer.toString(chainConf.getPrevChainIndex())); joinEl.appendChild(chainEl); PropertyEntityDefinition nestedTypeTarget = chainConf .getNestedTypeTarget(); Element nestedTargetEl = DOMEntityDefinitionHelper .propertyToDOM(nestedTypeTarget); if (nestedTargetEl != null) { Node nestedTargetAdopted = doc.adoptNode(nestedTargetEl); if (nestedTargetAdopted == null) { nestedTargetAdopted = doc.importNode(nestedTargetEl, true); } chainEl.appendChild(nestedTargetAdopted); } if (chainConf.mappingName != null && !chainConf.mappingName.trim().isEmpty()) { Element mappingEl = doc.createElementNS(APP_SCHEMA_NAMESPACE, "mapping"); mappingEl.setAttribute("name", chainConf.mappingName); chainEl.appendChild(mappingEl); } } } } } return featureChainingEl; } catch (ParserConfigurationException e) { throw new IllegalStateException(e); } } /** * @see eu.esdihumboldt.hale.common.core.io.ComplexValueType#getContextType() */ @Override public Class<? extends Void> getContextType() { return Void.class; } }