com.esri.geoevent.solutions.processor.geometry.QueryReportProcessor.java Source code

Java tutorial

Introduction

Here is the source code for com.esri.geoevent.solutions.processor.geometry.QueryReportProcessor.java

Source

package com.esri.geoevent.solutions.processor.geometry;

/*
 * #%L
 * Esri :: AGES :: Solutions :: Processor :: Geometry
 * $Id:$
 * $HeadURL:$
 * %%
 * Copyright (C) 2013 - 2014 Esri
 * %%
 * 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.
 * #L%
 */

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URL;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.joda.time.DateTime;

import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.LinearUnit;
import com.esri.core.geometry.MapGeometry;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.geometry.Unit;
import com.esri.core.map.FeatureSet;
import com.esri.core.map.Graphic;
import com.esri.ges.core.component.ComponentException;
import com.esri.ges.core.geoevent.DefaultFieldDefinition;
import com.esri.ges.core.geoevent.FieldDefinition;
import com.esri.ges.core.geoevent.FieldType;
import com.esri.ges.core.geoevent.GeoEvent;
import com.esri.ges.core.geoevent.GeoEventDefinition;
import com.esri.ges.core.geoevent.GeoEventPropertyName;
import com.esri.ges.datastore.agsconnection.ArcGISServerConnection;
import com.esri.ges.datastore.agsconnection.ArcGISServerType;
import com.esri.ges.datastore.agsconnection.Field;
import com.esri.ges.datastore.agsconnection.Layer;
import com.esri.ges.manager.datastore.agsconnection.ArcGISServerConnectionManager;
import com.esri.ges.manager.geoeventdefinition.GeoEventDefinitionManager;
import com.esri.ges.messaging.GeoEventCreator;
import com.esri.ges.messaging.Messaging;
import com.esri.ges.processor.GeoEventProcessorBase;
import com.esri.ges.processor.GeoEventProcessorDefinition;
import com.esri.ges.spatial.Geometry;
import com.esri.ges.spatial.GeometryException;
import com.esri.ges.spatial.Spatial;

public class QueryReportProcessor extends GeoEventProcessorBase {

    private static final Log LOG = LogFactory.getLog(RangeFanProcessor.class);
    public Spatial spatial;
    public GeoEventDefinitionManager manager;
    public ArcGISServerConnectionManager connectionManager;
    public Messaging messaging;
    private SpatialReference srIn;
    private SpatialReference srBuffer;
    private SpatialReference srOut;
    private ArrayList<Object> queries = new ArrayList<Object>();
    private HashMap<String, Object> responseMap = new HashMap<String, Object>();
    private com.esri.core.geometry.Geometry inGeometry;

    public QueryReportProcessor(GeoEventProcessorDefinition definition, Spatial s, GeoEventDefinitionManager m,
            ArcGISServerConnectionManager cm, Messaging msg) throws ComponentException {
        super(definition);
        spatial = s;
        manager = m;
        connectionManager = cm;
        messaging = msg;
        geoEventMutator = true;
    }

    //@Override
    public void onServiceStop() {
        definition.getPropertyDefinitions().clear();
        ((QueryReportProcessorDefinition) definition).GenerateProperties();
    }

