Package de.timefinder.core.io.text

Source Code of de.timefinder.core.io.text.ImportText

/*
*  Copyright 2009 Peter Karich, peat_hal 'at' users 'dot' sourceforge 'dot' net.
*
*  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.
*  under the License.
*/
package de.timefinder.core.io.text;

import de.timefinder.data.algo.DataPoolSettings;
import de.timefinder.algo.constraint.RasterConstraint;
import de.timefinder.core.util.FixRelationShip;
import de.timefinder.data.util.Helper;
import de.timefinder.data.DataPool;
import de.timefinder.data.Event;
import de.timefinder.data.Feature;
import de.timefinder.data.Location;
import de.timefinder.data.Person;
import de.timefinder.data.access.Dao;
import de.timefinder.data.util.MapEntry;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import javolution.util.FastMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Imports tab or comma separated text files.
*
* @author Peter Karich, peat_hal 'at' users 'dot' sourceforge 'dot' net
*/
public class ImportText {

    private Log logger = LogFactory.getLog(getClass());
    private DataPool dataPool;
    private File folder;
    private String propFile;
    private Properties prop;
    private BufferedReader eventReader;
    private BufferedReader featureReader;
    private BufferedReader locationReader;
    private BufferedReader personReader;
    private String columnSeparator;
    private String idSeparator;
    private ObjectParsing objParsing = new ObjectParsing();
    private Map<String, Class> aliases;
    protected DataPoolSettings settings;
    private boolean fixRelationShip;
    private Dao<Event> eDao;
    protected Map<Class, Map<Long, Object>> simpleDaos = FastMap.newInstance();

    public ImportText(DataPool dataPool, DataPoolSettings settings, File folder) {
        this.dataPool = dataPool;
        eDao = dataPool.getDao(Event.class);
        this.settings = settings;
        this.folder = folder;
        initProperties();
        initAliases();
    }

    public void initProperties() {
        propFile = "timefinder.properties";
        prop = new Properties();
        prop.setProperty("tf.column.separator", "TAB");
        prop.setProperty("tf.id.separator", "COMMA");
        prop.setProperty("tf.days", "5");
        prop.setProperty("tf.timeSlotsPerDay", "10");
        prop.setProperty("tf.msPerTimeSlot", "" + 1000 * 60 * 60L);
        prop.setProperty("tf.feature.file", "features.txt");
        prop.setProperty("tf.person.file", "persons.txt");
        prop.setProperty("tf.location.file", "locations.txt");
        prop.setProperty("tf.event.file", "events.txt");
        prop.setProperty("tf.fixRelationship", "true");
    }

    protected void readProperties() {
    }

    public void initAliases() {
        aliases = FastMap.newInstance();
        aliases.put("events", Event.class);
        aliases.put("persons", Person.class);
        aliases.put("locations", Location.class);
        aliases.put("features", Feature.class);
    }

    public void doWork() {
        logger.info("Start doWork");
        readSettings();

        initSimpleDao();

        initReaders();
        readData();

        fixRelationShip();

        addToDataPool();
        logger.info("End doWork");
    }

    public boolean isFixRelationShip() {
        return fixRelationShip;
    }

    public void setFixRelationShip(boolean fixRelationShip) {
        this.fixRelationShip = fixRelationShip;
    }

    public void setEventReader(Reader reader) {
        eventReader = new BufferedReader(reader);
    }

    public void setLocationReader(Reader reader) {
        locationReader = new BufferedReader(reader);
    }

    public void setFeatureReader(Reader reader) {
        featureReader = new BufferedReader(reader);
    }

    public void setPersonReader(Reader reader) {
        personReader = new BufferedReader(reader);
    }

    public Properties getProperties() {
        return prop;
    }

    public String propToString(String property) {
        if ("TAB".equalsIgnoreCase(property))
            return "\t";
        else if ("COMMA".equalsIgnoreCase(property) || ",".equalsIgnoreCase(property))
            return ",";
        else if ("RETURN".equalsIgnoreCase(property))
            return "\n";
        else
            return property;
    }

