001: /*
002: * Copyright 2005 Joe Walker
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.directwebremoting.impl;
017:
018: import java.io.IOException;
019: import java.util.concurrent.ScheduledFuture;
020: import java.util.concurrent.ScheduledThreadPoolExecutor;
021: import java.util.concurrent.TimeUnit;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.directwebremoting.ScriptBuffer;
026: import org.directwebremoting.ScriptSession;
027: import org.directwebremoting.extend.Alarm;
028: import org.directwebremoting.extend.RealScriptSession;
029: import org.directwebremoting.extend.ScriptConduit;
030: import org.directwebremoting.extend.Sleeper;
031: import org.directwebremoting.util.SharedObjects;
032:
033: /**
034: * An Alarm that goes off whenever output happens on a {@link ScriptSession}.
035: * @author Joe Walker [joe at getahead dot ltd dot uk]
036: */
037: public class OutputAlarm extends BasicAlarm implements Alarm {
038: /**
039: * @param scriptSession The script session to monitor
040: * @param maxWaitAfterWrite How long do we wait after output
041: */
042: public OutputAlarm(RealScriptSession scriptSession,
043: int maxWaitAfterWrite) {
044: this .maxWaitAfterWrite = maxWaitAfterWrite;
045: this .scriptSession = scriptSession;
046:
047: conduit = new AlarmScriptConduit();
048: }
049:
050: /* (non-Javadoc)
051: * @see org.directwebremoting.dwrp.Alarm#setAlarmAction(org.directwebremoting.dwrp.Sleeper)
052: */
053: @Override
054: public void setAlarmAction(Sleeper sleeper) {
055: try {
056: scriptSession.addScriptConduit(conduit);
057: } catch (IOException ex) {
058: log.warn("Error adding monitor to script session", ex);
059: }
060:
061: super .setAlarmAction(sleeper);
062: }
063:
064: /* (non-Javadoc)
065: * @see org.directwebremoting.dwrp.Alarm#cancel()
066: */
067: @Override
068: public void cancel() {
069: scriptSession.removeScriptConduit(conduit);
070: if (future != null) {
071: future.cancel(false);
072: }
073: super .cancel();
074: }
075:
076: /**
077: * @author Joe Walker [joe at getahead dot ltd dot uk]
078: */
079: protected class AlarmScriptConduit extends ScriptConduit {
080: /**
081: * Create an AlarmScriptConduit
082: */
083: protected AlarmScriptConduit() {
084: super (RANK_PROCEDURAL);
085: }
086:
087: /* (non-Javadoc)
088: * @see org.directwebremoting.extend.ScriptConduit#addScript(org.directwebremoting.ScriptBuffer)
089: */
090: @Override
091: public boolean addScript(ScriptBuffer script) {
092: // log.debug("Output alarm went off. Additional wait of " + maxWaitAfterWrite);
093:
094: if (maxWaitAfterWrite == 0) {
095: raiseAlarm();
096: } else {
097: Runnable runnable = new Runnable() {
098: public void run() {
099: raiseAlarm();
100: }
101: };
102:
103: ScheduledThreadPoolExecutor executor = SharedObjects
104: .getScheduledThreadPoolExecutor();
105: future = executor.schedule(runnable, maxWaitAfterWrite,
106: TimeUnit.MILLISECONDS);
107: }
108:
109: return false;
110: }
111: }
112:
113: /**
114: * A conduit to alert us if there is output
115: */
116: protected ScriptConduit conduit = null;
117:
118: /**
119: * How long do we wait after output happens in case there is more output
120: */
121: protected int maxWaitAfterWrite;
122:
123: /**
124: * The script session to monitor for output
125: */
126: protected RealScriptSession scriptSession;
127:
128: /**
129: * The log stream
130: */
131: protected static final Log log = LogFactory
132: .getLog(OutputAlarm.class);
133:
134: /**
135: * The future result that allows us to cancel the timer
136: */
137: protected ScheduledFuture<?> future;
138: }
|