Package org.thechiselgroup.choosel.core.client.importer

Source Code of org.thechiselgroup.choosel.core.client.importer.Importer

/*******************************************************************************
* Copyright 2009, 2010 Lars Grammel
*
* 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.thechiselgroup.choosel.core.client.importer;

import java.io.Serializable;
import java.util.Date;

import org.thechiselgroup.choosel.core.client.label.IncrementingSuffixLabelFactory;
import org.thechiselgroup.choosel.core.client.label.LabelProvider;
import org.thechiselgroup.choosel.core.client.resources.DefaultResourceSet;
import org.thechiselgroup.choosel.core.client.resources.Resource;
import org.thechiselgroup.choosel.core.client.resources.ResourceSet;
import org.thechiselgroup.choosel.core.client.resources.ResourceSetUtils;
import org.thechiselgroup.choosel.core.client.util.DataType;

import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.regexp.shared.RegExp;

/*
* TODO revisit error handling
* is this really what the user wants? --> probably not, because then
* numbers cannot be used like numbers columns (warning message would be
* better, and the ability to change this after the import would be the
* best choice) --> for now, we could display error messages (e.g.
* column x could not be parsed as a number, line y, data value)
*/
public class Importer {

    private static final String DEFAULT_LABEL = "import";

    /**
     * Format: "dd/MM/yyyy"
     *
     * @see #DATE_FORMAT_1_PATTERN
     * @see #dateFormat1
     */
    public static final RegExp DATE_FORMAT_1_REGEX = RegExp
            .compile("^(0[1-9]|[1-9]|[12][0-9]|3[01])/(0[1-9]|1[012]|[1-9])/\\d{4}$");

    /**
     * Format: "dd/MM/yyyy"
     *
     * @see #DATE_FORMAT_1_REGEX
     * @see #dateFormat1
     */
    public static final String DATE_FORMAT_1_PATTERN = "dd/MM/yyyy";

    /**
     * Format: "yyyy-MM-dd"
     *
     * @see #DATE_FORMAT_2_PATTERN
     * @see #dateFormat2
     */
    public static final RegExp DATE_FORMAT_2_REGEX = RegExp
            .compile("^\\d{4}-(0[1-9]|1[012]|[1-9])-(0[1-9]|[1-9]|[12][0-9]|3[01])$");

    /**
     * Format: "yyyy-MM-dd"
     *
     * @see #DATE_FORMAT_2_REGEX
     * @see #dateFormat2
     */
    public static final String DATE_FORMAT_2_PATTERN = "yyyy-MM-dd";

    /**
     * Format: "lat/long" with +/- decimal coordinates
     */
    public static final RegExp LOCATION_DETECTION_REGEX = RegExp
            .compile("^[-+]?[0-9]*\\.?[0-9]+\\/[-+]?[0-9]*\\.?[0-9]+$");

    /**
     * Format: "XXX.XXX"
     */
    public static final RegExp NUMBER_DETECTION_REGEX = RegExp
            .compile("^[-+]?[0-9]*\\.?[0-9]+$");

    private LabelProvider uriHeaderProvider;

    /**
     * @see #DATE_FORMAT_1_REGEX
     * @see #DATE_FORMAT_1_PATTERN
     */
    private DateTimeFormat dateFormat1;

    /**
     * @see #DATE_FORMAT_2_PATTERN
     * @see #DATE_FORMAT_2_REGEX
     */
    private DateTimeFormat dateFormat2;

    public Importer() {
        uriHeaderProvider = new IncrementingSuffixLabelFactory(DEFAULT_LABEL);
        initDateFormats();
    }

    protected Serializable calculateStringValue(String stringValue) {
        Serializable value;
        value = stringValue;
        return value;
    }

    protected Resource createLocationResource(String stringValue) {
        Resource locationResource = new Resource();
        String[] split = stringValue.split("\\/");
        locationResource.putValue(ResourceSetUtils.LATITUDE,
                Double.parseDouble(split[0]));
        locationResource.putValue(ResourceSetUtils.LONGITUDE,
                Double.parseDouble(split[1]));
        return locationResource;
    }

