package client.net.sf.saxon.ce.expr.instruct;
import client.net.sf.saxon.ce.LogController;
import client.net.sf.saxon.ce.SaxonceApi;
import client.net.sf.saxon.ce.expr.*;
import client.net.sf.saxon.ce.om.StandardNames;
import client.net.sf.saxon.ce.pattern.EmptySequenceTest;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.type.ItemType;
import client.net.sf.saxon.ce.type.TypeHierarchy;
import client.net.sf.saxon.ce.value.IntegerValue;
import com.google.gwt.logging.client.LogConfiguration;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import java.util.Arrays;
import java.util.Iterator;
import java.util.logging.*;
/**
* The compiled form of an ixsl:schedule-action instruction in the stylesheet.
*/
public class ScheduleExecution extends Instruction {
private CallTemplate call;
private Expression wait;
private static Logger logger = Logger.getLogger("ScheduleExecution");
/**
* Create a schedule-execution instruction
* @param call the instruction to be executed
* @param wait expression giving the amount of time to wait, in milliseconds
*/
public ScheduleExecution(CallTemplate call, Expression wait) {
this.call = call;
this.wait = wait;
adoptChildExpression(call);
adoptChildExpression(wait);
}
public int getInstructionNameCode() {
return StandardNames.IXSL_SCHEDULE_ACTION;
}
/**
* Simplify an expression. This performs any static optimization (by rewriting the expression
* as a different expression). The default implementation does nothing.
* @param visitor an expression visitor
* @return the simplified expression
* @throws client.net.sf.saxon.ce.trans.XPathException
* if an error is discovered during expression rewriting
*/
public Expression simplify(ExpressionVisitor visitor) throws XPathException {
call = (CallTemplate)visitor.simplify(call);
wait = visitor.simplify(wait);
return this;
}
public Expression typeCheck(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException {
call = (CallTemplate)visitor.typeCheck(call, contextItemType);
wait = visitor.typeCheck(wait, contextItemType);
return this;
}
public Expression optimize(ExpressionVisitor visitor, ItemType contextItemType) throws XPathException {
call = (CallTemplate)visitor.optimize(call, contextItemType);
wait = visitor.optimize(wait, contextItemType);
return this;
}
public int getIntrinsicDependencies() {
return StaticProperty.HAS_SIDE_EFFECTS;
}
/**
* Handle promotion offers, that is, non-local tree rewrites.
* @param offer The type of rewrite being offered
* @throws client.net.sf.saxon.ce.trans.XPathException
*/
protected void promoteInst(PromotionOffer offer) throws XPathException {
call = (CallTemplate)doPromotion(call, offer);
wait = doPromotion(wait, offer);
}
/**
* Get the item type of the items returned by evaluating this instruction
* @param th the type hierarchy cache
* @return the static item type of the instruction. This is empty: the set-attribute instruction
* returns nothing.
*/
public ItemType getItemType(TypeHierarchy th) {
return EmptySequenceTest.getInstance();
}
/**
* Get all the XPath expressions associated with this instruction
* (in XSLT terms, the expression present on attributes of the instruction,
* as distinct from the child instructions in a sequence construction)
*/
public Iterator<Expression> iterateSubExpressions() {
return Arrays.asList(call, wait).iterator();
}
/**
* Replace one subexpression by a replacement subexpression
* @param original the original subexpression
* @param replacement the replacement subexpression
* @return true if the original subexpression is found
*/
public boolean replaceSubExpression(Expression original, Expression replacement) {
boolean found = false;
if (wait == original) {
wait = replacement;
found = true;
}
return found;
}
public TailCall processLeavingTail(final XPathContext context) throws XPathException {
IntegerValue time = (IntegerValue)wait.evaluateItem(context);
final CallTemplate.CallTemplatePackage pack = (CallTemplate.CallTemplatePackage)call.processLeavingTail(context);
Timer t = new Timer() {
public void run() {
//Window.setTitle("Timer fired " + serial++);
boolean success = false;
logger.fine("processing ixsl:schedule-action");
if (LogConfiguration.loggingIsEnabled() && LogController.traceIsEnabled()) {
LogController.openTraceListener();
}
try {
TailCall tc = pack.processLeavingTail();
while (tc != null) {
tc = tc.processLeavingTail();
}
context.getController().getPendingUpdateList().apply(context);
success = true;
} catch (Exception err) {
logger.log(Level.SEVERE, "In delayed event: " + err.getMessage());
if (SaxonceApi.doThrowJsExceptions()) {
throw new RuntimeException(err.getMessage());
}
}
if (LogConfiguration.loggingIsEnabled() && LogController.traceIsEnabled()) {
LogController.closeTraceListener(success);
}
}
};
//Window.setTitle("Timer started " + serial + " (time " + time + "ms)");
t.schedule(time.getIntValue());
return null;
}
//private static int serial = 1;
}
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.