001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package javax.microedition.content;
028:
029: import com.sun.midp.content.RegistryImpl;
030:
031: /**
032: *<tt>ContentHandlerServer</tt> provides methods
033: * to get new Invocation requests, to finish the processing
034: * of requests and to get the access control information.
035: * This server interface extends {@link ContentHandler}
036: * to make available the registration information for types,
037: * suffixes, actions, ID, etc.
038: * Instances are thread safe.
039: *
040: * <h3>Responding to an Invocation</h3>
041: * <p>Content handler applications process requests using
042: * either blocking calls to {@link #getRequest getRequest} or can be
043: * notified of
044: * new requests with the {@link #setListener setListener} method.
045: * A content handler receives an Invocation by calling
046: * {@link #getRequest getRequest}.
047: * The content handler should use the
048: * {@link Invocation#getAction Invocation.getAction}
049: * method to determine the requested action and act on the content
050: * appropriately.
051: * The content handler will typically call the
052: * {@link Invocation#open Invocation.open} method to read the content.
053: * The <code>open</code> method returns a Connection from the Generic
054: * Connection framework that provides access to the content.
055: * When the content handler is finished processing the Invocation,
056: * it must call the
057: * {@link #finish finish} method to report the status.
058: * If a response was required the status and parameters are returned
059: * to the invoking application.
060: *
061: * <h3>Required Response to the Invoking Application</h3>
062: * <p>
063: * The invoking application decides whether it needs a response and
064: * sets the request state before calling
065: * {@link Registry#invoke Registry.invoke}.
066: * When an Invocation is completed either by using the
067: * {@link #finish finish}
068: * method or when the AMS is handling an error condition,
069: * the {@link Invocation#getResponseRequired Invocation.getResponseRequired}
070: * method is checked.
071: * If it is <code>true</code>, then the values from the Invocation are
072: * queued to the invoking application with the status set
073: * by the ContentHandler or AMS.
074: * When a response is queued, it will be dispatched to the invoking
075: * application.
076: * If a response is not required, it is not delivered to the invoking
077: * application and the invoking application is not started.
078: *
079: * <H3>Chaining Content Handlers</H3>
080: * <p> Content handlers link Invocations that are part of
081: * a user-driven task and depend on each other as part of a transaction.
082: * Suppose an application <i>A</i> creates an invocation
083: * <i>a</i>. When invoked, it is dispatched to content
084: * handler <i>B</i> which in-turn creates an invocation <i>b</i>
085: * and it is dispatched to content handler <i>C</i>. C displays the
086: * content and returns a response <i>b'</i> to B, B in turn
087: * completes processing and returns a response <i>a'</i> to A.</p>
088: * <p>
089: * The implementation MUST have the capacity and mechanisms to support
090: * the chaining of requests required for an application to invoke a
091: * content handler, and the content handler invoking another content
092: * handler, and for each content handler to return a response.
093: * This chain length of two active invocations is the minimum
094: * requirement. The implementation should not artificially
095: * limit the number of invocations and responses that are supported
096: * except as constrained by the resources of the device.</p>
097: *
098: * <p> To maintain continuity across the applications,
099: * chained invocations are part of the same transaction.
100: * Invoking an Invocation places it in a transaction.
101: * The transaction maintains the sequence of invocations
102: * across all of the applications involved.
103: * The transaction maintains the invocations regardless of whether
104: * a single application can run at a time or the applications
105: * execute in parallel in different runtime environments. The
106: * transaction is used to record and manage the steps in processing and
107: * dispatching to applications. </p>
108: *
109: * <p> For simple non-chaining use cases that involve only two
110: * applications with a single invocation and response,
111: * only the methods
112: * {@link #getRequest getRequest}, {@link #finish finish},
113: * {@link Registry#invoke Registry.invoke}, and
114: * {@link Registry#getResponse Registry.getResponse} are needed.</p>
115: * <p>
116: * For chained use cases, the methods {@link Registry#invoke Registry.invoke}
117: * and {@link Invocation#getPrevious Invocation.getPrevious}
118: * are used to establish
119: * the sequence and to retrieve the previous Invocation.
120: * The {@link Registry#invoke Registry.invoke} method places the new
121: * Invocation in the same transaction as a previous Invocation.
122: * The previous Invocation will be held in the transaction until
123: * the new Invocation is completed. When the response to the new
124: * Invocation is returned, the previously active Invocation can be
125: * retrieved with {@link Invocation#getPrevious Invocation.getPrevious}
126: * so the content handler can complete its processing.</p>
127: *
128: * <p>
129: * An Invocation can be delegated to another handler with the
130: * {@link Registry#reinvoke Registry.reinvoke} method.
131: * Responses to the reinvocation will be queued to the original invoking
132: * application. </p>
133: *
134: * <H3>Handling Faults</H3>
135: * If the content handler cannot or does not correctly handle the
136: * Invocation, then the AMS MUST handle it correctly.
137: * These actions prevent an incorrectly written content
138: * handler from being unresponsive or being run repeatedly but never
139: * processing queued invocations.
140: * <ul>
141: * <li>
142: * If an Invocation with a status of <code>ACTIVE</code> is dequeued by
143: * the content handler, but the handler does not call
144: * {@link #finish finish}
145: * or make a request to chain a new Invocation to the ACTIVE
146: * invocation before the content handler exits, then the AMS MUST
147: * complete the request with an ERROR status.
148: * This ensures that the invoking application
149: * will always get a response, if required, for each invocation
150: * regardless of whether the content handler correctly handles it.
151: * </li>
152: * <li>
153: * If the content handler is not running, or exits before processing
154: * all queued requests or responses, then it MUST be started.
155: * The content handler is expected to dequeue at least one
156: * invocation that was queued before it was started.
157: * If it does not dequeue any pending Invocations or can not be started,
158: * then Invocations that were in the queue for the content handler
159: * before it was started MUST be handled as follows:
160: * <ul>
161: * <li>Invocation requests with a status of <code>ACTIVE</code>
162: * are completed with the <code>ERROR</code> status.</li>
163: * <li>Invocation responses are discarded.</li>
164: * <li>Invocations queued after the content handler was started are
165: * retained and will require it to be restarted.</li>
166: * </ul>
167: * This serialization of queued requests and starting the content
168: * handler
169: * addresses a race condition. This condition may occur when the
170: * content handler is active but exits before processing Invocations that
171: * were queued after it was started or it last called
172: * {@link #getRequest getRequest} or
173: * {@link Registry#getResponse Registry.getResponse}.
174: * </li>
175: * </ul>
176: * <p>
177: * Invocations and invocation state MUST NOT be preserved
178: * across soft and hard restarts of the device software including
179: * unexpected power interruptions.</p>
180: *
181: *
182: */
183: public interface ContentHandlerServer extends ContentHandler {
184:
185: /**
186: * Gets the next Invocation request pending for this
187: * ContentHandlerServer.
188: * The method can be unblocked with a call to
189: * {@link #cancelGetRequest cancelGetRequest}.
190: * The application should process the Invocation as
191: * a request to perform the <code>action</code> on the content.
192: *
193: * @param wait <code>true</code> if the method must wait
194: * for an Invocation if one is not available;
195: * <code>false</code> if the method MUST NOT wait.
196: *
197: * @return the next pending Invocation or <code>null</code>
198: * if no Invocation is available; <code>null</code>
199: * if cancelled with {@link #cancelGetRequest cancelGetRequest}
200: * @see Registry#invoke
201: * @see #finish
202: */
203: public Invocation getRequest(boolean wait);
204:
205: /**
206: * Cancels a pending <code>getRequest</code>.
207: * This method will force all threads blocked in a call to the
208: * <code>getRequest</code> method for this ContentHandlerServer
209: * to return.
210: * If no threads are blocked; this call has no effect.
211: */
212: public void cancelGetRequest();
213:
214: /**
215: * Finishes the Invocation and sets the status for the response.
216: * The <code>finish</code> method can only be called when the
217: * Invocation
218: * has a status of <code>ACTIVE</code> or <code>HOLD</code>.
219: * <p>
220: * The content handler may modify the URL, type, action, or
221: * arguments before invoking <code>finish</code>.
222: * If the method
223: * {@link Invocation#getResponseRequired Invocation.getResponseRequired}
224: * returns <code>true</code>, then the modified
225: * values MUST be returned to the invoking application.
226: *
227: * @param invocation the Invocation to finish
228: * @param status the new status of the Invocation;
229: * MUST be either <code>OK</code>, <code>CANCELLED</code>
230: * or <code>INITIATED</code>
231: *
232: * @return <code>true</code> if the application MUST
233: * voluntarily exit to allow pending responses or requests
234: * to be handled;
235: * <code>false</code> otherwise
236: *
237: * @exception IllegalArgumentException if the new
238: * <code>status</code> of the Invocation
239: * is not <code>OK</code>, <code>CANCELLED</code>,
240: * or <code>INITIATED</code>
241: * @exception IllegalStateException if the current
242: * <code>status</code> of the
243: * Invocation is not <code>ACTIVE</code> or <code>HOLD</code>
244: * @exception NullPointerException if the invocation is <code>null</code>
245: */
246: public boolean finish(Invocation invocation, int status);
247:
248: /**
249: * Sets the listener to be notified when a new request is
250: * available for this content handler. The request is
251: * retrieved using {@link #getRequest getRequest}.
252: * If the listener is <code>non-null</code> and a request is
253: * available, the listener MUST be notified.
254: *
255: * @param listener the listener to register;
256: * <code>null</code> to remove the listener.
257: */
258: public void setListener(RequestListener listener);
259:
260: /**
261: * Gets the ID at the specified index of an application or content
262: * handler allowed access to this content handler.
263: * The ID returned for each index must be the equal to the ID
264: * at the same index in the <tt>accessAllowed</tt> array passed to
265: * {@link Registry#register Registry.register}.
266: *
267: * @param index the index of the ID
268: * @return the ID at the specified index
269: * @exception IndexOutOfBoundsException if index is less than zero or
270: * greater than or equal to the value of the
271: * {@link #accessAllowedCount accessAllowedCount} method.
272: */
273: public String getAccessAllowed(int index);
274:
275: /**
276: * Gets the number of IDs allowed access by the content handler.
277: * The number of IDs MUST be equal to the length of the array
278: * of <code>accessAllowed</code> passed to
279: * {@link Registry#register Registry.register}.
280: * If the number of IDs is zero then all applications and
281: * content handlers are allowed access.
282: *
283: * @return the number of IDs allowed access
284: */
285: public int accessAllowedCount();
286:
287: /**
288: * Determines if an ID MUST be allowed access by the content handler.
289: * Access MUST be allowed if the ID has a prefix that exactly matches
290: * any of the IDs returned by {@link #getAccessAllowed}.
291: * The prefix comparison is equivalent to
292: * <code>java.lang.String.startsWith</code>.
293: *
294: * @param ID the ID for which to check access
295: * @return <code>true</code> if access MUST be allowed by the
296: * content handler;
297: * <code>false</code> otherwise
298: * @exception NullPointerException if <code>ID</code>
299: * is <code>null</code>
300: */
301: public boolean isAccessAllowed(String ID);
302: }
|