org.azkfw.datasource.xml.XmlDatasourceBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.azkfw.datasource.xml.XmlDatasourceBuilder.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.azkfw.datasource.xml;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.digester3.Digester;
import org.azkfw.datasource.Datasource;
import org.azkfw.datasource.Field;
import org.azkfw.datasource.FieldType;
import org.azkfw.datasource.Record;
import org.azkfw.datasource.Table;
import org.azkfw.util.StringUtility;
import org.xml.sax.SAXException;

/**
 * ????XML????
 * 
 * @since 1.0.0
 * @version 1.0.0 2014/08/01
 * @author Kawakicchi
 */
public final class XmlDatasourceBuilder {

    /**
     * ?NULL
     */
    private static final String DEFAULT_NULL_STRING = "(NULL)";

    /** ?? */
    private String datasourceName;
    /** NULL */
    private String nullString;
    /** XML */
    private List<File> xmlFiles;

    /**
     * 
     */
    private XmlDatasourceBuilder() {
        datasourceName = null;
        nullString = DEFAULT_NULL_STRING;
        xmlFiles = new ArrayList<File>();
    }

    /**
     * 
     * 
     * @param aName ??
     */
    private XmlDatasourceBuilder(final String aName) {
        datasourceName = aName;
        nullString = DEFAULT_NULL_STRING;
        xmlFiles = new ArrayList<File>();
    }

    /**
     * ???
     * 
     * @return ?
     */
    public static XmlDatasourceBuilder newInstance() {
        XmlDatasourceBuilder builder = new XmlDatasourceBuilder();
        return builder;
    }

    /**
     * ???
     * 
     * @param aFile XML
     * @return ?
     */
    public static XmlDatasourceBuilder newInstance(final File aFile) {
        XmlDatasourceBuilder builder = new XmlDatasourceBuilder();
        builder = builder.addFile(aFile);
        return builder;
    }

    /**
     * ???
     * 
     * @param aFiles XML
     * @return ?
     */
    public static XmlDatasourceBuilder newInstance(final List<File> aFiles) {
        XmlDatasourceBuilder builder = new XmlDatasourceBuilder();
        builder = builder.addFiles(aFiles);
        return builder;
    }

    /**
     * ???
     * 
     * @param aName ??
     * @return ?
     */
    public static XmlDatasourceBuilder newInstance(final String aName) {
        XmlDatasourceBuilder builder = new XmlDatasourceBuilder(aName);
        return builder;
    }

    /**
     * ???
     * 
     * @param aName ??
     * @param aFile XML
     * @return ?
     */
    public static XmlDatasourceBuilder newInstance(final String aName, final File aFile) {
        XmlDatasourceBuilder builder = new XmlDatasourceBuilder(aName);
        builder = builder.addFile(aFile);
        return builder;
    }

    /**
     * ???
     * 
     * @param aName ??
     * @param aFiles XML
     * @return ?
     */
    public static XmlDatasourceBuilder newInstance(final String aName, final List<File> aFiles) {
        XmlDatasourceBuilder builder = new XmlDatasourceBuilder(aName);
        builder = builder.addFiles(aFiles);
        return builder;
    }

    /**
     * ???
     * 
     * @param aName ??
     * @return 
     */
    public XmlDatasourceBuilder setDatasourceName(final String aName) {
        datasourceName = aName;
        return this;
    }

    /**
     * XML?
     * 
     * @param aFile XML
     * @return 
     */
    public XmlDatasourceBuilder addFile(final File aFile) {
        xmlFiles.add(aFile);
        return this;
    }

    /**
     * XML?
     * 
     * @param aFiles XML
     * @return 
     */
    public XmlDatasourceBuilder addFiles(final Collection<File> aFiles) {
        xmlFiles.addAll(aFiles);
        return this;
    }

    /**
     * NULL?
     * 
     * @param aString NULL
     * @return 
     */
    public XmlDatasourceBuilder setNullString(final String aString) {
        nullString = aString;
        return this;
    }

