package org.oliot.epcis.service.query.mongodb;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.bind.JAXB;
import javax.xml.bind.JAXBElement;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import org.apache.log4j.Level;
import org.bson.BsonArray;
import org.bson.BsonDocument;
import org.bson.BsonInt32;
import org.bson.BsonInt64;
import org.bson.BsonString;
import org.json.JSONArray;
import org.json.JSONObject;
import org.oliot.epcis.configuration.Configuration;
import org.oliot.epcis.security.OAuthUtil;
import org.oliot.epcis.serde.mongodb.AggregationEventReadConverter;
import org.oliot.epcis.serde.mongodb.MasterDataReadConverter;
import org.oliot.epcis.serde.mongodb.ObjectEventReadConverter;
import org.oliot.epcis.serde.mongodb.QuantityEventReadConverter;
import org.oliot.epcis.serde.mongodb.TransactionEventReadConverter;
import org.oliot.epcis.serde.mongodb.TransformationEventReadConverter;
import org.oliot.epcis.service.subscription.MongoSubscription;
import org.oliot.epcis.service.subscription.MongoSubscriptionTask;
import org.oliot.epcis.service.subscription.TriggerEngine;
import org.oliot.model.epcis.AggregationEventType;
import org.oliot.model.epcis.AttributeType;
import org.oliot.model.epcis.EPCISQueryBodyType;
import org.oliot.model.epcis.EPCISQueryDocumentType;
import org.oliot.model.epcis.EventListType;
import org.oliot.model.epcis.InvalidURIException;
import org.oliot.model.epcis.ObjectEventType;
import org.oliot.model.epcis.QuantityEventType;
import org.oliot.model.epcis.QueryParam;
import org.oliot.model.epcis.QueryParameterException;
import org.oliot.model.epcis.QueryParams;
import org.oliot.model.epcis.QueryResults;
import org.oliot.model.epcis.QueryResultsBody;
import org.oliot.model.epcis.QuerySchedule;
import org.oliot.model.epcis.QueryTooLargeException;
import org.oliot.model.epcis.SubscribeNotPermittedException;
import org.oliot.model.epcis.SubscriptionControls;
import org.oliot.model.epcis.SubscriptionControlsException;
import org.oliot.model.epcis.SubscriptionType;
import org.oliot.model.epcis.TransactionEventType;
import org.oliot.model.epcis.TransformationEventType;
import org.oliot.model.epcis.VocabularyElementType;
import org.oliot.model.epcis.VocabularyListType;
import org.oliot.model.epcis.VocabularyType;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.springframework.web.bind.annotation.PathVariable;
import static org.quartz.TriggerKey.*;
import static org.quartz.JobKey.*;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import static org.oliot.epcis.service.query.mongodb.MongoQueryUtil.*;
/**
* Copyright (C) 2014-2016 Jaewook Byun
*
* This project is part of Oliot (oliot.org), pursuing the implementation of
* Electronic Product Code Information Service(EPCIS) v1.1 specification in
* EPCglobal.
* [http://www.gs1.org/gsmp/kc/epcglobal/epcis/epcis_1_1-standard-20140520.pdf]
*
*
* @author Jaewook Byun, Ph.D student
*
* Korea Advanced Institute of Science and Technology (KAIST)
*
* Real-time Embedded System Laboratory(RESL)
*
* bjw0829@kaist.ac.kr, bjw0829@gmail.com
*/
public class MongoQueryService {
public String subscribe(SubscriptionType subscription) {
String queryName = subscription.getQueryName();
String subscriptionID = subscription.getSubscriptionID();
String dest = subscription.getDest();
String cronExpression = subscription.getCronExpression();
boolean reportIfEmpty = subscription.isReportIfEmpty();
String initialRecordTime = subscription.getInitialRecordTime();
String eventType = subscription.getEventType();
String GE_eventTime = subscription.getGE_eventTime();
String LT_eventTime = subscription.getLT_eventTime();
String GE_recordTime = subscription.getGE_recordTime();
String LT_recordTime = subscription.getLT_recordTime();
String EQ_action = subscription.getEQ_action();
String EQ_bizStep = subscription.getEQ_bizStep();
String EQ_disposition = subscription.getEQ_disposition();
String EQ_readPoint = subscription.getEQ_readPoint();
String WD_readPoint = subscription.getWD_readPoint();
String EQ_bizLocation = subscription.getEQ_bizLocation();
String WD_bizLocation = subscription.getWD_bizLocation();
String EQ_transformationID = subscription.getEQ_transformationID();
String MATCH_epc = subscription.getMATCH_epc();
String MATCH_parentID = subscription.getMATCH_parentID();
String MATCH_inputEPC = subscription.getMATCH_inputEPC();
String MATCH_outputEPC = subscription.getMATCH_outputEPC();
String MATCH_anyEPC = subscription.getMATCH_anyEPC();
String MATCH_epcClass = subscription.getMATCH_epcClass();
String MATCH_inputEPCClass = subscription.getMATCH_inputEPCClass();
String MATCH_outputEPCClass = subscription.getMATCH_outputEPCClass();
String MATCH_anyEPCClass = subscription.getMATCH_anyEPCClass();
String EQ_quantity = subscription.getEQ_quantity();
String GT_quantity = subscription.getGT_quantity();
String GE_quantity = subscription.getGE_quantity();
String LT_quantity = subscription.getLT_quantity();
String LE_quantity = subscription.getLE_quantity();
String orderBy = subscription.getOrderBy();
String orderDirection = subscription.getOrderDirection();
String eventCountLimit = subscription.getEventCountLimit();
String maxEventCount = subscription.getMaxEventCount();
Map<String, String> paramMap = subscription.getParamMap();
// Oliot EPCIS doesn't support ignoreReceivedEvent for SOAP Interface
// Oliot EPCIS doesn't support triggered subscription for SOAP Interface
String result = subscribe(queryName, subscriptionID, dest, cronExpression, true, false, reportIfEmpty,
initialRecordTime, eventType, GE_eventTime, LT_eventTime, GE_recordTime, LT_recordTime, EQ_action,
EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation, WD_bizLocation,
EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC, MATCH_anyEPC,
MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass, EQ_quantity, GT_quantity,
GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection, eventCountLimit, maxEventCount, null,
paramMap);
return result;
}
public String subscribeEventQuery(String queryName, String subscriptionID, String dest, String cronExpression,
boolean isScheduledSubscription, boolean ignoreReceivedEvent, boolean reportIfEmpty,
String initialRecordTimeStr, String eventType, String GE_eventTime, String LT_eventTime,
String GE_recordTime, String LT_recordTime, String EQ_action, String EQ_bizStep, String EQ_disposition,
String EQ_readPoint, String WD_readPoint, String EQ_bizLocation, String WD_bizLocation,
String EQ_transformationID, String MATCH_epc, String MATCH_parentID, String MATCH_inputEPC,
String MATCH_outputEPC, String MATCH_anyEPC, String MATCH_epcClass, String MATCH_inputEPCClass,
String MATCH_outputEPCClass, String MATCH_anyEPCClass, String EQ_quantity, String GT_quantity,
String GE_quantity, String LT_quantity, String LE_quantity, String orderBy, String orderDirection,
String eventCountLimit, String maxEventCount, String format, Map<String, String> paramMap) {
// M27 - query params' constraint
// M39 - query params' constraint
String reason = checkConstraintSimpleEventQuery(queryName, eventType, GE_eventTime, LT_eventTime, GE_recordTime,
LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation,
WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC,
MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass, EQ_quantity,
GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection, eventCountLimit,
maxEventCount, paramMap);
if (reason != null) {
return makeErrorResult(reason, QueryParameterException.class);
}
// Existing subscription Check
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("Subscription",
BsonDocument.class);
BsonDocument exist = collection.find(new BsonDocument("subscriptionID", new BsonString(subscriptionID)))
.first();
if (exist != null) {
return "SubscriptionID : " + subscriptionID + " is already subscribed. ";
}
// cron Example
// 0/10 * * * * ? : every 10 second
// M30
try {
cronSchedule(cronExpression);
} catch (RuntimeException e) {
return makeErrorResult(e.toString(), SubscriptionControlsException.class);
}
// Add Schedule with Query
if (isScheduledSubscription == true) {
addScheduleToQuartz(queryName, subscriptionID, dest, cronExpression, isScheduledSubscription,
ignoreReceivedEvent, reportIfEmpty, initialRecordTimeStr, eventType, GE_eventTime, LT_eventTime,
GE_recordTime, LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint,
EQ_bizLocation, WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC,
MATCH_outputEPC, MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass,
MATCH_anyEPCClass, EQ_quantity, GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy,
orderDirection, eventCountLimit, maxEventCount, format, paramMap);
} else {
// Add Trigger with Query
SubscriptionType subscription = new SubscriptionType(queryName, subscriptionID, dest, cronExpression,
isScheduledSubscription, ignoreReceivedEvent, reportIfEmpty, initialRecordTimeStr, eventType,
GE_eventTime, LT_eventTime, GE_recordTime, LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition,
EQ_readPoint, WD_readPoint, EQ_bizLocation, WD_bizLocation, EQ_transformationID, MATCH_epc,
MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC, MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass,
MATCH_outputEPCClass, MATCH_anyEPCClass, EQ_quantity, GT_quantity, GE_quantity, LT_quantity,
LE_quantity, orderBy, orderDirection, eventCountLimit, maxEventCount, format, paramMap);
TriggerEngine.addTriggerSubscription(subscriptionID, subscription);
}
// Manage Subscription Persistently
addScheduleToDB(queryName, subscriptionID, dest, cronExpression, isScheduledSubscription, ignoreReceivedEvent,
reportIfEmpty, initialRecordTimeStr, eventType, GE_eventTime, LT_eventTime, GE_recordTime,
LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation,
WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC,
MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass, EQ_quantity,
GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection, eventCountLimit,
maxEventCount, format, paramMap);
String retString = "SubscriptionID : " + subscriptionID + " is successfully triggered. ";
return retString;
}
// Soap Query Adaptor
public void subscribe(String queryName, QueryParams params, URI dest, SubscriptionControls controls,
String subscriptionID) {
List<QueryParam> queryParamList = params.getParam();
String destStr = dest.toString();
String eventType = null;
String GE_eventTime = null;
String LT_eventTime = null;
String GE_recordTime = null;
String LT_recordTime = null;
String EQ_action = null;
String EQ_bizStep = null;
String EQ_disposition = null;
String EQ_readPoint = null;
String WD_readPoint = null;
String EQ_bizLocation = null;
String WD_bizLocation = null;
String EQ_transformationID = null;
String MATCH_epc = null;
String MATCH_parentID = null;
String MATCH_inputEPC = null;
String MATCH_outputEPC = null;
String MATCH_anyEPC = null;
String MATCH_epcClass = null;
String MATCH_inputEPCClass = null;
String MATCH_outputEPCClass = null;
String MATCH_anyEPCClass = null;
String EQ_quantity = null;
String GT_quantity = null;
String GE_quantity = null;
String LT_quantity = null;
String LE_quantity = null;
String orderBy = null;
String orderDirection = null;
String eventCountLimit = null;
String maxEventCount = null;
String cronExpression = null;
boolean reportIfEmpty = false;
Map<String, String> extMap = new HashMap<String, String>();
for (int i = 0; i < queryParamList.size(); i++) {
QueryParam qp = queryParamList.get(i);
String name = qp.getName();
String value = (String) qp.getValue();
if (name.equals("cronExpression")) {
cronExpression = value;
continue;
} else if (name.equals("eventType")) {
eventType = value;
continue;
} else if (name.equals("GE_eventTime")) {
GE_eventTime = value;
continue;
} else if (name.equals("LT_eventTime")) {
LT_eventTime = value;
continue;
} else if (name.equals("GE_recordTime")) {
GE_recordTime = value;
continue;
} else if (name.equals("LT_recordTime")) {
LT_recordTime = value;
continue;
} else if (name.equals("EQ_action")) {
EQ_action = value;
continue;
} else if (name.equals("EQ_bizStep")) {
EQ_bizStep = value;
continue;
} else if (name.equals("EQ_disposition")) {
EQ_disposition = value;
continue;
} else if (name.equals("EQ_readPoint")) {
EQ_readPoint = value;
continue;
} else if (name.equals("WD_readPoint")) {
WD_readPoint = value;
continue;
} else if (name.equals("EQ_bizLocation")) {
EQ_bizLocation = value;
continue;
} else if (name.equals("WD_bizLocation")) {
WD_bizLocation = value;
continue;
} else if (name.equals("EQ_transformationID")) {
EQ_transformationID = value;
continue;
} else if (name.equals("MATCH_epc")) {
MATCH_epc = value;
continue;
} else if (name.equals("MATCH_parentID")) {
MATCH_parentID = value;
continue;
} else if (name.equals("MATCH_inputEPC")) {
MATCH_inputEPC = value;
continue;
} else if (name.equals("MATCH_outputEPC")) {
MATCH_outputEPC = value;
continue;
} else if (name.equals("MATCH_anyEPC")) {
MATCH_anyEPC = value;
continue;
} else if (name.equals("MATCH_epcClass")) {
MATCH_epcClass = value;
continue;
} else if (name.equals("MATCH_inputEPCClass")) {
MATCH_inputEPCClass = value;
continue;
} else if (name.equals("MATCH_outputEPCClass")) {
MATCH_outputEPCClass = value;
continue;
} else if (name.equals("MATCH_anyEPCClass")) {
MATCH_anyEPCClass = value;
continue;
} else if (name.equals("EQ_quantity")) {
EQ_quantity = value;
continue;
} else if (name.equals("GT_quantity")) {
GT_quantity = value;
continue;
} else if (name.equals("GE_quantity")) {
GE_quantity = value;
continue;
} else if (name.equals("LT_quantity")) {
LT_quantity = value;
continue;
} else if (name.equals("LE_quantity")) {
LE_quantity = value;
continue;
} else if (name.equals("orderBy")) {
orderBy = value;
continue;
} else if (name.equals("orderDirection")) {
orderDirection = value;
continue;
} else if (name.equals("eventCountLimit")) {
eventCountLimit = value;
continue;
} else if (name.equals("maxEventCount")) {
maxEventCount = value;
continue;
} else {
extMap.put(name, value);
}
}
// Subscription Control Processing
/*
* QuerySchedule: (Optional) Defines the periodic schedule on which the
* query is to be executed. See Section 8.2.5.3. Exactly one of schedule
* or trigger is required; if both are specified or both are omitted,
* the implementation SHALL raise a SubscriptionControls- Exception..
*/
QuerySchedule querySchedule = controls.getSchedule();
if (cronExpression == null) {
String sec = querySchedule.getSecond();
String min = querySchedule.getMinute();
String hours = querySchedule.getHour();
String dayOfMonth = querySchedule.getDayOfMonth();
String month = querySchedule.getMonth();
String dayOfWeek = querySchedule.getDayOfWeek();
cronExpression = sec + " " + min + " " + hours + " " + dayOfMonth + " " + month + " " + dayOfWeek;
}
/*
* InitialRecordTime: (Optional) Specifies a time used to constrain what
* events are considered when processing the query when it is executed
* for the first time. See Section 8.2.5.2. If omitted, defaults to the
* time at which the subscription is created.
*/
XMLGregorianCalendar initialRecordTime = controls.getInitialRecordTime();
if (initialRecordTime == null) {
try {
initialRecordTime = DatatypeFactory.newInstance().newXMLGregorianCalendar();
} catch (DatatypeConfigurationException e) {
e.printStackTrace();
}
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date initialRecordDate = initialRecordTime.toGregorianCalendar().getTime();
String initialRecordTimeStr = sdf.format(initialRecordDate);
/*
* reportIfEmpty: If true, a QueryResults instance is always sent to the
* subscriber when the query is executed. If false, a QueryResults
* instance is sent to the subscriber only when the results are
* non-empty.
*/
reportIfEmpty = controls.isReportIfEmpty();
// Oliot doesn't support ignoreReceivedEvent for SOAP interface
// Oliot doesn't support to select output format for SOAP interface
subscribe(queryName, subscriptionID, destStr, cronExpression, true, false, reportIfEmpty, initialRecordTimeStr,
eventType, GE_eventTime, LT_eventTime, GE_recordTime, LT_recordTime, EQ_action, EQ_bizStep,
EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation, WD_bizLocation, EQ_transformationID,
MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC, MATCH_anyEPC, MATCH_epcClass,
MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass, EQ_quantity, GT_quantity, GE_quantity,
LT_quantity, LE_quantity, orderBy, orderDirection, eventCountLimit, maxEventCount, null, extMap);
}
public String subscribe(String queryName, String subscriptionID, String dest, String cronExpression,
boolean isScheduledSubscription, boolean ignoreReceivedEvent, boolean reportIfEmpty,
String initialRecordTimeStr, String eventType, String GE_eventTime, String LT_eventTime,
String GE_recordTime, String LT_recordTime, String EQ_action, String EQ_bizStep, String EQ_disposition,
String EQ_readPoint, String WD_readPoint, String EQ_bizLocation, String WD_bizLocation,
String EQ_transformationID, String MATCH_epc, String MATCH_parentID, String MATCH_inputEPC,
String MATCH_outputEPC, String MATCH_anyEPC, String MATCH_epcClass, String MATCH_inputEPCClass,
String MATCH_outputEPCClass, String MATCH_anyEPCClass, String EQ_quantity, String GT_quantity,
String GE_quantity, String LT_quantity, String LE_quantity, String orderBy, String orderDirection,
String eventCountLimit, String maxEventCount, String format, Map<String, String> paramMap) {
// M20 : Throw an InvalidURIException for an incorrect dest argument in
// the subscribe method in EPCIS Query Control Interface
try {
new URL(dest);
} catch (MalformedURLException e) {
return makeErrorResult(e.toString(), InvalidURIException.class);
}
// M24 : Virtual Error Handling
// Automatically processed by URI param
if (dest == null || cronExpression == null) {
return makeErrorResult("Fill the mandatory field in subscribe method", QueryParameterException.class);
}
// M46
if (queryName.equals("SimpleMasterDataQuery")) {
return makeErrorResult("SimpleMasterDataQuery is not available in subscription method",
SubscribeNotPermittedException.class);
}
String retString = "";
if (queryName.equals("SimpleEventQuery")) {
retString = subscribeEventQuery(queryName, subscriptionID, dest, cronExpression, isScheduledSubscription,
ignoreReceivedEvent, reportIfEmpty, initialRecordTimeStr, eventType, GE_eventTime, LT_eventTime,
GE_recordTime, LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint,
EQ_bizLocation, WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC,
MATCH_outputEPC, MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass,
MATCH_anyEPCClass, EQ_quantity, GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy,
orderDirection, eventCountLimit, maxEventCount, format, paramMap);
}
return retString;
}
public void unsubscribe(String subscriptionID) {
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("Subscription",
BsonDocument.class);
// Its size should be 0 or 1
BsonDocument s = collection
.findOneAndDelete(new BsonDocument("subscriptionID", new BsonString(subscriptionID)));
if (s != null) {
SubscriptionType subscription = new SubscriptionType(s);
if (subscription.isScheduledSubscription() == true) {
// Remove from current Quartz
removeScheduleFromQuartz(subscription);
}else{
TriggerEngine.removeTriggerSubscription(subscription.getSubscriptionID());
}
}
}
public String getSubscriptionIDsREST(@PathVariable String queryName) {
JSONArray retArray = new JSONArray();
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("Subscription",
BsonDocument.class);
Iterator<BsonDocument> subIterator = collection
.find(new BsonDocument("queryName", new BsonString(queryName)), BsonDocument.class).iterator();
while (subIterator.hasNext()) {
BsonDocument subscription = subIterator.next();
retArray.put(subscription.getString("subscriptionID").asString());
}
return retArray.toString(1);
}
public List<String> getSubscriptionIDs(String queryName) {
List<String> retList = new ArrayList<String>();
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("Subscription",
BsonDocument.class);
Iterator<BsonDocument> subIterator = collection
.find(new BsonDocument("queryName", new BsonString(queryName)), BsonDocument.class).iterator();
while (subIterator.hasNext()) {
BsonDocument subscription = subIterator.next();
retList.add(subscription.getString("subscriptionID").asString().getValue());
}
return retList;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public String pollEventQuery(String queryName, String eventType, String GE_eventTime, String LT_eventTime,
String GE_recordTime, String LT_recordTime, String EQ_action, String EQ_bizStep, String EQ_disposition,
String EQ_readPoint, String WD_readPoint, String EQ_bizLocation, String WD_bizLocation,
String EQ_transformationID, String MATCH_epc, String MATCH_parentID, String MATCH_inputEPC,
String MATCH_outputEPC, String MATCH_anyEPC, String MATCH_epcClass, String MATCH_inputEPCClass,
String MATCH_outputEPCClass, String MATCH_anyEPCClass, String EQ_quantity, String GT_quantity,
String GE_quantity, String LT_quantity, String LE_quantity, String orderBy, String orderDirection,
String eventCountLimit, String maxEventCount, String format, String userID, List<String> friendList,
Map<String, String> paramMap) {
// M27 - query params' constraint
// M39 - query params' constraint
String reason = checkConstraintSimpleEventQuery(queryName, eventType, GE_eventTime, LT_eventTime, GE_recordTime,
LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation,
WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC,
MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass, EQ_quantity,
GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection, eventCountLimit,
maxEventCount, paramMap);
if (reason != null) {
return makeErrorResult(reason, QueryParameterException.class);
}
// Make Base Result Document
EPCISQueryDocumentType epcisQueryDocumentType = null;
JSONObject retJSON = new JSONObject();
if (format == null || format.equals("XML")) {
epcisQueryDocumentType = makeBaseResultDocument(queryName);
} else if (format.equals("JSON")) {
// Do Nothing
} else {
return makeErrorResult("format param should be one of XML or JSON", QueryParameterException.class);
}
// Prepare container which query results are included
// eventObjects : Container which all the query results (events) will be
// contained
List<Object> eventObjects = null;
if (format == null || format.equals("XML")) {
eventObjects = epcisQueryDocumentType.getEPCISBody().getQueryResults().getResultsBody().getEventList()
.getObjectEventOrAggregationEventOrQuantityEvent();
} else {
// foramt == JSON -> Do Nothing
}
// To be filtered by eventType
boolean toGetAggregationEvent = true;
boolean toGetObjectEvent = true;
boolean toGetQuantityEvent = true;
boolean toGetTransactionEvent = true;
boolean toGetTransformationEvent = true;
/**
* EventType : If specified, the result will only include events whose
* type matches one of the types specified in the parameter value. Each
* element of the parameter value may be one of the following strings:
* ObjectEvent, AggregationEvent, QuantityEvent, TransactionEvent, or
* TransformationEvent. An element of the parameter value may also be
* the name of an extension event type. If omitted, all event types will
* be considered for inclusion in the result.
*/
if (eventType != null) {
toGetAggregationEvent = false;
toGetObjectEvent = false;
toGetQuantityEvent = false;
toGetTransactionEvent = false;
toGetTransformationEvent = false;
String[] eventTypeArray = eventType.split(",");
for (int i = 0; i < eventTypeArray.length; i++) {
String eventTypeString = eventTypeArray[i];
if (eventTypeString != null)
eventTypeString = eventTypeString.trim();
if (eventTypeString.equals("AggregationEvent"))
toGetAggregationEvent = true;
else if (eventTypeString.equals("ObjectEvent"))
toGetObjectEvent = true;
else if (eventTypeString.equals("QuantityEvent"))
toGetQuantityEvent = true;
else if (eventTypeString.equals("TransactionEvent"))
toGetTransactionEvent = true;
else if (eventTypeString.equals("TransformationEvent"))
toGetTransformationEvent = true;
}
}
if (toGetAggregationEvent == true) {
// Aggregation Event Collection
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("AggregationEvent",
BsonDocument.class);
// Queries
BsonArray queryList = makeQueryObjects("AggregationEvent", GE_eventTime, LT_eventTime, GE_recordTime,
LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation,
WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC,
MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass,
EQ_quantity, GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection,
eventCountLimit, maxEventCount, paramMap);
// Merge All the queries with $and
BsonDocument baseQuery = new BsonDocument();
FindIterable<BsonDocument> cursor;
if (queryList.isEmpty() == false) {
BsonArray aggreQueryList = new BsonArray();
for (int i = 0; i < queryList.size(); i++) {
aggreQueryList.add(queryList.get(i));
}
baseQuery.put("$and", aggreQueryList);
// Query
cursor = collection.find(baseQuery);
} else {
cursor = collection.find();
}
// Sort and Limit
cursor = makeSortedLimitedCursor(cursor, orderBy, orderDirection, eventCountLimit);
JSONArray aggrJSONArray = new JSONArray();
MongoCursor<BsonDocument> slCursor = cursor.iterator();
while (slCursor.hasNext()) {
BsonDocument dbObject = slCursor.next();
if (OAuthUtil.isAccessible(userID, friendList, dbObject) == false) {
continue;
}
if (format == null || format.equals("XML")) {
AggregationEventReadConverter con = new AggregationEventReadConverter();
JAXBElement element = new JAXBElement(new QName("AggregationEvent"), AggregationEventType.class,
con.convert(dbObject));
eventObjects.add(element);
} else {
dbObject.remove("_id");
aggrJSONArray.put(dbObject);
}
}
if (aggrJSONArray.length() > 0) {
retJSON.put("AggregationEvent", aggrJSONArray);
}
}
// For Each Event Type!
if (toGetObjectEvent == true) {
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("ObjectEvent",
BsonDocument.class);
// Queries
BsonArray queryList = makeQueryObjects("ObjectEvent", GE_eventTime, LT_eventTime, GE_recordTime,
LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation,
WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC,
MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass,
EQ_quantity, GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection,
eventCountLimit, maxEventCount, paramMap);
// Merge All the queries with $and
BsonDocument baseQuery = new BsonDocument();
FindIterable<BsonDocument> cursor;
if (queryList.isEmpty() == false) {
BsonArray aggreQueryList = new BsonArray();
for (int i = 0; i < queryList.size(); i++) {
aggreQueryList.add(queryList.get(i));
}
baseQuery.put("$and", aggreQueryList);
// Query
cursor = collection.find(baseQuery);
} else {
cursor = collection.find();
}
// Sort and Limit
cursor = makeSortedLimitedCursor(cursor, orderBy, orderDirection, eventCountLimit);
JSONArray objJSONArray = new JSONArray();
MongoCursor<BsonDocument> slCursor = cursor.iterator();
while (slCursor.hasNext()) {
BsonDocument dbObject = slCursor.next();
if (OAuthUtil.isAccessible(userID, friendList, dbObject) == false) {
continue;
}
if (format == null || format.equals("XML")) {
ObjectEventReadConverter con = new ObjectEventReadConverter();
JAXBElement element = new JAXBElement(new QName("ObjectEvent"), ObjectEventType.class,
con.convert(dbObject));
eventObjects.add(element);
} else {
dbObject.remove("_id");
objJSONArray.put(dbObject);
}
}
if (objJSONArray.length() > 0) {
retJSON.put("ObjectEvent", objJSONArray);
}
}
if (toGetQuantityEvent == true) {
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("QuantityEvent",
BsonDocument.class);
// Queries
BsonArray queryList = makeQueryObjects("QuantityEvent", GE_eventTime, LT_eventTime, GE_recordTime,
LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation,
WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC,
MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass,
EQ_quantity, GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection,
eventCountLimit, maxEventCount, paramMap);
// Merge All the queries with $and
BsonDocument baseQuery = new BsonDocument();
FindIterable<BsonDocument> cursor;
if (queryList.isEmpty() == false) {
BsonArray aggreQueryList = new BsonArray();
for (int i = 0; i < queryList.size(); i++) {
aggreQueryList.add(queryList.get(i));
}
baseQuery.put("$and", aggreQueryList);
// Query
cursor = collection.find(baseQuery);
} else {
cursor = collection.find();
}
// Sort and Limit
cursor = makeSortedLimitedCursor(cursor, orderBy, orderDirection, eventCountLimit);
JSONArray qntJSONArray = new JSONArray();
MongoCursor<BsonDocument> slCursor = cursor.iterator();
while (slCursor.hasNext()) {
BsonDocument dbObject = slCursor.next();
if (OAuthUtil.isAccessible(userID, friendList, dbObject) == false) {
continue;
}
if (format == null || format.equals("XML")) {
QuantityEventReadConverter con = new QuantityEventReadConverter();
JAXBElement element = new JAXBElement(new QName("QuantityEvent"), QuantityEventType.class,
con.convert(dbObject));
eventObjects.add(element);
} else {
dbObject.remove("_id");
qntJSONArray.put(dbObject);
}
}
if (qntJSONArray.length() > 0) {
retJSON.put("QuantityEvent", qntJSONArray);
}
}
if (toGetTransactionEvent == true) {
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("TransactionEvent",
BsonDocument.class);
// Queries
BsonArray queryList = makeQueryObjects("TransactionEvent", GE_eventTime, LT_eventTime, GE_recordTime,
LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation,
WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC,
MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass,
EQ_quantity, GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection,
eventCountLimit, maxEventCount, paramMap);
// Merge All the queries with $and
BsonDocument baseQuery = new BsonDocument();
FindIterable<BsonDocument> cursor;
if (queryList.isEmpty() == false) {
BsonArray aggreQueryList = new BsonArray();
for (int i = 0; i < queryList.size(); i++) {
aggreQueryList.add(queryList.get(i));
}
baseQuery.put("$and", aggreQueryList);
// Query
cursor = collection.find(baseQuery);
} else {
cursor = collection.find();
}
// Sort and Limit
cursor = makeSortedLimitedCursor(cursor, orderBy, orderDirection, eventCountLimit);
JSONArray transactionJSONArray = new JSONArray();
MongoCursor<BsonDocument> slCursor = cursor.iterator();
while (slCursor.hasNext()) {
BsonDocument dbObject = slCursor.next();
if (OAuthUtil.isAccessible(userID, friendList, dbObject) == false) {
continue;
}
if (format == null || format.equals("XML")) {
TransactionEventReadConverter con = new TransactionEventReadConverter();
JAXBElement element = new JAXBElement(new QName("TransactionEvent"), TransactionEventType.class,
con.convert(dbObject));
eventObjects.add(element);
} else {
dbObject.remove("_id");
transactionJSONArray.put(dbObject);
}
}
if (transactionJSONArray.length() > 0) {
retJSON.put("TransactionEvent", transactionJSONArray);
}
}
if (toGetTransformationEvent == true) {
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("TransformationEvent",
BsonDocument.class);
// Queries
BsonArray queryList = makeQueryObjects("TransformationEvent", GE_eventTime, LT_eventTime, GE_recordTime,
LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation,
WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC,
MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass,
EQ_quantity, GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection,
eventCountLimit, maxEventCount, paramMap);
// Merge All the queries with $and
BsonDocument baseQuery = new BsonDocument();
FindIterable<BsonDocument> cursor;
if (queryList.isEmpty() == false) {
BsonArray aggreQueryList = new BsonArray();
for (int i = 0; i < queryList.size(); i++) {
aggreQueryList.add(queryList.get(i));
}
baseQuery.put("$and", aggreQueryList);
// Query
cursor = collection.find(baseQuery);
} else {
cursor = collection.find();
}
// Sort and Limit
cursor = makeSortedLimitedCursor(cursor, orderBy, orderDirection, eventCountLimit);
JSONArray transformationJSONArray = new JSONArray();
MongoCursor<BsonDocument> slCursor = cursor.iterator();
while (slCursor.hasNext()) {
BsonDocument dbObject = slCursor.next();
if (OAuthUtil.isAccessible(userID, friendList, dbObject) == false) {
continue;
}
if (format == null || format.equals("XML")) {
TransformationEventReadConverter con = new TransformationEventReadConverter();
JAXBElement element = new JAXBElement(new QName("TransformationEvent"),
TransformationEventType.class, con.convert(dbObject));
eventObjects.add(element);
} else {
dbObject.remove("_id");
transformationJSONArray.put(dbObject);
}
}
if (transformationJSONArray.length() > 0) {
retJSON.put("TransformationEvent", transformationJSONArray);
}
}
// M44
if (maxEventCount != null) {
if (format == null || format.equals("XML")) {
if (eventObjects.size() > Integer.parseInt(maxEventCount)) {
return makeErrorResult("Violate maxEventCount", QueryTooLargeException.class);
}
} else {
int cnt = 0;
if (!retJSON.isNull("AggregationEvent")) {
cnt += retJSON.getJSONArray("AggregationEvent").length();
}
if (!retJSON.isNull("ObjectEvent")) {
cnt += retJSON.getJSONArray("ObjectEvent").length();
}
if (!retJSON.isNull("QuantityEvent")) {
cnt += retJSON.getJSONArray("QuantityEvent").length();
}
if (!retJSON.isNull("TransactionEvent")) {
cnt += retJSON.getJSONArray("TransactionEvent").length();
}
if (!retJSON.isNull("TransformationEvent")) {
cnt += retJSON.getJSONArray("TransformationEvent").length();
}
if (cnt > Integer.parseInt(maxEventCount)) {
return makeErrorResult("Violate maxEventCount", QueryTooLargeException.class);
}
}
}
if (format == null || format.equals("XML")) {
StringWriter sw = new StringWriter();
JAXB.marshal(epcisQueryDocumentType, sw);
return sw.toString();
} else {
// BSONObject doc = (BSONObject) JSON.parse(retJSON.toString());
// BasicBSONEncoder en = new BasicBSONEncoder();
// System.out.println(doc.toString().length());
// byte[] ret = en.encode(doc);
// try {
// FileUtils.writeByteArrayToFile(new File("/home/jack/temp.bson"),
// ret);
// } catch (IOException e) {
// e.printStackTrace();
// }
// System.out.println(ret.length);
// return new String(en.encode(doc));
// BasicBSONDecoder de = new BasicBSONDecoder();
// BSONObject obj = de.readObject(ret);
// System.out.println(obj);
return retJSON.toString(1);
}
}
public String pollMasterDataQuery(String queryName, String vocabularyName, boolean includeAttributes,
boolean includeChildren, String attributeNames, String eQ_name, String wD_name, String hASATTR,
String maxElementCount, String format, Map<String, String> paramMap) {
// Make Base Result Document
EPCISQueryDocumentType epcisQueryDocumentType = null;
JSONArray retArray = new JSONArray();
if (format == null || format.equals("XML")) {
epcisQueryDocumentType = makeBaseResultDocument(queryName);
} else if (format.equals("JSON")) {
// Do Nothing
} else {
return makeErrorResult("format param should be one of XML or JSON", QueryParameterException.class);
}
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("MasterData",
BsonDocument.class);
// Make Query
BsonArray queryList = makeMasterQueryObjects(vocabularyName, includeAttributes, includeChildren, attributeNames,
eQ_name, wD_name, hASATTR, maxElementCount, paramMap);
// Merge All the queries with $and
BsonDocument baseQuery = new BsonDocument();
FindIterable<BsonDocument> cursor;
if (queryList.isEmpty() == false) {
BsonArray aggreQueryList = new BsonArray();
for (int i = 0; i < queryList.size(); i++) {
aggreQueryList.add(queryList.get(i));
}
baseQuery.put("$and", aggreQueryList);
// Query
cursor = collection.find(baseQuery);
} else {
cursor = collection.find();
}
// Cursor needed to ordered
List<VocabularyType> vList = new ArrayList<>();
MongoCursor<BsonDocument> slCursor = cursor.iterator();
while (slCursor.hasNext()) {
BsonDocument dbObject = slCursor.next();
if (format == null || format.equals("XML")) {
MasterDataReadConverter con = new MasterDataReadConverter();
VocabularyType vt = con.convert(dbObject);
boolean isMatched = true;
if (vt.getVocabularyElementList() != null) {
if (vt.getVocabularyElementList().getVocabularyElement() != null) {
List<VocabularyElementType> vetList = vt.getVocabularyElementList().getVocabularyElement();
for (int i = 0; i < vetList.size(); i++) {
VocabularyElementType vet = vetList.get(i);
if (includeAttributes == false) {
vet.setAttribute(null);
} else if (includeAttributes == true && attributeNames != null) {
/**
* attributeNames : If specified, only those
* attributes whose names match one of the
* specified names will be included in the
* results. If omitted, all attributes for each
* matching vocabulary element will be included.
* (To obtain a list of vocabulary element names
* with no attributes, specify false for
* includeAttributes.) The value of this
* parameter SHALL be ignored if
* includeAttributes is false. Note that this
* parameter does not affect which vocabulary
* elements are included in the result; it only
* limits which attributes will be included with
* each vocabulary element.
*/
isMatched = false;
String[] attrArr = attributeNames.split(",");
Set<String> attrSet = new HashSet<String>();
for (int j = 0; j < attrArr.length; j++) {
attrSet.add(attrArr[j].trim());
}
List<AttributeType> atList = vet.getAttribute();
for (int j = 0; j < atList.size(); j++) {
if (attrSet.contains(atList.get(j).getId())) {
isMatched = true;
}
}
}
if (includeChildren == false) {
vet.setChildren(null);
}
}
}
}
if (isMatched == true)
vList.add(vt);
} else {
boolean isMatched = true;
dbObject.remove("_id");
if (includeAttributes == false) {
dbObject.remove("attributes");
} else if (includeAttributes == true && attributeNames != null) {
String[] attrArr = attributeNames.split(",");
Set<String> attrSet = new HashSet<String>();
for (int j = 0; j < attrArr.length; j++) {
attrSet.add(attrArr[j].trim());
}
BsonDocument attrObject = dbObject.get("attributes").asDocument();
isMatched = false;
if (attrObject != null) {
Iterator<String> attrKeys = attrObject.keySet().iterator();
while (attrKeys.hasNext()) {
String attrKey = attrKeys.next();
if (attrSet.contains(attrKey)) {
isMatched = true;
}
}
}
}
if (includeChildren == false) {
dbObject.remove("children");
}
if (isMatched == true) {
retArray.put(dbObject);
}
}
}
if (format == null || format.equals("XML")) {
QueryResultsBody qbt = epcisQueryDocumentType.getEPCISBody().getQueryResults().getResultsBody();
VocabularyListType vlt = new VocabularyListType();
vlt.setVocabulary(vList);
qbt.setVocabularyList(vlt);
}
// M47
if (maxElementCount != null) {
try {
int maxElement = Integer.parseInt(maxElementCount);
if (format == null || format.equals("XML")) {
if (vList.size() > maxElement) {
return makeErrorResult("Too Large Master Data result", QueryTooLargeException.class);
}
} else {
if (retArray.length() > maxElement) {
return makeErrorResult("Too Large Master Data result", QueryTooLargeException.class);
}
}
} catch (NumberFormatException e) {
}
}
if (format == null || format.equals("XML")) {
StringWriter sw = new StringWriter();
JAXB.marshal(epcisQueryDocumentType, sw);
return sw.toString();
} else {
return retArray.toString(1);
}
}
// Soap Service Adaptor
public String poll(String queryName, QueryParams queryParams) {
List<QueryParam> queryParamList = queryParams.getParam();
String eventType = null;
String GE_eventTime = null;
String LT_eventTime = null;
String GE_recordTime = null;
String LT_recordTime = null;
String EQ_action = null;
String EQ_bizStep = null;
String EQ_disposition = null;
String EQ_readPoint = null;
String WD_readPoint = null;
String EQ_bizLocation = null;
String WD_bizLocation = null;
String EQ_transformationID = null;
String MATCH_epc = null;
String MATCH_parentID = null;
String MATCH_inputEPC = null;
String MATCH_outputEPC = null;
String MATCH_anyEPC = null;
String MATCH_epcClass = null;
String MATCH_inputEPCClass = null;
String MATCH_outputEPCClass = null;
String MATCH_anyEPCClass = null;
String EQ_quantity = null;
String GT_quantity = null;
String GE_quantity = null;
String LT_quantity = null;
String LE_quantity = null;
String orderBy = null;
String orderDirection = null;
String eventCountLimit = null;
String maxEventCount = null;
String vocabularyName = null;
boolean includeAttributes = false;
boolean includeChildren = false;
String attributeNames = null;
String EQ_name = null;
String WD_name = null;
String HASATTR = null;
String maxElementCount = null;
Map<String, String> extMap = new HashMap<String, String>();
for (int i = 0; i < queryParamList.size(); i++) {
QueryParam qp = queryParamList.get(i);
String name = qp.getName();
String value = (String) qp.getValue();
if (name.equals("eventType")) {
eventType = value;
continue;
} else if (name.equals("GE_eventTime")) {
GE_eventTime = value;
continue;
} else if (name.equals("LT_eventTime")) {
LT_eventTime = value;
continue;
} else if (name.equals("GE_recordTime")) {
GE_recordTime = value;
continue;
} else if (name.equals("LT_recordTime")) {
LT_recordTime = value;
continue;
} else if (name.equals("EQ_action")) {
EQ_action = value;
continue;
} else if (name.equals("EQ_bizStep")) {
EQ_bizStep = value;
continue;
} else if (name.equals("EQ_disposition")) {
EQ_disposition = value;
continue;
} else if (name.equals("EQ_readPoint")) {
EQ_readPoint = value;
continue;
} else if (name.equals("WD_readPoint")) {
WD_readPoint = value;
continue;
} else if (name.equals("EQ_bizLocation")) {
EQ_bizLocation = value;
continue;
} else if (name.equals("WD_bizLocation")) {
WD_bizLocation = value;
continue;
} else if (name.equals("EQ_transformationID")) {
EQ_transformationID = value;
continue;
} else if (name.equals("MATCH_epc")) {
MATCH_epc = value;
continue;
} else if (name.equals("MATCH_parentID")) {
MATCH_parentID = value;
continue;
} else if (name.equals("MATCH_inputEPC")) {
MATCH_inputEPC = value;
continue;
} else if (name.equals("MATCH_outputEPC")) {
MATCH_outputEPC = value;
continue;
} else if (name.equals("MATCH_anyEPC")) {
MATCH_anyEPC = value;
continue;
} else if (name.equals("MATCH_epcClass")) {
MATCH_epcClass = value;
continue;
} else if (name.equals("MATCH_inputEPCClass")) {
MATCH_inputEPCClass = value;
continue;
} else if (name.equals("MATCH_outputEPCClass")) {
MATCH_outputEPCClass = value;
continue;
} else if (name.equals("MATCH_anyEPCClass")) {
MATCH_anyEPCClass = value;
continue;
} else if (name.equals("EQ_quantity")) {
EQ_quantity = value;
continue;
} else if (name.equals("GT_quantity")) {
GT_quantity = value;
continue;
} else if (name.equals("GE_quantity")) {
GE_quantity = value;
continue;
} else if (name.equals("LT_quantity")) {
LT_quantity = value;
continue;
} else if (name.equals("LE_quantity")) {
LE_quantity = value;
continue;
} else if (name.equals("orderBy")) {
orderBy = value;
continue;
} else if (name.equals("orderDirection")) {
orderDirection = value;
continue;
} else if (name.equals("eventCountLimit")) {
eventCountLimit = value;
continue;
} else if (name.equals("maxEventCount")) {
maxEventCount = value;
continue;
} else if (name.equals("vocabularyName")) {
vocabularyName = value;
continue;
} else if (name.equals("includeAttributes")) {
if (value.equals("true"))
includeAttributes = true;
else
includeAttributes = false;
continue;
} else if (name.equals("includeChildren")) {
if (value.equals("true"))
includeChildren = true;
else
includeChildren = false;
continue;
} else if (name.equals("attributeNames")) {
attributeNames = value;
continue;
} else if (name.equals("EQ_name")) {
EQ_name = value;
continue;
} else if (name.equals("WD_name")) {
WD_name = value;
continue;
} else if (name.equals("HASATTR")) {
HASATTR = value;
continue;
} else if (name.equals("maxElementCount")) {
maxElementCount = value;
continue;
} else {
extMap.put(name, value);
}
}
return poll(queryName, eventType, GE_eventTime, LT_eventTime, GE_recordTime, LT_recordTime, EQ_action,
EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation, WD_bizLocation,
EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC, MATCH_anyEPC,
MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass, EQ_quantity, GT_quantity,
GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection, eventCountLimit, maxEventCount,
vocabularyName, includeAttributes, includeChildren, attributeNames, EQ_name, WD_name, HASATTR,
maxElementCount, null, null, null, extMap);
}
public String poll(@PathVariable String queryName, String eventType, String GE_eventTime, String LT_eventTime,
String GE_recordTime, String LT_recordTime, String EQ_action, String EQ_bizStep, String EQ_disposition,
String EQ_readPoint, String WD_readPoint, String EQ_bizLocation, String WD_bizLocation,
String EQ_transformationID, String MATCH_epc, String MATCH_parentID, String MATCH_inputEPC,
String MATCH_outputEPC, String MATCH_anyEPC, String MATCH_epcClass, String MATCH_inputEPCClass,
String MATCH_outputEPCClass, String MATCH_anyEPCClass, String EQ_quantity, String GT_quantity,
String GE_quantity, String LT_quantity, String LE_quantity, String orderBy, String orderDirection,
String eventCountLimit, String maxEventCount,
String vocabularyName, boolean includeAttributes, boolean includeChildren, String attributeNames,
String EQ_name, String WD_name, String HASATTR, String maxElementCount, String format, String userID,
List<String> friendList, Map<String, String> paramMap) {
// M24
if (queryName == null) {
// It is not possible, automatically filtered by URI param
return makeErrorResult("queryName is mandatory field in poll method", QueryParameterException.class);
}
if (queryName.equals("SimpleEventQuery"))
return pollEventQuery(queryName, eventType, GE_eventTime, LT_eventTime, GE_recordTime, LT_recordTime,
EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint, WD_readPoint, EQ_bizLocation, WD_bizLocation,
EQ_transformationID, MATCH_epc, MATCH_parentID, MATCH_inputEPC, MATCH_outputEPC, MATCH_anyEPC,
MATCH_epcClass, MATCH_inputEPCClass, MATCH_outputEPCClass, MATCH_anyEPCClass, EQ_quantity,
GT_quantity, GE_quantity, LT_quantity, LE_quantity, orderBy, orderDirection, eventCountLimit,
maxEventCount, format, userID, friendList, paramMap);
if (queryName.equals("SimpleMasterDataQuery"))
return pollMasterDataQuery(queryName, vocabularyName, includeAttributes, includeChildren, attributeNames,
EQ_name, WD_name, HASATTR, maxElementCount, format, paramMap);
return "";
}
private String checkConstraintSimpleEventQuery(String queryName, String eventType, String GE_eventTime,
String LT_eventTime, String GE_recordTime, String LT_recordTime, String EQ_action, String EQ_bizStep,
String EQ_disposition, String EQ_readPoint, String WD_readPoint, String EQ_bizLocation,
String WD_bizLocation, String EQ_transformationID, String MATCH_epc, String MATCH_parentID,
String MATCH_inputEPC, String MATCH_outputEPC, String MATCH_anyEPC, String MATCH_epcClass,
String MATCH_inputEPCClass, String MATCH_outputEPCClass, String MATCH_anyEPCClass, String EQ_quantity,
String GT_quantity, String GE_quantity, String LT_quantity, String LE_quantity, String orderBy,
String orderDirection, String eventCountLimit, String maxEventCount, Map<String, String> paramMap) {
// M27
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
if (GE_eventTime != null)
sdf.parse(GE_eventTime);
if (LT_eventTime != null)
sdf.parse(LT_eventTime);
if (GE_recordTime != null)
sdf.parse(GE_recordTime);
if (LT_recordTime != null)
sdf.parse(LT_recordTime);
} catch (ParseException e) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
if (GE_eventTime != null)
sdf.parse(GE_eventTime);
if (LT_eventTime != null)
sdf.parse(LT_eventTime);
if (GE_recordTime != null)
sdf.parse(GE_recordTime);
if (LT_recordTime != null)
sdf.parse(LT_recordTime);
} catch (ParseException e1) {
return makeErrorResult(e.toString(), QueryParameterException.class);
}
}
// M27
if (orderBy != null) {
if (!orderBy.equals("eventTime") && !orderBy.equals("recordTime")) {
return makeErrorResult("orderBy should be eventTime or recordTime", QueryParameterException.class);
}
if (orderDirection != null) {
if (!orderDirection.equals("ASC") && !orderDirection.equals("DESC")) {
return makeErrorResult("orderDirection should be ASC or DESC", QueryParameterException.class);
}
}
}
// M27
if (eventCountLimit != null) {
try {
int c = Integer.parseInt(eventCountLimit);
if (c <= 0) {
return makeErrorResult("eventCount should be natural number", QueryParameterException.class);
}
} catch (NumberFormatException e) {
return makeErrorResult("eventCount: " + e.toString(), QueryParameterException.class);
}
}
// M27
if (maxEventCount != null) {
try {
int c = Integer.parseInt(maxEventCount);
if (c <= 0) {
return makeErrorResult("maxEventCount should be natural number", QueryParameterException.class);
}
} catch (NumberFormatException e) {
return makeErrorResult("maxEventCount: " + e.toString(), QueryParameterException.class);
}
}
// M39
if (EQ_action != null) {
if (!EQ_action.equals("ADD") && !EQ_action.equals("OBSERVE") && !EQ_action.equals("DELETE")) {
return makeErrorResult("EQ_action: ADD | OBSERVE | DELETE", QueryParameterException.class);
}
}
// M42
if (eventCountLimit != null && maxEventCount != null) {
return makeErrorResult("One of eventCountLimit and maxEventCount should be omitted",
QueryParameterException.class);
}
return null;
}
private EPCISQueryDocumentType makeBaseResultDocument(String queryName) {
// Make Base Result Document
EPCISQueryDocumentType epcisQueryDocumentType = new EPCISQueryDocumentType();
EPCISQueryBodyType epcisBody = new EPCISQueryBodyType();
epcisQueryDocumentType.setEPCISBody(epcisBody);
QueryResults queryResults = new QueryResults();
queryResults.setQueryName(queryName);
epcisBody.setQueryResults(queryResults);
QueryResultsBody queryResultsBody = new QueryResultsBody();
queryResults.setResultsBody(queryResultsBody);
EventListType eventListType = new EventListType();
queryResultsBody.setEventList(eventListType);
// Object instanceof JAXBElement
List<Object> eventObjects = new ArrayList<Object>();
eventListType.setObjectEventOrAggregationEventOrQuantityEvent(eventObjects);
return epcisQueryDocumentType;
}
boolean isExtraParameter(String paramName) {
if (paramName.contains("eventTime"))
return false;
if (paramName.contains("recordTime"))
return false;
if (paramName.contains("action"))
return false;
if (paramName.contains("bizStep"))
return false;
if (paramName.contains("disposition"))
return false;
if (paramName.contains("readPoint"))
return false;
if (paramName.contains("bizLocation"))
return false;
if (paramName.contains("bizTransaction"))
return false;
if (paramName.contains("source"))
return false;
if (paramName.contains("destination"))
return false;
if (paramName.contains("transformationID"))
return false;
return true;
}
public void addScheduleToQuartz(SubscriptionType subscription) {
try {
JobDataMap map = new JobDataMap();
map.put("queryName", subscription.getQueryName());
map.put("subscriptionID", subscription.getSubscriptionID());
map.put("dest", subscription.getDest());
map.put("cronExpression", subscription.getCronExpression());
map.put("initialRecordTime", subscription.getInitialRecordTime());
map.put("ignoreReceivedEvent", subscription.isIgnoreReceivedEvent());
map.put("reportIfEmpty", subscription.isReportIfEmpty());
if (subscription.getEventType() != null)
map.put("eventType", subscription.getEventType());
if (subscription.getGE_eventTime() != null)
map.put("GE_eventTime", subscription.getGE_eventTime());
if (subscription.getLT_eventTime() != null)
map.put("LT_eventTime", subscription.getLT_eventTime());
if (subscription.getGE_recordTime() != null)
map.put("GE_recordTime", subscription.getGE_recordTime());
if (subscription.getLT_recordTime() != null)
map.put("LT_recordTime", subscription.getLT_recordTime());
if (subscription.getEQ_action() != null)
map.put("EQ_action", subscription.getEQ_action());
if (subscription.getEQ_bizStep() != null)
map.put("EQ_bizStep", subscription.getEQ_bizStep());
if (subscription.getEQ_disposition() != null)
map.put("EQ_disposition", subscription.getEQ_disposition());
if (subscription.getEQ_readPoint() != null)
map.put("EQ_readPoint", subscription.getEQ_readPoint());
if (subscription.getWD_readPoint() != null)
map.put("WD_readPoint", subscription.getWD_readPoint());
if (subscription.getEQ_bizLocation() != null)
map.put("EQ_bizLocation", subscription.getEQ_bizLocation());
if (subscription.getWD_bizLocation() != null)
map.put("WD_bizLocation", subscription.getWD_bizLocation());
if (subscription.getEQ_transformationID() != null)
map.put("EQ_transformationID", subscription.getEQ_transformationID());
if (subscription.getMATCH_epc() != null)
map.put("MATCH_epc", subscription.getMATCH_epc());
if (subscription.getMATCH_parentID() != null)
map.put("MATCH_parentID", subscription.getMATCH_parentID());
if (subscription.getMATCH_inputEPC() != null)
map.put("MATCH_inputEPC", subscription.getMATCH_inputEPC());
if (subscription.getMATCH_outputEPC() != null)
map.put("MATCH_outputEPC", subscription.getMATCH_outputEPC());
if (subscription.getMATCH_anyEPC() != null)
map.put("MATCH_anyEPC", subscription.getMATCH_anyEPC());
if (subscription.getMATCH_epcClass() != null)
map.put("MATCH_epcClass", subscription.getMATCH_epcClass());
if (subscription.getMATCH_inputEPCClass() != null)
map.put("MATCH_inputEPCClass", subscription.getMATCH_inputEPCClass());
if (subscription.getMATCH_outputEPCClass() != null)
map.put("MATCH_outputEPCClass", subscription.getMATCH_outputEPCClass());
if (subscription.getMATCH_anyEPCClass() != null)
map.put("MATCH_anyEPCClass", subscription.getMATCH_anyEPCClass());
if (subscription.getEQ_quantity() != null)
map.put("EQ_quantity", subscription.getEQ_quantity());
if (subscription.getGT_quantity() != null)
map.put("GT_quantity", subscription.getGT_quantity());
if (subscription.getGE_quantity() != null)
map.put("GE_quantity", subscription.getGE_quantity());
if (subscription.getLT_quantity() != null)
map.put("LT_quantity", subscription.getLT_quantity());
if (subscription.getLE_quantity() != null)
map.put("LE_quantity", subscription.getLE_quantity());
if (subscription.getOrderBy() != null)
map.put("orderBy", subscription.getOrderBy());
if (subscription.getOrderDirection() != null)
map.put("orderDirection", subscription.getOrderDirection());
if (subscription.getEventCountLimit() != null)
map.put("eventCountLimit", subscription.getEventCountLimit());
if (subscription.getMaxEventCount() != null)
map.put("maxEventCount", subscription.getMaxEventCount());
if (subscription.getFormat() != null)
map.put("format", subscription.getFormat());
if (subscription.getParamMap() != null)
map.put("paramMap", subscription.getParamMap());
JobDetail job = newJob(MongoSubscriptionTask.class)
.withIdentity(subscription.getSubscriptionID(), subscription.getQueryName()).setJobData(map)
.storeDurably(false).build();
Trigger trigger = newTrigger().withIdentity(subscription.getSubscriptionID(), subscription.getQueryName())
.startNow().withSchedule(cronSchedule(subscription.getCronExpression())).build();
// ClassPathXmlApplicationContext context = new
// ClassPathXmlApplicationContext(
// "classpath:QuartzConfig.xml");
// Scheduler sched = (Scheduler) context
// .getBean("schedulerFactoryBean");
if (MongoSubscription.sched.isStarted() != true)
MongoSubscription.sched.start();
MongoSubscription.sched.scheduleJob(job, trigger);
Configuration.logger.log(Level.INFO,
"Subscription ID: " + subscription.getSubscriptionID() + " is added to quartz scheduler. ");
} catch (SchedulerException e) {
Configuration.logger.log(Level.ERROR, e.toString());
} catch (RuntimeException e) {
Configuration.logger.log(Level.ERROR, e.toString());
}
}
private void addScheduleToQuartz(String queryName, String subscriptionID, String dest, String cronExpression,
boolean isScheduledSubscription, boolean ignoreReceivedEvent, boolean reportIfEmpty,
String initialRecordTimeStr, String eventType, String GE_eventTime, String LT_eventTime,
String GE_recordTime, String LT_recordTime, String EQ_action, String EQ_bizStep, String EQ_disposition,
String EQ_readPoint, String WD_readPoint, String EQ_bizLocation, String WD_bizLocation,
String EQ_transformationID, String MATCH_epc, String MATCH_parentID, String MATCH_inputEPC,
String MATCH_outputEPC, String MATCH_anyEPC, String MATCH_epcClass, String MATCH_inputEPCClass,
String MATCH_outputEPCClass, String MATCH_anyEPCClass, String EQ_quantity, String GT_quantity,
String GE_quantity, String LT_quantity, String LE_quantity, String orderBy, String orderDirection,
String eventCountLimit, String maxEventCount, String format, Map<String, String> paramMap) {
try {
JobDataMap map = new JobDataMap();
map.put("queryName", queryName);
map.put("subscriptionID", subscriptionID);
map.put("dest", dest);
map.put("isScheduledSubscription", isScheduledSubscription);
map.put("ignoreReceivedEvent", ignoreReceivedEvent);
map.put("cronExpression", cronExpression);
map.put("reportIfEmpty", reportIfEmpty);
map.put("initialRecordTime", initialRecordTimeStr);
if (eventType != null)
map.put("eventType", eventType);
if (GE_eventTime != null)
map.put("GE_eventTime", GE_eventTime);
if (LT_eventTime != null)
map.put("LT_eventTime", LT_eventTime);
if (GE_recordTime != null)
map.put("GE_recordTime", GE_recordTime);
if (LT_recordTime != null)
map.put("LT_recordTime", LT_recordTime);
if (EQ_action != null)
map.put("EQ_action", EQ_action);
if (EQ_bizStep != null)
map.put("EQ_bizStep", EQ_bizStep);
if (EQ_disposition != null)
map.put("EQ_disposition", EQ_disposition);
if (EQ_readPoint != null)
map.put("EQ_readPoint", EQ_readPoint);
if (WD_readPoint != null)
map.put("WD_readPoint", WD_readPoint);
if (EQ_bizLocation != null)
map.put("EQ_bizLocation", EQ_bizLocation);
if (WD_bizLocation != null)
map.put("WD_bizLocation", WD_bizLocation);
if (EQ_transformationID != null)
map.put("EQ_transformationID", EQ_transformationID);
if (MATCH_epc != null)
map.put("MATCH_epc", MATCH_epc);
if (MATCH_parentID != null)
map.put("MATCH_parentID", MATCH_parentID);
if (MATCH_inputEPC != null)
map.put("MATCH_inputEPC", MATCH_inputEPC);
if (MATCH_outputEPC != null)
map.put("MATCH_outputEPC", MATCH_outputEPC);
if (MATCH_anyEPC != null)
map.put("MATCH_anyEPC", MATCH_anyEPC);
if (MATCH_epcClass != null)
map.put("MATCH_epcClass", MATCH_epcClass);
if (MATCH_inputEPCClass != null)
map.put("MATCH_inputEPCClass", MATCH_inputEPCClass);
if (MATCH_outputEPCClass != null)
map.put("MATCH_outputEPCClass", MATCH_outputEPCClass);
if (MATCH_anyEPCClass != null)
map.put("MATCH_anyEPCClass", MATCH_anyEPCClass);
if (EQ_quantity != null)
map.put("EQ_quantity", EQ_quantity);
if (GT_quantity != null)
map.put("GT_quantity", GT_quantity);
if (GE_quantity != null)
map.put("GE_quantity", GE_quantity);
if (LT_quantity != null)
map.put("LT_quantity", LT_quantity);
if (LE_quantity != null)
map.put("LE_quantity", LE_quantity);
if (orderBy != null)
map.put("orderBy", orderBy);
if (orderDirection != null)
map.put("orderDirection", orderDirection);
if (eventCountLimit != null)
map.put("eventCountLimit", eventCountLimit);
if (maxEventCount != null)
map.put("maxEventCount", maxEventCount);
if (format != null)
map.put("format", format);
if (paramMap != null)
map.put("paramMap", paramMap);
JobDetail job = newJob(MongoSubscriptionTask.class).withIdentity(subscriptionID, queryName).setJobData(map)
.storeDurably(false).build();
Trigger trigger = newTrigger().withIdentity(subscriptionID, queryName).startNow()
.withSchedule(cronSchedule(cronExpression)).build();
// ClassPathXmlApplicationContext context = new
// ClassPathXmlApplicationContext(
// "classpath:QuartzConfig.xml");
// Scheduler sched = (Scheduler) context
// .getBean("schedulerFactoryBean");
if (MongoSubscription.sched.isStarted() != true)
MongoSubscription.sched.start();
MongoSubscription.sched.scheduleJob(job, trigger);
Configuration.logger.log(Level.INFO,
"Subscription ID: " + subscriptionID + " is added to quartz scheduler. ");
} catch (SchedulerException e) {
Configuration.logger.log(Level.ERROR, e.toString());
}
}
private boolean addScheduleToDB(String queryName, String subscriptionID, String dest, String cronExpression,
boolean isScheduledSubscription, boolean ignoreReceivedEvent, boolean reportIfEmpty,
String initialRecordTime, String eventType, String GE_eventTime, String LT_eventTime, String GE_recordTime,
String LT_recordTime, String EQ_action, String EQ_bizStep, String EQ_disposition, String EQ_readPoint,
String WD_readPoint, String EQ_bizLocation, String WD_bizLocation, String EQ_transformationID,
String MATCH_epc, String MATCH_parentID, String MATCH_inputEPC, String MATCH_outputEPC, String MATCH_anyEPC,
String MATCH_epcClass, String MATCH_inputEPCClass, String MATCH_outputEPCClass, String MATCH_anyEPCClass,
String EQ_quantity, String GT_quantity, String GE_quantity, String LT_quantity, String LE_quantity,
String orderBy, String orderDirection, String eventCountLimit, String maxEventCount, String format,
Map<String, String> paramMap) {
SubscriptionType st = new SubscriptionType(queryName, subscriptionID, dest, cronExpression,
isScheduledSubscription, ignoreReceivedEvent, reportIfEmpty, initialRecordTime, eventType, GE_eventTime,
LT_eventTime, GE_recordTime, LT_recordTime, EQ_action, EQ_bizStep, EQ_disposition, EQ_readPoint,
WD_readPoint, EQ_bizLocation, WD_bizLocation, EQ_transformationID, MATCH_epc, MATCH_parentID,
MATCH_inputEPC, MATCH_outputEPC, MATCH_anyEPC, MATCH_epcClass, MATCH_inputEPCClass,
MATCH_outputEPCClass, MATCH_anyEPCClass, EQ_quantity, GT_quantity, GE_quantity, LT_quantity,
LE_quantity, orderBy, orderDirection, eventCountLimit, maxEventCount, format, paramMap);
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("Subscription",
BsonDocument.class);
BsonDocument subscription = collection.find(new BsonDocument("subscriptionID", new BsonString(subscriptionID)))
.first();
if (subscription == null) {
collection.insertOne(SubscriptionType.asBsonDocument(st));
}
Configuration.logger.log(Level.INFO, "Subscription ID: " + subscriptionID + " is added to DB. ");
return true;
}
private void removeScheduleFromQuartz(SubscriptionType subscription) {
try {
MongoSubscription.sched
.unscheduleJob(triggerKey(subscription.getSubscriptionID(), subscription.getQueryName()));
MongoSubscription.sched.deleteJob(jobKey(subscription.getSubscriptionID(), subscription.getQueryName()));
Configuration.logger.log(Level.INFO,
"Subscription ID: " + subscription.getSubscriptionID() + " is removed from scheduler");
} catch (SchedulerException e) {
Configuration.logger.log(Level.ERROR, e.toString());
}
}
@SuppressWarnings("unused")
private void removeScheduleFromDB(SubscriptionType subscription) {
MongoCollection<BsonDocument> collection = Configuration.mongoDatabase.getCollection("Subscription",
BsonDocument.class);
collection.deleteOne(new BsonDocument("subscriptionID", new BsonString(subscription.getSubscriptionID())));
Configuration.logger.log(Level.INFO,
"Subscription ID: " + subscription.getSubscriptionID() + " is removed from DB");
}
@SuppressWarnings("rawtypes")
private String makeErrorResult(String err, Class type) {
if (type == InvalidURIException.class) {
InvalidURIException e = new InvalidURIException();
e.setReason(err);
EPCISQueryDocumentType retDoc = new EPCISQueryDocumentType();
EPCISQueryBodyType retBody = new EPCISQueryBodyType();
retBody.setInvalidURIException(e);
retDoc.setEPCISBody(retBody);
StringWriter sw = new StringWriter();
JAXB.marshal(retDoc, sw);
return sw.toString();
}
if (type == QueryParameterException.class) {
QueryParameterException e = new QueryParameterException();
e.setReason(err);
EPCISQueryDocumentType retDoc = new EPCISQueryDocumentType();
EPCISQueryBodyType retBody = new EPCISQueryBodyType();
retBody.setQueryParameterException(e);
retDoc.setEPCISBody(retBody);
StringWriter sw = new StringWriter();
JAXB.marshal(retDoc, sw);
return sw.toString();
}
if (type == SubscriptionControlsException.class) {
SubscriptionControlsException e = new SubscriptionControlsException();
e.setReason(err);
EPCISQueryDocumentType retDoc = new EPCISQueryDocumentType();
EPCISQueryBodyType retBody = new EPCISQueryBodyType();
retBody.setSubscriptionControlsException(e);
retDoc.setEPCISBody(retBody);
StringWriter sw = new StringWriter();
JAXB.marshal(retDoc, sw);
return sw.toString();
}
if (type == QueryTooLargeException.class) {
QueryTooLargeException e = new QueryTooLargeException();
e.setReason(err);
EPCISQueryDocumentType retDoc = new EPCISQueryDocumentType();
EPCISQueryBodyType retBody = new EPCISQueryBodyType();
retBody.setQueryTooLargeException(e);
retDoc.setEPCISBody(retBody);
StringWriter sw = new StringWriter();
JAXB.marshal(retDoc, sw);
return sw.toString();
}
if (type == SubscribeNotPermittedException.class) {
SubscribeNotPermittedException e = new SubscribeNotPermittedException();
e.setReason(err);
EPCISQueryDocumentType retDoc = new EPCISQueryDocumentType();
EPCISQueryBodyType retBody = new EPCISQueryBodyType();
retBody.setSubscribeNotPermittedException(e);
retDoc.setEPCISBody(retBody);
StringWriter sw = new StringWriter();
JAXB.marshal(retDoc, sw);
return sw.toString();
}
return null;
}
private FindIterable<BsonDocument> makeSortedLimitedCursor(FindIterable<BsonDocument> cursor, String orderBy,
String orderDirection, String eventCountLimit) {
/**
* orderBy : If specified, names a single field that will be used to
* order the results. The orderDirection field specifies whether the
* ordering is in ascending sequence or descending sequence. Events
* included in the result that lack the specified field altogether may
* occur in any position within the result event list. The value of this
* parameter SHALL be one of: eventTime, recordTime, or the fully
* qualified name of an extension field whose type is Int, Float, Time,
* or String. A fully qualified fieldname is constructed as for the
* EQ_fieldname parameter. In the case of a field of type String, the
* ordering SHOULD be in lexicographic order based on the Unicode
* encoding of the strings, or in some other collating sequence
* appropriate to the locale. If omitted, no order is specified. The
* implementation MAY order the results in any order it chooses, and
* that order MAY differ even when the same query is executed twice on
* the same data. (In EPCIS 1.0, the value quantity was also permitted,
* but its use is deprecated in EPCIS 1.1.)
*
* orderDirection : If specified and orderBy is also specified,
* specifies whether the results are ordered in ascending or descending
* sequence according to the key specified by orderBy. The value of this
* parameter must be one of ASC (for ascending order) or DESC (for
* descending order); if not, the implementation SHALL raise a
* QueryParameterException. If omitted, defaults to DESC.
*/
// Update Query with ORDER and LIMIT
if (orderBy != null) {
// Currently only eventTime, recordTime can be used
if (orderBy.trim().equals("eventTime")) {
if (orderDirection != null) {
if (orderDirection.trim().equals("ASC")) {
cursor = cursor.sort(new BsonDocument("eventTime", new BsonInt32(1)));
} else if (orderDirection.trim().equals("DESC")) {
cursor = cursor.sort(new BsonDocument("eventTime", new BsonInt32(-1)));
}
}
} else if (orderBy.trim().equals("recordTime")) {
if (orderDirection != null) {
if (orderDirection.trim().equals("ASC")) {
cursor = cursor.sort(new BsonDocument("recordTime", new BsonInt32(1)));
} else if (orderDirection.trim().equals("DESC")) {
cursor = cursor.sort(new BsonDocument("recordTime", new BsonInt32(-1)));
}
}
}
}
/**
* eventCountLimit: If specified, the results will only include the
* first N events that match the other criteria, where N is the value of
* this parameter. The ordering specified by the orderBy and
* orderDirection parameters determine the meaning of “first” for this
* purpose. If omitted, all events matching the specified criteria will
* be included in the results. This parameter and maxEventCount are
* mutually exclusive; if both are specified, a QueryParameterException
* SHALL be raised. This parameter may only be used when orderBy is
* specified; if orderBy is omitted and eventCountLimit is specified, a
* QueryParameterException SHALL be raised. This parameter differs from
* maxEventCount in that this parameter limits the amount of data
* returned, whereas maxEventCount causes an exception to be thrown if
* the limit is exceeded.
*/
if (eventCountLimit != null) {
try {
int eventCount = Integer.parseInt(eventCountLimit);
cursor = cursor.limit(eventCount);
} catch (NumberFormatException nfe) {
Configuration.logger.log(Level.ERROR, nfe.toString());
}
}
return cursor;
}
private BsonArray makeQueryObjects(String eventType, String GE_eventTime, String LT_eventTime, String GE_recordTime,
String LT_recordTime, String EQ_action, String EQ_bizStep, String EQ_disposition, String EQ_readPoint,
String WD_readPoint, String EQ_bizLocation, String WD_bizLocation, String EQ_transformationID,
String MATCH_epc, String MATCH_parentID, String MATCH_inputEPC, String MATCH_outputEPC, String MATCH_anyEPC,
String MATCH_epcClass, String MATCH_inputEPCClass, String MATCH_outputEPCClass, String MATCH_anyEPCClass,
String EQ_quantity, String GT_quantity, String GE_quantity, String LT_quantity, String LE_quantity,
String orderBy, String orderDirection, String eventCountLimit, String maxEventCount,
Map<String, String> paramMap) {
BsonArray queryList = new BsonArray();
/**
* GE_eventTime: If specified, only events with eventTime greater than
* or equal to the specified value will be included in the result. If
* omitted, events are included regardless of their eventTime (unless
* constrained by the LT_eventTime parameter). Example:
* 2014-08-11T19:57:59.717+09:00 SimpleDateFormat sdf = new
* SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
* eventTime.setTime(sdf.parse(timeString)); e.g.
* 1988-07-04T12:08:56.235-07:00
*
* Verified
*/
if (GE_eventTime != null) {
long geEventTimeMillis = getTimeMillis(GE_eventTime);
BsonDocument query = new BsonDocument();
query.put("eventTime", new BsonDocument("$gte", new BsonInt64(geEventTimeMillis)));
queryList.add(query);
}
/**
* LT_eventTime: If specified, only events with eventTime less than the
* specified value will be included in the result. If omitted, events
* are included regardless of their eventTime (unless constrained by the
* GE_eventTime parameter).
*
* Verified
*/
if (LT_eventTime != null) {
long ltEventTimeMillis = getTimeMillis(LT_eventTime);
BsonDocument query = new BsonDocument();
query.put("eventTime", new BsonDocument("$lt", new BsonInt64(ltEventTimeMillis)));
queryList.add(query);
}
/**
* GE_recordTime: If provided, only events with recordTime greater than
* or equal to the specified value will be returned. The automatic
* limitation based on event record time (Section 8.2.5.2) may
* implicitly provide a constraint similar to this parameter. If
* omitted, events are included regardless of their recordTime, other
* than automatic limitation based on event record time (Section
* 8.2.5.2).
*
* Verified
*/
if (GE_recordTime != null) {
long geRecordTimeMillis = getTimeMillis(GE_recordTime);
BsonDocument query = new BsonDocument();
query.put("recordTime", new BsonDocument("$gte", new BsonInt64(geRecordTimeMillis)));
queryList.add(query);
}
/**
* LE_recordTime: If provided, only events with recordTime less than the
* specified value will be returned. If omitted, events are included
* regardless of their recordTime (unless constrained by the
* GE_recordTime parameter or the automatic limitation based on event
* record time).
*
* Verified
*/
if (LT_recordTime != null) {
long ltRecordTimeMillis = getTimeMillis(LT_recordTime);
BsonDocument query = new BsonDocument();
query.put("recordTime", new BsonDocument("$lt", new BsonInt64(ltRecordTimeMillis)));
queryList.add(query);
}
/**
* EQ_action: If specified, the result will only include events that (a)
* have an action field; and where (b) the value of the action field
* matches one of the specified values. The elements of the value of
* this parameter each must be one of the strings ADD, OBSERVE, or
* DELETE; if not, the implementation SHALL raise a
* QueryParameterException. If omitted, events are included regardless
* of their action field.
*
* Verified
*/
if (EQ_action != null) {
// Constrained already checked
BsonDocument query = new BsonDocument();
query.put("action", new BsonString(EQ_action));
queryList.add(query);
}
/**
* EQ_bizStep: If specified, the result will only include events that
* (a) have a non-null bizStep field; and where (b) the value of the
* bizStep field matches one of the specified values. If this parameter
* is omitted, events are returned regardless of the value of the
* bizStep field or whether the bizStep field exists at all.
*
* Verified
*/
if (EQ_bizStep != null) {
BsonDocument query = getINQueryObject("bizStep", EQ_bizStep);
if (query != null)
queryList.add(query);
}
/**
* EQ_disposition: Like the EQ_bizStep parameter, but for the
* disposition field.
*
* Verified
*/
if (EQ_disposition != null) {
BsonDocument query = getINQueryObject("disposition", EQ_disposition);
if (query != null)
queryList.add(query);
}
/**
* EQ_readPoint: If specified, the result will only include events that
* (a) have a non-null readPoint field; and where (b) the value of the
* readPoint field matches one of the specified values. If this
* parameter and WD_readPoint are both omitted, events are returned
* regardless of the value of the readPoint field or whether the
* readPoint field exists at all.
*/
Set<String> readPointSet = new HashSet<String>();
if (EQ_readPoint != null) {
String[] eqArr = EQ_readPoint.split(",");
for (int i = 0; i < eqArr.length; i++) {
String eqString = eqArr[i].trim();
readPointSet.add(eqString);
}
}
/**
* WD_readPoint: If specified, the result will only include events that
* (a) have a non-null readPoint field; and where (b) the value of the
* readPoint field matches one of the specified values, or is a direct
* or indirect descendant of one of the specified values. The meaning of
* “direct or indirect descendant” is specified by master data, as
* described in Section 6.5. (WD is an abbreviation for “with
* descendants.”) If this parameter and EQ_readPoint are both omitted,
* events are returned regardless of the value of the readPoint field or
* whether the readPoint field exists at all.
*/
if (WD_readPoint != null) {
String[] eqArr = WD_readPoint.split(",");
for (int i = 0; i < eqArr.length; i++) {
eqArr[i] = eqArr[i].trim();
}
for (int i = 0; i < eqArr.length; i++) {
// Invoke vocabulary query with EQ_name and includeChildren
readPointSet = getWDList(readPointSet, eqArr[i]);
}
}
if (!readPointSet.isEmpty()) {
BsonDocument query = getINQueryObject("readPoint.id", readPointSet);
if (query != null)
queryList.add(query);
}
/**
* EQ_bizLocation: Like the EQ_readPoint parameter, but for the
* bizLocation field.
*/
Set<String> bizLocationSet = new HashSet<String>();
if (EQ_bizLocation != null) {
String[] eqArr = EQ_bizLocation.split(",");
for (int i = 0; i < eqArr.length; i++) {
String eqString = eqArr[i].trim();
bizLocationSet.add(eqString);
}
}
/**
* WD_bizLocation: Like the WD_readPoint parameter, but for the
* bizLocation field.
*/
if (WD_bizLocation != null) {
String[] eqArr = WD_bizLocation.split(",");
for (int i = 0; i < eqArr.length; i++) {
eqArr[i] = eqArr[i].trim();
}
for (int i = 0; i < eqArr.length; i++) {
// Invoke vocabulary query with EQ_name and includeChildren
bizLocationSet = getWDList(bizLocationSet, eqArr[i]);
}
}
if (!bizLocationSet.isEmpty()) {
BsonDocument query = getINQueryObject("bizLocation.id", bizLocationSet);
if (query != null)
queryList.add(query);
}
/**
* EQ_transformationID: If this parameter is specified, the result will
* only include events that (a) have a transformationID field (that is,
* TransformationEvents or extension event type that extend
* TransformationEvent); and where (b) the transformationID field is
* equal to one of the values specified in this parameter.
*/
if (EQ_transformationID != null) {
BsonDocument query = getINQueryObject("transformationID", EQ_transformationID);
if (query != null)
queryList.add(query);
}
/**
* MATCH_epc: If this parameter is specified, the result will only
* include events that (a) have an epcList or a childEPCs field (that
* is, ObjectEvent, AggregationEvent, TransactionEvent or extension
* event types that extend one of those three); and where (b) one of the
* EPCs listed in the epcList or childEPCs field (depending on event
* type) matches one of the EPC patterns or URIs specified in this
* parameter, where the meaning of “matches” is as specified in Section
* 8.2.7.1.1. If this parameter is omitted, events are included
* regardless of their epcList or childEPCs field or whether the epcList
* or childEPCs field exists.
*
* Somewhat verified
*/
if (MATCH_epc != null) {
BsonDocument query = getINQueryObject(new String[] { "epcList.epc", "childEPCs.epc" }, MATCH_epc);
if (query != null)
queryList.add(query);
}
/**
* MATCH_parentID: Like MATCH_epc, but matches the parentID field of
* AggregationEvent, the parentID field of TransactionEvent, and
* extension event types that extend either AggregationEvent or
* TransactionEvent. The meaning of “matches” is as specified in Section
* 8.2.7.1.1.
*/
if (MATCH_parentID != null) {
BsonDocument query = getINQueryObject("parentID", MATCH_parentID);
if (query != null)
queryList.add(query);
}
/**
* MATCH_inputEPC: If this parameter is specified, the result will only
* include events that (a) have an inputEPCList (that is,
* TransformationEvent or an extension event type that extends
* TransformationEvent); and where (b) one of the EPCs listed in the
* inputEPCList field matches one of the EPC patterns or URIs specified
* in this parameter. The meaning of “matches” is as specified in
* Section 8.2.7.1.1. If this parameter is omitted, events are included
* regardless of their inputEPCList field or whether the inputEPCList
* field exists.
*/
if (MATCH_inputEPC != null) {
BsonDocument query = getINQueryObject("inputEPCList.epc", MATCH_inputEPC);
if (query != null)
queryList.add(query);
}
/**
* MATCH_outputEPC: If this parameter is specified, the result will only
* include events that (a) have an inputEPCList (that is,
* TransformationEvent or an extension event type that extends
* TransformationEvent); and where (b) one of the EPCs listed in the
* inputEPCList field matches one of the EPC patterns or URIs specified
* in this parameter. The meaning of “matches” is as specified in
* Section 8.2.7.1.1. If this parameter is omitted, events are included
* regardless of their inputEPCList field or whether the inputEPCList
* field exists.
*/
if (MATCH_outputEPC != null) {
BsonDocument query = getINQueryObject("outputEPCList.epc", MATCH_outputEPC);
if (query != null)
queryList.add(query);
}
/**
* MATCH_anyEPC: If this parameter is specified, the result will only
* include events that (a) have an epcList field, a childEPCs field, a
* parentID field, an inputEPCList field, or an outputEPCList field
* (that is, ObjectEvent, AggregationEvent, TransactionEvent,
* TransformationEvent, or extension event types that extend one of
* those four); and where (b) the parentID field or one of the EPCs
* listed in the epcList, childEPCs, inputEPCList, or outputEPCList
* field (depending on event type) matches one of the EPC patterns or
* URIs specified in this parameter. The meaning of “matches” is as
* specified in Section 8.2.7.1.1.
*/
if (MATCH_anyEPC != null) {
BsonDocument query = getINQueryObject(new String[] { "epcList.epc", "childEPCs.epc", "inputEPCList.epc",
"outputEPCList.epc", "parentID" }, MATCH_anyEPC);
if (query != null)
queryList.add(query);
}
/**
* MATCH_epcClass: If this parameter is specified, the result will only
* include events that (a) have a quantityList or a childQuantityList
* field (that is, ObjectEvent, AggregationEvent, TransactionEvent or
* extension event types that extend one of those three); and where (b)
* one of the EPC classes listed in the quantityList or
* childQuantityList field (depending on event type) matches one of the
* EPC patterns or URIs specified in this parameter. The result will
* also include QuantityEvents whose epcClass field matches one of the
* EPC patterns or URIs specified in this parameter. The meaning of
* “matches” is as specified in Section 8.2.7.1.1.
*/
if (MATCH_epcClass != null) {
BsonDocument query = getINQueryObject(
new String[] { "extension.quantityList.epcClass", "extension.childQuantityList.epcClass" },
MATCH_epcClass);
if (query != null)
queryList.add(query);
}
/**
* MATCH_inputEPCClass: If this parameter is specified, the result will
* only include events that (a) have an inputQuantityList field (that
* is, TransformationEvent or extension event types that extend it); and
* where (b) one of the EPC classes listed in the inputQuantityList
* field (depending on event type) matches one of the EPC patterns or
* URIs specified in this parameter. The meaning of “matches” is as
* specified in Section 8.2.7.1.1.
*/
if (MATCH_inputEPCClass != null) {
BsonDocument query = getINQueryObject("inputQuantityList.epcClass", MATCH_inputEPCClass);
if (query != null)
queryList.add(query);
}
/**
* MATCH_outputEPCClass: If this parameter is specified, the result will
* only include events that (a) have an outputQuantityList field (that
* is, TransformationEvent or extension event types that extend it); and
* where (b) one of the EPC classes listed in the outputQuantityList
* field (depending on event type) matches one of the EPC patterns or
* URIs specified in this parameter. The meaning of “matches” is as
* specified in Section 8.2.7.1.1.
*/
if (MATCH_outputEPCClass != null) {
BsonDocument query = getINQueryObject("outputQuantityList.epcClass", MATCH_outputEPCClass);
if (query != null)
queryList.add(query);
}
/**
* MATCH_anyEPCClass: If this parameter is specified, the result will
* only include events that (a) have a quantityList, childQuantityList,
* inputQuantityList, or outputQuantityList field (that is, ObjectEvent,
* AggregationEvent, TransactionEvent, TransformationEvent, or extension
* event types that extend one of those four); and where (b) one of the
* EPC classes listed in any of those fields matches one of the EPC
* patterns or URIs specified in this parameter. The result will also
* include QuantityEvents whose epcClass field matches one of the EPC
* patterns or URIs specified in this parameter. The meaning of
* “matches” is as specified in Section 8.2.7.1.1.
*/
if (MATCH_anyEPCClass != null) {
BsonDocument query = getINQueryObject(
new String[] { "extension.quantityList.epcClass", "extension.childQuantityList.epcClass",
"inputQuantityList.epcClass", "outputQuantityList.epcClass" },
MATCH_anyEPCClass);
if (query != null)
queryList.add(query);
}
/**
* (DEPCRECATED in EPCIS 1.1) EQ_quantity; GT_quantity; GE_quantity;
* LT_quantity; LE_quantity
**/
/**
* EQ_fieldname: This is not a single parameter, but a family of
* parameters. If a parameter of this form is specified, the result will
* only include events that (a) have a field named fieldname whose type
* is either String or a vocabulary type; and where (b) the value of
* that field matches one of the values specified in this parameter.
* Fieldname is the fully qualified name of an extension field. The name
* of an extension field is an XML qname; that is, a pair consisting of
* an XML namespace URI and a name. The name of the corresponding query
* parameter is constructed by concatenating the following: the string
* EQ_, the namespace URI for the extension field, a pound sign (#), and
* the name of the extension field.
*/
Iterator<String> paramIter = paramMap.keySet().iterator();
while (paramIter.hasNext()) {
String paramName = paramIter.next();
String paramValues = paramMap.get(paramName);
/**
* EQ_bizTransaction_type: This is not a single parameter, but a
* family of parameters. If a parameter of this form is specified,
* the result will only include events that (a) include a
* bizTransactionList; (b) where the business transaction list
* includes an entry whose type subfield is equal to type extracted
* from the name of this parameter; and (c) where the bizTransaction
* subfield of that entry is equal to one of the values specified in
* this parameter.
*/
if (paramName.contains("EQ_bizTransaction_")) {
String type = paramName.substring(18, paramName.length());
BsonDocument query = getINFamilyQueryObject(type, "bizTransactionList", paramValues);
if (query != null)
queryList.add(query);
}
/**
* EQ_source_type: This is not a single parameter, but a family of
* parameters. If a parameter of this form is specified, the result
* will only include events that (a) include a sourceList; (b) where
* the source list includes an entry whose type subfield is equal to
* type extracted from the name of this parameter; and (c) where the
* source subfield of that entry is equal to one of the values
* specified in this parameter.
*/
if (paramName.contains("EQ_source_")) {
String type = paramName.substring(10, paramName.length());
if (eventType.equals("AggregationEvent") || eventType.equals("ObjectEvent")
|| eventType.equals("TransactionEvent")) {
BsonDocument query = getINFamilyQueryObject(type, "extension.sourceList", paramValues);
if (query != null)
queryList.add(query);
}
if (eventType.equals("TransformationEvent")) {
BsonDocument query = getINFamilyQueryObject(type, "sourceList", paramValues);
if (query != null)
queryList.add(query);
}
}
/**
* EQ_destination_type: This is not a single parameter, but a family
* of parameters. If a parameter of this form is specified, the
* result will only include events that (a) include a
* destinationList; (b) where the destination list includes an entry
* whose type subfield is equal to type extracted from the name of
* this parameter; and (c) where the destination subfield of that
* entry is equal to one of the values specified in this parameter.
*/
if (paramName.contains("EQ_destination_")) {
String type = paramName.substring(15, paramName.length());
if (eventType.equals("AggregationEvent") || eventType.equals("ObjectEvent")
|| eventType.equals("TransactionEvent")) {
BsonDocument query = getINFamilyQueryObject(type, "extension.destinationList", paramValues);
if (query != null)
queryList.add(query);
}
if (eventType.equals("TransformationEvent")) {
BsonDocument query = getINFamilyQueryObject(type, "destinationList", paramValues);
if (query != null)
queryList.add(query);
}
}
boolean isExtraParam = isExtraParameter(paramName);
if (isExtraParam == true) {
/**
* EQ_fieldname: This is not a single parameter, but a family of
* parameters. If a parameter of this form is specified, the
* result will only include events that (a) have a field named
* fieldname whose type is either String or a vocabulary type;
* and where (b) the value of that field matches one of the
* values specified in this parameter. Fieldname is the fully
* qualified name of an extension field. The name of an
* extension field is an XML qname; that is, a pair consisting
* of an XML namespace URI and a name. The name of the
* corresponding query parameter is constructed by concatenating
* the following: the string EQ_, the namespace URI for the
* extension field, a pound sign (#), and the name of the
* extension field.
*/
if (paramName.startsWith("EQ_")) {
String type = paramName.substring(3, paramName.length());
/*
* if (eventType.equals("AggregationEvent") ||
* eventType.equals("ObjectEvent") ||
* eventType.equals("TransactionEvent")) { DBObject query =
* getINExtensionQueryObject(type, new String[] {
* "extension.extension.any." + type,
* "extension.extension.otherAttributes." + type },
* paramValues); if (query != null) queryList.add(query); }
* if (eventType.equals("QuantityEvent") ||
* eventType.equals("TransformationEvent")) { DBObject query
* = getINExtensionQueryObject( type, new String[] {
* "extension.any." + type, "extension.otherAttributes." +
* type }, paramValues); if (query != null)
* queryList.add(query); }
*/
BsonDocument query = getINExtensionQueryObject(type,
new String[] { "any." + type, "otherAttributes." + type }, paramValues);
if (query != null)
queryList.add(query);
}
/**
* GT/GE/LT/LE_fieldname: Like EQ_fieldname as described above,
* but may be applied to a field of type Int, Float, or Time.
* The result will include events that (a) have a field named
* fieldname; and where (b) the type of the field matches the
* type of this parameter (Int, Float, or Time); and where (c)
* the value of the field is greater than the specified value.
* Fieldname is constructed as for EQ_fieldname.
*/
if (paramName.startsWith("GT_") || paramName.startsWith("GE_") || paramName.startsWith("LT_")
|| paramName.startsWith("LE_")) {
String type = paramName.substring(3, paramName.length());
/*
* if (eventType.equals("AggregationEvent") ||
* eventType.equals("ObjectEvent") ||
* eventType.equals("TransactionEvent")) { if
* (paramName.startsWith("GT_")) { DBObject query =
* getCompExtensionQueryObject( type, new String[] {
* "extension.extension.any." + type,
* "extension.extension.otherAttributes." + type },
* paramValues, "GT"); if (query != null)
* queryList.add(query); } if (paramName.startsWith("GE_"))
* { DBObject query = getCompExtensionQueryObject( type, new
* String[] { "extension.extension.any." + type,
* "extension.extension.otherAttributes." + type },
* paramValues, "GE"); if (query != null)
* queryList.add(query); } if (paramName.startsWith("LT_"))
* { DBObject query = getCompExtensionQueryObject( type, new
* String[] { "extension.extension.any." + type,
* "extension.extension.otherAttributes." + type },
* paramValues, "LT"); if (query != null)
* queryList.add(query); } if (paramName.startsWith("LE_"))
* { DBObject query = getCompExtensionQueryObject( type, new
* String[] { "extension.extension.any." + type,
* "extension.extension.otherAttributes." + type },
* paramValues, "LE"); if (query != null)
* queryList.add(query); } } if
* (eventType.equals("QuantityEvent") ||
* eventType.equals("TransformationEvent")) { if
* (paramName.startsWith("GT_")) {
*
* DBObject query = getCompExtensionQueryObject( type, new
* String[] { "extension.any." + type,
* "extension.otherAttributes." + type }, paramValues,
* "GT"); if (query != null) queryList.add(query); } if
* (paramName.startsWith("GE_")) {
*
* DBObject query = getCompExtensionQueryObject( type, new
* String[] { "extension.any." + type,
* "extension.otherAttributes." + type }, paramValues,
* "GE"); if (query != null) queryList.add(query); } if
* (paramName.startsWith("LT_")) { DBObject query =
* getCompExtensionQueryObject( type, new String[] {
* "extension.any." + type, "extension.otherAttributes." +
* type }, paramValues, "LT"); if (query != null)
* queryList.add(query); } if (paramName.startsWith("LE_"))
* {
*
* DBObject query = getCompExtensionQueryObject( type, new
* String[] { "extension.any." + type,
* "extension.otherAttributes." + type }, paramValues,
* "LE"); if (query != null) queryList.add(query); } }
*/
if (paramName.startsWith("GT_")) {
BsonDocument query = getCompExtensionQueryObject(type,
new String[] { "any." + type, "otherAttributes." + type }, paramValues, "GT");
if (query != null)
queryList.add(query);
}
if (paramName.startsWith("GE_")) {
BsonDocument query = getCompExtensionQueryObject(type,
new String[] { "any." + type, "otherAttributes." + type }, paramValues, "GE");
if (query != null)
queryList.add(query);
}
if (paramName.startsWith("LT_")) {
BsonDocument query = getCompExtensionQueryObject(type,
new String[] { "any." + type, "otherAttributes." + type }, paramValues, "LT");
if (query != null)
queryList.add(query);
}
if (paramName.startsWith("LE_")) {
BsonDocument query = getCompExtensionQueryObject(type,
new String[] { "any." + type, "otherAttributes." + type }, paramValues, "LE");
if (query != null)
queryList.add(query);
}
}
}
}
return queryList;
}
private BsonArray makeMasterQueryObjects(String vocabularyName, boolean includeAttributes, boolean includeChildren,
String attributeNames, String eQ_name, String wD_name, String hASATTR, String maxElementCount,
Map<String, String> paramMap) {
BsonArray queryList = new BsonArray();
/**
* vocabularyName : If specified, only vocabulary elements drawn from
* one of the specified vocabularies will be included in the results.
* Each element of the specified list is the formal URI name for a
* vocabulary; e.g., one of the URIs specified in the table at the end
* of Section 7.2. If omitted, all vocabularies are considered.
*/
if (vocabularyName != null) {
BsonDocument query = getINQueryObject("type", vocabularyName);
if (query != null)
queryList.add(query);
}
/**
* EQ_name : If specified, the result will only include vocabulary
* elements whose names are equal to one of the specified values. If
* this parameter and WD_name are both omitted, vocabulary elements are
* included regardless of their names.
*/
Set<String> idSet = new HashSet<String>();
if (eQ_name != null) {
String[] eqArr = eQ_name.split(",");
for (int i = 0; i < eqArr.length; i++) {
String eqString = eqArr[i].trim();
idSet.add(eqString);
}
}
/**
* WD_name : If specified, the result will only include vocabulary
* elements that either match one of the specified names, or are direct
* or indirect descendants of a vocabulary element that matches one of
* the specified names. The meaning of “direct or indirect descendant”
* is described in Section 6.5. (WD is an abbreviation for “with
* descendants.”) If this parameter and EQ_name are both omitted,
* vocabulary elements are included regardless of their names.
*/
if (wD_name != null) {
String[] eqArr = wD_name.split(",");
for (int i = 0; i < eqArr.length; i++) {
eqArr[i] = eqArr[i].trim();
}
for (int i = 0; i < eqArr.length; i++) {
// Invoke vocabulary query with EQ_name and includeChildren
idSet = getWDList(idSet, eqArr[i]);
}
}
if (!idSet.isEmpty()) {
BsonDocument query = getINQueryObject("id", idSet);
if (query != null)
queryList.add(query);
}
/**
* HASATTR : If specified, the result will only include vocabulary
* elements that have a non-null attribute whose name matches one of the
* values specified in this parameter.
*/
if (hASATTR != null) {
String[] attrArr = hASATTR.split(",");
for (int i = 0; i < attrArr.length; i++) {
String attrString = attrArr[i].trim();
BsonDocument query = getExistsQueryObject("attributes", attrString);
if (query != null)
queryList.add(query);
}
}
/**
* EQATTR_attrnam : This is not a single parameter, but a family of
* parameters. If a parameter of this form is specified, the result will
* only include vocabulary elements that have a non-null attribute named
* attrname, and where the value of that attribute matches one of the
* values specified in this parameter.
*/
if (paramMap != null) {
Iterator<String> paramIter = paramMap.keySet().iterator();
while (paramIter.hasNext()) {
String paramName = paramIter.next();
String paramValues = paramMap.get(paramName);
if (paramName.contains("EQATTR_")) {
String type = paramName.substring(7, paramName.length());
BsonDocument query = getVocFamilyQueryObject(type, "attributes", paramValues);
if (query != null)
queryList.add(query);
}
}
}
return queryList;
}
private long getTimeMillis(String standardDateString) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
GregorianCalendar eventTimeCalendar = new GregorianCalendar();
eventTimeCalendar.setTime(sdf.parse(standardDateString));
return eventTimeCalendar.getTimeInMillis();
} catch (ParseException e) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
GregorianCalendar eventTimeCalendar = new GregorianCalendar();
eventTimeCalendar.setTime(sdf.parse(standardDateString));
return eventTimeCalendar.getTimeInMillis();
} catch (ParseException e1) {
Configuration.logger.log(Level.ERROR, e1.toString());
}
}
// Never Happened
return 0;
}
}