    public DataPool getDataPool() {
        return dataPool;
    }

    public File getFolder() {
        return folder;
    }

    protected void readFile(BufferedReader reader, Class clazz) throws
            IOException, InstantiationException, IllegalAccessException {

        if (reader == null)
            return;

        String firstLine = reader.readLine();
        if (firstLine == null)
            return;

        if (firstLine.length() == 0) {
            logger.fatal("The first line should define the property names and should start with #"
                    + "\n for class: " + clazz);
            return;
        }

        Map<String, Method> setterMethods = FastMap.newInstance();
        Helper.fillSettersAndGetters(clazz, setterMethods, null);
        firstLine = firstLine.substring(1).trim();
        List<Entry<Method, Parsing>> columns = new ArrayList();
        Parsing idParsing = null;
        int idColumn = -1;
        int counter = 0;

        for (String column : firstLine.split(columnSeparator)) {
            column = column.trim();
            Method method = setterMethods.get(column);

            if (method == null)
                continue;

            Class[] params = method.getParameterTypes();
            if (params.length != 1) {
                logger.warn("Setter method " + method.getName() + " should have one parameter!");
                continue;
            }
            Parsing parsing = objParsing.getParsing(params[0]);

            if (parsing == null) {
                if (Collection.class.isAssignableFrom(params[0])) {
                    Class innerType = aliases.get(column);
                    if (innerType != null)
                        parsing = new TextCollectionParsing(idSeparator, simpleDaos.get(innerType), innerType);
                }
            }

            if (parsing == null) {
                columns.add(null);
                logger.warn("Cannot find setter for property: " + column);
            } else {
                if ("id".equalsIgnoreCase(column)) {
                    idParsing = parsing;
                    idColumn = counter;
                }

                columns.add(new MapEntry(method, parsing));
            }
            counter++;
        }

        if (columns.size() == 0) {
            logger.fatal("Couldn't find property definition for: " + clazz);
            return;
        }

        if (idParsing == null || idColumn < 0) {
            logger.fatal("Couldn't find id property in the first line (property definition) for: " + clazz);
            return;
        }

        Map<Long, Object> dao = simpleDaos.get(clazz);
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.startsWith("#"))
                continue;

            counter = 0;
            String[] cols = line.split(columnSeparator);

            Long id = (Long) idParsing.parse(cols[idColumn]);
            Object obj = dao.get(id);

            if (obj == null) {
                obj = clazz.newInstance();
                dao.put(id, obj);
            }

