package org.openestate.io.openimmo.xml;

import java.io.Serializable;
import javax.annotation.Generated;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
import org.jvnet.jaxb2_commons.lang.CopyStrategy2;
import org.jvnet.jaxb2_commons.lang.CopyTo2;
import org.jvnet.jaxb2_commons.lang.Equals2;
import org.jvnet.jaxb2_commons.lang.EqualsStrategy2;
import org.jvnet.jaxb2_commons.lang.JAXBCopyStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBEqualsStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBToStringStrategy;
import org.jvnet.jaxb2_commons.lang.ToString2;
import org.jvnet.jaxb2_commons.lang.ToStringStrategy2;
import org.jvnet.jaxb2_commons.locator.ObjectLocator;
import org.jvnet.jaxb2_commons.locator.util.LocatorUtils;

/**
 * Java class for <max_mietdauer> element.
 *
 *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "content"
})
@XmlRootElement(name = "max_mietdauer")
@Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
public class MaxMietdauer implements Serializable, Cloneable, CopyTo2, Equals2, ToString2
{

    @XmlValue
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    protected String content;
    @XmlAttribute(name = "max_dauer")
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    protected MaxMietdauer.MaxDauer maxDauer;

    /**
     * Gets the value of the content property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public String getContent() {
        return content;
    }

    /**
     * Sets the value of the content property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public void setContent(String value) {
        this.content = value;
    }

    /**
     * Gets the value of the maxDauer property.
     *
     * @return
     *     possible object is
     *     {@link MaxMietdauer.MaxDauer }
     *
     */
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public MaxMietdauer.MaxDauer getMaxDauer() {
        return maxDauer;
    }

    /**
     * Sets the value of the maxDauer property.
     *
     * @param value
     *     allowed object is
     *     {@link MaxMietdauer.MaxDauer }
     *
     */
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public void setMaxDauer(MaxMietdauer.MaxDauer value) {
        this.maxDauer = value;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public String toString() {
        final ToStringStrategy2 strategy = JAXBToStringStrategy.INSTANCE;
        final StringBuilder buffer = new StringBuilder();
        append(null, buffer, strategy);
        return buffer.toString();
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public StringBuilder append(ObjectLocator locator, StringBuilder buffer, ToStringStrategy2 strategy) {
        strategy.appendStart(locator, this, buffer);
        appendFields(locator, buffer, strategy);
        strategy.appendEnd(locator, this, buffer);
        return buffer;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public StringBuilder appendFields(ObjectLocator locator, StringBuilder buffer, ToStringStrategy2 strategy) {
        {
            String theContent;
            theContent = this.getContent();
            strategy.appendField(locator, this, "content", buffer, theContent, (this.content!= null));
        }
        {
            MaxMietdauer.MaxDauer theMaxDauer;
            theMaxDauer = this.getMaxDauer();
            strategy.appendField(locator, this, "maxDauer", buffer, theMaxDauer, (this.maxDauer!= null));
        }
        return buffer;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public Object clone() {
        return copyTo(createNewInstance());
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public Object copyTo(Object target) {
        final CopyStrategy2 strategy = JAXBCopyStrategy.INSTANCE;
        return copyTo(null, target, strategy);
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public Object copyTo(ObjectLocator locator, Object target, CopyStrategy2 strategy) {
        final Object draftCopy = ((target == null)?createNewInstance():target);
        if (draftCopy instanceof MaxMietdauer) {
            final MaxMietdauer copy = ((MaxMietdauer) draftCopy);
            {
                Boolean contentShouldBeCopiedAndSet = strategy.shouldBeCopiedAndSet(locator, (this.content!= null));
                if (contentShouldBeCopiedAndSet == Boolean.TRUE) {
                    String sourceContent;
                    sourceContent = this.getContent();
                    String copyContent = ((String) strategy.copy(LocatorUtils.property(locator, "content", sourceContent), sourceContent, (this.content!= null)));
                    copy.setContent(copyContent);
                } else {
                    if (contentShouldBeCopiedAndSet == Boolean.FALSE) {
                        copy.content = null;
                    }
                }
            }
            {
                Boolean maxDauerShouldBeCopiedAndSet = strategy.shouldBeCopiedAndSet(locator, (this.maxDauer!= null));
                if (maxDauerShouldBeCopiedAndSet == Boolean.TRUE) {
                    MaxMietdauer.MaxDauer sourceMaxDauer;
                    sourceMaxDauer = this.getMaxDauer();
                    MaxMietdauer.MaxDauer copyMaxDauer = ((MaxMietdauer.MaxDauer) strategy.copy(LocatorUtils.property(locator, "maxDauer", sourceMaxDauer), sourceMaxDauer, (this.maxDauer!= null)));
                    copy.setMaxDauer(copyMaxDauer);
                } else {
                    if (maxDauerShouldBeCopiedAndSet == Boolean.FALSE) {
                        copy.maxDauer = null;
                    }
                }
            }
        }
        return draftCopy;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public Object createNewInstance() {
        return new MaxMietdauer();
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Object object, EqualsStrategy2 strategy) {
        if ((object == null)||(this.getClass()!= object.getClass())) {
            return false;
        }
        if (this == object) {
            return true;
        }
        final MaxMietdauer that = ((MaxMietdauer) object);
        {
            String lhsContent;
            lhsContent = this.getContent();
            String rhsContent;
            rhsContent = that.getContent();
            if (!strategy.equals(LocatorUtils.property(thisLocator, "content", lhsContent), LocatorUtils.property(thatLocator, "content", rhsContent), lhsContent, rhsContent, (this.content!= null), (that.content!= null))) {
                return false;
            }
        }
        {
            MaxMietdauer.MaxDauer lhsMaxDauer;
            lhsMaxDauer = this.getMaxDauer();
            MaxMietdauer.MaxDauer rhsMaxDauer;
            rhsMaxDauer = that.getMaxDauer();
            if (!strategy.equals(LocatorUtils.property(thisLocator, "maxDauer", lhsMaxDauer), LocatorUtils.property(thatLocator, "maxDauer", rhsMaxDauer), lhsMaxDauer, rhsMaxDauer, (this.maxDauer!= null), (that.maxDauer!= null))) {
                return false;
            }
        }
        return true;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public boolean equals(Object object) {
        final EqualsStrategy2 strategy = JAXBEqualsStrategy.INSTANCE;
        return equals(null, null, object, strategy);
    }

    /**
     *
     *                     Java enum for max_dauer attribute in <max_mietdauer> elements.
     *
     *
Java class for null.
     *
     *
The following schema fragment specifies the expected content contained within this class.
     *

     *

     * <simpleType>
     *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
     *     <enumeration value="TAG"/>
     *     <enumeration value="WOCHE"/>
     *     <enumeration value="MONAT"/>
     *     <enumeration value="JAHR"/>
     *   </restriction>
     * </simpleType>
     *

     *
     */
    @XmlType(name = "")
    @XmlEnum
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public enum MaxDauer {

        TAG,
        WOCHE,
        MONAT,
        JAHR;

        public String value() {
            return name();
        }

        public static MaxMietdauer.MaxDauer fromValue(String v) {
            return valueOf(v);
        }

    }

}


/*
 * Copyright 2015-2018 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.filemaker;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.openestate.io.core.XmlUtils;
import org.openestate.io.core.XmlValidationHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * Some helper functions for the XML format of
 * Filemaker.
 *
 * @author Andreas Rudolph
 * @since 1.0
 */
@SuppressWarnings("WeakerAccess")
public class FilemakerUtils {
    @SuppressWarnings("unused")
    private final static Logger LOGGER = LoggerFactory.getLogger(FilemakerUtils.class);
    private static JAXBContext JAXB = null;

    /*
     * the latest implemented version of this format
     *
     * public final static String VERSION = "1.0";
     */

    /**
     * the XML target namespace of this format
     */
    @SuppressWarnings("unused")
    public final static String NAMESPACE = StringUtils.EMPTY;

    /**
     * the package, where generated JAXB classes are located
     */
    @SuppressWarnings("unused")
    public final static String PACKAGE = "org.openestate.io.filemaker.xml.result"
            + ":org.openestate.io.filemaker.xml.layout";

    /**
     * the factory for creation of JAXB objects in FMPXMLLAYOUT format
     */
    @SuppressWarnings("unused")
    public final static org.openestate.io.filemaker.xml.layout.ObjectFactory FACTORY_LAYOUT = new org.openestate.io.filemaker.xml.layout.ObjectFactory();

    /**
     * the factory for creation of JAXB objects in FMPXMLRESULT format
     */
    @SuppressWarnings("unused")
    public final static org.openestate.io.filemaker.xml.result.ObjectFactory FACTORY_RESULT = new org.openestate.io.filemaker.xml.result.ObjectFactory();

    private FilemakerUtils() {
    }

    /**
     * Creates a {@link FilemakerDocument} from an {@link InputStream}.
     *
     * @param input XML input
     * @return created document or null, of the document is not supported by this format
     * @throws SAXException                 if XML is invalid
     * @throws IOException                  if reading failed
     * @throws ParserConfigurationException if the parser is not properly configured
     */
    public static FilemakerDocument createDocument(InputStream input) throws SAXException, IOException, ParserConfigurationException {
        return createDocument(XmlUtils.newDocument(input, true));
    }

    /**
     * Creates a {@link FilemakerDocument} from a {@link File}.
     *
     * @param xmlFile XML file
     * @return created document or null, of the document is not supported by this format
     * @throws SAXException                 if XML is invalid
     * @throws IOException                  if reading failed
     * @throws ParserConfigurationException if the parser is not properly configured
     */
    public static FilemakerDocument createDocument(File xmlFile) throws SAXException, IOException, ParserConfigurationException {
        return createDocument(XmlUtils.newDocument(xmlFile, true));
    }

    /**
     * Creates a {@link FilemakerDocument} from a {@link String}.
     *
     * @param xmlString XML string
     * @return created document or null, of the document is not supported by this format
     * @throws SAXException                 if XML is invalid
     * @throws IOException                  if reading failed
     * @throws ParserConfigurationException if the parser is not properly configured
     */
    public static FilemakerDocument createDocument(String xmlString) throws SAXException, IOException, ParserConfigurationException {
        return createDocument(XmlUtils.newDocument(xmlString, true));
    }

    /**
     * Creates a {@link FilemakerDocument} from a {@link Document}.
     *
     * @param doc XML document
     * @return created document or null, of the document is not supported by this format
     */
    public static FilemakerDocument createDocument(Document doc) {
        if (FilemakerResultDocument.isReadable(doc))
            return new FilemakerResultDocument(doc);
        else if (FilemakerLayoutDocument.isReadable(doc))
            return new FilemakerLayoutDocument(doc);
        else
            return null;
    }

    /**
     * Creates a {@link Marshaller} to write JAXB objects into XML.
     *
     * @return created marshaller
     * @throws JAXBException if a problem with JAXB occurred
     */
    @SuppressWarnings("unused")
    public static Marshaller createMarshaller() throws JAXBException {
        return createMarshaller(Charset.defaultCharset().name(), true);
    }

    /**
     * Creates a {@link Marshaller} to write JAXB objects into XML.
     *
     * @param encoding  encoding of written XML
     * @param formatted if written XML is pretty printed
     * @return created marshaller
     * @throws JAXBException if a problem with JAXB occurred
     */
    @SuppressWarnings("Duplicates")
    public static Marshaller createMarshaller(String encoding, boolean formatted) throws JAXBException {
        Marshaller m = getContext().createMarshaller();
        m.setProperty(Marshaller.JAXB_ENCODING, encoding);
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, formatted);
        m.setEventHandler(new XmlValidationHandler());
        return m;
    }

    /**
     * Creates a {@link Unmarshaller} to read JAXB objects from XML.
     *
     * @return created unmarshaller
     * @throws JAXBException if a problem with JAXB occurred
     */
    public static Unmarshaller createUnmarshaller() throws JAXBException {
        Unmarshaller m = getContext().createUnmarshaller();
        m.setEventHandler(new XmlValidationHandler());
        return m;
    }

    /**
     * Returns the {@link JAXBContext} for this format.
     *
     * @return context
     * @throws JAXBException if a problem with JAXB occurred
     */
    public synchronized static JAXBContext getContext() throws JAXBException {
        if (JAXB == null) initContext(Thread.currentThread().getContextClassLoader());
        return JAXB;
    }

    /**
     * Returns the {@link org.openestate.io.filemaker.xml.layout.ObjectFactory} for FMPXMLLAYOUT format.
     *
     * @return object factory
     */
    public synchronized static org.openestate.io.filemaker.xml.layout.ObjectFactory getFactoryForLayout() {
        return FACTORY_LAYOUT;
    }

    /**
     * Returns the {@link org.openestate.io.filemaker.xml.result.ObjectFactory} for FMPXMLRESULT format.
     *
     * @return object factory
     */
    public synchronized static org.openestate.io.filemaker.xml.result.ObjectFactory getFactoryForResult() {
        return FACTORY_RESULT;
    }

    /**
     * Initializes the {@link JAXBContext} for this format.
     *
     * @param classloader the classloader to load the generated JAXB classes with
     * @throws JAXBException if a problem with JAXB occurred
     */
    public synchronized static void initContext(ClassLoader classloader) throws JAXBException {
        JAXB = JAXBContext.newInstance(PACKAGE, classloader);
    }

    public static Boolean parseBoolean(String value) {
        value = StringUtils.trimToNull(value);
        if ("yes".equalsIgnoreCase(value))
            return true;
        if ("no".equalsIgnoreCase(value))
            return false;
        return null;
    }

    public static String printBoolean(Boolean value) {
        if (Boolean.TRUE.equals(value))
            return "YES";
        if (Boolean.FALSE.equals(value))
            return "NO";
        throw new IllegalArgumentException("Can't print boolean value!");
    }
}


/*
 * Copyright 2015-2018 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.examples;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Currency;
import java.util.List;
import java.util.Locale;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.commons.io.output.NullWriter;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.PropertyConfigurator;
import org.openestate.io.examples.utils.RandomStringUtils;
import org.openestate.io.idx.IdxPrinter;
import org.openestate.io.idx.IdxRecord;
import org.openestate.io.idx.types.GrossPremium;
import org.openestate.io.idx.types.Language;
import org.openestate.io.idx.types.Media;
import org.openestate.io.idx.types.ObjectType;
import org.openestate.io.idx.types.OfferType;
import org.openestate.io.idx.types.PriceUnit;
import org.openestate.io.idx.types.Salutation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Example for writing IDX files.
 * <p>
 * This example illustrates the programmatic creation of IDX records and how they
 * are written into CSV.
 *
 * @author Andreas Rudolph
 * @since 1.0
 */
@SuppressWarnings("WeakerAccess")
public class IdxWritingExample {
    private final static Logger LOGGER = LoggerFactory.getLogger(IdxWritingExample.class);
    private final static String PACKAGE = "/org/openestate/io/examples";

    /**
     * Start the example application.
     *
     * @param args command line arguments
     */
    @SuppressWarnings("Duplicates")
    public static void main(String[] args) {
        // init logging
        PropertyConfigurator.configure(
                IdxWritingExample.class.getResource(PACKAGE + "/log4j.properties"));

        // create some CSV records
        List<IdxRecord> records = new ArrayList<>();
        records.add(createRecord());
        records.add(createRecord());
        records.add(createRecord());
        records.add(createRecord());

        // write CSV records into a java.io.File
        try {
            write(records, File.createTempFile("output-", ".csv"));
        } catch (IOException ex) {
            LOGGER.error("Can't create temporary file!");
            LOGGER.error("> " + ex.getLocalizedMessage(), ex);
            System.exit(1);
        }

        // write CSV records into a java.io.OutputStream
        write(records, new NullOutputStream());

        // write CSV records into a java.io.Writer
        write(records, new NullWriter());

        // write CSV records into a string and send it to the console
        writeToConsole(records);
    }

    /**
     * Create an {@link IdxRecord} with some example data.
     *
     * @return created example object
     */
    protected static IdxRecord createRecord() {
        // create an example real estate
        IdxRecord obj = new IdxRecord();
        obj.setAdvertisementId(RandomStringUtils.random(5));
        obj.setAgencyCity("Berlin");
        obj.setAgencyCountry(Locale.GERMANY.getCountry());
        obj.setAgencyEmail("tester@test.org");
        obj.setAgencyFax("030/123456");
        obj.setAgencyId(RandomStringUtils.random(5));
        obj.setAgencyName("agency name");
        obj.setAgencyName2("additional agency name");
        obj.setAgencyPhone("030/123457");
        obj.setAgencyReference(RandomStringUtils.random(5));
        obj.setAgencyStreet("example street 123");
        obj.setAgencyZip("12345");
        obj.setAnimalAllowed(RandomUtils.nextInt(0, 2) == 1);
        obj.setAvailableFrom(Calendar.getInstance());
        obj.setBalcony(RandomUtils.nextInt(0, 2) == 1);
        obj.setBillingCompany("agency name");
        obj.setBillingCountry("Germany");
        obj.setBillingFirstName("Max");
        obj.setBillingLanguage(Language.GERMAN);
        obj.setBillingMobile("030/132456");
        obj.setBillingName("Mustermann");
        obj.setBillingPhone("030/123457");
        obj.setBillingPhone2("030/123458");
        obj.setBillingPlaceName("Berlin");
        obj.setBillingPostBox("additional address notes");
        obj.setBillingSalutation(Salutation.MALE);
        obj.setBillingStreet("example street 123");
        obj.setBillingZip("12345");
        obj.setBuildingLandConnected(RandomUtils.nextInt(0, 2) == 1);
        obj.setCableTv(RandomUtils.nextInt(0, 2) == 1);
        obj.setCarryingCapacityCrane(RandomUtils.nextDouble(500, 5000));
        obj.setCarryingCapacityElevator(RandomUtils.nextDouble(500, 5000));
        obj.setCeilingHeight(RandomUtils.nextDouble(2, 10));
        obj.setChildFriendly(RandomUtils.nextInt(0, 2) == 1);
        obj.setCornerHouse(RandomUtils.nextInt(0, 2) == 1);
        obj.setCurrency(Currency.getInstance("EUR"));
        obj.setDistanceKindergarten(RandomUtils.nextInt(50, 5000));
        obj.setDistanceMotorway(RandomUtils.nextInt(50, 5000));
        obj.setDistancePublicTransport(RandomUtils.nextInt(50, 5000));
        obj.setDistanceSchool1(RandomUtils.nextInt(50, 5000));
        obj.setDistanceSchool2(RandomUtils.nextInt(50, 5000));
        obj.setDistanceShop(RandomUtils.nextInt(50, 5000));
        obj.setElevator(RandomUtils.nextInt(0, 2) == 1);
        obj.setFireplace(RandomUtils.nextInt(0, 2) == 1);
        obj.setFlatSharingCommunity(RandomUtils.nextInt(0, 2) == 1);
        obj.setFloor(RandomUtils.nextInt(0, 10));
        obj.setGarage(RandomUtils.nextInt(0, 2) == 1);
        obj.setGardenhouse(RandomUtils.nextInt(0, 2) == 1);
        obj.setGasSupply(RandomUtils.nextInt(0, 2) == 1);
        obj.setGrossPremium(GrossPremium.FROM_4_UNTIL_5);
        obj.setHallHeight(RandomUtils.nextDouble(3, 15));
        obj.setIsdn(RandomUtils.nextInt(0, 2) == 1);
        obj.setLastModified(Calendar.getInstance());
        obj.setLiftingPlatform(RandomUtils.nextInt(0, 2) == 1);
        obj.setMaximalFloorLoading(RandomUtils.nextDouble(50, 5000));
        obj.setMiddleHouse(RandomUtils.nextInt(0, 2) == 1);
        obj.setMinEnergyCertified(RandomUtils.nextInt(0, 2) == 1);
        obj.setMinEnergyGeneral(RandomUtils.nextInt(0, 2) == 1);
        obj.setNewBuilding(RandomUtils.nextInt(0, 2) == 1);
        obj.setNumberOfApartments(RandomUtils.nextDouble(1, 10));
        obj.setNumberOfFloors(RandomUtils.nextInt(1, 10));
        obj.setNumberOfRooms(RandomUtils.nextDouble(1, 10));
        obj.setObjectCity("Berlin");
        obj.setObjectCountry(Locale.GERMANY.getCountry());
        obj.setObjectDescription("some description" + System.lineSeparator() + " about the object");
        obj.setObjectSituation("some description about the location");
        obj.setObjectState("BE");
        obj.setObjectStreet("example street 124");
        obj.setObjectTitle("title of object");
        obj.setObjectType(ObjectType.HOUSE_VILLA);
        obj.setObjectZip("12345");
        obj.setOfferType(OfferType.SALE);
        obj.setOldBuilding(RandomUtils.nextInt(0, 2) == 1);
        obj.setOwnObjectUrl("http://test.org/object/123");
        obj.setParking(RandomUtils.nextInt(0, 2) == 1);
        obj.setPowerSupply(RandomUtils.nextInt(0, 2) == 1);
        obj.setPriceUnit(PriceUnit.MONTHLY);
        obj.setRailwayTerminal(RandomUtils.nextInt(0, 2) == 1);
        obj.setRaisedGroundFloor(RandomUtils.nextInt(0, 2) == 1);
        obj.setRamp(RandomUtils.nextInt(0, 2) == 1);
        obj.setRefHouse(RandomStringUtils.random(5));
        obj.setRefObject(RandomStringUtils.random(5));
        obj.setRefProperty(RandomStringUtils.random(5));
        obj.setRentExtra(RandomUtils.nextLong(100, 1000));
        obj.setRentNet(RandomUtils.nextLong(100, 1000));
        obj.setRestrooms(RandomUtils.nextInt(0, 2) == 1);
        obj.setSellingPrice(RandomUtils.nextLong(100, 1000));
        obj.setSenderId("OpenEstate.org");
        obj.setSewageSupply(RandomUtils.nextInt(0, 2) == 1);
        obj.setSparefield1("spare field 1");
        obj.setSparefield2("spare field 2");
        obj.setSparefield3("spare field 3");
        obj.setSparefield4("spare field 4");
        obj.setSurfaceLiving(RandomUtils.nextLong(50, 300));
        obj.setSurfaceProperty(RandomUtils.nextLong(100, 1000));
        obj.setSurfaceUsable(RandomUtils.nextLong(100, 1000));
        obj.setSwimmingpool(RandomUtils.nextInt(0, 2) == 1);
        obj.setUnderBuildingLaws(RandomUtils.nextInt(0, 2) == 1);
        obj.setUnderRoof(RandomUtils.nextInt(0, 2) == 1);
        obj.setUrl("http://test.org/object/123");
        obj.setView(RandomUtils.nextInt(0, 2) == 1);
        obj.setVisitName("Max Mustermann");
        obj.setVisitPhone("030/123456");
        obj.setVisitRemark("notes about the contact person");
        obj.setVolume(RandomUtils.nextLong(50, 500));
        obj.setWaterSupply(RandomUtils.nextInt(0, 2) == 1);
        obj.setWheelcharAccessible(RandomUtils.nextInt(0, 2) == 1);
        obj.setYearBuilt(RandomUtils.nextInt(1900, 1995));
        obj.setYearRenovated(RandomUtils.nextInt(1995, 2010));

        obj.setDocument(
                new Media("document.pdf", "a document about the object"));
        obj.setMovie(
                new Media("document.mp4", "a document about the object"));
        obj.setPicture1(
                new Media("image1.jpg", "title for image 1", "description for image 1"));
        obj.setPicture2(
                new Media("image2.jpg", "title for image 2", "description for image 2"));
        obj.setPicture3(
                new Media("image3.jpg", "title for image 3", "description for image 3"));
        obj.setPicture4(
                new Media("image4.jpg", "title for image 4", "description for image 4"));
        obj.setPicture5(
                new Media("image5.jpg", "title for image 5", "description for image 5"));
        obj.setPicture6(
                new Media("image6.jpg", "title for image 6", "description for image 6"));
        obj.setPicture7(
                new Media("image7.jpg", "title for image 7", "description for image 7"));
        obj.setPicture8(
                new Media("image8.jpg", "title for image 8", "description for image 8"));
        obj.setPicture9(
                new Media("image9.jpg", "title for image 9", "description for image 9"));
        obj.setPicture10(
                new Media("image10.jpg", "title for image 10", "description for image 10"));
        obj.setPicture11(
                new Media("image11.jpg", "title for image 11", "description for image 11"));
        obj.setPicture12(
                new Media("image12.jpg", "title for image 12", "description for image 12"));
        obj.setPicture13(
                new Media("image13.jpg", "title for image 13", "description for image 13"));

        return obj;
    }

    /**
     * Write some {@link IdxRecord} objects into a {@link File}.
     *
     * @param records the CSV records to write
     * @param file    the file, where the document is written to
     */
    protected static void write(List<IdxRecord> records, File file) {
        LOGGER.info("writing document");
        try (IdxPrinter printer = IdxPrinter.create(file)) {
            printer.printRecords(records);
            LOGGER.info("> written to: " + file.getAbsolutePath());
        } catch (Exception ex) {
            LOGGER.error("Can't write document into a file!");
            LOGGER.error("> " + ex.getLocalizedMessage(), ex);
            System.exit(1);
        }
    }

    /**
     * Write some {@link IdxRecord} objects into an {@link OutputStream}.
     *
     * @param records the CSV records to write
     * @param output  the stream, where the document is written to
     */
    protected static void write(List<IdxRecord> records, OutputStream output) {
        LOGGER.info("writing document");
        try {
            IdxPrinter printer = IdxPrinter.create(output);
            printer.printRecords(records);
            LOGGER.info("> written to a java.io.OutputStream");
        } catch (Exception ex) {
            LOGGER.error("Can't write document into an OutputStream!");
            LOGGER.error("> " + ex.getLocalizedMessage(), ex);
            System.exit(1);
        }
    }

    /**
     * Write some {@link IdxRecord} objects into a {@link Writer}.
     *
     * @param records the CSV records to write
     * @param output  the writer, where the document is written to
     */
    protected static void write(List<IdxRecord> records, Writer output) {
        LOGGER.info("writing document");
        try {
            IdxPrinter printer = IdxPrinter.create(output);
            printer.printRecords(records);
            LOGGER.info("> written to a java.io.Writer");
        } catch (Exception ex) {
            LOGGER.error("Can't write document into an OutputStream!");
            LOGGER.error("> " + ex.getLocalizedMessage(), ex);
            System.exit(1);
        }
    }

    /**
     * Write some {@link IdxRecord} objects into a {@link String} and print the
     * results to the console.
     *
     * @param records the CSV records to write
     */
    protected static void writeToConsole(List<IdxRecord> records) {
        LOGGER.info("writing document");
        StringBuilder csv = new StringBuilder();
        try (IdxPrinter printer = IdxPrinter.create(csv)) {
            printer.printRecords(records);
            LOGGER.info(StringUtils.repeat("-", 50)
                    + System.lineSeparator() + csv.toString());
        } catch (Exception ex) {
            LOGGER.error("Can't write document into a string!");
            LOGGER.error("> " + ex.getLocalizedMessage(), ex);
            System.exit(1);
        }
    }
}


package org.openestate.io.openimmo.xml;

import java.io.Serializable;
import javax.annotation.Generated;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.jvnet.jaxb2_commons.lang.CopyStrategy2;
import org.jvnet.jaxb2_commons.lang.CopyTo2;
import org.jvnet.jaxb2_commons.lang.Equals2;
import org.jvnet.jaxb2_commons.lang.EqualsStrategy2;
import org.jvnet.jaxb2_commons.lang.JAXBCopyStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBEqualsStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBToStringStrategy;
import org.jvnet.jaxb2_commons.lang.ToString2;
import org.jvnet.jaxb2_commons.lang.ToStringStrategy2;
import org.jvnet.jaxb2_commons.locator.ObjectLocator;
import org.jvnet.jaxb2_commons.locator.util.LocatorUtils;

/**
 * Java class for <erschliessung_umfang> element.
 *
 *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "")
@XmlRootElement(name = "erschliessung_umfang")
@Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
public class ErschliessungUmfang implements Serializable, Cloneable, CopyTo2, Equals2, ToString2
{

    @XmlAttribute(name = "erschl_attr")
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    protected ErschliessungUmfang.ErschlAttr erschlAttr;

    /**
     * Gets the value of the erschlAttr property.
     *
     * @return
     *     possible object is
     *     {@link ErschliessungUmfang.ErschlAttr }
     *
     */
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public ErschliessungUmfang.ErschlAttr getErschlAttr() {
        return erschlAttr;
    }

    /**
     * Sets the value of the erschlAttr property.
     *
     * @param value
     *     allowed object is
     *     {@link ErschliessungUmfang.ErschlAttr }
     *
     */
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public void setErschlAttr(ErschliessungUmfang.ErschlAttr value) {
        this.erschlAttr = value;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public String toString() {
        final ToStringStrategy2 strategy = JAXBToStringStrategy.INSTANCE;
        final StringBuilder buffer = new StringBuilder();
        append(null, buffer, strategy);
        return buffer.toString();
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public StringBuilder append(ObjectLocator locator, StringBuilder buffer, ToStringStrategy2 strategy) {
        strategy.appendStart(locator, this, buffer);
        appendFields(locator, buffer, strategy);
        strategy.appendEnd(locator, this, buffer);
        return buffer;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public StringBuilder appendFields(ObjectLocator locator, StringBuilder buffer, ToStringStrategy2 strategy) {
        {
            ErschliessungUmfang.ErschlAttr theErschlAttr;
            theErschlAttr = this.getErschlAttr();
            strategy.appendField(locator, this, "erschlAttr", buffer, theErschlAttr, (this.erschlAttr!= null));
        }
        return buffer;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public Object clone() {
        return copyTo(createNewInstance());
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public Object copyTo(Object target) {
        final CopyStrategy2 strategy = JAXBCopyStrategy.INSTANCE;
        return copyTo(null, target, strategy);
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public Object copyTo(ObjectLocator locator, Object target, CopyStrategy2 strategy) {
        final Object draftCopy = ((target == null)?createNewInstance():target);
        if (draftCopy instanceof ErschliessungUmfang) {
            final ErschliessungUmfang copy = ((ErschliessungUmfang) draftCopy);
            {
                Boolean erschlAttrShouldBeCopiedAndSet = strategy.shouldBeCopiedAndSet(locator, (this.erschlAttr!= null));
                if (erschlAttrShouldBeCopiedAndSet == Boolean.TRUE) {
                    ErschliessungUmfang.ErschlAttr sourceErschlAttr;
                    sourceErschlAttr = this.getErschlAttr();
                    ErschliessungUmfang.ErschlAttr copyErschlAttr = ((ErschliessungUmfang.ErschlAttr) strategy.copy(LocatorUtils.property(locator, "erschlAttr", sourceErschlAttr), sourceErschlAttr, (this.erschlAttr!= null)));
                    copy.setErschlAttr(copyErschlAttr);
                } else {
                    if (erschlAttrShouldBeCopiedAndSet == Boolean.FALSE) {
                        copy.erschlAttr = null;
                    }
                }
            }
        }
        return draftCopy;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public Object createNewInstance() {
        return new ErschliessungUmfang();
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Object object, EqualsStrategy2 strategy) {
        if ((object == null)||(this.getClass()!= object.getClass())) {
            return false;
        }
        if (this == object) {
            return true;
        }
        final ErschliessungUmfang that = ((ErschliessungUmfang) object);
        {
            ErschliessungUmfang.ErschlAttr lhsErschlAttr;
            lhsErschlAttr = this.getErschlAttr();
            ErschliessungUmfang.ErschlAttr rhsErschlAttr;
            rhsErschlAttr = that.getErschlAttr();
            if (!strategy.equals(LocatorUtils.property(thisLocator, "erschlAttr", lhsErschlAttr), LocatorUtils.property(thatLocator, "erschlAttr", rhsErschlAttr), lhsErschlAttr, rhsErschlAttr, (this.erschlAttr!= null), (that.erschlAttr!= null))) {
                return false;
            }
        }
        return true;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public boolean equals(Object object) {
        final EqualsStrategy2 strategy = JAXBEqualsStrategy.INSTANCE;
        return equals(null, null, object, strategy);
    }

    /**
     *
     *                     Java enum for erschl_attr attribute in <erschliessung_umfang> elements.
     *
     *
Java class for null.
     *
     *
The following schema fragment specifies the expected content contained within this class.
     *

     *

     * <simpleType>
     *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
     *     <enumeration value="GAS"/>
     *     <enumeration value="WASSER"/>
     *     <enumeration value="STROM"/>
     *     <enumeration value="TK"/>
     *   </restriction>
     * </simpleType>
     *

     *
     */
    @XmlType(name = "")
    @XmlEnum
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:54:50+02:00", comments = "JAXB RI v2.2.11")
    public enum ErschlAttr {

        GAS,
        WASSER,
        STROM,
        TK;

        public String value() {
            return name();
        }

        public static ErschliessungUmfang.ErschlAttr fromValue(String v) {
            return valueOf(v);
        }

    }

}


package org.openestate.io.daft_ie.xml;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
import org.jvnet.jaxb2_commons.lang.CopyStrategy2;
import org.jvnet.jaxb2_commons.lang.CopyTo2;
import org.jvnet.jaxb2_commons.lang.Equals2;
import org.jvnet.jaxb2_commons.lang.EqualsStrategy2;
import org.jvnet.jaxb2_commons.lang.JAXBCopyStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBEqualsStrategy;
import org.jvnet.jaxb2_commons.lang.JAXBToStringStrategy;
import org.jvnet.jaxb2_commons.lang.ToString2;
import org.jvnet.jaxb2_commons.lang.ToStringStrategy2;
import org.jvnet.jaxb2_commons.locator.ObjectLocator;
import org.jvnet.jaxb2_commons.locator.util.LocatorUtils;

/**
 *
Java class for featuresType complex type.
 *
 *
The following schema fragment specifies the expected content contained within this class.
 *
 *

 * <complexType name="featuresType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="feature" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="10" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 *

 *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "featuresType", propOrder = {
    "feature"
})
@Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
public class FeaturesType implements Serializable, Cloneable, CopyTo2, Equals2, ToString2
{

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    protected List<String> feature;

    /**
     * Gets the value of the feature property.
     *
     *

     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a set method for the feature property.
     *
     *

     * For example, to add a new item, do as follows:
     *

     *    getFeature().add(newItem);
     *

     *
     *
     *

     * Objects of the following type(s) are allowed in the list
     * {@link String }
     *
     *
     */
    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    public List<String> getFeature() {
        if (feature == null) {
            feature = new ArrayList<String>();
        }
        return this.feature;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    public String toString() {
        final ToStringStrategy2 strategy = JAXBToStringStrategy.INSTANCE;
        final StringBuilder buffer = new StringBuilder();
        append(null, buffer, strategy);
        return buffer.toString();
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    public StringBuilder append(ObjectLocator locator, StringBuilder buffer, ToStringStrategy2 strategy) {
        strategy.appendStart(locator, this, buffer);
        appendFields(locator, buffer, strategy);
        strategy.appendEnd(locator, this, buffer);
        return buffer;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    public StringBuilder appendFields(ObjectLocator locator, StringBuilder buffer, ToStringStrategy2 strategy) {
        {
            List<String> theFeature;
            theFeature = (((this.feature!= null)&&(!this.feature.isEmpty()))?this.getFeature():null);
            strategy.appendField(locator, this, "feature", buffer, theFeature, ((this.feature!= null)&&(!this.feature.isEmpty())));
        }
        return buffer;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    public Object clone() {
        return copyTo(createNewInstance());
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    public Object copyTo(Object target) {
        final CopyStrategy2 strategy = JAXBCopyStrategy.INSTANCE;
        return copyTo(null, target, strategy);
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    public Object copyTo(ObjectLocator locator, Object target, CopyStrategy2 strategy) {
        final Object draftCopy = ((target == null)?createNewInstance():target);
        if (draftCopy instanceof FeaturesType) {
            final FeaturesType copy = ((FeaturesType) draftCopy);
            {
                Boolean featureShouldBeCopiedAndSet = strategy.shouldBeCopiedAndSet(locator, ((this.feature!= null)&&(!this.feature.isEmpty())));
                if (featureShouldBeCopiedAndSet == Boolean.TRUE) {
                    List<String> sourceFeature;
                    sourceFeature = (((this.feature!= null)&&(!this.feature.isEmpty()))?this.getFeature():null);
                    @SuppressWarnings("unchecked")
                    List<String> copyFeature = ((List<String> ) strategy.copy(LocatorUtils.property(locator, "feature", sourceFeature), sourceFeature, ((this.feature!= null)&&(!this.feature.isEmpty()))));
                    copy.feature = null;
                    if (copyFeature!= null) {
                        List<String> uniqueFeaturel = copy.getFeature();
                        uniqueFeaturel.addAll(copyFeature);
                    }
                } else {
                    if (featureShouldBeCopiedAndSet == Boolean.FALSE) {
                        copy.feature = null;
                    }
                }
            }
        }
        return draftCopy;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    public Object createNewInstance() {
        return new FeaturesType();
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Object object, EqualsStrategy2 strategy) {
        if ((object == null)||(this.getClass()!= object.getClass())) {
            return false;
        }
        if (this == object) {
            return true;
        }
        final FeaturesType that = ((FeaturesType) object);
        {
            List<String> lhsFeature;
            lhsFeature = (((this.feature!= null)&&(!this.feature.isEmpty()))?this.getFeature():null);
            List<String> rhsFeature;
            rhsFeature = (((that.feature!= null)&&(!that.feature.isEmpty()))?that.getFeature():null);
            if (!strategy.equals(LocatorUtils.property(thisLocator, "feature", lhsFeature), LocatorUtils.property(thatLocator, "feature", rhsFeature), lhsFeature, rhsFeature, ((this.feature!= null)&&(!this.feature.isEmpty())), ((that.feature!= null)&&(!that.feature.isEmpty())))) {
                return false;
            }
        }
        return true;
    }

    @Generated(value = "com.sun.tools.xjc.Driver", date = "2018-10-12T02:41:42+02:00", comments = "JAXB RI v2.2.11")
    public boolean equals(Object object) {
        final EqualsStrategy2 strategy = JAXBEqualsStrategy.INSTANCE;
        return equals(null, null, object, strategy);
    }

}


/*
 * Copyright 2015-2018 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.core;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVPrinter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A general CSV format specification, that supports reading through
 * {@link CsvParser} and writing through {@link CsvPrinter}.
 *
 * @param <Parser>  the class used for CSV parsing
 * @param <Printer> the class used for CSV printing
 * @author Andreas Rudolph
 * @since 1.0
 */
public abstract class CsvFormat<Parser extends CsvParser, Printer extends CsvPrinter> {
    private final static Logger LOGGER = LoggerFactory.getLogger(CsvFormat.class);
    private final CSVFormat format;

    /**
     * Create with specifications of a {@link CSVFormat}.
     *
     * @param format the CSV format from
     *               commons-csv
     */
    protected CsvFormat(CSVFormat format) {
        this.format = format;
    }

    /**
     * Returns the encoding of created CSV data.
     *
     * @return encoding
     */
    public abstract String getEncoding();

    /**
     * Returns the contained {@link CSVFormat}.
     *
     * @return the contained format
     */
    public final CSVFormat getFormat() {
        return this.format;
    }

    /**
     * Creates a new {@link CsvParser} for a {@link CSVParser}.
     *
     * @param parser the CSV parser from
     *               commons-csv
     * @return created parser
     */
    protected abstract Parser newParser(CSVParser parser);

    /**
     * Creates a new {@link CsvPrinter} for a {@link CSVPrinter}.
     *
     * @param printer the CSV printer from
     *                commons-csv
     * @return created printer
     */
    protected abstract Printer newPrinter(CSVPrinter printer);

    /**
     * Creates a {@link CsvParser} from a {@link String} with CSV data.
     *
     * @param csvString CSV string
     * @return created parser
     * @throws IOException if CSV is not readable
     */
    public final Parser parse(String csvString) throws IOException {
        return this.parse(new StringReader(csvString));
    }

    /**
     * Creates a {@link CsvParser} from a {@link File} with CSV data.
     *
     * @param csvFile CSV file
     * @return created parser
     * @throws IOException if CSV is not readable
     */
    @SuppressFBWarnings(
            value = "OBL_UNSATISFIED_OBLIGATION",
            justification = "The stream is closed later together with the parser.")
    public final Parser parse(File csvFile) throws IOException {
        return this.parse(new FileInputStream(csvFile));
    }

    /**
     * Creates a {@link CsvParser} from an {@link InputStream} with CSV data.
     *
     * @param input CSV input
     * @return created parser
     * @throws IOException if CSV is not readable
     */
    public final Parser parse(InputStream input) throws IOException {
        return this.parse(new InputStreamReader(input, this.getEncoding()));
    }

    /**
     * Creates a {@link CsvParser} from a {@link Reader} with CSV data.
     *
     * @param input CSV input
     * @return created parser
     * @throws IOException if CSV is not readable
     */
    public Parser parse(Reader input) throws IOException {
        return this.newParser(new CSVParser(input, this.getFormat()));
    }

    /**
     * Creates a {@link CsvPrinter}, that writes CSV data into a
     * {@link StringBuffer}.
     *
     * @param csvString where CSV is written to
     * @return created printer
     * @throws IOException if CSV is not writable
     */
    public final Printer print(StringBuffer csvString) throws IOException {
        return print((Appendable) csvString);
    }

    /**
     * Creates a {@link CsvPrinter}, that writes CSV data into a
     * {@link StringBuilder}.
     *
     * @param csvString where CSV is written to
     * @return created printer
     * @throws IOException if CSV is not writable
     */
    public final Printer print(StringBuilder csvString) throws IOException {
        return print((Appendable) csvString);
    }

    /**
     * Creates a {@link CsvPrinter}, that writes CSV data into a {@link File}.
     *
     * @param csvFile where CSV is written to
     * @return created printer
     * @throws IOException if CSV is not writable
     */
    @SuppressFBWarnings(
            value = "OBL_UNSATISFIED_OBLIGATION",
            justification = "The stream is closed later together with the printer.")
    public final Printer print(File csvFile) throws IOException {
        return print(new FileOutputStream(csvFile));
    }

    /**
     * Creates a {@link CsvPrinter}, that writes CSV data into an
     * {@link OutputStream}.
     *
     * @param output where CSV is written to
     * @return created printer
     * @throws IOException if CSV is not writable
     */
    public final Printer print(OutputStream output) throws IOException {
        return print(new OutputStreamWriter(output, this.getEncoding()));
    }

    /**
     * Creates a {@link CsvPrinter}, that writes CSV data into a {@link Writer}.
     *
     * @param output where CSV is written to
     * @return created printer
     * @throws IOException if CSV is not writable
     */
    public final Printer print(Writer output) throws IOException {
        return print((Appendable) output);
    }

    /**
     * Creates a {@link CsvPrinter}, that writes CSV data into an
     * {@link Appendable} object.
     *

     * Use this function to, to override the print methods through inheritance.
     *
     * @param output where CSV is written to
     * @return created printer
     * @throws IOException if CSV is not writable
     */
    protected Printer print(Appendable output) throws IOException {
        return newPrinter(new CSVPrinter(output, this.getFormat()));
    }
}


/*
 * Copyright 2015-2018 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.core;

import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A general CSV printer, that is bound to a {@link CsvFormat} and writes CSV
 * data from {@link CsvRecord} objects.
 *
 * @param <Record> the class used for a record, that is printed to a CSV file
 * @author Andreas Rudolph
 * @since 1.0
 */
public abstract class CsvPrinter<Record extends CsvRecord> implements Closeable, Flushable {
    private final static Logger LOGGER = LoggerFactory.getLogger(CsvPrinter.class);
    private final static Pattern LINES = Pattern.compile("^(.*)$", Pattern.MULTILINE);
    private final CSVPrinter printer;

    /**
     * Create with specifications of a {@link CSVPrinter}.
     *
     * @param printer the CSV printer from
     *                commons-csv
     */
    protected CsvPrinter(CSVPrinter printer) {
        this.printer = printer;
    }

    /**
     * Closes the printer instance.
     *
     * @throws IOException if closing failed
     */
    @Override
    public void close() throws IOException {
        this.printer.close();
    }

    /**
     * Flushes the printer instance.
     *
     * @throws IOException if flushing failed
     */
    @Override
    public void flush() throws IOException {
        this.printer.flush();
    }

    /**
     * Prints a single CSV value.
     *
     * @param value CSV value to print
     * @throws IOException if printing failed
     */
    protected void print(String value) throws IOException {
        this.printer.print(value);
    }

    /**
     * Prints a record separator (line break).
     *
     * @throws IOException if printing failed
     */
    protected void println() throws IOException {
        this.printer.println();
    }

    /**
     * Prints a comment.
     *
     * @param comment comment to print
     * @throws IOException if printing failed
     */
    protected void printComment(String comment) throws IOException {
        this.printer.printComment(comment);
    }

    /**
     * Print a {@link CsvRecord} followed by a record separator (line break).
     *
     * @param record record to print
     * @throws IOException if printing failed
     */
    public void printRecord(Record record) throws IOException {
        for (String value : record.print()) {
            this.print(value);
        }
        this.println();
    }

    /**
     * Print multiple {@link CsvRecord} objects.
     *
     * @param records records to print
     * @throws IOException if printing failed
     */
    public void printRecords(Iterable<Record> records) throws IOException {
        for (Record record : records) {
            this.printRecord(record);
        }
        this.flush();
    }

    /**
     * Helper function to replace line breaks in a string with <br/> before
     * printing.
     *

     * This method may be used by inheriting classes, if the particular format
     * does not support line breaks.
     *
     * @param value value to replace
     * @return value with replaced line breaks
     */
    protected static String replaceLineBreaks(String value) {
        return replaceLineBreaks(value, null);
    }

    /**
     * Helper function to replace line breaks in a string with a custom value
     * before printing.
     *

     * This method may be used by inheriting classes, if the particular format
     * does not support line breaks.
     *
     * @param value     value to replace
     * @param lineBreak value, that is used for replacement of line breaks - if null, <br/>
     *                  is used
     * @return value with replaced line breaks
     */
    protected static String replaceLineBreaks(String value, String lineBreak) {
        value = StringUtils.trimToNull(value);
        if (value == null) return null;
        if (lineBreak == null) lineBreak = "
";
        Matcher m = LINES.matcher(value);
        StringBuilder out = new StringBuilder();
        while (m.find()) {
            out.append(StringUtils.trimToEmpty(m.group()));
            if (!m.hitEnd()) out.append(lineBreak);
        }
        return out.toString();
    }
}


/*
 * Copyright 2015-2018 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.immobiliare_it;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.Calendar;
import java.util.Currency;
import java.util.Locale;
import javax.xml.bind.DatatypeConverter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.lang3.StringUtils;
import org.openestate.io.core.LocaleUtils;
import org.openestate.io.core.XmlUtils;
import org.openestate.io.core.XmlValidationHandler;
import org.openestate.io.immobiliare_it.xml.ObjectFactory;
import org.openestate.io.immobiliare_it.xml.types.Category;
import org.openestate.io.immobiliare_it.xml.types.EnergyUnit;
import org.openestate.io.immobiliare_it.xml.types.LandSizeUnit;
import org.openestate.io.immobiliare_it.xml.types.SizeUnit;
import org.openestate.io.immobiliare_it.xml.types.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * Some helper functions for the XML format of
 * immobiliare.it.
 *
 * @author Andreas Rudolph
 * @since 1.0
 */
@SuppressWarnings("WeakerAccess")
public class ImmobiliareItUtils {
    @SuppressWarnings("unused")
    private final static Logger LOGGER = LoggerFactory.getLogger(ImmobiliareItUtils.class);
    private static JAXBContext JAXB = null;

    /**
     * the latest implemented version of this format
     */
    @SuppressWarnings("unused")
    public final static ImmobiliareItVersion VERSION = ImmobiliareItVersion.V2_5;

    /**
     * the XML target namespace of this format
     */
    @SuppressWarnings("unused")
    public final static String NAMESPACE = "http://feed.immobiliare.it";

    /**
     * the default locale of this format
     */
    @SuppressWarnings("unused")
    public final static Locale DEFAULT_LOCALE = Locale.ENGLISH;

    /**
     * the package, where generated JAXB classes are located
     */
    @SuppressWarnings("unused")
    public final static String PACKAGE = "org.openestate.io.immobiliare_it.xml";

    /**
     * the factory for creation of JAXB objects
     */
    @SuppressWarnings("unused")
    public final static ObjectFactory FACTORY = new ObjectFactory();

    private ImmobiliareItUtils() {
    }

    /**
     * Creates a {@link ImmobiliareItDocument} from an {@link InputStream}.
     *
     * @param input XML input
     * @return created document or null, of the document is not supported by this format
     * @throws SAXException                 if XML is invalid
     * @throws IOException                  if reading failed
     * @throws ParserConfigurationException if the parser is not properly configured
     */
    public static ImmobiliareItDocument createDocument(InputStream input) throws SAXException, IOException, ParserConfigurationException {
        return createDocument(XmlUtils.newDocument(input, true));
    }

    /**
     * Creates a {@link ImmobiliareItDocument} from a {@link File}.
     *
     * @param xmlFile XML file
     * @return created document or null, of the document is not supported by this format
     * @throws SAXException                 if XML is invalid
     * @throws IOException                  if reading failed
     * @throws ParserConfigurationException if the parser is not properly configured
     */
    public static ImmobiliareItDocument createDocument(File xmlFile) throws SAXException, IOException, ParserConfigurationException {
        return createDocument(XmlUtils.newDocument(xmlFile, true));
    }

    /**
     * Creates a {@link ImmobiliareItDocument} from a {@link String}.
     *
     * @param xmlString XML string
     * @return created document or null, of the document is not supported by this format
     * @throws SAXException                 if XML is invalid
     * @throws IOException                  if reading failed
     * @throws ParserConfigurationException if the parser is not properly configured
     */
    public static ImmobiliareItDocument createDocument(String xmlString) throws SAXException, IOException, ParserConfigurationException {
        return createDocument(XmlUtils.newDocument(xmlString, true));
    }

    /**
     * Creates a {@link ImmobiliareItDocument} from a {@link Document}.
     *
     * @param doc XML document
     * @return created document or null, of the document is not supported by this format
     */
    public static ImmobiliareItDocument createDocument(Document doc) {
        if (ImmobiliareItDocument.isReadable(doc))
            return new ImmobiliareItDocument(doc);
        else
            return null;
    }

    /**
     * Creates a {@link Marshaller} to write JAXB objects into XML.
     *
     * @return created marshaller
     * @throws JAXBException if a problem with JAXB occurred
     */
    @SuppressWarnings("unused")
    public static Marshaller createMarshaller() throws JAXBException {
        return createMarshaller(Charset.defaultCharset().name(), true);
    }

    /**
     * Creates a {@link Marshaller} to write JAXB objects into XML.
     *
     * @param encoding  encoding of written XML
     * @param formatted if written XML is pretty printed
     * @return created marshaller
     * @throws JAXBException if a problem with JAXB occurred
     */
    public static Marshaller createMarshaller(String encoding, boolean formatted) throws JAXBException {
        Marshaller m = getContext().createMarshaller();
        m.setProperty(Marshaller.JAXB_ENCODING, encoding);
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, formatted);
        m.setEventHandler(new XmlValidationHandler());
        return m;
    }

    /**
     * Creates a {@link Unmarshaller} to read JAXB objects from XML.
     *
     * @return created unmarshaller
     * @throws JAXBException if a problem with JAXB occurred
     */
    public static Unmarshaller createUnmarshaller() throws JAXBException {
        Unmarshaller m = getContext().createUnmarshaller();
        m.setEventHandler(new XmlValidationHandler());
        return m;
    }

    /**
     * Returns the {@link JAXBContext} for this format.
     *
     * @return context
     * @throws JAXBException if a problem with JAXB occurred
     */
    public synchronized static JAXBContext getContext() throws JAXBException {
        if (JAXB == null) initContext(Thread.currentThread().getContextClassLoader());
        return JAXB;
    }

    /**
     * Returns a country code, as it is preferred by this format.
     *
     * @param country country name to convert
     * @return converted country code or null, if no matching country was found
     */
    public static String getCountryCode(String country) {
        return LocaleUtils.getCountryISO2(country);
    }

    /**
     * Returns the {@link ObjectFactory} for this format.
     *
     * @return object factory
     */
    public synchronized static ObjectFactory getFactory() {
        return FACTORY;
    }

    /**
     * Initializes the {@link JAXBContext} for this format.
     *
     * @param classloader the classloader to load the generated JAXB classes with
     * @throws JAXBException if a problem with JAXB occurred
     */
    public synchronized static void initContext(ClassLoader classloader) throws JAXBException {
        JAXB = JAXBContext.newInstance(PACKAGE, classloader);
    }

    public static boolean isValidDateUpdatedType(Calendar value) {
        final Calendar min = DatatypeConverter.parseDateTime("2000-12-31T00:00:00");
        return value != null && !value.before(min);
    }

    public static boolean isValidEmailType(String value) {
        return value != null && value.matches("[^@]+@[^\\.]+\\..+");
    }

    public static boolean isValidLatitude(BigDecimal value) {
        //return value!=null && isValidLatitude( value.doubleValue() );
        BigDecimal min = new BigDecimal("27.2");
        BigDecimal max = new BigDecimal("71.1");
        return value != null && value.compareTo(min) >= 0 && value.compareTo(max) <= 0;
    }

    @Deprecated
    public static boolean isValidLatitude(Double value) {
        //return value!=null && value>=27.2 && value<=71.1;
        return isValidLatitude(BigDecimal.valueOf(value));
    }

    public static boolean isValidLongitude(BigDecimal value) {
        BigDecimal min = new BigDecimal("31.2");
        BigDecimal max = new BigDecimal("38.9");
        return value != null && value.compareTo(min) >= 0 && value.compareTo(max) <= 0;
    }

    @Deprecated
    public static boolean isValidLongitude(Double value) {
        //return value!=null && value>=-31.2 && value<=38.9;
        return isValidLongitude(BigDecimal.valueOf(value));
    }

    public static boolean isValidRooms(Integer value) {
        return value != null && value >= 1 && value <= 100;
    }

    public static boolean isValidYear(Integer value) {
        return value != null && value >= 1000 && value <= 2020;
    }

    public static Category parseCategory(String value) {
        value = StringUtils.trimToNull(value);
        if (value == null) return null;

        Category cat = Category.fromXmlValue(value);
        if (cat == null)
            throw new IllegalArgumentException("Can't parse category value '" + value + "'!");

        return cat;
    }

    public static String parseCountry(String value) {
        return StringUtils.trimToNull(value);
    }

    public static Currency parseCurrency(String value) {
        value = StringUtils.trimToNull(value);
        if (value == null) return null;
        try {
            if (value.trim().length() != 3)
                throw new Exception("Currency code must contain of 3 characters.");

            return Currency.getInstance(value.trim().toUpperCase());
        } catch (Exception ex) {
            throw new IllegalArgumentException("Can't parse currency value '" + value + "'!", ex);
        }
    }

    public static Calendar parseDateUpdatedType(String value) {
        try {
            return XmlUtils.parseDateTime(value);
        } catch (Exception ex) {
            throw new IllegalArgumentException("Can't parse date-updated value '" + value + "'!", ex);
        }
    }

    public static String parseEmailType(String value) {
        //value = StringUtils.trimToNull( value );
        //if (value==null)
        //  return null;
        //else if (value.matches( "[^@]+@[^\\.]+\\..+" ))
        //  return value;
        //else
        //  throw new IllegalArgumentException( "Can't parse e-mail value '" + value + "'!" );
        return StringUtils.trimToNull(value);
    }

    public static EnergyUnit parseEnergyUnit(String value) {
        value = StringUtils.trimToNull(value);
        if (value == null) return null;

        EnergyUnit unit = EnergyUnit.fromXmlValue(value);
        if (unit == null)
            throw new IllegalArgumentException("Can't parse energy-unit value '" + value + "'!");

        return unit;
    }

    public static BigInteger parseInteger(String value) {
        value = StringUtils.trimToNull(value);
        return (value != null) ? DatatypeConverter.parseInteger(value) : null;
    }

    public static LandSizeUnit parseLandSizeUnit(String value) {
        value = StringUtils.trimToNull(value);
        if (value == null) return null;

        LandSizeUnit unit = LandSizeUnit.fromXmlValue(value);
        if (unit == null)
            throw new IllegalArgumentException("Can't parse land-size-unit value '" + value + "'!");

        return unit;
    }

    public static BigDecimal parseLatitude(String value) {
        value = StringUtils.trimToNull(value);
        return (value != null) ? DatatypeConverter.parseDecimal(value) : null;
    }

    public static BigDecimal parseLongitude(String value) {
        value = StringUtils.trimToNull(value);
        return (value != null) ? DatatypeConverter.parseDecimal(value) : null;
    }

    public static Integer parseRooms(String value) {
        value = StringUtils.trimToNull(value);
        return (value != null) ? DatatypeConverter.parseInt(value) : null;
    }

    public static SizeUnit parseSizeUnit(String value) {
        value = StringUtils.trimToNull(value);
        if (value == null) return null;

        SizeUnit unit = SizeUnit.fromXmlValue(value);
        if (unit == null)
            throw new IllegalArgumentException("Can't parse size-unit value '" + value + "'!");

        return unit;
    }

    @SuppressWarnings({"SameParameterValue", "unused"})
    private static String parseText(String value, int length) {
        return StringUtils.trimToNull(value);
    }

    public static String parseText3000(String value) {
        return parseText(value, 3000);
    }

    @SuppressWarnings("unused")
    public static Transaction parseTransaction(String value) {
        value = StringUtils.trimToNull(value);
        if (value == null) return null;

        Transaction unit = Transaction.fromXmlValue(value);
        if (unit == null)
            throw new IllegalArgumentException("Can't parse transaction value '" + value + "'!");

        return unit;
    }

    public static Integer parseYear(String value) {
        value = StringUtils.trimToNull(value);
        return (value != null) ? DatatypeConverter.parseInt(value) : null;
    }

    public static Boolean parseYesNo(String value) {
        value = StringUtils.trimToEmpty(value);
        if ("yes".equalsIgnoreCase(value))
            return Boolean.TRUE;
        else if ("no".equalsIgnoreCase(value))
            return Boolean.FALSE;
        else
            throw new IllegalArgumentException("Can't parse yes-no value '" + value + "'!");
    }

    public static Boolean parseYN(String value) {
        value = StringUtils.trimToEmpty(value);
        if ("y".equalsIgnoreCase(value))
            return Boolean.TRUE;
        else if ("n".equalsIgnoreCase(value))
            return Boolean.FALSE;
        else
            throw new IllegalArgumentException("Can't parse y-n value '" + value + "'!");
    }

    public static String printCategory(Category value) {
        if (value == null)
            throw new IllegalArgumentException("Can't print category value!");
        else
            return value.getXmlValue();
    }

    public static String printCountry(String value) {
        value = StringUtils.trimToNull(value);
        if (value == null)
            throw new IllegalArgumentException("Can't print country value!");

        String iso2 = StringUtils.trimToNull(ImmobiliareItUtils.getCountryCode(value));
        if (iso2 == null)
            throw new IllegalArgumentException("Can't convert country '" + value + "' to its ISO2 code!");
        else
            return iso2;
    }

    public static String printCurrency(Currency value) {
        if (value == null)
            throw new IllegalArgumentException("Can't print currency value!");
        else
            return value.getCurrencyCode();
    }

    public static String printDateUpdatedType(Calendar value) {
        if (value == null || !isValidDateUpdatedType(value))
            throw new IllegalArgumentException("Can't print date-updated value!");
        else
            return DatatypeConverter.printDateTime(value);
    }

    public static String printEmailType(String value) {
        if (!isValidEmailType(value))
            throw new IllegalArgumentException("Can't print email value!");
        else
            return value;
    }

    public static String printEnergyUnit(EnergyUnit value) {
        if (value == null)
            throw new IllegalArgumentException("Can't print energy-unit value!");
        else
            return value.getXmlValue();
    }

    public static String printInteger(BigInteger value) {
        if (value == null)
            throw new IllegalArgumentException("Can't print integer value!");
        else
            return DatatypeConverter.printInteger(value);
    }

    public static String printLandSizeUnit(LandSizeUnit value) {
        if (value == null)
            throw new IllegalArgumentException("Can't print land-size-unit value!");
        else
            return value.getXmlValue();
    }

    public static String printLatitude(BigDecimal value) {
        if (value == null || !isValidLatitude(value))
            throw new IllegalArgumentException("Can't print latitude value!");
        else
            return DatatypeConverter.printDecimal(value);
    }

    public static String printLongitude(BigDecimal value) {
        if (value == null || !isValidLongitude(value))
            throw new IllegalArgumentException("Can't print longitude value!");
        else
            return DatatypeConverter.printDecimal(value);
    }

    public static String printRooms(Integer value) {
        if (!isValidRooms(value))
            throw new IllegalArgumentException("Can't print rooms value!");
        else
            return DatatypeConverter.printInt(value);
    }

    public static String printSizeUnit(SizeUnit value) {
        if (value == null)
            throw new IllegalArgumentException("Can't print size-unit value!");
        else
            return value.getXmlValue();
    }

    @SuppressWarnings({"SameParameterValue", "Duplicates"})
    private static String printText(String value, int maxLength) {
        value = StringUtils.trimToEmpty(value);
        int length = value.length();
        if (length <= 0)
            return StringUtils.EMPTY;
        else if (length <= maxLength)
            return value;
        else if (maxLength > 3)
            return StringUtils.abbreviate(value, maxLength);
        else
            return value.substring(0, maxLength);
    }

    public static String printText3000(String value) {
        return printText(value, 3000);
    }

    @SuppressWarnings("unused")
    public static String printTransaction(Transaction value) {
        if (value == null)
            throw new IllegalArgumentException("Can't print transaction value!");
        else
            return value.getXmlValue();
    }

    public static String printYear(Integer value) {
        if (!isValidYear(value))
            throw new IllegalArgumentException("Can't print year value!");
        else
            return DatatypeConverter.printInt(value);
    }

    public static String printYesNo(Boolean value) {
        if (Boolean.TRUE.equals(value))
            return "yes";
        else if (Boolean.FALSE.equals(value))
            return "no";
        else
            throw new IllegalArgumentException("Can't print yes-no value!");
    }

    public static String printYN(Boolean value) {
        if (Boolean.TRUE.equals(value))
            return "Y";
        else if (Boolean.FALSE.equals(value))
            return "N";
        else
            throw new IllegalArgumentException("Can't print y-n value!");
    }
}