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.kyero.converters; import java.util.List; import org.apache.commons.lang3.ArrayUtils; 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.kyero.KyeroDocument; import org.openestate.io.kyero.KyeroUtils; import org.openestate.io.kyero.KyeroVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Converter for version 3. * * @since 1.0 * @author Andreas Rudolph */ public class Kyero_3 extends XmlConverter<KyeroDocument, KyeroVersion> { private final static Logger LOGGER = LoggerFactory.getLogger(Kyero_3.class); @Override public KyeroVersion getVersion() { return KyeroVersion.V3; } /** * Downgrade a Kyero document from version 3. * * @param doc Kyero document in version 3 */ @Override public void downgradeToPreviousVersion(KyeroDocument doc) { doc.setDocumentVersion(KyeroVersion.V2_1); try { this.downgradeNewBuildElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <new_build> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeTypeElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <type> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.downgradeUrlElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't downgrade <url> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeLocationElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove <location> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeEnergyRatingElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove <energy_rating> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeNotesElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove <notes> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.removeUnsupportedLanguageElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove unsupported translation elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } } /** * Upgrade a Kyero document to version 3. * * @param doc Kyero document in version 2.1 */ @Override public void upgradeFromPreviousVersion(KyeroDocument doc) { doc.setDocumentVersion(KyeroVersion.V3); try { this.removeCustomElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't remove <custom> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.upgradeNewBuildElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't upgrade <new_build> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.upgradeTypeElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't upgrade <type> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.upgradeCurrencyElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't upgrade <currency> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } try { this.upgradeUrlElements(doc.getDocument()); } catch (Exception ex) { LOGGER.error("Can't upgrade <url> elements!"); LOGGER.error("> " + ex.getLocalizedMessage(), ex); } } /** * Downgrade <new_build> elements to Kyero 2.1. * <p> * The <new_build> elements are not available in version 2.1. Instead * the value "new_build" is used in the <price_freq> element. * <p> * Any <new_build> elements are removed. If its value is set to "1", * then <price_freq>sale</price_freq> is convertet to * <price_freq>new_build</price_freq>, * * @param doc Kyero document in version 3 * @throws JaxenException */ protected void downgradeNewBuildElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:new_build", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); String value = StringUtils.trimToNull(node.getTextContent()); if ("1".equals(value)) { Element priceFreqNode = (Element) XmlUtils.newXPath("io:price_freq", doc) .selectSingleNode(parentNode); if (priceFreqNode == null) { priceFreqNode = doc.createElementNS(KyeroUtils.NAMESPACE, "price_freq"); priceFreqNode.setTextContent("new_build"); parentNode.appendChild(priceFreqNode); } else if ("sale".equalsIgnoreCase(priceFreqNode.getTextContent())) { priceFreqNode.setTextContent("new_build"); } } parentNode.removeChild(node); } } /** * Downgrade <type> elements to Kyero 2.1. * <p> * The <type> elements require a <en> child element in version * 2.1. * <p> * An <en> child element is created for any <type> element. * * @param doc Kyero document in version 3 * @throws JaxenException */ protected void downgradeTypeElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:type", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getTextContent()); node.setTextContent(null); Element childNode = doc.createElementNS(KyeroUtils.NAMESPACE, "en"); childNode.setTextContent(value); node.appendChild(childNode); } } /** * Downgrade <url> elements to Kyero 2.1. * <p> * The <url> elements only support a simple text value in version * 2.1. Version 3 allows different URL's for different languages. * <p> * Any children of <url> elements are removed. The english URL or the * first found URL is copied as simple value into the <url> element. * * @param doc Kyero document in version 3 * @throws JaxenException */ protected void downgradeUrlElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:url", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String enUrlValue = null; String fallbackUrlValue = null; List childNodes = XmlUtils.newXPath("*", doc).selectNodes(node); for (Object childItem : childNodes) { Element langNode = (Element) childItem; if ("en".equalsIgnoreCase(langNode.getLocalName())) enUrlValue = StringUtils.trimToNull(langNode.getTextContent()); else if (fallbackUrlValue == null) fallbackUrlValue = StringUtils.trimToNull(langNode.getTextContent()); node.removeChild(langNode); } node.setTextContent((enUrlValue != null) ? enUrlValue : fallbackUrlValue); } } /** * Remove <custom> elements. * <p> * Kyero 3 does not support <custom> elements in <property> and * <agent>. * <p> * Any occurence of these elements is removed. * * @param doc OpenImmo document in version 2.1 * @throws JaxenException */ protected void removeCustomElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:custom | " + "/io:root/io:agent/io:custom", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove <energy_rating> elements. * <p> * Kyero 2.1 does not support <energy_rating> elements. * * @param doc OpenImmo document in version 3 * @throws JaxenException */ protected void removeEnergyRatingElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:energy_rating", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove <location> elements. * <p> * Kyero 2.1 does not support <location> elements. * * @param doc OpenImmo document in version 3 * @throws JaxenException */ protected void removeLocationElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:location", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove <notes> elements. * <p> * Kyero 2.1 does not support <notes> elements. * * @param doc OpenImmo document in version 3 * @throws JaxenException */ protected void removeNotesElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:notes", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } } /** * Remove elements with translations in unsupported languages. * <p> * Kyero 2.1 does only support translation in <title> (for images), * <desc> (for properties) elements for "en", "es", "de", "nl", "fr". * * @param doc OpenImmo document in version 3 * @throws JaxenException */ protected void removeUnsupportedLanguageElements(Document doc) throws JaxenException { String[] unsupportedLanguages = new String[] { "ar", "bg", "ca", "cs", "da", "el", "et", "fa", "fi", "he", "hi", "hu", "id", "it", "ja", "ko", "lt", "lv", "no", "pl", "pt", "ro", "ru", "sk", "sl", "sv", "th", "tr", "uk", "vi", "zh", }; List nodes = XmlUtils .newXPath("/io:root/io:property/io:desc | " + "/io:root/io:property/io:images/io:image/io:title", doc) .selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; List childNodes = XmlUtils.newXPath("*", doc).selectNodes(node); for (Object childItem : childNodes) { Element langNode = (Element) childItem; String lang = langNode.getLocalName().toLowerCase(); if (ArrayUtils.contains(unsupportedLanguages, lang)) { node.removeChild(langNode); } } } } /** * Upgrade <currency> elements to Kyero 3. * <p> * The <currency> only supports the values "EUR", "GBP", "USD" in * version 3. * <p> * Any <currency> with an unsupported value is removed from the * document. * * @param doc Kyero document in version 2.1 * @throws JaxenException */ protected void upgradeCurrencyElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:currency", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); String value = StringUtils.trimToNull(node.getTextContent()); if ("EUR".equalsIgnoreCase(value)) node.setTextContent("EUR"); else if ("GBP".equalsIgnoreCase(value)) node.setTextContent("GBP"); else if ("USD".equalsIgnoreCase(value)) node.setTextContent("USD"); else parentNode.removeChild(node); } } /** * Upgrade <new_build> elements for Kyero 3. * <p> * The <new_build> elements are not available in version 2.1. Instead * the value "new_build" is used in the <price_freq> element. * <p> * Any occurences of <price_freq>new_build</price_freq> is * replaced by <price_freq>sale</price_freq> and * <new_build>1</new_build> is added to the property. * * @param doc Kyero document in version 2.1 * @throws JaxenException */ protected void upgradeNewBuildElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:price_freq", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; Element parentNode = (Element) node.getParentNode(); if (!"new_build".equalsIgnoreCase(node.getTextContent())) continue; node.setTextContent("sale"); Element newBuildNode = doc.createElementNS(KyeroUtils.NAMESPACE, "new_build"); newBuildNode.setTextContent("1"); parentNode.appendChild(newBuildNode); } } /** * Upgrade <type> elements to Kyero 3. * <p> * The <type> elements do not support any child element in version 3. * <p> * Any child elements of <type> are removed. The text from the * <en> child element is copied into the <type> element. * * @param doc Kyero document in version 2.1 * @throws JaxenException */ protected void upgradeTypeElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:type", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String enTypeValue = null; String fallbackTypeValue = null; List childNodes = XmlUtils.newXPath("*", doc).selectNodes(node); for (Object childItem : childNodes) { Element langNode = (Element) childItem; if ("en".equalsIgnoreCase(langNode.getLocalName())) enTypeValue = StringUtils.trimToNull(langNode.getTextContent()); else if (fallbackTypeValue == null) fallbackTypeValue = StringUtils.trimToNull(langNode.getTextContent()); node.removeChild(langNode); } node.setTextContent((enTypeValue != null) ? enTypeValue : fallbackTypeValue); } } /** * Upgrade <url> elements to Kyero 3. * <p> * The <url> elements only support a simple text value in version * 2.1. Version 3 allows different URL's for different languages. * <p> * The simple value of <url> elements is removed and copied into the * <en> child element. * * @param doc Kyero document in version 2.1 * @throws JaxenException */ protected void upgradeUrlElements(Document doc) throws JaxenException { List nodes = XmlUtils.newXPath("/io:root/io:property/io:url", doc).selectNodes(doc); for (Object item : nodes) { Element node = (Element) item; String value = StringUtils.trimToNull(node.getTextContent()); node.setTextContent(null); if (value == null) { Element parentNode = (Element) node.getParentNode(); parentNode.removeChild(node); } else { Element childNode = doc.createElementNS(KyeroUtils.NAMESPACE, "en"); childNode.setTextContent(value); node.appendChild(childNode); } } } }