            for (int ii = 0; ii < cols.length; ii++, counter++) {
                String columnContent = cols[ii].trim();
                if (counter >= columns.size()) {
                    logger.warn("Cannot parse column " + (counter + 1) + " with content:" + columnContent + "\n because only "
                            + columns.size() + " properties were specified in header: " + columns);
                    break;
                }

                Entry<Method, Parsing> propertyEntry = columns.get(counter);
                if (propertyEntry == null)
                    continue;

                Object property = propertyEntry.getValue().parse(columnContent);
                try {
                    propertyEntry.getKey().invoke(obj, property);
                } catch (InvocationTargetException ex) {
                    logger.warn("Cannot set parameter: " + propertyEntry.getKey().getName(), ex);
                }
            } // iterate through every column
        } // iterate through every line of the text file      
    }

    protected void readSettings() {
        try {
            FileReader propReader = new FileReader(new File(folder, propFile));
            prop.load(propReader);
        } catch (FileNotFoundException ex) {
            logger.info("File not found: " + propFile + " - Will apply default properties:" + prop);
        } catch (IOException ex) {
            logger.fatal("Couldn't load properties from " + propFile);
        }

        columnSeparator = propToString(prop.getProperty("tf.column.separator"));
        idSeparator = propToString(prop.getProperty("tf.id.separator"));

        try {
            settings.setNumberOfDays(Integer.parseInt(prop.getProperty("tf.days")));
        } catch (Exception ex) {
            logger.warn("Couldn't change number of days: " + prop.getProperty("tf.days"));
        }

        try {
            settings.setTimeslotsPerDay(Integer.parseInt(prop.getProperty("tf.timeSlotsPerDay")));
        } catch (Exception ex) {
            logger.warn("Couldn't change time-slots per day: " + prop.getProperty("tf.timeSlotsPerDay"));
        }

        try {
            settings.setMillisPerTimeslot(Long.parseLong(prop.getProperty("tf.msPerTimeSlot")));
        } catch (Exception ex) {
            logger.warn("Couldn't change ms / time-slot: " + prop.getProperty("tf.msPerTimeSlot"));
        }
    }

    public void fixRelationShip() {
        try {
            fixRelationShip = true;
            fixRelationShip = Boolean.parseBoolean(prop.getProperty("tf.fixRelationship"));
        } catch (Exception ex) {
            logger.warn("Couldn't change fixRelationship: " + prop.getProperty("tf.fixRelationship"));
        }
        if (fixRelationShip) {
            int counter = new FixRelationShip(dataPool).doWork();
            if (counter > 1)
                logger.warn("Had to fix " + counter + " relationships");
        }
    }

    protected void initReaders() {
        String fFile = prop.getProperty("tf.feature.file");
        try {
            if (featureReader == null)
                setFeatureReader(new FileReader(new File(folder, fFile)));
        } catch (FileNotFoundException ex) {
            logger.fatal("Couldn't find " + fFile);
        }

        String eFile = prop.getProperty("tf.event.file");
        try {
            if (eventReader == null)
                setEventReader(new FileReader(new File(folder, eFile)));
        } catch (FileNotFoundException ex) {
            logger.fatal("Couldn't find " + eFile);
        }

        String pFile = prop.getProperty("tf.person.file");
        try {
            if (personReader == null)
                setPersonReader(new FileReader(new File(folder, pFile)));
        } catch (FileNotFoundException ex) {
            logger.fatal("Couldn't find " + pFile);
        }

        String lFile = prop.getProperty("tf.location.file");
        try {
            if (locationReader == null)
                setLocationReader(new FileReader(new File(folder, lFile)));
        } catch (FileNotFoundException ex) {
            logger.fatal("Couldn't find " + lFile);
        }
    }

    protected void readData() {
        try {
            readFile(eventReader, Event.class);
        } catch (Exception ex) {
            logger.fatal("Failed to parse event file!", ex);
        }

        try {
            readFile(personReader, Person.class);
        } catch (Exception ex) {
            logger.fatal("Failed to parse person file!", ex);
        }

        try {
            readFile(featureReader, Feature.class);
        } catch (Exception ex) {
            logger.fatal("Failed to parse feature file!", ex);
        }

        try {
            readFile(locationReader, Location.class);
        } catch (Exception ex) {
            logger.fatal("Failed to parse location file!", ex);
        }
    }

    public void initSimpleDao() {
        for (Dao dao : dataPool.getDaos()) {
            simpleDaos.put(dao.getType(), new FastMap<Long, Object>());
        }
    }

    public void addToDataPool() {
        for (Entry<Class, Map<Long, Object>> sDao : simpleDaos.entrySet()) {
            Dao tmpDao = dataPool.getDao(sDao.getKey());
            if (tmpDao == null) {
                logger.warn("Dao for " + sDao.getKey() + " not found in data pool!?");
                continue;
            }

            tmpDao.attachAll(sDao.getValue().values());
        }
    }

    protected Event newEvent() {
        Event ev = eDao.create();
        ev.putConstraint(new RasterConstraint(settings.createWeekRaster()));
        return ev;
    }
}
TOP

Related Classes of de.timefinder.core.io.text.ImportText

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.