Skip to content
Andreas Rudolph edited this page Aug 16, 2021 · 15 revisions

How to use Filemaker format

Document types in Filemaker format

Filemaker specifies two types of XML documents:

  1. A document with a <FMPXMLRESULT> root element contains database contents and structural informations about Filemaker database. This type of document is represented by the org.openestate.io.filemaker.FilemakerResultDocument class.

  2. A document with a <FMPXMLLAYOUT> root element contains structural informations about Filemaker database. This type of document is represented by the org.openestate.io.filemaker.FilemakerLayoutDocument class.

Both document classes are extending the general / abstract org.openestate.io.filemaker.FilemakerDocument class.

Reading XML in FMPXMLRESULT format

The class org.openestate.io.filemaker.FilemakerUtils provides a static createDocument() function to read XML data in Filemaker format from a java.io.File, java.io.InputStream, java.lang.String or org.w3c.dom.Document into a org.openestate.io.filemaker.FilemakerDocument.

The createDocument() function returns either a org.openestate.io.filemaker.FilemakerResultDocument or a org.openestate.io.filemaker.FilemakerLayoutDocument - depending on the type of Filemaker document.

import java.io.File;
import org.openestate.io.filemaker.FilemakerResultDocument;
import org.openestate.io.filemaker.FilemakerUtils;
import org.openestate.io.filemaker.xml.result.FMPXMLRESULT;
import org.openestate.io.filemaker.xml.result.MetaDataType;
import org.openestate.io.filemaker.xml.result.ResultSetType;

public class FilemakerReadingExample {
    public static void main(String[] args) throws Exception {
        if (args.length < 1) {
            System.err.println("No file was specified!");
            System.exit(1);
        }

        // read file into a FilemakerResultDocument
        FilemakerResultDocument doc = (FilemakerResultDocument)
                FilemakerUtils.createDocument(new File(args[0]));
        if (doc == null) {
            System.err.println("Can't read XML file!");
            System.exit(1);
        }

        // convert FilemakerResultDocument into a Java object
        FMPXMLRESULT result = doc.toObject();

        // now we can access the XML content through ordinary Java objects
        System.out.println("> error code       : " + result.getERRORCODE());
        if (result.getPRODUCT() != null) {
            System.out.println("> product name     : " + result.getPRODUCT().getNAME());
            System.out.println("> product version  : " + result.getPRODUCT().getVERSION());
            System.out.println("> product build    : " + result.getPRODUCT().getBUILD());
        }
        if (result.getDATABASE() != null) {
            System.out.println("> database name    : " + result.getDATABASE().getNAME());
            System.out.println("> database layout  : " + result.getDATABASE().getLAYOUT());
            System.out.println("> database date    : " + result.getDATABASE().getDATEFORMAT());
            System.out.println("> database time    : " + result.getDATABASE().getTIMEFORMAT());
            System.out.println("> database records : " + result.getDATABASE().getRECORDS());
        }
        if (result.getMETADATA() != null) {
            for (MetaDataType.FIELD field : result.getMETADATA().getFIELD()) {
                System.out.println("> database field   : " + field.getNAME());
                System.out.println(">> type            : " + field.getTYPE());
                System.out.println(">> max repeat      : " + field.getMAXREPEAT());
            }
        }
        if (result.getRESULTSET() != null) {
            System.out.println("> result set found : " + result.getRESULTSET().getFOUND());
            for (ResultSetType.ROW row : result.getRESULTSET().getROW()) {
                System.out.println("> result set row   : " + row.getRECORDID() + " / " + row.getMODID());
                for (ResultSetType.ROW.COL col : row.getCOL()) {
                    for (String data : col.getDATA()) {
                        System.out.println(">> " + data);
                    }
                }
            }
        }
    }
}

See a full example at FilemakerReadingExample.java.

Accessing XML data in FMPXMLRESULT format