    /**
     * ?
     * 
     * @return 
     * @throws FileNotFoundException
     * @throws ParseException
     * @throws IOException
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Datasource build() throws FileNotFoundException, ParseException, IOException {
        XmlDatasource datasource = new XmlDatasource();
        datasource.name = datasourceName;

        InputStream stream = null;
        try {
            List<XmlTable> tables = new ArrayList<XmlTable>();

            for (File file : xmlFiles) {
                List<XmlTableEntity> tableList = null;

                stream = new FileInputStream(file);
                Digester digester = new Digester();

                digester.addObjectCreate("datasource/tables", ArrayList.class);

                digester.addObjectCreate("datasource/tables/table", XmlTableEntity.class);
                digester.addSetProperties("datasource/tables/table");
                digester.addSetNext("datasource/tables/table", "add");

                digester.addObjectCreate("datasource/tables/table/fields", ArrayList.class);
                digester.addSetNext("datasource/tables/table/fields", "setFields");

                digester.addObjectCreate("datasource/tables/table/fields/field", XmlFieldEntity.class);
                digester.addSetProperties("datasource/tables/table/fields/field");
                digester.addSetNext("datasource/tables/table/fields/field", "add");

                digester.addObjectCreate("datasource/tables/table/records", ArrayList.class);
                digester.addSetNext("datasource/tables/table/records", "setRecords");

                digester.addObjectCreate("datasource/tables/table/records/record", XmlRecordEntity.class);
                digester.addSetNext("datasource/tables/table/records/record", "add");

                digester.addObjectCreate("datasource/tables/table/records/record/data", XmlRecordDataEntity.class);
                digester.addSetProperties("datasource/tables/table/records/record/data");
                digester.addSetNext("datasource/tables/table/records/record/data", "add");

                tableList = digester.parse(stream);

                for (XmlTableEntity t : tableList) {
                    XmlTable table = new XmlTable();
                    table.label = t.label;
                    table.name = t.name;

                    // Read Field
                    List<XmlField> fields = new ArrayList<XmlField>();
                    for (int col = 0; col < t.fields.size(); col++) {
                        XmlFieldEntity f = t.fields.get(col);
                        XmlField field = readField(col, f);
                        fields.add(field);
                    }

                    // Read Data
                    List<XmlRecord> records = new ArrayList<XmlRecord>();
                    for (int row = 0; row < t.records.size(); row++) {
                        XmlRecordEntity r = t.records.get(row);
                        if (r.data.size() == fields.size()) {
                            XmlRecord record = readData(row, r, fields);
                            records.add(record);
                        } else {
                            System.out.println("Skip row(unmatch field count).[table: " + table.getName()
                                    + "; row: " + r + ";]");
                        }
                    }

                    table.fields = (List) fields;
                    table.records = (List) records;

                    tables.add(table);
                }
            }

            datasource.tables = (List) tables;

        } catch (SAXException ex) {
            throw new ParseException(ex.getMessage(), -1);
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (null != stream) {
                try {
                    stream.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }

        return datasource;
    }

    private XmlField readField(final int aCol, final XmlFieldEntity aField) throws ParseException {
        if (StringUtility.isEmpty(aField.name)) {
            throw new ParseException("Field name is empty.[row: 2; col: " + aCol + ";]", 2);
        }
        if (StringUtility.isEmpty(aField.type)) {
            throw new ParseException("Field type is empty.[row: 2; col: " + aCol + ";]", 2);
        }

        FieldType fieldType = FieldType.valueOfName(aField.type.trim());
        if (FieldType.Unknown == fieldType) {
            throw new ParseException("Undefined type.[type: " + aField.type + "; col: " + aCol + ";]", 2);
        }

        XmlField field = new XmlField();
        field.label = aField.label;
        field.name = aField.name;
        field.type = fieldType;

        return field;
    }

    private XmlRecord readData(final int aRowNum, final XmlRecordEntity aRecord, final List<XmlField> aFields)
            throws ParseException {
        Map<String, Object> data = new HashMap<String, Object>();
        for (int i = 0; i < aFields.size(); i++) {
            XmlField field = aFields.get(i);
            XmlRecordDataEntity d = aRecord.data.get(i);

            String value = d.value;

            if (nullString.equals(value)) {
                data.put(field.name, null);
            } else {
                if (FieldType.String == field.type) {
                    String obj = value;
                    data.put(field.name, obj);
                } else if (FieldType.Boolean == field.type) {
                    Boolean obj = Boolean.parseBoolean(value);
                    data.put(field.name, obj);
                } else if (FieldType.Integer == field.type) {
                    Double obj = Double.parseDouble(value);
                    data.put(field.name, Integer.valueOf(obj.intValue()));
                } else if (FieldType.Long == field.type) {
                    Double obj = Double.parseDouble(value);
                    data.put(field.name, Long.valueOf(obj.longValue()));
                } else if (FieldType.Float == field.type) {
                    Float obj = Float.parseFloat(value);
                    data.put(field.name, obj);
                } else if (FieldType.Double == field.type) {
                    Double obj = Double.parseDouble(value);
                    data.put(field.name, obj);
                } else if (FieldType.Timestamp == field.type) {
                    Timestamp obj = new Timestamp(
                            new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").parse(value).getTime());
                    data.put(field.name, obj);
                } else if (FieldType.Date == field.type) {
                    Timestamp ts = new Timestamp(new SimpleDateFormat("yyyy/MM/dd").parse(value).getTime());
                    Date obj = new Date(ts.getTime());
                    data.put(field.name, obj);
                } else if (FieldType.Time == field.type) {
                    Timestamp ts = new Timestamp(new SimpleDateFormat("HH:mm:ss").parse(value).getTime());
                    Time obj = new Time(ts.getTime());
                    data.put(field.name, obj);
                } else {
                    throw new ParseException("Undefined type.[" + field.getType() + "]", aRowNum);
                }
            }
        }

        XmlRecord record = new XmlRecord();
        record.data = data;
        return record;
    }

    /**
     * ????XML??????
     * 
     * @since 1.0.0
     * @version 1.0.0 2014/08/02
     * @author Kawakicchi
     */
    private final class XmlDatasource implements Datasource {

