Merge "Issue #1521 add extra validation and checks to grid factory Change-Id: If7903f96bad2d21e9e9eaea86fa5ccc9b9374c9c" into development

Former-commit-id: f1cf8bff45 [formerly 88b52e25f2] [formerly b765544b40 [formerly af723dd7ec322d586b7eb48381105c1043f32e67]]
Former-commit-id: b765544b40
Former-commit-id: 8952df8497
This commit is contained in:
Nate Jensen 2013-01-30 15:01:19 -06:00 committed by Gerrit Code Review
commit 2db9dc1130
5 changed files with 201 additions and 169 deletions

View file

@ -0,0 +1,119 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.dataaccess.exception;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
/**
* An exception for when a request is sent that a factory cannot process because
* of unrecognized or missing identifiers.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 13, 2012 njensen Initial creation
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class InvalidIdentifiersException extends DataAccessException {
private static final long serialVersionUID = 1L;
private final String datatype;
private final Collection<String> missingIdentifiers;
private final Collection<String> invalidIdentifiers;
public InvalidIdentifiersException(String datatype,
Collection<String> missingIdentifiers,
Collection<String> invalidIdentifiers) {
// Life is easier if we can assume these are non null.
if (missingIdentifiers == null) {
missingIdentifiers = Collections.emptyList();
}
if (invalidIdentifiers == null) {
invalidIdentifiers = Collections.emptyList();
}
if (missingIdentifiers.isEmpty() && invalidIdentifiers.isEmpty()) {
throw new IllegalArgumentException(this.getClass().getSimpleName()
+ " must be contain either invalid or missing identifiers.");
}
this.datatype = datatype;
this.missingIdentifiers = missingIdentifiers;
this.invalidIdentifiers = invalidIdentifiers;
}
@Override
public String getMessage() {
StringBuilder sb = new StringBuilder();
sb.append("Request of ");
sb.append(getDatatype());
sb.append(" data ");
if (!missingIdentifiers.isEmpty()) {
sb.append("is missing identifiers: ");
Iterator<String> itr = missingIdentifiers.iterator();
while (itr.hasNext()) {
sb.append(itr.next());
if (itr.hasNext()) {
sb.append(", ");
}
}
if (!invalidIdentifiers.isEmpty()) {
sb.append(" and ");
}
}
if (!invalidIdentifiers.isEmpty()) {
if (missingIdentifiers.isEmpty())
sb.append("has invalid identifiers: ");
Iterator<String> itr = invalidIdentifiers.iterator();
while (itr.hasNext()) {
sb.append(itr.next());
if (itr.hasNext()) {
sb.append(", ");
}
}
}
return sb.toString();
}
public String getDatatype() {
return datatype;
}
public Collection<String> getMissingIdentifiers() {
return missingIdentifiers;
}
public Collection<String> getInvalidIdentifiers() {
return invalidIdentifiers;
}
}

View file

@ -1,83 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.dataaccess.exception;
/**
* An exception for when a request is sent that a factory cannot process without
* one or more specific identifiers.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 13, 2012 njensen Initial creation
*
* </pre>
*
* @author njensen
* @version 1.0
*/
public class MissingRequiredIdentifierException extends DataAccessException {
private static final long serialVersionUID = 1L;
/**
* Constructor
*/
public MissingRequiredIdentifierException() {
super();
}
/**
* Constructor
*
* @param message
* the error message
*/
public MissingRequiredIdentifierException(String message) {
super(message);
}
/**
* Constructor
*
* @param message
* the error message
* @param cause
* the cause of the error
*/
public MissingRequiredIdentifierException(String message, Throwable cause) {
super(message, cause);
}
/**
* Constructor
*
* @param cause
* the cause of the error
*/
public MissingRequiredIdentifierException(Throwable cause) {
super(cause);
}
}

View file