    protected Resource createResourceFromRow(StringTable table,
            DataType[] columnTypes, int row, String uriType)
            throws ParseException {

        Resource resource = new Resource(getResourceURI(uriType, row, table));

        for (int column = 0; column < table.getColumnCount(); column++) {
            String stringValue = table.getValue(row, column);

            resource.putValue(table.getColumnName(column),
                    getColumnValue(columnTypes, row, column, stringValue));
        }
        return resource;
    }

    // TODO test
    // TODO pass set of parsers... --> separate step in which parsers are
    // determined
    public ResourceSet createResources(StringTable table) throws ParseException {
        return createResources(table, DEFAULT_LABEL);
    }

    // TODO test
    // TODO pass set of parsers... --> separate step in which parsers are
    // determined
    public ResourceSet createResources(StringTable table, String label)
            throws ParseException {
        assert table != null;

        String uriType = uriHeaderProvider.nextLabel();

        ResourceSet resources = new DefaultResourceSet();
        resources.setLabel(label); // TODO changeable, inc number

        if (table.getRowCount() == 0) {
            return resources;
        }

        // use first row to determine types
        DataType[] columnTypes = determineColumnTypes(table);

        for (int row = 0; row < table.getRowCount(); row++) {
            resources.add(createResourceFromRow(table, columnTypes, row,
                    uriType));
        }

        return resources;
    }

    protected DataType[] determineColumnTypes(StringTable table) {
        DataType[] columnTypes = new DataType[table.getColumnCount()];
        for (int column = 0; column < table.getColumnCount(); column++) {
            String stringValue = table.getValue(0, column);

            if (NUMBER_DETECTION_REGEX.test(stringValue)) {
                columnTypes[column] = DataType.NUMBER;
            } else if (isDate(stringValue)) {
                columnTypes[column] = DataType.DATE;
            } else if (LOCATION_DETECTION_REGEX.test(stringValue)) {
                columnTypes[column] = DataType.LOCATION;
            } else {
                columnTypes[column] = DataType.TEXT;
            }
        }
        return columnTypes;
    }

    protected Serializable getColumnValue(DataType[] columnTypes, int row,
            int column, String stringValue) throws ParseException {
        Serializable value;

        switch (columnTypes[column]) {
        case NUMBER:
            if (!NUMBER_DETECTION_REGEX.test(stringValue)) {
                throw new ParseException("Invalid number", stringValue, row + 1);
            }
            value = new Double(stringValue);
            break;
        case DATE:
            value = resolveDateString(row, stringValue);
            break;
        case LOCATION:
            if (!LOCATION_DETECTION_REGEX.test(stringValue)) {
                throw new ParseException("Invalid location", stringValue,
                        row + 1);
            }

            value = createLocationResource(stringValue);
            break;
        default:
            value = calculateStringValue(stringValue);
            break;
        }
        return value;
    }

    protected String getResourceURI(String uriType, int row, StringTable table) {
        return uriType + ":" + row;
    }

    // override in test enables GWT independence for JRE testing
    protected void initDateFormats() {
        dateFormat1 = DateTimeFormat.getFormat(DATE_FORMAT_1_PATTERN);
        dateFormat2 = DateTimeFormat.getFormat(DATE_FORMAT_2_PATTERN);
    }

    protected boolean isDate(String input) {
        return DATE_FORMAT_2_REGEX.test(input)
                || DATE_FORMAT_1_REGEX.test(input);
    }

    protected Date parseDate(String dateStr) {
        if (DATE_FORMAT_1_REGEX.test(dateStr)) {
            return dateFormat1.parse(dateStr);
        } else if (DATE_FORMAT_2_REGEX.test(dateStr)) {
            return dateFormat2.parse(dateStr);
        }
        return null;
    }

    protected Date parseDate1(String stringValue) {
        return dateFormat1.parse(stringValue);
    }

    protected Date parseDate2(String stringValue) {
        return dateFormat2.parse(stringValue);
    }

    protected Serializable resolveDateString(int row, String stringValue)
            throws ParseException {
        Serializable value;

        if (isDate(stringValue)) {
            value = parseDate(stringValue);
        } else if (stringValue == null || stringValue.isEmpty()) {
            value = null;
        } else {
            throw new ParseException("Invalid date", stringValue, row + 1);
        }
        return value;
    }

}
TOP

Related Classes of org.thechiselgroup.choosel.core.client.importer.Importer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.