/**
* Copyright (C) 2012-2017 52°North Initiative for Geospatial Open Source
* Software GmbH
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* If the program is linked with libraries which are licensed under one of
* the following licenses, the combination of the program with the linked
* library is not considered a "derivative work" of the program:
*
* - Apache License, version 2.0
* - Apache Software License, version 1.0
* - GNU Lesser General Public License, version 3
* - Mozilla Public License, versions 1.0, 1.1 and 2.0
* - Common Development and Distribution License (CDDL), version 1.0
*
* Therefore the distribution of the program linked with libraries licensed
* under the aforementioned licenses, is permitted by the copyright holders
* if the distribution is compliant with both the GNU General Public
* License version 2 and the aforementioned licenses.
*
* This program 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 General
* Public License for more details.
*/
package org.n52.sos.ogc.om;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.n52.sos.exception.CodedException;
import org.n52.sos.exception.sos.ResponseExceedsSizeLimitException;
import org.n52.sos.ogc.om.values.Value;
import org.n52.sos.ogc.ows.OWSConstants.AdditionalRequestParams;
import org.n52.sos.ogc.ows.OwsExceptionReport;
import org.n52.sos.ogc.sos.Sos2Constants;
import org.n52.sos.service.Configurator;
import org.n52.sos.service.ServiceConfiguration;
import org.n52.sos.util.CollectionHelper;
import org.n52.sos.util.GeometryHandler;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.vividsolutions.jts.geom.Geometry;
public abstract class AbstractStreaming extends AbstractObservationValue<Value<OmObservation>> {
private static final long serialVersionUID = -4290319005184152231L;
private Map<AdditionalRequestParams, Object> additionalRequestParams = Maps.newHashMap();
private String responseFormat;
private int maxNumberOfValues = Integer.MIN_VALUE;
private int currentNumberOfValues = 0;
public abstract boolean hasNextValue() throws OwsExceptionReport;
public abstract OmObservation nextSingleObservation() throws OwsExceptionReport;
public Collection<OmObservation> mergeObservation() throws OwsExceptionReport {
List<OmObservation> observations = getObservation();
// TODO merge all observations with the same observationContellation
// FIXME Failed to set the observation type to sweArrayObservation for
// the merged Observations
// (proc, obsProp, foi)
if (CollectionHelper.isNotEmpty(observations)) {
final List<OmObservation> mergedObservations = new LinkedList<OmObservation>();
int obsIdCounter = 1;
for (final OmObservation sosObservation : observations) {
if (mergedObservations.isEmpty()) {
sosObservation.setObservationID(Integer.toString(obsIdCounter++));
mergedObservations.add(sosObservation);
} else {
boolean combined = false;
for (final OmObservation combinedSosObs : mergedObservations) {
if (combinedSosObs.checkForMerge(sosObservation)) {
combinedSosObs.setResultTime(null);
combinedSosObs.mergeWithObservation(sosObservation);
combined = true;
break;
}
}
if (!combined) {
mergedObservations.add(sosObservation);
}
}
}
return mergedObservations;
}
return observations;
}
public List<OmObservation> getObservation() throws OwsExceptionReport {
List<OmObservation> observations = Lists.newArrayList();
do {
OmObservation obs = nextSingleObservation();
if (obs != null) {
observations.add(obs);
}
} while (hasNextValue());
return observations;
}
public void add(AdditionalRequestParams parameter, Object object) {
additionalRequestParams.put(parameter, object);
}
public boolean contains(AdditionalRequestParams parameter) {
return additionalRequestParams.containsKey(parameter);
}
public boolean isSetAdditionalRequestParams() {
return CollectionHelper.isNotEmpty(additionalRequestParams);
}
protected Object getAdditionalRequestParams(AdditionalRequestParams parameter) {
return additionalRequestParams.get(parameter);
}
/**
* Check and modify observation for Spatial Filtering Profile and requested
* crs
*
* @param observation
* {@link OmObservation} to check
* @throws OwsExceptionReport
* If an error occurs when modifying the {@link OmObservation}
*/
@SuppressWarnings("unchecked")
protected void checkForModifications(OmObservation observation) throws OwsExceptionReport {
if (isSetAdditionalRequestParams() && contains(AdditionalRequestParams.crs)) {
Object additionalRequestParam = getAdditionalRequestParams(AdditionalRequestParams.crs);
int targetCRS = -1;
if (additionalRequestParam instanceof Integer) {
targetCRS = (Integer) additionalRequestParam;
} else if (additionalRequestParam instanceof String) {
targetCRS = Integer.parseInt((String) additionalRequestParam);
}
if (observation.isSetParameter()) {
for (NamedValue<?> namedValue : observation.getParameter()) {
if (Sos2Constants.HREF_PARAMETER_SPATIAL_FILTERING_PROFILE.equals(namedValue.getName().getHref())) {
NamedValue<Geometry> spatialFilteringProfileParameter = (NamedValue<Geometry>) namedValue;
spatialFilteringProfileParameter.getValue().setValue(
GeometryHandler.getInstance().transform(
spatialFilteringProfileParameter.getValue().getValue(), targetCRS));
}
}
}
}
}
@Override
public boolean isSetValue() {
return true;
}
public void setResponseFormat(String responseFormat) {
this.responseFormat = responseFormat;
}
public String getResponseFormat() {
if (Strings.isNullOrEmpty(responseFormat)) {
this.responseFormat = Configurator.getInstance().getProfileHandler().getActiveProfile().getObservationResponseFormat();
}
return responseFormat;
}
/**
* @return the maxNumberOfValues
*/
public int getMaxNumberOfValues() {
return maxNumberOfValues;
}
/**
* @param maxNumberOfValues the maxNumberOfValues to set
*/
public void setMaxNumberOfValues(int maxNumberOfValues) {
this.maxNumberOfValues = maxNumberOfValues;
}
/**
* Check if the max number of returned values is exceeded
*
* @param size
* Max number count
* @throws CodedException
* If the size limit is exceeded
*/
protected void checkMaxNumberOfReturnedValues(int size) throws CodedException {
if (ServiceConfiguration.getInstance().getMaxNumberOfReturnedValues() > 0) {
currentNumberOfValues += size;
if (currentNumberOfValues > getMaxNumberOfValues()) {
throw new ResponseExceedsSizeLimitException().at("maxNumberOfReturnedValues");
}
}
}
}