The class org.openestate.io.filemaker.xml.FMPXMLRESULT is equivalent to a <FMPXMLRESULT> root element in a FMPXMLRESULT document. For example the following code creates a FMPXMLRESULT document programmatically:

import java.math.BigInteger;
import org.apache.commons.lang3.StringUtils;
import org.openestate.io.filemaker.FilemakerUtils;
import org.openestate.io.filemaker.xml.result.DatabaseType;
import org.openestate.io.filemaker.xml.result.FMPXMLRESULT;
import org.openestate.io.filemaker.xml.result.FieldType;
import org.openestate.io.filemaker.xml.result.MetaDataType;
import org.openestate.io.filemaker.xml.result.ObjectFactory;
import org.openestate.io.filemaker.xml.result.ProductType;
import org.openestate.io.filemaker.xml.result.ResultSetType;

public class FilemakerWritingExample {
    private final static ObjectFactory FACTORY = FilemakerUtils.getFactoryForResult();

    public static void main(String[] args) {
        // create a FMPXMLRESULT object with some example data
        // this object corresponds to the <FMPXMLRESULT> root element in XML
        FMPXMLRESULT result = FilemakerUtils.getFactoryForResult().createFMPXMLRESULT();
        result.setERRORCODE("0");
        result.setPRODUCT(createProduct());
        result.setDATABASE(createDatabase());
        result.setMETADATA(createMetaData());
        result.setRESULTSET(createResultSet());

        // now make something useful with the object
    }

    /**
     * Create a {@link DatabaseType} with some example data.
     *
     * @return created example object
     */
    private static DatabaseType createDatabase() {
        DatabaseType database = FACTORY.createDatabaseType();
        database.setNAME("example database");
        database.setLAYOUT("fmmedia2universal");
        database.setDATEFORMAT("D.m.yyyy");
        database.setTIMEFORMAT("k:mm:ss");
        database.setRECORDS(BigInteger.ZERO);
        return database;
    }

    /**
     * Create a {@link MetaDataType} with some example data.
     *
     * @return created example object
     */
    private static MetaDataType createMetaData() {
        MetaDataType metadata = FACTORY.createMetaDataType();
        MetaDataType.FIELD field;

        field = FACTORY.createMetaDataTypeFIELD();
        field.setNAME("number of rooms");
        field.setEMPTYOK(true);
        field.setMAXREPEAT(BigInteger.ONE);
        field.setTYPE(FieldType.NUMBER);
        metadata.getFIELD().add(field);

        field = FACTORY.createMetaDataTypeFIELD();
        field.setNAME("price");
        field.setEMPTYOK(false);
        field.setMAXREPEAT(BigInteger.ONE);
        field.setTYPE(FieldType.NUMBER);
        metadata.getFIELD().add(field);

        field = FACTORY.createMetaDataTypeFIELD();
        field.setNAME("description");
        field.setEMPTYOK(true);
        field.setMAXREPEAT(BigInteger.ONE);
        field.setTYPE(FieldType.TEXT);
        metadata.getFIELD().add(field);

        return metadata;
    }

    /**
     * Create a {@link ProductType} with some example data.
     *
     * @return created example object
     */
    private static ProductType createProduct() {
        ProductType product = FACTORY.createProductType();
        product.setNAME("My application");
        product.setVERSION(RandomStringUtils.randomNumeric(2));
        product.setBUILD("123");
        return product;
    }

    /**
     * Create a {@link ResultSetType} with some example data.
     *
     * @return created example object
     */
    private static ResultSetType createResultSet() {
        ResultSetType result = FACTORY.createResultSetType();
        result.getROW().add(createResultSetRow(1, 3, 100, "a first example"));
        result.getROW().add(createResultSetRow(2, null, 200, "a second example"));
        result.getROW().add(createResultSetRow(3, 5, 300, null));
        result.setFOUND(BigInteger.valueOf(result.getROW().size()));
        return result;
    }

