/**
* 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 Ionut Iosifescu
* @author Ali Salehi
* @author Timotee Maret
* @author Sofiane Sarni
*/
package org.openiot.gsn.http;
import org.openiot.gsn.Main;
import org.openiot.gsn.Mappings;
import org.openiot.gsn.beans.DataField;
import org.openiot.gsn.beans.StreamElement;
import org.openiot.gsn.beans.VSensorConfig;
import org.openiot.gsn.http.ac.DataSource;
import org.openiot.gsn.http.ac.User;
import org.openiot.gsn.storage.DataEnumerator;
import java.io.IOException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.collections.KeyValue;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.log4j.Logger;
import org.openiot.gsn.http.ac.UserUtils;
public class GMLHandler implements RequestHandler {
private static transient Logger logger = Logger.getLogger(GMLHandler.class);
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setStatus(HttpServletResponse.SC_OK);
String reqName = request.getParameter("name");
String reqGroup = request.getParameter("group");
String reqUsername = request.getParameter("username");
String reqPassword = request.getParameter("password");
response.getWriter().write(buildOutput(reqName, reqGroup, reqUsername, reqPassword));
}
//return only the requested sensor(s) if specified (otherwise use null)
public String buildOutput(String reqName, String reqGroup, String reqUsername, String reqPassword) {
boolean authenticateUserFromURL = false;
User user = null;
if (Main.getContainerConfig().isAcEnabled()) {
if ((reqUsername != null) && (reqPassword != null)) {
authenticateUserFromURL = true;
user = UserUtils.allowUserToLogin(reqUsername, reqPassword);
}
}
SimpleDateFormat sdf = new SimpleDateFormat(Main.getContainerConfig().getTimeFormat());
StringBuilder outsb = new StringBuilder("<gsn:FeatureCollection xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"./gsn.xsd\" xmlns:gsn=\"http://gsn.ch/\" xmlns:gml=\"http://www.opengis.net/gml\"> \n");
Iterator<VSensorConfig> vsIterator = Mappings.getAllVSensorConfigs();
HashSet<String> sensorsSet = new HashSet<String>();
if (reqName != null && reqName.contains(","))
sensorsSet = new HashSet<String>(Arrays.asList(reqName.split(",")));
else sensorsSet.add(reqName);
while (vsIterator.hasNext()) {
StringBuilder sb = new StringBuilder();
String lat = null;
String lon = null;
VSensorConfig sensorConfig = vsIterator.next();
if (reqName != null && !sensorsSet.contains(sensorConfig.getName())) continue;
if (reqGroup != null && !(sensorConfig.getName().startsWith(reqGroup + "_"))) continue;
if (Main.getContainerConfig().isAcEnabled()) {
if (user == null) {
if (authenticateUserFromURL)
continue; // means that username and password provided are rejected dince they don't map to a correct User object
else // no username was provided, show only public sensors
if (DataSource.isVSManaged(sensorConfig.getName()))
continue; //skip sensor if it is managed by access control
} else // user authenticated, verify that it has the right credentials
if (!user.hasReadAccessRight(sensorConfig.getName()) && !user.isAdmin() && !DataSource.isVSManaged(sensorConfig.getName()))
continue;
}
for (KeyValue df : sensorConfig.getAddressing()) {
if (StringEscapeUtils.escapeXml(df.getKey().toString().toLowerCase()).contentEquals("latitude"))
lat = new String(StringEscapeUtils.escapeXml(df.getValue().toString()));
if (StringEscapeUtils.escapeXml(df.getKey().toString().toLowerCase()).contentEquals("longitude"))
lon = new String(StringEscapeUtils.escapeXml(df.getValue().toString()));
}
if (lat != null && lon != null) {
sb.append("<gml:featureMember>\n");
sb.append("<gsn:sensors");
sb.append(" fid=\"").append(sensorConfig.getName()).append("\"");
sb.append(">\n");
sb.append("\t<gsn:geometryProperty><gml:Point><gml:coordinates>").append(lon).append(",").append(lat).append("</gml:coordinates></gml:Point></gsn:geometryProperty>\n");
} else continue;
if (lat.isEmpty() || lon.isEmpty()) // skip sensors with empty coordinates
continue;
ArrayList<StreamElement> ses = getMostRecentValueFor(sensorConfig.getName());
int counter = 1;
if (ses != null) {
for (StreamElement se : ses) {
sb.append("\t<gsn:sensor>").append(sensorConfig.getName()).append("</gsn:sensor>\n");
for (KeyValue df : sensorConfig.getAddressing()) {
sb.append("\t<gsn:").append(StringEscapeUtils.escapeXml(df.getKey().toString().toLowerCase())).append(">");
sb.append(StringEscapeUtils.escapeXml(df.getValue().toString()));
sb.append("</gsn:").append(StringEscapeUtils.escapeXml(df.getKey().toString().toLowerCase())).append(">\n");
}
for (DataField df : sensorConfig.getOutputStructure()) {
sb.append("\t<gsn:").append(df.getName().toLowerCase()).append(">");
if (se != null)
if (df.getType().toLowerCase().trim().indexOf("binary") > 0)
sb.append(se.getData(df.getName()));
else
sb.append(se.getData(StringEscapeUtils.escapeXml(df.getName())));
sb.append("</gsn:").append(df.getName().toLowerCase()).append(">\n");
}
counter++;
}
}
sb.append("</gsn:sensors>\n");
sb.append("</gml:featureMember>\n");
outsb.append(sb);
}
outsb.append("</gsn:FeatureCollection>\n");
return outsb.toString();
}
public boolean isValid(HttpServletRequest request, HttpServletResponse response) throws IOException {
return true;
}
/**
* returns null if there is an error.
*
* @param virtual_sensor_name
* @return
*/
public static ArrayList<StreamElement> getMostRecentValueFor(String virtual_sensor_name) {
StringBuilder query = new StringBuilder("select * from ").append(virtual_sensor_name).append(" where timed = (select max(timed) from ").append(virtual_sensor_name).append(")");
ArrayList<StreamElement> toReturn = new ArrayList<StreamElement>();
try {
DataEnumerator result = Main.getStorage(virtual_sensor_name).executeQuery(query, true);
while (result.hasMoreElements())
toReturn.add(result.nextElement());
} catch (SQLException e) {
logger.error("ERROR IN EXECUTING, query: " + query);
logger.error(e.getMessage(), e);
return null;
}
return toReturn;
}
}