/** * Copyright (C) 2012 52°North Initiative for Geospatial Open Source Software GmbH * * 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.n52.sos.handler; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.n52.ows.ExceptionReport; import org.n52.ows.InvalidParameterValueException; import org.n52.ows.MissingParameterValueException; import org.n52.ows.NoApplicableCodeException; import org.n52.sos.Constants; import org.n52.sos.dataTypes.Procedure; import org.n52.sos.db.AccessGDB; import org.n52.sos.encoder.OGCProcedureEncoder; import com.esri.arcgis.interop.AutomationException; import com.esri.arcgis.server.json.JSONObject; /** * @author <a href="mailto:broering@52north.org">Arne Broering</a> */ public class DescribeSensorOperationHandler extends OGCOperationRequestHandler { private static final String DESCRIBE_SENSOR_OPERATION_NAME = "DescribeSensor"; private static final String invalidOrMissingProcedureDescriptionFormat = "Error, operation requires 'procedureDescriptionFormat' parameter with value: '" + Constants.RESPONSE_FORMAT_SENSORML_20 + "' or '"+ Constants.RESPONSE_FORMAT_SENSORML_101 + "'."; private static final InvalidParameterValueException invalidParamExc = new InvalidParameterValueException(invalidOrMissingProcedureDescriptionFormat); private static final MissingParameterValueException missingParamExc = new MissingParameterValueException(invalidOrMissingProcedureDescriptionFormat); public DescribeSensorOperationHandler() { super(); } /** * realizes the DescribeSensor operation. Expects the following parameters in the inputObject: * <code>service, version, request, procedure, procedureDescriptionFormat</code> */ public byte[] invokeOGCOperation(AccessGDB geoDB, JSONObject inputObject, String[] responseProperties) throws ExceptionReport { super.invokeOGCOperation(geoDB, inputObject, responseProperties); // check 'version' parameter: checkMandatoryParameter(inputObject, "version", VERSION); // check 'procedureDescriptionFormat' parameter: String[] procedureDescriptionFormat = null; if (! inputObject.has("procedureDescriptionFormat")) { throw missingParamExc; } else { procedureDescriptionFormat = inputObject.getString("procedureDescriptionFormat").split(","); if (procedureDescriptionFormat.length != 1) { throw invalidParamExc; } else if (procedureDescriptionFormat[0].equalsIgnoreCase(Constants.RESPONSE_FORMAT_SENSORML_20)) { // TODO: implement 2.0 support: throw new UnsupportedOperationException("SensorML 2.0 not yet supported..."); //return encodeProcedures(geoDB, inputObject, PROCEDURE_DESC_FORMAT_20); } else if (procedureDescriptionFormat[0].equalsIgnoreCase(Constants.RESPONSE_FORMAT_SENSORML_101)) { try { return queryAndEncodeProcedures(geoDB, inputObject, Constants.RESPONSE_FORMAT_SENSORML_101); } catch (IOException e) { throw new NoApplicableCodeException(e); } } else { throw invalidParamExc; } } } /** * * @param inputObject * @param sensorMLVersion * @return * @throws IOException * @throws AutomationException * @throws InvalidParameterValueException * @throws NoApplicableCodeException */ private byte[] queryAndEncodeProcedures(AccessGDB geoDB, JSONObject inputObject, String sensorMLVersion) throws AutomationException, IOException, InvalidParameterValueException, NoApplicableCodeException { String[] procedures = null; if (inputObject.has("procedure")) { procedures = inputObject.getString("procedure").split(","); } /* * The 'procedure' parameter of DescribeSensor can either be a * NETWORK identifier or a PROCEDURE resource. * * Hence, we have to check what they are first: */ List<String> proceduresWhichAreNetworks = new ArrayList<String>(); List<String> proceduresWhichAreProcedures = new ArrayList<String>(); for (String procedure : procedures) { if (geoDB.getProcedureAccess().isNetwork(procedure)) { proceduresWhichAreNetworks.add(procedure); } else if (geoDB.getProcedureAccess().isProcedure(procedure)) { proceduresWhichAreProcedures.add(procedure); } } /* * We only support the request of one kind of procedure per request: */ if (proceduresWhichAreNetworks.size() > 0 && proceduresWhichAreProcedures.size() > 0) { throw new InvalidParameterValueException("The parameter 'PROCEDURE' can either contain NETWORK identifiers or PROCEDURE resource identifiers. A mix is unsupported."); } /* * Depending on type of procedure: query & encode accordingly: */ String result = ""; if (proceduresWhichAreNetworks.size() > 0) { Map<String, Collection<Procedure>> mapOfProceduresPerNetwork = new HashMap<String, Collection<Procedure>>(); for (String networkID : procedures) { Collection<Procedure> procedureCollection = geoDB.getProcedureAccess().getProceduresForNetwork(networkID); mapOfProceduresPerNetwork.put(networkID, procedureCollection); } if (sensorMLVersion.equalsIgnoreCase(Constants.RESPONSE_FORMAT_SENSORML_20)){ throw new UnsupportedOperationException(); } else { result = new OGCProcedureEncoder().encodeNetwork_SensorML101(mapOfProceduresPerNetwork); } } else if (proceduresWhichAreProcedures.size() > 0) { Collection<Procedure> procedureCollection = geoDB.getProcedureAccess().getProceduresComplete(procedures); if (sensorMLVersion.equalsIgnoreCase(Constants.RESPONSE_FORMAT_SENSORML_20)){ throw new UnsupportedOperationException(); } else { LOGGER.info("start encoding components as SensorML 1.0.1"); result = new OGCProcedureEncoder().encodeComponents_SensorML101(procedureCollection); } } else { // case: no valid procedure was given in the request throw new InvalidParameterValueException("The passed procedure parameter did not specify existing procedure IDs."); } return result.getBytes("utf-8"); } protected String getOperationName() { return DESCRIBE_SENSOR_OPERATION_NAME; } @Override public int getExecutionPriority() { return 10; } }