    /**
     * Create a {@link org.openestate.io.filemaker.xml.result.ResultSetType.ROW}
     * with some example data.
     *
     * @param id            id of the record
     * @param numberOfRooms value for number of rooms
     * @param price         value for price
     * @param description   value for description
     * @return created example object
     */
    @SuppressWarnings("ConstantConditions")
    private static ResultSetType.ROW createResultSetRow(long id, Number numberOfRooms, Number price, String description) {
        ResultSetType.ROW.COL col;

        ResultSetType.ROW row = FACTORY.createResultSetTypeROW();
        row.setRECORDID(BigInteger.valueOf(id));
        row.setMODID(BigInteger.valueOf(id));

        col = FACTORY.createResultSetTypeROWCOL();
        if (numberOfRooms != null)
            col.getDATA().add(StringUtils.EMPTY);
        else
            col.getDATA().add(String.valueOf(numberOfRooms));
        row.getCOL().add(col);

        col = FACTORY.createResultSetTypeROWCOL();
        if (price != null)
            col.getDATA().add("0");
        else
            col.getDATA().add(String.valueOf(price));
        row.getCOL().add(col);

        col = FACTORY.createResultSetTypeROWCOL();
        col.getDATA().add(StringUtils.trimToEmpty(description));
        row.getCOL().add(col);

        return row;
    }
}

See a full example at FilemakerWritingExample.java.

Writing XML in FMPXMLRESULT format

After a org.openestate.io.filemaker.xml.FMPXMLRESULT object was created, it can be converted into a org.openestate.io.filemaker.FilemakerResultDocument with the static newDocument() function.

The class org.openestate.io.filemaker.FilemakerResultDocument provides a toXml() function, that finally writes the contents of the FMPXMLRESULT object as XML into a java.io.File, java.io.OutputStream or java.io.Writer.

import java.io.File;
import java.io.OutputStream;
import java.io.Writer;
import org.openestate.io.filemaker.FilemakerResultDocument;
import org.openestate.io.filemaker.xml.result.FMPXMLRESULT;

public class FilemakerWritingExample {
    private final static boolean PRETTY_PRINT = true;

    /**
     * Convert a {@link FMPXMLRESULT} to XML and write it into a {@link File}.
     *
     * @param result Java object representing the XML root element
     * @param file   the file, where the document is written to
     * @throws Exception if the document can't be written
     */
    private static void write(FMPXMLRESULT result, File file) throws Exception {
        FilemakerResultDocument
                .newDocument(result)
                .toXml(file, PRETTY_PRINT);
    }

    /**
     * Convert a {@link FMPXMLRESULT} to XML and write it into an {@link OutputStream}.
     *
     * @param result Java object representing the XML root element
     * @param output the stream, where the document is written to
     * @throws Exception if the document can't be written
     */
    private static void write(FMPXMLRESULT result, OutputStream output) throws Exception {
        FilemakerResultDocument
                .newDocument(result)
                .toXml(output, PRETTY_PRINT);
    }

    /**
     * Convert a {@link FMPXMLRESULT} to XML and write it into a {@link Writer}.
     *
     * @param result Java object representing the XML root element
     * @param output the writer, where the document is written to
     * @throws Exception if the document can't be written
     */
    private static void write(FMPXMLRESULT result, Writer output) throws Exception {
        FilemakerResultDocument
                .newDocument(result)
                .toXml(output, PRETTY_PRINT);
    }

    /**
     * Convert a {@link FMPXMLRESULT} to XML and print the results to the console.
     *
     * @param result Java object representing the XML root element
     * @throws Exception if the document can't be written
     */
    private static void writeToConsole(FMPXMLRESULT result) throws Exception {
        System.out.println(
            FilemakerResultDocument
                .newDocument(result)
                .toXmlString(PRETTY_PRINT)
        );
    }
}

See a full example at FilemakerWritingExample.java.