    @Override
    public GeoEvent process(GeoEvent ge) throws Exception {
        //CreateQueryMap();
        CreateQueries();
        double radius = (Double) properties.get("radius").getValue();
        String units = properties.get("units").getValue().toString();
        int inwkid = (Integer) properties.get("wkidin").getValue();
        int outwkid = (Integer) properties.get("wkidout").getValue();
        int bufferwkid = (Integer) properties.get("wkidbuffer").getValue();
        srIn = SpatialReference.create(inwkid);
        srBuffer = SpatialReference.create(bufferwkid);
        srOut = SpatialReference.create(outwkid);

        com.esri.ges.spatial.Geometry geo = ge.getGeometry();
        com.esri.ges.spatial.Geometry inGeo = null;
        if (properties.get("geosrc").getValueAsString().equals("Buffer")) {
            inGeometry = constructGeometry(geo);
            Unit u = queryUnit(units);
            inGeo = constructBuffer(geo, radius, u);
        } else if (properties.get("geosrc").getValueAsString().equals("Event Definition")) {

            String eventfld = properties.get("geoeventdef").getValue().toString();
            String[] arr = eventfld.split(":");
            String geostr = (String) ge.getField(arr[1]);
            com.esri.ges.spatial.Geometry g = constructGeometryFromString(geostr);
            com.esri.core.geometry.Geometry polyGeo = constructGeometry(g);
            Envelope env = new Envelope();
            polyGeo.queryEnvelope(env);
            inGeometry = env.getCenter();
            com.esri.core.geometry.Geometry projGeo = GeometryEngine.project(polyGeo, srBuffer, srOut);
            String json = GeometryEngine.geometryToJson(srOut, projGeo);
            inGeo = spatial.fromJson(json);
        } else {

            com.esri.core.geometry.Geometry polyGeo = constructGeometry(geo);
            Envelope env = new Envelope();
            polyGeo.queryEnvelope(env);
            inGeometry = env.getCenter();
            com.esri.core.geometry.Geometry projGeo = GeometryEngine.project(polyGeo, srBuffer, srOut);
            String json = GeometryEngine.geometryToJson(srOut, projGeo);
            inGeo = spatial.fromJson(json);

        }
        String jsonGeo = inGeo.toJson();
        String geotype = GeometryUtility.parseGeometryType(inGeo.getType());
        ExecuteRestQueries(jsonGeo, geotype);
        String timestamp = "";
        if ((Boolean) properties.get("usetimestamp").getValue()) {
            String eventfld = properties.get("timestamp").getValueAsString();
            String[] arr = eventfld.split(":");
            timestamp = ge.getField(arr[1]).toString();
        }
        DateTime dt = DateTime.now();
        String ts = ((Integer) dt.getYear()).toString() + ((Integer) dt.getMonthOfYear()).toString()
                + ((Integer) dt.getDayOfMonth()).toString() + ((Integer) dt.getHourOfDay()).toString()
                + ((Integer) dt.getMinuteOfHour()).toString() + ((Integer) dt.getSecondOfMinute()).toString();
        String file = properties.get("filename").getValueAsString() + ts + ".html";

        ParseResponses(timestamp, file);
        String host = properties.get("host").getValueAsString();
        if (host.contains("http://")) {
            host.replace("http://", "");
        }
        String url = "http://" + host + ":6180/geoevent/assets/reports/" + file;
        GeoEventDefinition geoDef = ge.getGeoEventDefinition();
        String outDefName = geoDef.getName() + "_out";
        GeoEventDefinition edOut;
        if ((edOut = manager.searchGeoEventDefinition(outDefName, getId())) == null) {
            List<FieldDefinition> fds = Arrays
                    .asList(((FieldDefinition) new DefaultFieldDefinition("url", FieldType.String)));
            edOut = geoDef.augment(fds);
            edOut.setOwner(getId());
            edOut.setName(outDefName);
            manager.addGeoEventDefinition(edOut);
        }
        GeoEventCreator geoEventCreator = messaging.createGeoEventCreator();
        GeoEvent geOut = geoEventCreator.create(edOut.getGuid(), new Object[] { ge.getAllFields(), url });
        geOut.setProperty(GeoEventPropertyName.TYPE, "message");
        geOut.setProperty(GeoEventPropertyName.OWNER_ID, getId());
        geOut.setProperty(GeoEventPropertyName.OWNER_ID, definition.getUri());

        for (Map.Entry<GeoEventPropertyName, Object> property : ge.getProperties())
            if (!geOut.hasProperty(property.getKey()))
                geOut.setProperty(property.getKey(), property.getValue());
        queries.clear();
        responseMap.clear();
        return geOut;

    }

    private Unit queryUnit(String units) {
        UnitConverter uc = new UnitConverter();
        String cn = uc.findConnonicalName(units);
        int unitout = uc.findWkid(cn);
        Unit u = new LinearUnit(unitout);
        return u;
    }