@ -19,14 +19,14 @@
**/
package com.raytheon.uf.common.dataaccess.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import com.raytheon.uf.common.dataaccess.IDataRequest;
import com.raytheon.uf.common.dataaccess.exception.MissingRequiredIdentifierException;
import com.raytheon.uf.common.dataaccess.exception.InvalidIdentifiersException;
/**
*
@ -55,7 +55,19 @@ public abstract class AbstractDataFactory {
*
* @return the required identifiers
*/
public abstract String[] getRequiredIdentifiers();
public String[] getRequiredIdentifiers(){
return null;
}
/**
* Return the complete set of all valid identifiers for a request, or null
* if there is no well defined set or if no validation should occur.
*
* @return the valid identifiers.
*/
public String[] getValidIdentifiers() {
return null;
}
/**
* Validates that a request is compatible with the factory
@ -65,36 +77,26 @@ public abstract class AbstractDataFactory {
*/
public void validateRequest(IDataRequest<?> request) {
String[] required = getRequiredIdentifiers();
List<String> missing = null;
if (required != null && required.length > 0) {
Map<String, Object> identifiers = request.getIdentifiers();
if (identifiers != null) {
for (String s : required) {
if (!identifiers.containsKey(s)) {
if (missing == null) {
missing = new ArrayList<String>(required.length);
}
missing.add(s);
}
}
} else {
missing = Arrays.asList(required);
Collection<String> missing = Collections.emptySet();
Collection<String> invalid = Collections.emptySet();
Map<String, Object> identifiers = request.getIdentifiers();
if (identifiers != null) {
if (required != null) {
missing = new HashSet<String>(Arrays.asList(required));
missing.removeAll(identifiers.keySet());
}
String[] valid = getValidIdentifiers();
if (valid != null) {
invalid = new HashSet<String>(identifiers.keySet());
invalid.removeAll(Arrays.asList(valid));
}
} else if (required != null) {
missing = Arrays.asList(required);
}
if (missing != null) {
StringBuilder sb = new StringBuilder();
sb.append("Request of ");
sb.append(request.getDatatype());
sb.append(" data is missing identifiers: ");
Iterator<String> itr = missing.iterator();
while (itr.hasNext()) {
sb.append(itr.next());
if (itr.hasNext()) {
sb.append(", ");
}
}
throw new MissingRequiredIdentifierException(sb.toString());
if (!missing.isEmpty() || !invalid.isEmpty()) {
throw new InvalidIdentifiersException(request.getDatatype(), missing,
invalid);
}
}
}

View file

@ -78,32 +78,36 @@ public class GridDataAccessFactory extends AbstractGridDataPluginFactory
private static final String NAMESPACE = "namespace";
private static final String[] VALID_IDENTIFIERS = {
GridConstants.DATASET_ID, GridConstants.SECONDARY_ID,
GridConstants.ENSEMBLE_ID, NAMESPACE };
@Override
public String[] getValidIdentifiers() {
return VALID_IDENTIFIERS;
}
@Override
public GridGeometry2D getGeometry(IGridRequest request) {
Object locationId = null;
if (request.getIdentifiers().containsKey(GridConstants.LOCATION_ID)) {
locationId = request.getIdentifiers()
.get(GridConstants.LOCATION_ID);
} else {
DbQueryRequest dbQueryRequest = this.buildDbQueryRequest(request);
dbQueryRequest.setDistinct(Boolean.TRUE);
dbQueryRequest.addRequestField(GridConstants.LOCATION_ID);
DbQueryRequest dbQueryRequest = this.buildDbQueryRequest(request);
dbQueryRequest.setDistinct(Boolean.TRUE);
dbQueryRequest.addRequestField(GridConstants.LOCATION_ID);
DbQueryResponse dbQueryResponse = this.executeDbQueryRequest(
dbQueryRequest, request.toString());
DbQueryResponse dbQueryResponse = this.executeDbQueryRequest(
dbQueryRequest, request.toString());
if (dbQueryResponse.getResults().isEmpty()) {
return null;
}
if (dbQueryResponse.getResults().size() > 1) {
throw new DataRetrievalException(
"The provided request parameters refer to more than one geographical location.");
}
locationId = dbQueryResponse.getResults().get(0)
.get(GridConstants.LOCATION_ID);
if (dbQueryResponse.getResults().isEmpty()) {
return null;
}
if (dbQueryResponse.getResults().size() > 1) {
throw new DataRetrievalException(
"The provided request parameters refer to more than one geographical location.");
}
locationId = dbQueryResponse.getResults().get(0)
.get(GridConstants.LOCATION_ID);
GridCoverage cov = GridCoverageLookup.getInstance().getCoverage(
Integer.parseInt(locationId.toString()));
if (cov != null) {
@ -114,13 +118,6 @@ public class GridDataAccessFactory extends AbstractGridDataPluginFactory
}
}
@Override
public String[] getRequiredIdentifiers() {
// What is required? Technically it would be nice if you specified a
// datasetid, but some parameters are only in one model so maybe it's
// not required.
return null;
}
@Override
protected Map<String, RequestConstraint> buildConstraintsFromRequest(
@ -130,7 +127,7 @@ public class GridDataAccessFactory extends AbstractGridDataPluginFactory
Map<String, Object> identifiers = request.getIdentifiers();
try {
GridQueryAssembler assembler = new GridQueryAssembler();
if (identifiers.containsKey(NAMESPACE)) {
if (identifiers != null && identifiers.containsKey(NAMESPACE)) {
assembler.setNamespace(identifiers.get(NAMESPACE).toString());
}
if (request.getParameters() != null) {
@ -163,19 +160,20 @@ public class GridDataAccessFactory extends AbstractGridDataPluginFactory
assembler.setLevelTwoValue(null);
}
if (identifiers.containsKey(GridConstants.DATASET_ID)) {
assembler.setDatasetId(identifiers
.get(GridConstants.DATASET_ID).toString());
if (identifiers != null) {
if (identifiers.containsKey(GridConstants.DATASET_ID)) {
assembler.setDatasetId(identifiers.get(
GridConstants.DATASET_ID).toString());
}
if (identifiers.containsKey(GridConstants.ENSEMBLE_ID)) {
assembler.setEnsembleId(identifiers.get(
GridConstants.ENSEMBLE_ID).toString());
}
if (identifiers.containsKey(GridConstants.SECONDARY_ID)) {
assembler.setSecondaryId(identifiers.get(
GridConstants.SECONDARY_ID).toString());
}
}
if (identifiers.containsKey(GridConstants.ENSEMBLE_ID)) {
assembler.setEnsembleId(identifiers.get(
GridConstants.ENSEMBLE_ID).toString());
}
if (identifiers.containsKey(GridConstants.SECONDARY_ID)) {
assembler.setSecondaryId(identifiers.get(
GridConstants.SECONDARY_ID).toString());
}
mergeConstraintMaps(assembler.getConstraintMap(), result);
} catch (CommunicationException e) {
throw new DataRetrievalException(e);
@ -224,7 +222,8 @@ public class GridDataAccessFactory extends AbstractGridDataPluginFactory
String datasetId = gridRecord.getDatasetId();
Level level = gridRecord.getLevel();
if (request.getIdentifiers().containsKey(NAMESPACE)) {
Map<String, Object> identifiers = request.getIdentifiers();
if (identifiers != null && identifiers.containsKey(NAMESPACE)) {
// perform reverse mappings so the parameters and levels that are
// returned match exactly what was requested.
String namespace = request.getIdentifiers().get(NAMESPACE)
@ -234,9 +233,8 @@ public class GridDataAccessFactory extends AbstractGridDataPluginFactory
parameter = reverseResolveMapping(ParameterMapper.getInstance(),
parameter, namespace, requestParameters);
if (request.getIdentifiers().containsKey(GridConstants.DATASET_ID)) {
List<String> requestedDatasets = Arrays.asList(request
.getIdentifiers().get(GridConstants.DATASET_ID)
if (identifiers.containsKey(GridConstants.DATASET_ID)) {
List<String> requestedDatasets = Arrays.asList(identifiers.get(GridConstants.DATASET_ID)
.toString());
datasetId = reverseResolveMapping(
DatasetIdMapper.getInstance(), datasetId, namespace,
@ -275,8 +273,7 @@ public class GridDataAccessFactory extends AbstractGridDataPluginFactory
defaultGridData.setParameter(parameter);
defaultGridData.setLevel(level);
defaultGridData.setUnit(gridRecord.getParameter().getUnit());
Map<String, Object> attributes = new HashMap<String, Object>(
request.getIdentifiers());
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(GridConstants.DATASET_ID, datasetId);
attributes.put(GridConstants.SECONDARY_ID, gridRecord.getSecondaryId());
attributes.put(GridConstants.ENSEMBLE_ID, gridRecord.getEnsembleId());

View file

@ -72,6 +72,9 @@ public class SatelliteGridFactory extends AbstractGridDataPluginFactory
private static final String FIELD_SECTOR_ID = "sectorID";
private static final String[] VALID_IDENTIFIERS = { "source",
"creatingEntity", FIELD_SECTOR_ID, FIELD_PYHSICAL_ELEMENT };
private Map<String, GridGeometry2D> sectorGeometryMapCache;
public SatelliteGridFactory() {
@ -178,15 +181,9 @@ public class SatelliteGridFactory extends AbstractGridDataPluginFactory
.toString();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.common.dataaccess.impl.AbstractDataFactory#
* getRequiredIdentifiers()
*/
@Override
public String[] getRequiredIdentifiers() {
return null;
public String[] getValidIdentifiers() {
return VALID_IDENTIFIERS;
}
protected DefaultGridData constructGridDataResponse(IGridRequest request,