org.openiot.gsn.wrappers.GridDataWrapper.java Source code

Java tutorial

Introduction

Here is the source code for org.openiot.gsn.wrappers.GridDataWrapper.java

Source

/**
*    Copyright (c) 2011-2014, OpenIoT
*   
*    This file is part of OpenIoT.
*
*    OpenIoT is free software: you can redistribute it and/or modify
*    it under the terms of the GNU Lesser General Public License as published by
*    the Free Software Foundation, version 3 of the License.
*
*    OpenIoT is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU Lesser General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public License
*    along with OpenIoT.  If not, see <http://www.gnu.org/licenses/>.
*
*     Contact: OpenIoT mailto: info@openiot.eu
 * @author Sofiane Sarni
*/

package org.openiot.gsn.wrappers;

import org.openiot.gsn.beans.AddressBean;
import org.openiot.gsn.beans.DataField;
import org.openiot.gsn.beans.StreamElement;
import org.apache.log4j.Logger;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GridDataWrapper extends AbstractWrapper {
    private static final transient Logger logger = Logger.getLogger(GridDataWrapper.class);
    private static int threadCounter;

    private String directory;
    private String fileExtension;
    private String timeFormat;
    private String fileMask;
    private long latestProcessedTimestamp;

    private static final String PARAM_DIRECTORY = "directory";
    private static final String PARAM_FILE_MASK = "file-mask";
    private static final String PARAM_TIME_FORMAT = "time-format";
    private static final String PARAM_EXTENSION = "extension";
    private static final String PARAM_RATE = "rate";

    private static final String[] ESRI_Format = { "ncols", "nrows", "xllcorner", "yllcorner", "cellsize",
            "NODATA_value" };

    private String header[] = new String[6];

    private int ncols;
    private int nrows;
    private double xllcorner;
    private double yllcorner;
    private double cellsize;
    private double NODATA_value;
    private Double[][] rawData;

    private long rate;

    public boolean initialize() {
        setName(getWrapperName() + "-" + (++threadCounter));

        AddressBean addressBean = getActiveAddressBean();

        fileExtension = addressBean.getPredicateValue(PARAM_EXTENSION);
        if (fileExtension == null) {
            logger.warn("The > " + PARAM_EXTENSION + " < parameter is missing from the wrapper for VS "
                    + this.getActiveAddressBean().getVirtualSensorName());
            return false;
        }

        timeFormat = addressBean.getPredicateValue(PARAM_TIME_FORMAT);
        if (timeFormat == null) {
            logger.warn("The > " + PARAM_TIME_FORMAT + " < parameter is missing from the wrapper for VS "
                    + this.getActiveAddressBean().getVirtualSensorName());
            return false;
        }

        fileMask = addressBean.getPredicateValue(PARAM_FILE_MASK);
        if (fileMask == null) {
            logger.warn("The > " + PARAM_FILE_MASK + " < parameter is missing from the wrapper for VS "
                    + this.getActiveAddressBean().getVirtualSensorName());
            return false;
        }

        directory = addressBean.getPredicateValue(PARAM_DIRECTORY);
        if (directory == null) {
            logger.warn("The > " + PARAM_DIRECTORY + " < parameter is missing from the wrapper for VS "
                    + this.getActiveAddressBean().getVirtualSensorName());
            return false;
        }

        String rateStr = addressBean.getPredicateValue(PARAM_RATE);
        if (rateStr != null) {

            try {
                rate = Integer.parseInt(rateStr);
            } catch (NumberFormatException e) {
                logger.warn("The > " + PARAM_RATE + " < parameter is invalid for wrapper in VS "
                        + this.getActiveAddressBean().getVirtualSensorName());
                return false;
            }
        } else {
            logger.warn("The > " + PARAM_RATE + " < parameter is missing from the wrapper in VS "
                    + this.getActiveAddressBean().getVirtualSensorName());
            return false;
        }

        latestProcessedTimestamp = -1;

        return true;
    }

    public DataField[] getOutputFormat() {
        return new DataField[] { new DataField("ncols", "int", "number of columns"),
                new DataField("nrows", "int", "number of rows"), new DataField("xllcorner", "double", "xll corner"),
                new DataField("yllcorner", "double", "yll corner"),
                new DataField("cellsize", "double", "cell size"),
                new DataField("nodata_value", "double", "no data value"),
                new DataField("grid", "binary:image/raw", "raw raster data") };
    }

    public void run() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            logger.error(e.getMessage(), e);
        }

        while (isActive()) {
            try {

                listOfNewFiles(directory, fileMask);
                Thread.sleep(rate);
            } catch (InterruptedException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    public boolean parseFile(String fileName) {
        boolean success = true;
        String line;
        BufferedReader reader = null;
        List<String> lines = new ArrayList<String>();
        try {

            reader = new BufferedReader(new FileReader(fileName));

            line = reader.readLine();
            while (line != null) {
                lines.add(line);
                line = reader.readLine();
            }

            //System.out.println(lines);

        } catch (FileNotFoundException e) {
            success = false;
            logger.warn("File not found: " + fileName);
            logger.warn(e);
        } catch (IOException e) {
            success = false;
            logger.warn("IO exception on opening of file: " + fileName);
            logger.warn(e);
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                logger.warn("IO exception on closing of file: " + fileName);
                logger.warn(e);
            }
        }

        if ((success) && (lines != null)) {

            // trim white spaces, replace tabs and multiple spaces with a single space
            for (int i = 0; i < lines.size(); i++) {
                lines.set(i, lines.get(i).trim().replaceAll("[ \t]+", " "));
                //System.out.println(lines.get(i));
            }

            logger.debug("size " + lines.size());

            try {
                for (int i = 0; i < 6; i++) {
                    String[] split = lines.get(i).split(" ");

                    header[i] = split[1];
                    logger.debug(split[0] + " <=> " + ESRI_Format[i]);
                    if (!split[0].equals(ESRI_Format[i])) {
                        logger.debug("=> inCorrect");
                        success = false;
                    }
                }
            } catch (IndexOutOfBoundsException e) {
                success = false;
                logger.warn("Badly formatted file: " + fileName);
                logger.warn(e);
            }

            if (success) {
                System.out.println("format is correct");
                ncols = Integer.parseInt(header[0]);
                nrows = Integer.parseInt(header[1]);
                xllcorner = Double.parseDouble(header[2]);
                yllcorner = Double.parseDouble(header[3]);
                cellsize = Double.parseDouble(header[4]);
                NODATA_value = Double.parseDouble(header[5]);

                logger.debug("ncols " + ncols);
                logger.debug("nrows " + nrows);
                logger.debug("xllcorner " + xllcorner);
                logger.debug("yllcorner " + yllcorner);
                logger.debug("cellsize " + cellsize);
                logger.debug("NODATA_value " + NODATA_value);
            }

            //parse raw data
            if (success) {
                List raw = new ArrayList<Double>();

                for (int i = 6; i < lines.size(); i++) {
                    String[] aLine = lines.get(i).split(" ");
                    for (int j = 0; j < aLine.length; j++) {

                        try {
                            Double d = Double.parseDouble(aLine[j]);
                            if (d != null)
                                raw.add(d);
                            else
                                raw.add(NODATA_value);
                        } catch (java.lang.NumberFormatException e) {
                            logger.warn(j + ": \"" + aLine[j] + "\"");
                            logger.warn(e);
                            logger.warn(e.getMessage());
                        }
                        //System.out.println(i + "," + j + " : " + d);
                    }

                }

                logger.debug("Size of list => " + raw.size() + " ? " + ncols * nrows);
                logger.debug(raw);

                if (raw.size() == nrows * ncols) {
                    rawData = new Double[nrows][ncols];
                    for (int i = 0; i < nrows; i++)
                        for (int j = 0; j < ncols; j++) {
                            rawData[i][j] = (Double) raw.get(i * ncols + j);
                            //System.out.println(i + "," + j + " : " + rawData[i][j]);
                        }
                    logger.debug("rawData.length " + rawData.length);
                    logger.debug("rawData[0].length " + rawData[0].length);
                } else {
                    success = false;
                }
            }

        }

        return success;
    }

    public void dispose() {
        threadCounter--;
    }

    private Vector<String> listOfNewFiles(String dir, String regexFileMask) {

        File f = new File(dir);
        String[] files = f.list();

        Arrays.sort(files);

        Vector<String> v = new Vector<String>();
        logger.warn("*** found " + files.length + " files ***");
        for (int i = 0; i < files.length; i++) {
            String file = files[i];
            Pattern pattern = Pattern.compile(regexFileMask);
            Matcher matcher = pattern.matcher(file);
            logger.warn("(" + i + ") Testing... " + file);
            if (matcher.find()) {
                String date = getTimeStampFromFileName(file, regexFileMask);
                long epoch = strTime2Long(date, timeFormat);
                logger.warn("Matching => " + file + " date = " + date + " epoch = " + epoch);
                if (epoch > latestProcessedTimestamp) {
                    logger.warn("New file => " + epoch);
                    latestProcessedTimestamp = epoch;
                    v.add(file);
                    postData(dir + "/" + file, epoch);
                }
            }
        }

        return v;
    }

    /*
    * Posting data to database
    * */
    private boolean postData(String filePath, long timed) {

        parseFile(filePath);

        boolean success = true;

        Serializable[] stream = new Serializable[7];

        try {

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(rawData);
            oos.flush();
            oos.close();
            bos.close();

            System.out.println("size => " + bos.toByteArray().length);

            stream[0] = new Integer(ncols);
            stream[1] = new Integer(nrows);
            stream[2] = new Double(xllcorner);
            stream[3] = new Double(yllcorner);
            stream[4] = new Double(cellsize);
            stream[5] = new Double(NODATA_value);
            stream[6] = bos.toByteArray();

            logger.debug("size => " + bos.toByteArray().length);

            //testDeserialize(bos.toByteArray());

        } catch (IOException e) {
            logger.warn(e.getMessage(), e);
            success = false;
        }

        StreamElement se = new StreamElement(getOutputFormat(), stream, timed);

        if (success) {
            success = postStreamElement(se);
        }

        return success;
    }

    /*
    * Test deserialization
    * */
    public static void testDeserialize(byte[] bytes) {

        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            ObjectInputStream in = null;

            in = new ObjectInputStream(bis);

            Double deserial[][] = new Double[0][];

            deserial = (Double[][]) in.readObject();
            in.close();

            logger.debug("deserial.length" + deserial.length);
            logger.debug("deserial[0].length" + deserial[0].length);

            for (int i = 0; i < deserial.length; i++) {
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < deserial[0].length; j++) {
                    sb.append(deserial[i][j]).append(" ");
                }
                System.out.println(sb.toString());
            }

        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        } catch (ClassNotFoundException e) {
            logger.error(e.getMessage(), e);
        }
    }

    public String getWrapperName() {
        return "GridDataWrapper";
    }

    private long strTime2Long(String s, String timeFormat) {

        long l = -1;
        try {
            DateTimeFormatter fmt = DateTimeFormat.forPattern(timeFormat);
            l = fmt.parseDateTime(s).getMillis();
        } catch (java.lang.IllegalArgumentException e) {
            logger.warn(e.getMessage(), e);
        }
        return l;
    }

    private String getTimeStampFromFileName(String fileName, String regexMask) {

        Pattern pattern = Pattern.compile(regexMask);
        Matcher matcher = pattern.matcher(fileName);
        if (matcher.find()) {
            logger.debug("Date => " + matcher.group(1));
            return matcher.group(1);
        } else {
            logger.debug("Date => null");
            return null;
        }
    }
}