    private com.esri.core.geometry.Geometry constructGeometry(com.esri.ges.spatial.Geometry geo) throws Exception {
        try {
            String jsonIn = geo.toJson();
            JsonFactory jf = new JsonFactory();
            JsonParser jp = jf.createJsonParser(jsonIn);
            MapGeometry mgeo = GeometryEngine.jsonToGeometry(jp);
            com.esri.core.geometry.Geometry geoIn = mgeo.getGeometry();
            return GeometryEngine.project(geoIn, srIn, srBuffer);
        } catch (Exception e) {
            LOG.error(e.getMessage());
            LOG.error(e.getStackTrace());
            throw (e);
        }
    }

    private com.esri.ges.spatial.Geometry constructGeometryFromString(String geoString) throws GeometryException {
        String[] pairs = geoString.split(" ");

        Polygon polygon = new Polygon();
        Boolean firstit = true;
        for (String coords : pairs) {

            String[] tuple = coords.split(",");
            Double x = Double.parseDouble(tuple[0]);
            Double y = Double.parseDouble(tuple[1]);
            Point p = new Point(x, y);
            Double z = Double.NaN;
            if (tuple.length > 2) {
                z = Double.parseDouble(tuple[2]);
                p.setZ(z);
            }
            if (firstit) {
                polygon.startPath(p);
                firstit = false;
            } else {
                polygon.lineTo(p);
            }
        }
        polygon.closeAllPaths();
        String json = GeometryEngine.geometryToJson(srIn, polygon);
        return spatial.fromJson(json);
    }

    private com.esri.ges.spatial.Geometry constructBuffer(Geometry geo, double radius, Unit u)
            throws GeometryException, JsonParseException, IOException {

        com.esri.core.geometry.Geometry buffer = GeometryEngine.buffer(inGeometry, srBuffer, radius, u);
        com.esri.core.geometry.Geometry bufferout = GeometryEngine.project(buffer, srBuffer, srOut);
        String json = GeometryEngine.geometryToJson(srOut, bufferout);
        return spatial.fromJson(json);

    }

    public void CreateQueries() {
        String connName = properties.get("connection").getValueAsString();
        ArcGISServerConnection conn = connectionManager.getArcGISServerConnection(connName);
        URL url = conn.getUrl();
        String folder = properties.get("folder").getValueAsString();

        String service = properties.get("service").getValueAsString();
        String lyrName = properties.get("layer").getValueAsString();
        Layer layer = conn.getLayer(folder, service, lyrName, ArcGISServerType.FeatureServer);
        String layerId = ((Integer) layer.getId()).toString();
        String field = properties.get("field").getValueAsString();

        String baseUrl = url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + url.getPath()
                + "rest/services/";
        String curPath = baseUrl + "/" + folder + "/" + service + "/FeatureServer/" + layerId;
        String restpath = curPath + "/query?";
        HashMap<String, Object> query = new HashMap<String, Object>();
        HashMap<String, String> fieldMap = new HashMap<String, String>();
        String fldsString = field;
        Field[] fields = conn.getFields(folder, service, layer.getId(), ArcGISServerType.FeatureServer);

        Boolean usingDist = false;
        String lyrHeaderCfg = "";
        String distToken = "";
        String distUnits = "";
        String wc = "";
        String itemConfig = "";
        wc = properties.get("wc").getValueAsString();
        lyrHeaderCfg = properties.get("lyrheader").getValueAsString();
        usingDist = (Boolean) properties.get("calcDistance").getValue();
        if (usingDist) {
            distToken = properties.get("dist_token").getValueAsString();
            distUnits = properties.get("dist_units").getValueAsString();
        }
        String token = properties.get("field-token").getValueAsString();
        fieldMap.put(field, token);
        itemConfig = properties.get("item-config").getValueAsString();
        query.put("restpath", restpath);
        query.put("path", curPath);
        query.put("whereclause", wc);
        query.put("fields", fldsString);
        query.put("outfields", fields);
        query.put("tokenMap", fieldMap);
        query.put("headerconfig", lyrHeaderCfg);
        query.put("usingdist", usingDist);
        query.put("distunits", distUnits);
        query.put("disttoken", distToken);
        query.put("itemconfig", itemConfig);
        query.put("layer", layer.getName());
        UUID uid = UUID.randomUUID();
        query.put("id", uid);
        queries.add(query);
    }

