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.List; 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.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; /** * Converter for version 1.2.2. * * @since 1.0 * @author Andreas Rudolph */ public class OpenImmo_1_2_2 extends XmlConverter<OpenImmoDocument, OpenImmoVersion> { private final static Logger LOGGER = LoggerFactory.getLogger(OpenImmo_1_2_2.class); @Override public OpenImmoVersion getVersion() { return OpenImmoVersion.V1_2_2; } /** * Downgrade an OpenImmo document from version 1.2.2 to 1.2.1. * * @param doc OpenImmo document in version 1.2.2 */ @Override public void downgradeToPreviousVersion(OpenImmoDocument doc) { doc.setDocumentVersion(OpenImmoVersion.V1_2_1); if (doc instanceof OpenImmoTransferDocument) { try { this.downgradeUebertragungElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <uebertragung> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeVersteigerungElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove <versteigerung> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeProvisionspflichtigElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove <provisionspflichtig> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeAusstattungChildElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove unsupported children of <ausstattung> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeObjektartElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <objektart> 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); } try { this.downgradeBodenElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <boden> 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.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.downgradeGrundstueckElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <grundstueck> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeBueroPraxenElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <buero_praxen> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeEinzelhandelElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <einzelhandel> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeGastgewerbeElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <gastgewerbe> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeHallenLagerProdElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <hallen_lager_prod> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeLandUndForstwirtschaftElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <land_und_forstwirtschaft> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeFreizeitimmobilieGewerblichElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <freizeitimmobilie_gewerblich> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } } } /** * Upgrade an OpenImmo document from version 1.2.1 to 1.2.2. * * @param doc OpenImmo document in version 1.2.1 */ @Override public void upgradeFromPreviousVersion(OpenImmoDocument doc) { doc.setDocumentVersion(OpenImmoVersion.V1_2_2); 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 <befeuerung> elements to OpenImmo 1.2.1. * <p> * The attribute "LUFTWP" for <befeuerung> elements is not available in * version 1.2.1. * <p> * Any occurences of these values are removed. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeBefeuerungElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:ausstattung/io:befeuerung[@LUFTWP]", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; node.removeAttribute("LUFTWP"); } } /** * Downgrade <boden> elements to OpenImmo 1.2.1. * <p> * The attributes "FERTIGPARKETT", "LAMINAT", "LINOLEUM" for <boden> * elements are not available in version 1.2.1. * <p> * Any occurences of these values are removed. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeBodenElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:ausstattung/io:boden[@FERTIGPARKETT or @LAMINAT or @LINOLEUM]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; node.removeAttribute("FERTIGPARKETT"); node.removeAttribute("LAMINAT"); node.removeAttribute("LINOLEUM"); } } /** * Downgrade <buero_praxen> elements to OpenImmo 1.2.1. * <p> * The options "BUEROZENTRUM", "LOFT_ATELIER", "PRAXISFLAECHE", "PRAXISHAUS" * for the "buero_typ" attribute of <buero_praxen> elements are not * available in version 1.2.1. * <p> * Any occurence of these values is replaced by the general "BUEROFLAECHE" * value. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeBueroPraxenElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:objektkategorie/io:objektart/io:buero_praxen[@buero_typ]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("buero_typ")); if ("BUEROZENTRUM".equalsIgnoreCase(value)) node.setAttribute("buero_typ", "BUEROFLAECHE"); else if ("LOFT_ATELIER".equalsIgnoreCase(value)) node.setAttribute("buero_typ", "BUEROFLAECHE"); else if ("PRAXISFLAECHE".equalsIgnoreCase(value)) node.setAttribute("buero_typ", "BUEROFLAECHE"); else if ("PRAXISHAUS".equalsIgnoreCase(value)) node.setAttribute("buero_typ", "BUEROFLAECHE"); } } /** * Downgrade <einzelhandel> elements to OpenImmo 1.2.1. * <p> * The options "KAUFHAUS", "FACTORY_OUTLET", "KIOSK", "VERKAUFSFLAECHE", * "AUSSTELLUNGSFLAECHE" for the "handel_typ" attribute of * <einzelhandel> elements are not available in version 1.2.1. * <p> * Any occurence of these values is removed. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeEinzelhandelElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:objektkategorie/io:objektart/io:einzelhandel[@handel_typ]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("handel_typ")); if ("KAUFHAUS".equalsIgnoreCase(value)) node.removeAttribute("handel_typ"); else if ("FACTORY_OUTLET".equalsIgnoreCase(value)) node.removeAttribute("handel_typ"); else if ("KIOSK".equalsIgnoreCase(value)) node.removeAttribute("handel_typ"); else if ("VERKAUFSFLAECHE".equalsIgnoreCase(value)) node.removeAttribute("handel_typ"); else if ("AUSSTELLUNGSFLAECHE".equalsIgnoreCase(value)) node.removeAttribute("handel_typ"); } } /** * Downgrade <energiepass> elements to OpenImmo 1.2.1. * <p> * The <epart> child element of the <energiepass> element is * renamed to <art> in version 1.2.1. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeEnergiepassElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:zustand_angaben/io:energiepass/io:epart", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); Element newNode = doc.createElementNS(StringUtils.EMPTY, "art"); newNode.setTextContent(node.getTextContent()); parentNode.replaceChild(newNode, node); } } /** * Downgrade <freizeitimmobilie_gewerblich> elements to OpenImmo 1.2.1. * <p> * The option "FREIZEITANLAGE" for the "freizeit_typ" attribute of * <freizeitimmobilie_gewerblich> elements is not available in version * 1.2.1. * <p> * Any occurence of these values is removed. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeFreizeitimmobilieGewerblichElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:objektkategorie/io:objektart/io:freizeitimmobilie_gewerblich[@freizeit_typ]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("freizeit_typ")); if ("FREIZEITANLAGE".equalsIgnoreCase(value)) node.removeAttribute("freizeit_typ"); } } /** * Downgrade <einzelhandel> elements to OpenImmo 1.2.1. * <p> * The options "BAR", "CAFE", "DISCOTHEK", "RESTAURANT", "RAUCHERLOKAL", * "EINRAUMLOKAL" for the "gastgew_typ" attribute of * <gastgewerbe> elements are not available in version 1.2.1. * <p> * Any occurence of these values is removed. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeGastgewerbeElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:objektkategorie/io:objektart/io:gastgewerbe[@gastgew_typ]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("gastgew_typ")); if ("BAR".equalsIgnoreCase(value)) node.removeAttribute("gastgew_typ"); else if ("CAFE".equalsIgnoreCase(value)) node.removeAttribute("gastgew_typ"); else if ("DISCOTHEK".equalsIgnoreCase(value)) node.removeAttribute("gastgew_typ"); else if ("RESTAURANT".equalsIgnoreCase(value)) node.removeAttribute("gastgew_typ"); else if ("RAUCHERLOKAL".equalsIgnoreCase(value)) node.removeAttribute("gastgew_typ"); else if ("EINRAUMLOKAL".equalsIgnoreCase(value)) node.removeAttribute("gastgew_typ"); } } /** * Downgrade <grundstueck> elements to OpenImmo 1.2.1. * <p> * The option "GEWERBEPARK" for the "grundst_typ" attribute of * <grundstueck> elements is not available in version 1.2.1. * <p> * Any occurence of these values is removed. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeGrundstueckElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:objektkategorie/io:objektart/io:grundstueck[@grundst_typ]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("grundst_typ")); if ("GEWERBEPARK".equalsIgnoreCase(value)) node.removeAttribute("grundst_typ"); } } /** * Downgrade <hallen_lager_prod> elements to OpenImmo 1.2.1. * <p> * The options "INDUSTRIEHALLE", "LAGERFLAECHEN", "LAGER_MIT_FREIFLAECHE", * "SPEDITIONSLAGER", "KUEHLHAUS" for the "hallen_typ" attribute of * <hallen_lager_prod> elements are not available in version 1.2.1. * <p> * Any occurence of "KUEHLHAUS" is removed. Other unsupported options are * replaced by "HALLE" or "LAGER". * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeHallenLagerProdElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:objektkategorie/io:objektart/io:hallen_lager_prod[@hallen_typ]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("hallen_typ")); if ("INDUSTRIEHALLE".equalsIgnoreCase(value)) node.setAttribute("hallen_typ", "HALLE"); else if ("LAGERFLAECHEN".equalsIgnoreCase(value)) node.setAttribute("hallen_typ", "LAGER"); else if ("LAGER_MIT_FREIFLAECHE".equalsIgnoreCase(value)) node.setAttribute("hallen_typ", "LAGER"); else if ("SPEDITIONSLAGER".equalsIgnoreCase(value)) node.setAttribute("hallen_typ", "LAGER"); else if ("KUEHLHAUS".equalsIgnoreCase(value)) node.removeAttribute("hallen_typ"); } } /** * Downgrade <haus> elements to OpenImmo 1.2.1. * <p> * The option "KEINE_ANGABE" for the "haustyp" attribute of <haus> * elements are not available in version 1.2.1. * <p> * Any occurence of these values is removed. * * @param doc OpenImmo document in version 1.2.2 * @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 ("KEINE_ANGABE".equalsIgnoreCase(value)) node.removeAttribute("haustyp"); } } /** * Downgrade <land_und_forstwirtschaft> elements to OpenImmo 1.2.1. * <p> * The option "ANWESEN" for the "land_typ" attribute of * <land_und_forstwirtschaft> elements is not available in version * 1.2.1. * <p> * Any occurence of these values is replaced by the * "SONSTIGE_LANDWIRTSCHAFTSIMMOBILIEN" value. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeLandUndForstwirtschaftElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath( "/io:openimmo/io:anbieter/io:immobilie/io:objektkategorie/io:objektart/io:land_und_forstwirtschaft[@land_typ]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getAttribute("land_typ")); if ("ANWESEN".equalsIgnoreCase(value)) node.setAttribute("land_typ", "SONSTIGE_LANDWIRTSCHAFTSIMMOBILIEN"); } } /** * Downgrade <objektart> elements to OpenImmo 1.2.1. * <p> * The <objektart> element does only allow the same type of child * element in version 1.2.1. * <p> * Any child type, that differs from the first child type, is removed. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeObjektartElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:openimmo/io:anbieter/io:immobilie/io:objektkategorie/io:objektart", doc) .selectNodes(doc); for (Object item : nodes) { Element parentNode = (Element) item; String type = null; List childNodes = XmlUtils.newXPath("*", doc).selectNodes(parentNode); for (Object childItem : childNodes) { Element node = (Element) childItem; if (type == null) { //LOGGER.debug( "PRIMARY TYPE: " + node.getLocalName() ); type = node.getLocalName(); } else if (!type.equalsIgnoreCase(node.getLocalName())) { //LOGGER.debug( "REMOVE SECONDARY TYPE: " + node.getLocalName() ); parentNode.removeChild(node); } } } } /** * Downgrade <uebertragung> elements to OpenImmo 1.2.1. * <p> * The attribute "timestamp" for <uebertragung> elements is not * available in version 1.2.1. * <p> * Any occurences of these values are removed. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void downgradeUebertragungElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:openimmo/io:uebertragung[@timestamp]", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; node.removeAttribute("timestamp"); } } /** * Downgrade <wohnung> elements to OpenImmo 1.2.1. * <p> * The option "KEINE_ANGABE" for the "wohnungtyp" attribute of <wohnung> * elements is not available in version 1.2.1. * <p> * Any occurence of these values is removed. * * @param doc OpenImmo document in version 1.2.2 * @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 ("KEINE_ANGABE".equalsIgnoreCase(value)) node.removeAttribute("wohnungtyp"); } } /** * Remove unsupported children from all <ausstattung> elements. * <p> * OpenImmo 1.2.1 does not support the following children for * <ausstattung> elements: <ausstatt_kategorie>, <dachform>, * <bauweise>, <ausbaustufe> * <p> * These elements are removed by this function. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void removeAusstattungChildElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:ausstattung/io:ausstatt_kategorie | " + "/io:openimmo/io:anbieter/io:immobilie/io:ausstattung/io:dachform | " + "/io:openimmo/io:anbieter/io:immobilie/io:ausstattung/io:bauweise | " + "/io:openimmo/io:anbieter/io:immobilie/io:ausstattung/io:ausbaustufe", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove <provisionspflichtig> elements. * <p> * OpenImmo 1.2.1 does not support <provisionspflichtig> elements. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void removeProvisionspflichtigElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:preise/io:provisionspflichtig", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove <versteigerung> elements. * <p> * OpenImmo 1.2.1 does not support <versteigerung> elements. * * @param doc OpenImmo document in version 1.2.2 * @throws JaxenException */ protected void removeVersteigerungElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:openimmo/io:anbieter/io:immobilie/io:versteigerung", 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.2. * <p> * The <art> child element of the <energiepass> element is * renamed to <epart> in version 1.2.2. * * @param doc OpenImmo document in version 1.2.1 * @throws JaxenException */ protected void upgradeEnergiepassElements(Document doc) throws JaxenException { List nodes = XmlUtils .newXPath("/io:openimmo/io:anbieter/io:immobilie/io:zustand_angaben/io:energiepass/io:art", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); Element newNode = doc.createElementNS(StringUtils.EMPTY, "epart"); newNode.setTextContent(node.getTextContent()); parentNode.replaceChild(newNode, node); } } }