X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2Futil%2FEvaluatingListener.java;h=1ea261b52e366e49b6e3459a75cd25193ada94b9;hb=1cd631466bc35e05bc585999b2f325f148cd5629;hp=59dcc5910e2e018402945007d0bd28ab8d24519b;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/EvaluatingListener.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/EvaluatingListener.java index 59dcc5910..1ea261b52 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/EvaluatingListener.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/EvaluatingListener.java @@ -1,199 +1,199 @@ -/******************************************************************************* - * Copyright (c) 2012 Association for Decentralized Information Management in - * Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.db.layer0.util; - -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -import org.simantics.db.Session; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.procedure.Listener; -import org.simantics.db.request.Read; - -/** - * A database listener that disposes itself based on a criterion evaluated using - * the request results received by the listener. If the results pass the - * criterion, the listener is disposed and the result is either accepted or - * discarded based on the evaluation. - * - *

- * The reason for the existence of this class is that sometimes database - * requests always perform asynchronously, i.e. return empty results at first - * and later get updated to their final results. For example, a the results of a - * web request would take a while to be delivered. This listener makes it a bit - * easier to deal with these situations when results are needed synchronously. - * - *

- * {@link #trySyncRequest(Session, Read, Criterion, long, TimeUnit)} provides a - * utility for executing a synchronous read request with this listener so that - * the implementation will wait for a criterion accepted result for the - * specified amount of time. If an accepted result is reached within the time - * limit, it will be returned. If the time limit is reached and no accepted - * result is attained, null will be returned. If the request - * produces an exception, it will be thrown. - * - * @author Tuukka Lehtonen - * - * @param database request result type - * - * @see EvaluatingListener.Evaluation - * @see EvaluatingListener.Criterion - */ -public class EvaluatingListener implements Listener { - - public static enum Evaluation { - /** - * Keep on listening to further results. - */ - IGNORE, - /** - * Dispose listener and discard the results. - */ - DISCARD, - /** - * Dispose listener and return the latest result. - */ - ACCEPT - } - - /** - * An evaluable criterion for the result received by - * {@link Listener#execute(Object)} to tell whether to accept the result, - * wait for another result or to consider the listener disposed. - * - * @param the type of the result - */ - public static interface Criterion { - Evaluation evaluate(T result); - } - - /** - * The criterion the listener evaluates. When it evaluates to - * {@value Evaluation#DISCARD}, this field is nullified and the listener is - * considered disposed. - */ - private volatile Criterion criterion; - private T result; - private Throwable exception; - private Semaphore wait = new Semaphore(0); - - public EvaluatingListener(Criterion criterion) { - if (criterion == null) - throw new NullPointerException("null criterion"); - this.criterion = criterion; - } - - /** - * @param session - * @param request - * @param criterion - * @param timeout - * @param unit - * @return - * @throws InterruptedException - * @throws DatabaseException - */ - public static T trySyncRequest(Session session, Read request, Criterion criterion, long timeout, TimeUnit unit) throws InterruptedException, DatabaseException { - EvaluatingListener l = new EvaluatingListener(criterion); - session.asyncRequest(request, l); - l.tryWaitForResult(timeout, unit); - // Make sure the listener is disposed. - l.dispose(); - l.throwPossibleException(); - return l.getResult(); - } - - public T waitForResult() throws InterruptedException { - wait.acquire(); - return getResult(); - } - - public boolean tryWaitForResult(long timeout, TimeUnit unit) throws InterruptedException { - return wait.tryAcquire(timeout, unit); - } - - public T getResult() { - return result; - } - - public Throwable getException() { - return exception; - } - - public void throwPossibleException() throws DatabaseException { - if (exception != null) { - if (exception instanceof DatabaseException) - throw (DatabaseException) exception; - throw new DatabaseException(exception); - } - } - - @Override - public void execute(T result) { - Criterion crit = criterion; - if (crit == null) - return; - EvaluatingListener.Evaluation e = crit.evaluate(result); - switch (e) { - case IGNORE: - ignored(result); - return; - case ACCEPT: - this.result = result; - try { - accepted(result); - } finally { - dispose(); - wait.release(); - } - return; - case DISCARD: - dispose(); - wait.release(); - return; - } - } - - /** - * Override to process results that were ignored. - * - * @param result - */ - public void ignored(T result) { - } - - /** - * Override this to immediately process an accepted result in the listener. - * This method is invoked before the listener is disposed - * - * @param result - */ - public void accepted(T result) { - } - - @Override - public void exception(Throwable t) { - this.exception = t; - dispose(); - wait.release(); - } - - private void dispose() { - this.criterion = null; - } - - @Override - public boolean isDisposed() { - return criterion == null; - } - +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.db.layer0.util; + +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + +import org.simantics.db.Session; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; + +/** + * A database listener that disposes itself based on a criterion evaluated using + * the request results received by the listener. If the results pass the + * criterion, the listener is disposed and the result is either accepted or + * discarded based on the evaluation. + * + *

+ * The reason for the existence of this class is that sometimes database + * requests always perform asynchronously, i.e. return empty results at first + * and later get updated to their final results. For example, a the results of a + * web request would take a while to be delivered. This listener makes it a bit + * easier to deal with these situations when results are needed synchronously. + * + *

+ * {@link #trySyncRequest(Session, Read, Criterion, long, TimeUnit)} provides a + * utility for executing a synchronous read request with this listener so that + * the implementation will wait for a criterion accepted result for the + * specified amount of time. If an accepted result is reached within the time + * limit, it will be returned. If the time limit is reached and no accepted + * result is attained, null will be returned. If the request + * produces an exception, it will be thrown. + * + * @author Tuukka Lehtonen + * + * @param database request result type + * + * @see EvaluatingListener.Evaluation + * @see EvaluatingListener.Criterion + */ +public class EvaluatingListener implements Listener { + + public static enum Evaluation { + /** + * Keep on listening to further results. + */ + IGNORE, + /** + * Dispose listener and discard the results. + */ + DISCARD, + /** + * Dispose listener and return the latest result. + */ + ACCEPT + } + + /** + * An evaluable criterion for the result received by + * {@link Listener#execute(Object)} to tell whether to accept the result, + * wait for another result or to consider the listener disposed. + * + * @param the type of the result + */ + public static interface Criterion { + Evaluation evaluate(T result); + } + + /** + * The criterion the listener evaluates. When it evaluates to + * {@value Evaluation#DISCARD}, this field is nullified and the listener is + * considered disposed. + */ + private volatile Criterion criterion; + private T result; + private Throwable exception; + private Semaphore wait = new Semaphore(0); + + public EvaluatingListener(Criterion criterion) { + if (criterion == null) + throw new NullPointerException("null criterion"); + this.criterion = criterion; + } + + /** + * @param session + * @param request + * @param criterion + * @param timeout + * @param unit + * @return + * @throws InterruptedException + * @throws DatabaseException + */ + public static T trySyncRequest(Session session, Read request, Criterion criterion, long timeout, TimeUnit unit) throws InterruptedException, DatabaseException { + EvaluatingListener l = new EvaluatingListener(criterion); + session.asyncRequest(request, l); + l.tryWaitForResult(timeout, unit); + // Make sure the listener is disposed. + l.dispose(); + l.throwPossibleException(); + return l.getResult(); + } + + public T waitForResult() throws InterruptedException { + wait.acquire(); + return getResult(); + } + + public boolean tryWaitForResult(long timeout, TimeUnit unit) throws InterruptedException { + return wait.tryAcquire(timeout, unit); + } + + public T getResult() { + return result; + } + + public Throwable getException() { + return exception; + } + + public void throwPossibleException() throws DatabaseException { + if (exception != null) { + if (exception instanceof DatabaseException) + throw (DatabaseException) exception; + throw new DatabaseException(exception); + } + } + + @Override + public void execute(T result) { + Criterion crit = criterion; + if (crit == null) + return; + EvaluatingListener.Evaluation e = crit.evaluate(result); + switch (e) { + case IGNORE: + ignored(result); + return; + case ACCEPT: + this.result = result; + try { + accepted(result); + } finally { + dispose(); + wait.release(); + } + return; + case DISCARD: + dispose(); + wait.release(); + return; + } + } + + /** + * Override to process results that were ignored. + * + * @param result + */ + public void ignored(T result) { + } + + /** + * Override this to immediately process an accepted result in the listener. + * This method is invoked before the listener is disposed + * + * @param result + */ + public void accepted(T result) { + } + + @Override + public void exception(Throwable t) { + this.exception = t; + dispose(); + wait.release(); + } + + private void dispose() { + this.criterion = null; + } + + @Override + public boolean isDisposed() { + return criterion == null; + } + } \ No newline at end of file