    public void CreateQueryMap() {
        Collection<ArcGISServerConnection> serviceConnections = this.connectionManager.getArcGISServerConnections();

        Iterator<ArcGISServerConnection> it = serviceConnections.iterator();
        ArcGISServerConnection conn;
        while (it.hasNext()) {
            conn = it.next();

            //String connName = conn.getName();
            String[] folders = conn.getFolders();

            URL url = conn.getUrl();

            String baseUrl = url.getProtocol() + "://" + url.getHost() + ":" + url.getPort() + url.getPath()
                    + "rest/services/";
            //HashMap<String, Object> folderMap = new HashMap<String, Object>();
            for (int i = 0; i < folders.length; ++i) {
                String path = baseUrl + folders[i] + "/";
                String folder = folders[i];
                String[] fservices = conn.getFeatureServices(folder);
                //HashMap<String,Object>serviceMap = new HashMap<String,Object>();
                for (int j = 0; j < fservices.length; ++j) {
                    String fs = fservices[j];
                    path += fs + "/FeatureServer/";
                    String fqService = folder + "_" + fs;
                    String pdName = "use_" + fqService;
                    pdName = pdName.replace(" ", "_");
                    if ((Boolean) properties.get(pdName).getValue()) {

                        ArrayList<Layer> layers = (ArrayList<Layer>) conn.getLayers(folder, fs,
                                ArcGISServerType.FeatureServer);
                        //HashMap<String, Object> layerMap = new HashMap<String, Object>();

                        for (int k = 0; k < layers.size(); ++k) {
                            HashMap<String, Object> query = new HashMap<String, Object>();
                            HashMap<String, String> fieldMap = new HashMap<String, String>();
                            String fldsString = "";
                            Field[] fields = conn.getFields(folder, fs, k, ArcGISServerType.FeatureServer);
                            Boolean usingDist = false;
                            String curPath = "";
                            String restpath = "";
                            String lyrHeaderCfg = "";
                            String distToken = "";
                            String distUnits = "";
                            String wc = "";
                            String itemConfig = "";
                            String curLyr = layers.get(k).getName();
                            String lyrName = fqService + "_" + ((Integer) k).toString();
                            lyrName = lyrName.replace(" ", "_");
                            if ((Boolean) properties.get(lyrName).getValue()) {
                                curPath = path + ((Integer) k).toString();
                                restpath = path + ((Integer) k).toString() + "/query?";
                                wc = properties.get(lyrName + "_whereclause").getValueAsString();
                                lyrHeaderCfg = properties.get(lyrName + "_header").getValueAsString();
                                usingDist = (Boolean) properties.get(lyrName + "_calcDistance").getValue();
                                if (usingDist) {
                                    distToken = properties.get(lyrName + "_dist_token").getValueAsString();
                                    distUnits = properties.get(lyrName + "_dist_units").getValueAsString();
                                }

                                itemConfig = properties.get(lyrName + "_config").getValueAsString();

                                Boolean first = true;
                                for (int l = 0; l < fields.length; ++l) {
                                    String fld = fields[l].getName();

                                    String fldPropName = lyrName + fld;
                                    fldPropName = fldPropName.replace(" ", "_");

                                    if ((Boolean) properties.get(fldPropName).getValue()) {
                                        if (!first) {
                                            fldsString += ",";
                                        } else {
                                            first = false;
                                        }
                                        fldsString += fld;
                                        String fldToken = fldPropName + "_token";
                                        String token = properties.get(fldToken).getValueAsString();
                                        fieldMap.put(fld, token);
                                    }
                                }
                                query.put("restpath", restpath);
                                query.put("path", curPath);
                                query.put("whereclause", wc);
                                query.put("fields", fldsString);
                                query.put("outfields", fields);
                                query.put("tokenMap", fieldMap);
                                query.put("headerconfig", lyrHeaderCfg);
                                query.put("usingdist", usingDist);
                                query.put("distunits", distUnits);
                                query.put("disttoken", distToken);
                                query.put("itemconfig", itemConfig);
                                query.put("layer", curLyr);
                                UUID uid = UUID.randomUUID();
                                query.put("id", uid);
                                queries.add(query);
                                //layerMap.put(layers.get(k).getName(), fieldMap);
                            }

                        }

                    }

                }
                //folderMap.put(folder, serviceMap);
            }
            //connmap.put(connName,folderMap);
        }

    }

