Java tutorial
/* * Copyright 2015-2016 OpenEstate.org. * * 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.openestate.io.openimmo.converters; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.jaxen.JaxenException; import org.openestate.io.core.XmlConverter; import org.openestate.io.core.XmlUtils; import org.openestate.io.openimmo.OpenImmoUtils; import org.openestate.io.openimmo.OpenImmoVersion; import org.openestate.io.openimmo.OpenImmoDocument; import org.openestate.io.openimmo.OpenImmoTransferDocument; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * Converter for version 1.2.7. * * @since 1.0 * @author Andreas Rudolph */ public class OpenImmo_1_2_7 extends XmlConverter<OpenImmoDocument, OpenImmoVersion> { private final static Logger LOGGER = LoggerFactory.getLogger(OpenImmo_1_2_7.class); @Override public OpenImmoVersion getVersion() { return OpenImmoVersion.V1_2_7; } /** * Downgrade an OpenImmo document from version 1.2.7 to 1.2.6. * * @param doc OpenImmo document in version 1.2.7 */ @Override public void downgradeToPreviousVersion(OpenImmoDocument doc) { doc.setDocumentVersion(OpenImmoVersion.V1_2_6); if (doc instanceof OpenImmoTransferDocument) { try { this.removeMultipleEnergiepassElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove odd <energiepass> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeObjektTextElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove odd <objekt_text> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeSummemietenettoElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <summemietenetto> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeBefeuerungElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <befeuerung> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeAnhangElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <anhang> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeAktionElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <aktion> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeEnergiepassElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <energiepass> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } } } /** * Upgrade an OpenImmo document from version 1.2.6 to 1.2.7. * * @param doc OpenImmo document in version 1.2.6 */ @Override public void upgradeFromPreviousVersion(OpenImmoDocument doc) { doc.setDocumentVersion(OpenImmoVersion.V1_2_7); if (doc instanceof OpenImmoTransferDocument) { try { this.upgradeSummemietenettoElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't upgrade <summemietenetto> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.upgradeEnergiepassElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't upgrade <energiepass> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } } } /** * Downgrade <aktion> elements to OpenImmo 1.2.6. * <p> * The option "REFERENZ" for the "aktionart" attribute of * <aktion> elements is not available in version 1.2.6. * <p> * Any occurence of the "REFERENZ" value is replaced by the "CHANGE" value. * * @param doc OpenImmo document in version 1.2.7 * @throws JaxenException */ protected void downgradeAktionElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:verwaltung_techn/io:aktion[@aktionart]", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("aktionart")); if ("REFERENZ".equalsIgnoreCase(value)) node.setAttribute("aktionart", "CHANGE"); } } /** * Downgrade <anhang> elements to OpenImmo 1.2.6. * <p> * The options "EPASS-SKALA", "ANBOBJURL" for the "gruppe" attribute of * <anhang> elements are not available in version 1.2.6 * * @param doc OpenImmo document in version 1.2.7 * @throws JaxenException */ protected void downgradeAnhangElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:anhang[@gruppe] | " + "/io:openimmo/io:anbieter/io:immobilie/io:anhaenge/io:anhang[@gruppe]", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("gruppe")); if ("EPASS-SKALA".equalsIgnoreCase(value)) node.removeAttribute("gruppe"); else if ("ANBOBJURL".equalsIgnoreCase(value)) node.removeAttribute("gruppe"); } } /** * Downgrade <befeuerung> elements to OpenImmo 1.2.6. * <p> * The attributes "KOHLE", "HOLZ", "FLUESSIGGAS" of <befeuerung> * elements are not available in OpenImmo 1.2.6. * * @param doc OpenImmo document in version 1.2.7 * @throws JaxenException */ protected void downgradeBefeuerungElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:ausstattung/io:befeuerung[@KOHLE or @HOLZ or @FLUESSIGGAS]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; node.removeAttribute("KOHLE"); node.removeAttribute("HOLZ"); node.removeAttribute("FLUESSIGGAS"); } } /** * Downgrade <energiepass> elements to OpenImmo 1.2.6. * <p> * The child elements <stromwert>, <waermewert>, * <wertklasse>, <baujahr>, <ausstelldatum>, * <jahrgang>, <gebaeudeart> are copied into separate * <user_defined_simplefield> elements as it was * <a href="http://www.openimmo.de/go.php/p/44/cm_enev2014.htm">suggested by OpenImmo e.V.</a>. * <p> * The child elements <primaerenergietraeger>, <epasstext> * are not available in OpenImmo 1.2.6. * * @param doc OpenImmo document in version 1.2.7 * @throws JaxenException */ protected void downgradeEnergiepassElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:zustand_angaben/io:energiepass", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); boolean stromwertPassed = false; boolean waermewertPassed = false; boolean wertklassePassed = false; boolean baujahrPassed = false; boolean ausstelldatumPassed = false; boolean jahrgangPassed = false; boolean gebaeudeartPassed = false; List childNodes; // <primaerenergietraeger> elements are not supported in version 1.2.6 childNodes = XmlUtils.newXPath("io:primaerenergietraeger", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; node.removeChild(childNode); } // <epasstext> elements are not supported in version 1.2.6 childNodes = XmlUtils.newXPath("io:epasstext", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; node.removeChild(childNode); } // create a <user_defined_simplefield> for <stromwert> elements childNodes = XmlUtils.newXPath("io:stromwert", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!stromwertPassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if (value != null) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_stromwert", value)); stromwertPassed = true; } } node.removeChild(childNode); } // create a <user_defined_simplefield> for <waermewert> elements childNodes = XmlUtils.newXPath("io:waermewert", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!waermewertPassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if (value != null) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_waermewert", value)); waermewertPassed = true; } } node.removeChild(childNode); } // create a <user_defined_simplefield> for <wertklasse> elements childNodes = XmlUtils.newXPath("io:wertklasse", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!wertklassePassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if (value != null) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_wertklasse", value)); wertklassePassed = true; } } node.removeChild(childNode); } // create a <user_defined_simplefield> for <baujahr> elements childNodes = XmlUtils.newXPath("io:baujahr", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!baujahrPassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if (value != null) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_baujahr", value)); baujahrPassed = true; } } node.removeChild(childNode); } // create a <user_defined_simplefield> for <ausstelldatum> elements childNodes = XmlUtils.newXPath("io:ausstelldatum", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!ausstelldatumPassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if (value != null) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_ausstelldatum", value)); ausstelldatumPassed = true; } } node.removeChild(childNode); } // create a <user_defined_simplefield> for <jahrgang> elements childNodes = XmlUtils.newXPath("io:jahrgang", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!jahrgangPassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if ("2008".equalsIgnoreCase(value) || "2014".equalsIgnoreCase(value) || "ohne".equalsIgnoreCase(value)) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_jahrgang", value)); jahrgangPassed = true; } } node.removeChild(childNode); } // create a <user_defined_simplefield> for <gebaeudeart> elements childNodes = XmlUtils.newXPath("io:gebaeudeart", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!gebaeudeartPassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if ("wohn".equalsIgnoreCase(value) || "nichtwohn".equalsIgnoreCase(value) || "ohne".equalsIgnoreCase(value)) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_gebaeudeart", value)); gebaeudeartPassed = true; } } node.removeChild(childNode); } } } /** * Downgrade <summemietenetto> elements to OpenImmo 1.2.6. * <p> * The attribute "summemieteust" of <summemietenetto> elements are * renamed to "sonstigemieteust" in OpenImmo 1.2.6. * * @param doc OpenImmo document in version 1.2.7 * @throws JaxenException */ protected void downgradeSummemietenettoElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:preise/io:summemietenetto[@summemieteust]", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("summemieteust")); if (value != null) node.setAttribute("sonstigemieteust", value); node.removeAttribute("summemieteust"); } } /** * Only use one <energiepass> element for each <immobilie>. * <p> * OpenImmo 1.2.6 does not allow more then one <energiepass> element * for each <immobilie> (maxOccurs=1). Odd <energiepass> elements * are removed by this function. * * @param doc OpenImmo document in version 1.2.7 * @throws JaxenException */ protected void removeMultipleEnergiepassElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:openimmo/io:anbieter/io:immobilie/io:zustand_angaben", doc) .selectNodes(doc); for (Object item : nodes) { Element parentNode = (Element) item; List childNodes = XmlUtils.newXPath("io:energiepass", doc).selectNodes(parentNode); if (childNodes.size() < 2) continue; for (int j = 1; j < childNodes.size(); j++) { parentNode.removeChild((Node) childNodes.get(j)); } } } /** * Remove <objekt_text> elements. * <p> * OpenImmo 1.2.6 does not support <objekt_text> elements. * * @param doc OpenImmo document in version 1.2.7 * @throws JaxenException */ protected void removeObjektTextElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:openimmo/io:anbieter/io:immobilie/io:freitexte/io:objekt_text", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Upgrade <energiepass> elements to OpenImmo 1.2.7. * <p> * The <user_defined_simplefield> elements for EnEv2014, that were * <a href="http://www.openimmo.de/go.php/p/44/cm_enev2014.htm">suggested by OpenImmo e.V.</a>, * are explicitly supported in OpenImmo 1.2.7 as child elements of * <energiepass>. Any matching <user_defined_simplefield> elements * are moved into the <energiepass> element. * * @param doc OpenImmo document in version 1.2.6 * @throws JaxenException */ protected void upgradeEnergiepassElements(Document doc) throws JaxenException { Map<String, String> fields = new HashMap<String, String>(); fields.put("stromwert", "user_defined_simplefield[@feldname='epass_stromwert']"); fields.put("waermewert", "user_defined_simplefield[@feldname='epass_waermewert']"); fields.put("wertklasse", "user_defined_simplefield[@feldname='epass_wertklasse']"); fields.put("baujahr", "user_defined_simplefield[@feldname='epass_baujahr']"); fields.put("ausstelldatum", "user_defined_simplefield[@feldname='epass_ausstelldatum']"); fields.put("jahrgang", "user_defined_simplefield[@feldname='epass_jahrgang']"); fields.put("gebaeudeart", "user_defined_simplefield[@feldname='epass_gebaeudeart']"); List nodes = XmlUtils.newXPath("/io:openimmo/io:anbieter/io:immobilie/io:zustand_angaben", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element energiepassNode = (Element) XmlUtils.newXPath("io:energiepass", doc).selectSingleNode(node); if (energiepassNode == null) { energiepassNode = doc.createElementNS(StringUtils.EMPTY, "energiepass"); } for (Map.Entry<String, String> entry : fields.entrySet()) { boolean fieldProcessed = false; List childNodes = XmlUtils.newXPath(entry.getValue(), doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!fieldProcessed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if (value != null) { Element newElement = doc.createElementNS(StringUtils.EMPTY, entry.getKey()); newElement.setTextContent(value); energiepassNode.appendChild(newElement); fieldProcessed = true; } } node.removeChild(childNode); } } if (energiepassNode.getParentNode() == null && energiepassNode.hasChildNodes()) { node.appendChild(energiepassNode); } } } /** * Upgrade <summemietenetto> elements to OpenImmo 1.2.7. * <p> * The attribute "sonstigemieteust" of <summemietenetto> elements is * renamed to "summemieteust" in OpenImmo 1.2.7. * * @param doc OpenImmo document in version 1.2.6 * @throws JaxenException */ protected void upgradeSummemietenettoElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:preise/io:summemietenetto[@sonstigemieteust]", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("sonstigemieteust")); if (value != null) node.setAttribute("summemieteust", value); node.removeAttribute("sonstigemieteust"); } } }