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.extend;
017:
018: import java.io.IOException;
019:
020: import javax.servlet.ServletOutputStream;
021:
022: import org.directwebremoting.ScriptBuffer;
023:
024: /**
025: * While a Marshaller is processing a request it can register a ScriptConduit
026: * with the ScriptSession to say - pass scripts straight to me and bypass the
027: * temporary storage area.
028: * This interface allows this to happen.
029: * @author Joe Walker [joe at getahead dot ltd dot uk]
030: */
031: public abstract class ScriptConduit implements
032: Comparable<ScriptConduit> {
033: /**
034: * All ScriptConduit need a rank
035: * @param rank How does this ScriptConduit sort
036: */
037: public ScriptConduit(int rank) {
038: this .rank = rank;
039: }
040:
041: /**
042: * ScriptConduits have a rank that indicates the priority order in which we
043: * should send scripts to them.
044: * The rank is a number from 1 to 10, and should only be one of the defined
045: * values: ScriptConduit.RANK_*.
046: * @see ScriptConduit#RANK_PROCEDURAL
047: * @see ScriptConduit#RANK_FAST
048: * @see ScriptConduit#RANK_SLOW
049: * @return The rank of this ScriptConduit
050: */
051: public int getRank() {
052: return rank;
053: }
054:
055: /**
056: * Indicates that this ScriptConduit is used for control-flow and will
057: * probably not actually convey the script, but does need to tell someone
058: * else about it
059: */
060: public static final int RANK_PROCEDURAL = 10;
061:
062: /**
063: * Indicates that this ScriptConduit is a very good way of getting scripts
064: * to the client and should be used as a preferred method
065: */
066: public static final int RANK_FAST = 5;
067:
068: /**
069: * Indicates that this ScriptConduit is a poor way of getting scripts to the
070: * client and should only be used as a last resort.
071: */
072: public static final int RANK_SLOW = 1;
073:
074: /**
075: * Add a script to the list bound for remote execution.
076: * <p>It is not an error to refuse to handle the script and return false, it
077: * just indicates that this ScriptConduit did not accept the script.
078: * If the ScriptConduit can no longer function then it should throw an
079: * exception and it will be assumed to be no longer useful.
080: * If you want to implement this method then you will probably be doing
081: * something like calling {@link ServletOutputStream#print(String)} and
082: * passing in the results of calling ScriptBufferUtil.createOutput().
083: * @param script The script to execute
084: * @return true if this ScriptConduit handled the script.
085: * @throws IOException If this conduit is broken and should not be used
086: * @throws MarshallException If objects in the script can not be marshalled
087: */
088: public abstract boolean addScript(ScriptBuffer script)
089: throws IOException, MarshallException;
090:
091: /* (non-Javadoc)
092: * @see java.lang.Comparable#compareTo(java.lang.Object)
093: */
094: @SuppressWarnings({"SubtractionInCompareTo","NumericCastThatLosesPrecision"})
095: public int compareTo(ScriptConduit that) {
096: int rankdiff = that.getRank() - this .getRank();
097: if (rankdiff != 0) {
098: return rankdiff;
099: }
100:
101: return (int) (this .id - that.id);
102: }
103:
104: /* (non-Javadoc)
105: * @see java.lang.Object#equals(java.lang.Object)
106: */
107: @Override
108: public boolean equals(Object obj) {
109: if (obj == null) {
110: return false;
111: }
112:
113: if (obj == this ) {
114: return true;
115: }
116:
117: if (!this .getClass().equals(obj.getClass())) {
118: return false;
119: }
120:
121: ScriptConduit that = (ScriptConduit) obj;
122: return this .id == that.id;
123: }
124:
125: /* (non-Javadoc)
126: * @see java.lang.Object#hashCode()
127: */
128: @SuppressWarnings({"NumericCastThatLosesPrecision"})
129: @Override
130: public int hashCode() {
131: return 17 + (int) id;
132: }
133:
134: /* (non-Javadoc)
135: * @see java.lang.Object#toString()
136: */
137: @Override
138: public String toString() {
139: return getClass().getSimpleName() + "[id=" + id + "]";
140: }
141:
142: /**
143: * The rank of this ScriptConduit
144: */
145: private int rank;
146:
147: /**
148: * Our ID, to get around serialization issues
149: */
150: private final long id = getNextId();
151:
152: /**
153: * Get the next unique ID in a thread safe way
154: * @return a unique id
155: */
156: private static synchronized long getNextId() {
157: nextId++;
158: return nextId;
159: }
160:
161: /**
162: * The next ID, to get around serialization issues
163: */
164: private static long nextId = 0L;
165: }
|