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.OpenImmoFeedbackDocument; 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.5. * * @since 1.0 * @author Andreas Rudolph */ public class OpenImmo_1_2_5 extends XmlConverter<OpenImmoDocument, OpenImmoVersion> { private final static Logger LOGGER = LoggerFactory.getLogger(OpenImmo_1_2_5.class); @Override public OpenImmoVersion getVersion() { return OpenImmoVersion.V1_2_5; } /** * Downgrade an OpenImmo document from version 1.2.5 to 1.2.4. * * @param doc OpenImmo document in version 1.2.5 */ @Override public void downgradeToPreviousVersion(OpenImmoDocument doc) { doc.setDocumentVersion(OpenImmoVersion.V1_2_4); // downgrade a feedback document if (doc instanceof OpenImmoFeedbackDocument) { try { this.removeFeedbackObjektChildElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove unsupported children of <objekt> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } } // downgrade a transfer document else if (doc instanceof OpenImmoTransferDocument) { try { this.removeKontaktpersonChildElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove unsupported children of <kontaktperson> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeMwstGesamtElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove unsupported <mwst_gesamt> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeVerkehrswertElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove unsupported <verkehrswert> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeAnzahlLogiaElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove unsupported <anzahl_logia> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeErschliessungUmfangElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove unsupported <erschliessung_umfang> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeVerwaltungTechnChildElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove unsupported children of <verwaltung_techn> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeZustandElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <zustand> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeBebaubarNachElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <bebaubar_nach> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeErschliessungElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <erschliessung> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeWohnungElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <wohnung> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeHausElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <haus> 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.4 to 1.2.5. * * @param doc OpenImmo document in version 1.2.4 */ @Override public void upgradeFromPreviousVersion(OpenImmoDocument doc) { doc.setDocumentVersion(OpenImmoVersion.V1_2_5); if (doc instanceof OpenImmoTransferDocument) { try { this.upgradeEnergiepassElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't upgrade <energiepass> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } } } /** * Downgrade <bebaubar_nach> elements to OpenImmo 1.2.4. * <p> * The option "BAULAND_OHNE_B_PLAN" for the "bebaubar_attr" attribute of * <bebaubar_nach> elements is not available in version 1.2.4. * <p> * Any occurences of these values are removed. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void downgradeBebaubarNachElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:zustand_angaben/io:bebaubar_nach[@bebaubar_attr]", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("bebaubar_attr")); if ("BAULAND_OHNE_B_PLAN".equalsIgnoreCase(value)) node.removeAttribute("bebaubar_attr"); } } /** * Downgrade <energiepass> elements to OpenImmo 1.2.4. * <p> * The child elements <hwbwert>, <hwbklasse>, * <fgeewert>, <fgeeklasse> are copied into separate * <user_defined_simplefield> elements as it was * suggested by OpenImmo e.V.. * * @param doc OpenImmo document in version 1.2.5 * @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 hwbwertPassed = false; boolean hwbklassePassed = false; boolean fgeewertPassed = false; boolean fgeeklassePassed = false; List childNodes; // create a <user_defined_simplefield> for <hwbwert> elements childNodes = XmlUtils.newXPath("io:hwbwert", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!hwbwertPassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if (value != null) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_hwbwert", value)); hwbwertPassed = true; } } node.removeChild(childNode); } // create a <user_defined_simplefield> for <hwbklasse> elements childNodes = XmlUtils.newXPath("io:hwbklasse", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!hwbklassePassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if (value != null) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_hwbklasse", value)); hwbklassePassed = true; } } node.removeChild(childNode); } // create a <user_defined_simplefield> for <fgeewert> elements childNodes = XmlUtils.newXPath("io:fgeewert", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!fgeewertPassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if (value != null) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_fgeewert", value)); fgeewertPassed = true; } } node.removeChild(childNode); } // create a <user_defined_simplefield> for <baujahr> elements childNodes = XmlUtils.newXPath("io:fgeeklasse", doc).selectNodes(node); for (Object childItem : childNodes) { Node childNode = (Node) childItem; if (!fgeeklassePassed) { String value = StringUtils.trimToNull(childNode.getTextContent()); if (value != null) { parentNode.appendChild( OpenImmoUtils.createUserDefinedSimplefield(doc, "epass_fgeeklasse", value)); fgeeklassePassed = true; } } node.removeChild(childNode); } } } /** * Downgrade <erschliessung> elements to OpenImmo 1.2.4. * <p> * The option "ORTSUEBLICHERSCHLOSSEN" for the "erschl_attr" attribute of * <erschliessung> elements is not available in version 1.2.4. * <p> * Any occurence of these values are removed. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void downgradeErschliessungElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:zustand_angaben/io:erschliessung[@erschl_attr]", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("erschl_attr")); if ("ORTSUEBLICHERSCHLOSSEN".equalsIgnoreCase(value)) node.removeAttribute("erschl_attr"); } } /** * Downgrade <haus> elements to OpenImmo 1.2.4. * <p> * The option "FERTIGHAUS" for the "haustyp" attribute of <haus> * elements is not available in version 1.2.4. * <p> * Any occurence of these values is replaced by the "KEINE_ANGABE" value. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void downgradeHausElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:objektkategorie/io:objektart/io:haus[@haustyp]", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("haustyp")); if ("FERTIGHAUS".equalsIgnoreCase(value)) node.setAttribute("haustyp", "KEINE_ANGABE"); } } /** * Downgrade <wohnung> elements to OpenImmo 1.2.4. * <p> * The option "ATTIKAWOHNUNG" for the "wohnungtyp" attribute of * <wohnung> elements is not available in version 1.2.4. * <p> * Any occurence of these values is replaced by the "KEINE_ANGABE" value. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void downgradeWohnungElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:objektkategorie/io:objektart/io:wohnung[@wohnungtyp]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("wohnungtyp")); if ("ATTIKAWOHNUNG".equalsIgnoreCase(value)) node.setAttribute("wohnungtyp", "KEINE_ANGABE"); } } /** * Downgrade <zustand> elements to OpenImmo 1.2.4. * <p> * The options "TEIL_SANIERT", "VOLL_SANIERT", "SANIERUNGSBEDUERFTIG" for the * "zustand_art" attribute of <zustand> elements are not available in * version 1.2.4. * <p> * Any occurence of the "TEIL_SANIERT" value is replaced by the * "TEIL_VOLLSANIERT" value. * <p> * Any occurence of the "VOLL_SANIERT" value is replaced by the * "TEIL_VOLLSANIERT" value. * <p> * Any occurence of the "SANIERUNGSBEDUERFTIG" value is removed. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void downgradeZustandElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:zustand_angaben/io:zustand[@zustand_art]", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("zustand_art")); if ("TEIL_SANIERT".equalsIgnoreCase(value)) node.setAttribute("zustand_art", "TEIL_VOLLSANIERT"); else if ("VOLL_SANIERT".equalsIgnoreCase(value)) node.setAttribute("zustand_art", "TEIL_VOLLSANIERT"); else if ("SANIERUNGSBEDUERFTIG".equalsIgnoreCase(value)) node.removeAttribute("zustand_art"); } } /** * Remove <anzahl_logia> elements. * <p> * OpenImmo 1.2.4 does not support <anzahl_logia> elements. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void removeAnzahlLogiaElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:openimmo/io:anbieter/io:immobilie/io:flaechen/io:anzahl_logia", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove <erschliessung_umfang> elements. * <p> * OpenImmo 1.2.4 does not support <erschliessung_umfang> elements. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void removeErschliessungUmfangElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:zustand_angaben/io:erschliessung_umfang", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove unsupported children from all <objekt> elements in feedback * XML. * <p> * OpenImmo 1.2.4 does not support the following children in feedback XML's * for <objekt> elements: <land>, <stadtbezirk>, * <anzahl_zimmer>, <flaeche> * <p> * These elements are removed by this function. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void removeFeedbackObjektChildElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo_feedback/io:objekt/io:land |" + "/io:openimmo_feedback/io:objekt/io:stadtbezirk |" + "/io:openimmo_feedback/io:objekt/io:anzahl_zimmer |" + "/io:openimmo_feedback/io:objekt/io:flaeche", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove unsupported children from all <kontaktperson> elements. * <p> * OpenImmo 1.2.4 does not support the following children for * <kontaktperson> elements: <position>, * <immobilientreuhaenderid>, <foto> * <p> * These elements are removed by this function. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void removeKontaktpersonChildElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:openimmo/io:anbieter/io:immobilie/io:kontaktperson/io:position |" + "/io:openimmo/io:anbieter/io:immobilie/io:kontaktperson/io:immobilientreuhaenderid |" + "/io:openimmo/io:anbieter/io:immobilie/io:kontaktperson/io:foto", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove <mwst_gesamt> elements. * <p> * OpenImmo 1.2.4 does not support <mwst_gesamt> elements. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void removeMwstGesamtElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:openimmo/io:anbieter/io:immobilie/io:preise/io:mwst_gesamt", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove <verkehrswert> elements. * <p> * OpenImmo 1.2.4 does not support <verkehrswert> elements. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void removeVerkehrswertElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:versteigerung/io:verkehrswert", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove unsupported children from all <verwaltung_techn> elements. * <p> * OpenImmo 1.2.4 does not support the following children for * <verwaltung_techn> elements: <gruppen_kennung>, <master>, * <sprache> * <p> * These elements are removed by this function. * * @param doc OpenImmo document in version 1.2.5 * @throws JaxenException */ protected void removeVerwaltungTechnChildElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:verwaltung_techn/io:gruppen_kennung |" + "/io:openimmo/io:anbieter/io:immobilie/io:verwaltung_techn/io:master |" + "/io:openimmo/io:anbieter/io:immobilie/io:verwaltung_techn/io:sprache", 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.5. * <p> * The <user_defined_simplefield> elements for Austria, that were * suggested by OpenImmo e.V., are explicitly supported in OpenImmo 1.2.5 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.4 * @throws JaxenException */ protected void upgradeEnergiepassElements(Document doc) throws JaxenException { Map<String, String> fields = new HashMap<String, String>(); fields.put("hwbwert", "user_defined_simplefield[@feldname='epass_hwbwert']"); fields.put("hwbklasse", "user_defined_simplefield[@feldname='epass_hwbklasse']"); fields.put("fgeewert", "user_defined_simplefield[@feldname='epass_fgeewert']"); fields.put("fgeeklasse", "user_defined_simplefield[@feldname='epass_fgeeklasse']"); 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); } } } }