if (! (source instanceof I_Queue) )
throw new XmlBlasterException(this.global, ErrorCode.INTERNAL_ILLEGALARGUMENT, ME, "Wrong type of source for query. Expected an 'I_Queue' implementation but was '" + source.getClass().getName() + "'");
if (query == null)
throw new XmlBlasterException(this.global, ErrorCode.INTERNAL_ILLEGALARGUMENT, ME, "The query string is null");
I_Queue queue = (I_Queue)source;
int maxEntries = 1;
long maxSize = -1L;
boolean consumable = false;
long waitingDelay = 0L; // no wait is default
// get the query properties
//if (querySpec.getQuery() != null) query = querySpec.getQuery().getQuery();
// "maxEntries=3&maxSize=1000&consumable=true&waitingDelay=1000"
Map props = StringPairTokenizer.parseToStringClientPropertyPairs(query, "&", "=");
ClientProperty prop = (ClientProperty)props.get("maxEntries");
if (prop != null) maxEntries = prop.getIntValue();
prop = (ClientProperty)props.get("maxSize");
if (prop != null) maxSize = prop.getLongValue();
if (maxSize > -1L) {
log.warning(" Query specification of maxSize is not implemented, please use the default value -1 or leave it untouched: '" + query + "'");
throw new XmlBlasterException(this.global, ErrorCode.USER_ILLEGALARGUMENT, ME, "Query specification of maxSize is not implemented, please use the default value -1 or leave it untouched");
}
prop = (ClientProperty)props.get("consumable");
if (prop != null) consumable = prop.getBooleanValue();
prop = (ClientProperty)props.get("waitingDelay");
if (prop != null) waitingDelay = prop.getLongValue();
if (log.isLoggable(Level.FINE))
log.fine("query: waitingDelay='" + waitingDelay + "' consumable='" + consumable + "' maxEntries='" + maxEntries + "' maxSize='" + maxSize + "'");
if (waitingDelay != 0L) {
if (log.isLoggable(Level.FINE)) log.fine("query: waiting delay is " + waitingDelay);
if (maxEntries < 1 && maxSize < 1L && waitingDelay < 0L) {
log.warning("If you specify a blocking get you must also specify a maximum size or maximum number of entries to retreive, otherwise specify non-blocking by setting 'waitingDelay' to zero, query is illegal: '" + query + "'");
throw new XmlBlasterException(this.global, ErrorCode.USER_ILLEGALARGUMENT, ME, "If you specify a blocking get you must also specify a maximum size or maximum number of entries to retreive, otherwise specify non-blocking by setting 'waitingDelay' to zero");
}
WaitingQuery wq = new WaitingQuery(maxEntries, maxSize);
if (checkIfNeedsWaiting((int)queue.getNumOfEntries(), queue.getNumOfBytes(), wq)) {
if (log.isLoggable(Level.FINE)) log.fine("query: going to wait due to first check");
try {
synchronized (this.waitingThreads) {
this.waitingThreads.add(wq);
}
queue.addStorageSizeListener(this);
boolean timedOut = false;
try {
if (waitingDelay < 0L)
wq.startSignal.await();
else
timedOut = !wq.startSignal.await(waitingDelay, TimeUnit.MILLISECONDS);
if (log.isLoggable(Level.FINE)) log.fine("just waked up after waiting for incoming entries, timedOut=" + timedOut);
}
catch (InterruptedException ex) {
if (log.isLoggable(Level.FINE)) log.fine("just waked up because of interrupt: " + ex.toString());
}
}
catch (Throwable e) {
log.severe("Can't handle query: " + e.toString());
}
finally {
try {
synchronized (this.waitingThreads) {
this.waitingThreads.remove(wq);
}
queue.removeStorageSizeListener(this);
if (log.isLoggable(Level.FINE)) log.fine("query: removed myself as a QueueSizeListener");
}
catch (Throwable ex) {
ex.printStackTrace();
log.severe("query: exception occurred when removing the QueueSizeListener from the queue:" + ex.toString());
}
}
}
}
List<I_Entry> list = queue.peek(maxEntries, maxSize);
ArrayList entryListChecked = DispatchManager.prepareMsgsFromQueue(ME, log, queue, list);
MsgQueueEntry[] entries = (MsgQueueEntry[])entryListChecked.toArray(new MsgQueueEntry[entryListChecked.size()]);
ArrayList ret = new ArrayList(entries.length);
for (int i=0; i < entries.length; i++) {
// TODO: REQ engine.qos.update.queue states that the queue size is passed and not the curr msgArr.length
ReferenceEntry entry = (ReferenceEntry)entries[i];
MsgUnit mu = entry.getMsgUnitOrNull();
if (mu == null)
continue;
MsgQosData msgQosData = (MsgQosData)mu.getQosData().clone();
msgQosData.setTopicProperty(null);
if (entry instanceof MsgQueueUpdateEntry) {
MsgQueueUpdateEntry updateEntry = (MsgQueueUpdateEntry)entry;
msgQosData.setState(updateEntry.getState());
msgQosData.setSubscriptionId(updateEntry.getSubscriptionId());
}
msgQosData.setQueueIndex(i);
msgQosData.setQueueSize(entries.length);
if (msgQosData.getNumRouteNodes() == 1) {
msgQosData.clearRoutes();
}
ret.add(new MsgUnit(mu, null, null, msgQosData));
// ret[i] = new MsgUnitRaw(mu, mu.getKeyData().toXml(), mu.getContent(), mu.getQosData().toXml());
}
if (consumable) queue.removeRandom(entries);
return (MsgUnit[])ret.toArray(new MsgUnit[ret.size()]);
}