        private String name;
        private List<Table> tables;

        @Override
        public String getName() {
            return name;
        }

        @Override
        public List<Table> getTables() {
            return tables;
        }

    }

    /**
     * ????XML??????
     * 
     * @since 1.0.0
     * @version 1.0.0 2014/08/02
     * @author Kawakicchi
     */
    private final class XmlTable implements Table {

        private String label;
        private String name;
        private List<Field> fields;
        private List<Record> records;

        @Override
        public String getLabel() {
            return label;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public List<Field> getFields() {
            return fields;
        }

        @Override
        public List<Record> getRecords() {
            return records;
        }

    }

    /**
     * ????XML??????
     * 
     * @since 1.0.0
     * @version 1.0.0 2014/08/02
     * @author Kawakicchi
     */
    private final class XmlField implements Field {

        private String label;
        private String name;
        private FieldType type;

        @Override
        public String getLabel() {
            return label;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public FieldType getType() {
            return type;
        }

    }

    /**
     * ????XML??????
     * 
     * @since 1.0.0
     * @version 1.0.0 2014/08/02
     * @author Kawakicchi
     */
    private final class XmlRecord implements Record {

        private Map<String, Object> data;

        @Override
        public Object get(final String aName) {
            return data.get(aName);
        }

    }

    public static class XmlTableEntity {

        private String label;
        private String name;

        private List<XmlFieldEntity> fields;
        private List<XmlRecordEntity> records;

        public void setLabel(final String aLabel) {
            label = aLabel;
        }

        public void setName(final String aName) {
            name = aName;
        }

        public void setFields(final List<XmlFieldEntity> aFields) {
            fields = aFields;
        }

        public void setRecords(final List<XmlRecordEntity> aRecord) {
            records = aRecord;
        }
    }

    public static class XmlFieldEntity {
        private String label;
        private String name;
        private String type;

        public void setLabel(final String aLabel) {
            label = aLabel;
        }

        public void setName(final String aName) {
            name = aName;
        }

        public void setType(final String aType) {
            type = aType;
        }
    }

    public static class XmlRecordEntity {

        private List<XmlRecordDataEntity> data;

        public XmlRecordEntity() {
            data = new ArrayList<XmlRecordDataEntity>();
        }

        public void add(final XmlRecordDataEntity aData) {
            data.add(aData);
        }
    }

    public static class XmlRecordDataEntity {
        private String value;

        public void setValue(final String aValue) {
            value = aValue;
        }
    }
}