    private void ExecuteRestQueries(String jsonGeometry, String geoType)
            throws GeometryException, UnsupportedEncodingException {
        String contentType = "application/json";
        HttpClient httpclient = new DefaultHttpClient();
        for (int i = 0; i < queries.size(); ++i) {
            @SuppressWarnings("unchecked")
            HashMap<String, Object> query = (HashMap<String, Object>) queries.get(i);
            String path = (String) query.get("restpath");
            String wc = URLEncoder.encode((String) query.get("whereclause"), "UTF-8");
            String geo = URLEncoder.encode(jsonGeometry, "UTF-8");
            String fields = (String) query.get("fields");
            @SuppressWarnings("unchecked")
            HashMap<String, String> tokenMap = (HashMap<String, String>) query.get("tokenMap");
            String itemConfig = (String) query.get("itemconfig");
            //
            String args = "where=" + wc + "&objectIds=&time=&geometry=" + geo + "&geometryType=" + geoType
                    + "&inSR=&spatialRel=esriSpatialRelIntersects&relationParam=&outFields=" + fields
                    + "&returnGeometry=true&maxAllowableOffset=&geometryPrecision=&outSR=&gdbVersion=&returnDistinctValues=false&returnIdsOnly=false&returnCountOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&f=json";
            String uri = path + args;
            try {
                HttpPost httppost = new HttpPost(uri);
                httppost.setHeader("Accept", contentType);
                HttpResponse response = httpclient.execute(httppost);

                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    InputStream instream = entity.getContent();
                    try {
                        // instream.read();
                        BufferedReader br = new BufferedReader(new InputStreamReader((instream)));
                        String output = "";
                        String ln;
                        while ((ln = br.readLine()) != null) {
                            output += ln;
                        }
                        JsonFactory jf = new JsonFactory();
                        JsonParser jp = jf.createJsonParser(output);
                        FeatureSet fset = FeatureSet.fromJson(jp);
                        HashMap<String, Object> tuple = new HashMap<String, Object>();
                        String lyr = (String) query.get("layer");
                        String lyrheadercfg = (String) query.get("headerconfig");
                        Boolean calcdist = (Boolean) query.get("usingdist");
                        String distToken = (String) query.get("disttoken");
                        String distUnits = (String) query.get("distunits");
                        String id = query.get("id").toString();
                        tuple.put("fset", fset);
                        tuple.put("tokenmap", tokenMap);
                        tuple.put("config", itemConfig);
                        tuple.put("layer", lyr);
                        tuple.put("lyrheader", lyrheadercfg);
                        tuple.put("calcdist", calcdist);
                        tuple.put("distunits", distUnits);
                        tuple.put("disttoken", distToken);
                        responseMap.put(id, tuple);

                    } catch (IOException ex) {
                        // In case of an IOException the connection will be
                        // released
                        // back to the connection manager automatically
                        LOG.error(ex);
                        throw ex;
                    } catch (RuntimeException ex) {
                        // In case of an unexpected exception you may want to
                        // abort
                        // the HTTP request in order to shut down the underlying
                        // connection immediately.
                        LOG.error(ex);
                        httppost.abort();
                        throw ex;
                    } finally {
                        // Closing the input stream will trigger connection
                        // release
                        try {
                            instream.close();
                        } catch (Exception ignore) {
                        }
                    }
                }

            } catch (Exception ex) {
                LOG.error(ex);
                ex.printStackTrace();
            }

        }
    }

    private String GetDistAsString(Graphic g, SpatialReference inputSr, String units) {
        com.esri.core.geometry.Geometry geo = g.getGeometry();
        com.esri.core.geometry.Geometry curGeo;

        if (!inputSr.equals(srBuffer)) {
            curGeo = GeometryEngine.project(geo, inputSr, srBuffer);
        } else {
            curGeo = geo;
        }
        double tmpDist = GeometryEngine.distance(inGeometry, curGeo, srBuffer);
        UnitConverter uc = new UnitConverter();
        int inUnitWkid = uc.findWkid(srBuffer.getUnit().getName());
        String cn = uc.findConnonicalName(units);
        int outUnitWkid = uc.findWkid(cn);
        double dist;
        if (inUnitWkid != outUnitWkid) {
            dist = uc.Convert(tmpDist, inUnitWkid, outUnitWkid);
        } else {
            dist = tmpDist;
        }

        DecimalFormat df = new DecimalFormat("#.00");
        return df.format(dist);
    }

    private void ParseResponses(String timestamp, String file) {
        Set<String> keys = responseMap.keySet();
        Iterator<String> it = keys.iterator();
        String body = "";
        while (it.hasNext()) {
            String k = it.next();
            @SuppressWarnings("unchecked")
            HashMap<String, Object> response = (HashMap<String, Object>) responseMap.get(k);
            FeatureSet fset = (FeatureSet) response.get("fset");
            String cfg = (String) response.get("config");
            @SuppressWarnings("unchecked")
            HashMap<String, Object> tokenmap = (HashMap<String, Object>) response.get("tokenmap");
            String layer = (String) response.get("layer");
            Graphic[] features = fset.getGraphics();
            String lyrHeader = (String) response.get("lyrheader");
            if (!lyrHeader.isEmpty()) {
                lyrHeader = "<h3>" + lyrHeader + "</h3>";
            }
            String items = "";

            items += "<b>" + layer.toUpperCase() + ": </b>";

            Boolean usingDist = (Boolean) response.get("calcdist");
            String distUnits = (String) response.get("distunits");
            String distToken = (String) response.get("disttoken");
            SpatialReference fsetSr = fset.getSpatialReference();
            for (int i = 0; i < features.length; ++i) {
                Graphic f = features[i];
                Map<String, Object> att = f.getAttributes();
                Set<String> fields = tokenmap.keySet();
                Iterator<String> itFields = fields.iterator();
                String item = cfg;
                if (usingDist) {
                    String d = this.GetDistAsString(f, fsetSr, distUnits);
                    item = item.replace(distToken, d);
                }
                while (itFields.hasNext()) {
                    String fldname = itFields.next();
                    String token = (String) tokenmap.get(fldname);
                    item = item.replace(token, att.get(fldname).toString());

                    if (i > 0) {
                        items += ", ";
                    }
                    items += item;

                }
            }
            items = "<p>" + items + "</p>";
            body += lyrHeader + items;
        }
        String content = "";
        //File file = new File("C:/Dev/Java/DefenseSolution/defense-geometry-processor/src/main/resources/ReportTemplate.html"); //for ex foo.txt
        try {
            //String name = this.getClass().getName();
            InputStream is = this.getClass().getClassLoader().getResourceAsStream("ReportTemplate.html");
            //FileInputStream is = new FileInputStream(file);
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String ln;
            while ((ln = br.readLine()) != null) {
                content += ln;
            }
            String title = properties.get("title").getValueAsString();
            String header = properties.get("header").getValueAsString();
            if (!timestamp.isEmpty()) {
                String tsToken = properties.get("timestamptoken").getValueAsString();
                title = title.replace(tsToken, timestamp);
                header = header.replace(tsToken, timestamp);
                body = body.replace(tsToken, timestamp);
            }
            content = content.replace("[$TITLE]", "<h1>" + title + "</h1>");
            content = content.replace("[$HEADING]", "<h2>" + header + "</h2>");
            content = content.replace("[$BODY]", body);
            br.close();
            File dir = new File("assets/reports");
            if (!dir.exists()) {
                dir.mkdir();
            }
            String filename = "assets/reports/" + file;

            File outfile = new File(filename);

            FileOutputStream fos = new FileOutputStream(outfile);
            OutputStreamWriter osw = new OutputStreamWriter(fos);
            Writer w = new BufferedWriter(osw);
            w.write(content);
            w.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}