0001: /*
0002: *
0003: *
0004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006: *
0007: * This program is free software; you can redistribute it and/or
0008: * modify it under the terms of the GNU General Public License version
0009: * 2 only, as published by the Free Software Foundation.
0010: *
0011: * This program is distributed in the hope that it will be useful, but
0012: * WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * General Public License version 2 for more details (a copy is
0015: * included at /legal/license.txt).
0016: *
0017: * You should have received a copy of the GNU General Public License
0018: * version 2 along with this work; if not, write to the Free Software
0019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020: * 02110-1301 USA
0021: *
0022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023: * Clara, CA 95054 or visit www.sun.com if you need additional
0024: * information or have any questions.
0025: */
0026:
0027: package javax.microedition.content;
0028:
0029: import java.io.IOException;
0030:
0031: import com.sun.midp.content.RegistryImpl;
0032: import com.sun.midp.content.InvocationImpl;
0033: import com.sun.midp.content.ContentHandlerImpl;
0034:
0035: import com.sun.midp.security.SecurityToken;
0036: import com.sun.midp.security.SecurityInitializer;
0037: import com.sun.midp.security.ImplicitlyTrustedClass;
0038:
0039: import java.util.Vector;
0040:
0041: /**
0042: * The <tt>Registry</tt> provides method to invoke,
0043: * register,
0044: * unregister, and query information about content handlers.
0045: * An application registers, for each content handler,
0046: * zero or more content types, suffixes, and actions.
0047: * Access to the registry is via the {@link #getRegistry getRegistry}
0048: * method. The Registry class is thread safe.
0049: * Applications are responsible for the thread safety of
0050: * Invocation objects passed as arguments to Registry methods.
0051: * <p>
0052: * Multiple content handlers can be registered for each type, suffix,
0053: * and action.
0054: * The types, suffixes, and actions registered for a handler
0055: * can be used to select a handler.
0056: * The content handler ID is set during registration and is
0057: * used to uniquely identify the content handler
0058: * and to enforce access controls.
0059: *
0060: * <p>
0061: * A content handler is any application that is registered to
0062: * handle some content. It responds to requests and displays
0063: * or acts on the content.
0064: * Registration can occur dynamically or statically.
0065: * Static registration occurs during the installation of the
0066: * application package, while dynamic registration occurs via this API.
0067: * A content handler may be a Java or a non-Java application.
0068: * For example, MIDlet suites and Personal Basis Profile applications
0069: * using the Xlet application model can be content handlers.
0070: * Refer to the {@link ContentHandler ContentHandler}
0071: * class for information on registering Java platform content handlers.</P>
0072: *
0073: * <p>
0074: * When a content handler is processing an invocation, it may be
0075: * necessary to invoke another content handler before it is able
0076: * to satisfy the first request.
0077: * The invocation and chaining of content handlers is managed
0078: * to maintain the context and sequence across
0079: * application executions.</p>
0080: *
0081: * <P>
0082: * The term <em>application</em> is used more generally than the term
0083: * <em>content handler</em>.
0084: * The term application is used to refer to the
0085: * common handling for making requests, handling responses,
0086: * and querying the content handler registrations.
0087: * The term <em>content handler</em> is used for an application
0088: * that registers for types, suffixes, actions, etc. and processes
0089: * the requests queued to it.</p>
0090: *
0091: *
0092: * <H3>Content Types</H3>
0093: * <P>
0094: * A content handler can register a set of types that it can handle.
0095: * Content types are simple opaque strings that are NOT case sensitive.
0096: * Type strings are not case sensitive, types that differ
0097: * only by case are treated as a single type.
0098: * </P>
0099: *
0100: * <h3>Suffix Processing</h3>
0101: * <P>
0102: * A content handler can register a set of suffixes that identify
0103: * from the syntax of a URL the content it can handle.
0104: * Suffixes are NOT case sensitive.
0105: * </P>
0106: *
0107: * <H3>Content Handler Actions</H3>
0108: * <P>Each content handler may register a set of actions
0109: * it supports.
0110: * The set of actions is extensible but applications should
0111: * choose from the actions defined in the {@link ContentHandler}
0112: * class when they are appropriate.
0113: * The predefined actions are:
0114: * {@link ContentHandler#ACTION_OPEN open},
0115: * {@link ContentHandler#ACTION_EDIT edit},
0116: * {@link ContentHandler#ACTION_NEW new},
0117: * {@link ContentHandler#ACTION_SEND send},
0118: * {@link ContentHandler#ACTION_SAVE save},
0119: * {@link ContentHandler#ACTION_EXECUTE execute},
0120: * {@link ContentHandler#ACTION_SELECT select},
0121: * {@link ContentHandler#ACTION_INSTALL install},
0122: * {@link ContentHandler#ACTION_PRINT print}, and
0123: * {@link ContentHandler#ACTION_STOP stop}.
0124: *
0125: *
0126: * <H3>Content Handler IDs</H3>
0127: * <P>The content handler ID is a string chosen by the
0128: * application vendor to identify the content handler. The
0129: * ID registered by a content handler MUST be unique and MUST NOT
0130: * match the prefix of any other registered content handler.
0131: * IDs are case sensitive and are treated as opaque strings.
0132: * They are compared for equality or as prefixes of IDs
0133: * when used to locate an appropriate content handler.
0134: * </P>
0135: *
0136: * <P>Content handler IDs should follow the form of
0137: * fully qualified Java class names or any naming
0138: * syntax that provides a natural way to disambiguate between
0139: * vendors. For example, IDs may be URLs
0140: * including scheme, authority (server), and path information.</P>
0141: * <p>
0142: * For example, if registered in the order below,
0143: * the following content handler IDs would be valid
0144: * or invalid as indicated because there is an ambiguity due
0145: * to prefix comparisons.
0146: * <ol>
0147: * <li><code>com.sun.applications.calc</code> - valid</li>
0148: * <li><code>com.sun.applications.trig</code> - valid</li>
0149: * <li><code>com.sun.application</code> - invalid,
0150: * this is the prefix of the <code>calc</code> ID</li>
0151: * <li><code>com.sun.applications.calc.decimal</code> -
0152: * invalid, the <code>calc</code> ID is prefix of <code>decimal</code></li>
0153: * </ol>
0154: *
0155: * <H3>Java Application Class</H3>
0156: * <P>The content handler to be launched is identified by the
0157: * application class. The class MUST contain entry point(s)
0158: * and be packaged according to the Java runtime environment.
0159: * For MIDP, the application class MUST extend
0160: * <code>javax.microedition.midlet.MIDlet</code>.
0161: * The application class uniquely identifies a content handler
0162: * within the application package, which is usually a JAR file.
0163: * Each application class can only be registered to a single content
0164: * handler. Registering a content handler for a class will replace any
0165: * content handler previously registered to that class.
0166: *
0167: * <h3>Content Handler Authentication</h3>
0168: * Applications and content handlers using the API may,
0169: * for security purposes, need or want to authenticate
0170: * the invoked content handler or the invoking application.
0171: * The CHAPI implementation cooperates with the application management
0172: * software to authenticate the applications (if possible) and pass the
0173: * authentication information to the application. If the application
0174: * can be authenticated, then the
0175: * {@link ContentHandler#getAuthority ContentHandler.getAuthority}
0176: * method will return the authority used in the authentication.
0177: * <p>
0178: * While processing an invocation request the content handler can use the
0179: * {@link Invocation#getInvokingAuthority Invocation.getInvokingAuthority}
0180: * method to verify the authenticity of the invoking application.</p>
0181: *
0182: * <h3>Content Handler Access Control</h3>
0183: * The visibility and accessibility of a content handler
0184: * can be controlled by the content handler itself either through
0185: * dynamic or static registration. To restrict
0186: * access and visibility, the content handler MUST provide the IDs of
0187: * the content handlers that MUST be allowed access.
0188: * If any of the allowed IDs match
0189: * the beginning of the ID of the content handler requesting access, then the
0190: * application will be granted visibility and access to
0191: * the content handler. The comparison is performed as
0192: * if the <code>java.lang.string.startsWith</code> method was used.
0193: * The access controls are only visible to the content handler
0194: * itself using the method
0195: * {@link ContentHandlerServer#getAccessAllowed
0196: * ContentHandlerServer.getAccessAllowed}.
0197: *
0198: * By default,
0199: * access is allowed to all applications and content handlers.
0200: * Access restrictions are established when the content handler is
0201: * registered with the {@link #register register} method.
0202: *
0203: * <A NAME="dynamic"><h3>Dynamic Registration</h3></A>
0204: * <p>
0205: * Dynamic registration is performed by
0206: * initializing the classname, types, suffixes,
0207: * actions, action names, ID, and access restrictions, and passing
0208: * them to the {@link #register register} method.
0209: * The {@link #unregister unregister} method removes
0210: * a registered content handler.
0211: * <p>
0212: * The current registrations can be examined by using various methods to
0213: * get the {@link #getTypes types},
0214: * {@link #getIDs IDs},
0215: * {@link #getSuffixes suffixes},
0216: * {@link #getActions actions},
0217: * or to find a content handler
0218: * by content handler {@link #getServer classname}, or
0219: * to get all of the matching content handlers
0220: * by {@link #forID ID},
0221: * by {@link #forType content type},
0222: * by {@link #forSuffix suffix}, or
0223: * by {@link #forAction action}.
0224: * Only content handlers that are accessible and visible to the
0225: * application will be returned.
0226: *
0227: * <h3><A name="execution"></A>Invoking a Content Handler</h3>
0228: * <P>
0229: * To invoke a content handler, an application initializes an
0230: * Invocation instance with the information needed to identify the
0231: * content and/or the content handler. Typically this could include the
0232: * URL, type, action, and content handler ID.
0233: * The application may also supply arguments and data, and set
0234: * whether a response is required.
0235: *
0236: * The application may request information about the content
0237: * and the content handler that will process it before invocation.
0238: *
0239: * Calling the {@link Registry#invoke Registry.invoke} method
0240: * starts the request.
0241: * <P>
0242: * When invoked, the ID, type, URL, and action are used to identify a
0243: * target content handler. If multiple content handlers are registered
0244: * for the ID, type, suffixes or action, the implementation can decide
0245: * which to use to satisfy the request. If the application needs to
0246: * select which handler to use, the
0247: * {@link Registry#findHandler findHandler} method will
0248: * return the set of matching ContentHandlers. The application can
0249: * choose from the content handlers returned and use
0250: * {@link Invocation#setID Invocation.setID}
0251: * to select a specific handler.
0252: * <P>
0253: * In a runtime environment in which only a single application can
0254: * run at a time, the invoking application must exit before the
0255: * content handler can be started to handle the request.
0256: * Invocation requests are queued so that the invoking
0257: * application and the content handler can be run sequentially in
0258: * resource-constrained environments.
0259: * The return value of {@link Registry#invoke invoke}
0260: * is <code>true</code> to indicate that the application must exit.
0261: * This allows the invoking application to save the users context
0262: * and leave the user interface, if any, with some visual that the
0263: * user will see until the content handler is ready.</P>
0264: *
0265: * <P>
0266: * Invocation processing involves the invoking application,
0267: * the invoked
0268: * content handler, and the application management software (AMS).
0269: * The implementation of the API and the AMS MUST implement the
0270: * queuing of invocations to the appropriate content handler and
0271: * the necessary interactions with the lifecycle to start and
0272: * restart applications and content handlers.
0273: * <p>
0274: * The {@link Registry#invoke invoke} methods initiate the request.
0275: * The URL, type, action, and ID, as described above, are used to
0276: * dispatch the request to an appropriate content handler.
0277: * If the content handler is not running, it MUST be started to process
0278: * the request. If the content handler is already running,
0279: * then the new request MUST be queued to the content handler.
0280: * Only a single instance of each content handler application can be
0281: * active at a time.
0282: * The {@link ContentHandlerServer} class is used to dequeue and process
0283: * requests.
0284: */
0285: public class Registry {
0286:
0287: /**
0288: * Inner class to request security token from SecurityInitializer.
0289: * SecurityInitializer should be able to check this inner class name.
0290: */
0291: static private class SecurityTrusted implements
0292: ImplicitlyTrustedClass {
0293: };
0294:
0295: /** This class has a different security domain than the MIDlet suite */
0296: private static SecurityToken classSecurityToken = SecurityInitializer
0297: .requestToken(new SecurityTrusted());
0298:
0299: /** The mutex used to avoid corruption between threads. */
0300: private static final Object mutex = new Object();
0301:
0302: /** The reference to the RegistryImpl with the real implementation. */
0303: private RegistryImpl impl;
0304:
0305: /**
0306: * Gets the Registry for the application or content handler
0307: * that will be calling registry methods.
0308: * The application is identified by the classname that implements
0309: * the lifecycle of the Java runtime environment.
0310: * The classname must be the name of a registered application class
0311: * or a registered content handler.
0312: * <p>
0313: * For a MIDP implementation,
0314: * application classes must be registered with the
0315: * <code>MIDlet-<n></code> attribute; content handlers are
0316: * registered with the <code>MicroEdition-Handler-<n></code>
0317: * attribute or the {@link #register register} method.
0318: *
0319: * @param classname the application class
0320: * @return a Registry instance providing access to content handler
0321: * registrations and invocations; MUST NOT be <code>null</code>
0322: * @exception IllegalArgumentException is thrown if the classname
0323: * is not a registered application or content handler
0324: * @exception NullPointerException if <code>classname</code> is
0325: * <code>null</code>
0326: */
0327: public static Registry getRegistry(String classname) {
0328: // Find the RegistryImpl instance and get/create the Registry
0329: try {
0330: return findRegistryImpl(classname).getRegistry();
0331: } catch (ContentHandlerException che) {
0332: throw new IllegalArgumentException(che.getMessage());
0333: }
0334: }
0335:
0336: /**
0337: * Gets the RegistryImpl for the classname.
0338: * Create the Registry instance if it has not already been created.
0339: *
0340: * @param classname the classname
0341: * @return RegistryImpl
0342: *
0343: * @exception ContentHandlerException is thrown with a reason of
0344: * <code>NO_REGISTERED_HANDLER</code> if the classname
0345: * is not a registered application or content handler
0346: */
0347: private static RegistryImpl findRegistryImpl(String classname)
0348: throws ContentHandlerException {
0349: synchronized (mutex) {
0350: RegistryImpl impl = RegistryImpl.getRegistryImpl(classname,
0351: classSecurityToken);
0352: // Make sure there is a Registry;
0353: if (impl.getRegistry() == null) {
0354: impl.setRegistry(new Registry(impl));
0355: }
0356: return impl;
0357: }
0358: }
0359:
0360: /**
0361: * Constructor to create a new Registry with a RegistryImpl
0362: * and to insert it int the list of known Registry instances.
0363: * @param impl the RegistryImpl to delegate to
0364: *
0365: * @exception ContentHandlerException if
0366: * the <code>classname</code> is not registered either
0367: * as a MIDlet or a content handler
0368: */
0369: private Registry(RegistryImpl impl) throws ContentHandlerException {
0370: this .impl = impl;
0371: }
0372:
0373: /**
0374: * Gets the content handler server registered for the content
0375: * handler.
0376: * The <code>classname</code> MUST be registered as
0377: * a content handler in the current application package using
0378: * either the {@link #register register} method or
0379: * the static registration attributes.
0380: *
0381: * @param classname the name of an application class or
0382: * content handler registered by this application package
0383: * @return the content handler for the registered
0384: * <code>classname</code> registered by this application package;
0385: * MUST NOT be <code>null</code>
0386: *
0387: * @exception NullPointerException if <code>classname</code> is
0388: * <code>null</code>
0389: * @exception ContentHandlerException is thrown with a reason of
0390: * <code>NO_REGISTERED_HANDLER</code> if there is no
0391: * content handler registered for the classname in the current
0392: * application package
0393: */
0394: public static ContentHandlerServer getServer(String classname)
0395: throws ContentHandlerException {
0396: RegistryImpl registryImpl = findRegistryImpl(classname);
0397: // Insure only one thread promotes to ContentHandlerServer
0398: ContentHandlerImpl server = null;
0399: synchronized (mutex) {
0400: server = registryImpl.getServer();
0401: if (server == null) {
0402: throw new ContentHandlerException(
0403: "No registered handler",
0404: ContentHandlerException.NO_REGISTERED_HANDLER);
0405: }
0406:
0407: if (!(server instanceof ContentHandlerServer)) {
0408: // Not already a ContentHandlerServer; replace
0409: server = new ContentHandlerServerImpl(server);
0410: registryImpl.setServer(server);
0411: }
0412: }
0413: return (ContentHandlerServer) server;
0414: }
0415:
0416: /**
0417: * Registers the application class using content
0418: * type(s), suffix(es), and action(s), action name(s),
0419: * access restrictions and content handler ID.
0420: * <p>
0421: * This method will replace any content handler
0422: * registration in the application package
0423: * that has the same classname.
0424: * The update occurs atomically: the update to the registry
0425: * either occurs or it does not.
0426: * <p>
0427: * The content handler may register the following items:
0428: * <ul>
0429: * <li>zero or more content types</li>
0430: * <li>zero or more suffixes</li>
0431: * <li>zero or more actions</li>
0432: * <li>zero or more mappings from actions to action names</li>
0433: * <li>zero or more IDs of applications allowed access </li>
0434: * <li>an optional application ID</li>
0435: * </ul>
0436: *
0437: * <p>
0438: * If no exceptions are thrown, then the type(s), suffix(s), action(s),
0439: * action names, access restrictions, and ID
0440: * will be registered for the application class.
0441: * <p>
0442: * If an exception is thrown, then the previous registration, if
0443: * any, will not be removed or modified.
0444: *
0445: * @param classname the name of an application class or
0446: * content handler in this application package;
0447: * the value MUST NOT be <code>null</code>;
0448: * and the handler MUST implement the lifecycle of the Java runtime
0449: * environment
0450: * @param types an array of types to register;
0451: * if <code>null</code> it is treated the same as an empty array
0452: * @param suffixes an array of suffixes to register;
0453: * if <code>null</code> it is treated the same as an empty array
0454: * @param actions an array of actions to register;
0455: * if <code>null</code> it is treated the same as an empty array
0456: * @param actionnames an array of ActionNameMaps to register;
0457: * if <code>null</code> it is treated the same as an empty array
0458: * @param ID the content handler ID; if <code>null</code>
0459: * a default non-null value MUST be provided by the implementation
0460: * @param accessAllowed the IDs of applications and content
0461: * handlers that are
0462: * allowed visibility and access to this content handler;
0463: * if <code>null</code> or an empty array then all applications and
0464: * content handlers are allowed access;
0465: * otherwise ONLY applications and content handlers with matching IDs
0466: * are allowed access.
0467: *
0468: * @return the registered ContentHandler; MUST NOT be <code>null</code>
0469: * @exception NullPointerException if any of the following items is
0470: * <code>null</code>:
0471: * <ul>
0472: * <li><code>classname</code></li>
0473: * <li>any array element of <code>types</code>, <code>suffixes</code>,
0474: * <code>actions</code>, <code>actionnames</code>, and
0475: * <code>accessAllowed</code></li>
0476: * </ul>
0477: *
0478: * @exception IllegalArgumentException is thrown:
0479: * <ul>
0480: * <li>if any of the <code>types</code>, <code>suffix</code>,
0481: * <code>actions</code>, or <code>accessAllowed</code>
0482: * strings have a length of zero, or </li>
0483: * <li>if the <code>classname</code> does not implement the valid
0484: * lifecycle for the Java runtime environment,</li>
0485: * <li>if the ID has a length of zero or contains any
0486: * control character or space (U+0000-U+00020),</li>
0487: * <li>if the sequence of actions in any ActionNameMap
0488: * is not the same as the sequence of <code>actions</code>,
0489: * or </li>
0490: * <li>if the locales of the ActionNameMaps are not unique.</li>
0491: * </ul>
0492: * @exception ClassNotFoundException if the <code>classname</code>
0493: * is not present
0494: * @exception ContentHandlerException with an error code of
0495: * {@link ContentHandlerException#AMBIGUOUS} if <code>ID</code>
0496: * (or if ID is null, the default ID)
0497: * is a prefix of any registered handler or if any registered
0498: * handler ID is a prefix of this ID,
0499: * except where the registration is replacing or updating
0500: * an existing registration with the same <code>classname</code>
0501: *
0502: * @exception SecurityException if registration
0503: * is not permitted
0504: */
0505: public ContentHandlerServer register(String classname,
0506: String[] types, String[] suffixes, String[] actions,
0507: ActionNameMap[] actionnames, String ID,
0508: String[] accessAllowed) throws SecurityException,
0509: IllegalArgumentException, ClassNotFoundException,
0510: ContentHandlerException {
0511: // First register the new/replacement handler
0512: impl.register(classname, types, suffixes, actions, actionnames,
0513: ID, accessAllowed);
0514: // Return the value from {#link #getServer(classname)}.
0515: return getServer(classname);
0516: }
0517:
0518: /**
0519: * Removes the content handler registration for the application
0520: * class and any bindings made during registration to the content ID,
0521: * type(s), suffix(es), and action(s), etc.
0522: * Only content handlers registered either statically or dynamically
0523: * in the current application package will be removed.
0524: *
0525: * @param classname the name of the content handler class
0526: * @return <code>true</code> if the content handler registered
0527: * by this application was found and removed;
0528: * <code>false</code> otherwise
0529: * @exception NullPointerException if <code>classname</code> is
0530: * <code>null</code>
0531: */
0532: public boolean unregister(String classname) {
0533: return impl.unregister(classname);
0534: }
0535:
0536: /**
0537: * Gets all of the unique content types for which there are registered
0538: * handlers.
0539: * Type strings are not case sensitive, types that differ
0540: * only by case are treated as a single type.
0541: * Each type is returned only once.
0542: * After a successful registration, the content handler's type(s),
0543: * if any, will appear in this list.
0544: * <P>
0545: * Only content handlers that this application is
0546: * allowed to access will be included.</p>
0547: *
0548: * @return an array of types; MUST NOT be <code>null</code>
0549: */
0550: public String[] getTypes() {
0551: return impl.getTypes();
0552: }
0553:
0554: /**
0555: * Gets the IDs of the registered content handlers.
0556: * <P>
0557: * Only content handlers that this application is
0558: * allowed to access will be included.</p>
0559: * @return an array of content handler IDs;
0560: * MUST NOT be <code>null</code>
0561: */
0562: public String[] getIDs() {
0563: return impl.getIDs();
0564: }
0565:
0566: /**
0567: * Gets the unique actions of the registered content handlers.
0568: * No duplicate strings will be returned.
0569: * After a successful registration the content handler's action(s),
0570: * if any, will appear in this list.
0571: * <P>
0572: * Only content handlers that this application is
0573: * allowed to access will be included.</p>
0574: * @return an array of content handler actions;
0575: * MUST NOT be <code>null</code>
0576: */
0577: public String[] getActions() {
0578: return impl.getActions();
0579: }
0580:
0581: /**
0582: * Gets the unique suffixes of the registered content handlers.
0583: * Suffix strings are not case sensitive, suffixes that differ
0584: * only by case are treated as a single suffix.
0585: * Each suffix is returned only once.
0586: * After a successful registration the content handler's suffix(es),
0587: * if any, will appear in this list.
0588: * <P>
0589: * Only content handlers that this application is
0590: * allowed to access will be included.</p>
0591: * @return an array of content handler suffixes;
0592: * MUST NOT be <code>null</code>
0593: */
0594: public String[] getSuffixes() {
0595: return impl.getSuffixes();
0596: }
0597:
0598: /**
0599: * Gets the registered content handlers for the content type.
0600: * <P>
0601: * Only content handlers that are visible and accessible to this
0602: * application are returned.
0603: *
0604: * @param type the type of the requested content handlers
0605: * @return an array of the <code>ContentHandler</code>s registered
0606: * for the type; MUST NOT be <code>null</code>.
0607: * An empty array is returned if there are no
0608: * <code>ContentHandler</code>s accessible to
0609: * this application with the type equal to the request type.
0610: * @exception NullPointerException if <code>type</code> is
0611: * <code>null</code>
0612: */
0613: public ContentHandler[] forType(String type) {
0614: return impl.forType(type);
0615: }
0616:
0617: /**
0618: * Gets the registered content handlers that support the action.
0619: * <P>
0620: * Only content handlers that are visible and accessible to this
0621: * application are returned.
0622: *
0623: * @param action content handlers for which the action is supported
0624: * @return an array of the <code>ContentHandler</code>s registered
0625: * for the action; MUST NOT be <code>null</code>;
0626: * an empty array is returned if no <code>ContentHandler</code>s
0627: * are accessible to this application
0628: * @exception NullPointerException if <code>action</code> is
0629: * <code>null</code>
0630: */
0631: public ContentHandler[] forAction(String action) {
0632: return impl.forAction(action);
0633: }
0634:
0635: /**
0636: * Gets the content handlers for the suffix.
0637: * <p>
0638: * Only content handlers that are visible and accessible to this
0639: * application are returned.
0640: *
0641: * @param suffix the suffix to be used to get the associated
0642: * content handlers
0643: *
0644: * @return an array of the <code>ContentHandler</code>s registered
0645: * for the suffix; MUST NOT be <code>null</code>.
0646: * An empty array is returned if there are none accessible to
0647: * this application
0648: *
0649: * @exception NullPointerException if <code>suffix</code> is
0650: * <code>null</code>
0651: */
0652: public ContentHandler[] forSuffix(String suffix) {
0653: return impl.forSuffix(suffix);
0654: }
0655:
0656: /**
0657: * Gets the registered content handler for the ID.
0658: * The query can be for an exact match or for the handler
0659: * matching the prefix of the requested ID.
0660: * <P>
0661: * Only a content handler which is visible to and accessible to this
0662: * application will be returned.
0663: * <P>
0664: * The <code>forID</code> method may be useful for applications
0665: * with multiple components or subsystems
0666: * to define a base ID for the application.
0667: * A request to a particular component can be made by appending an
0668: * additional string to the base ID. The additional string can be
0669: * used by the handler itself to dispatch to
0670: * the component or subsystem. The <code>forID</code> method can be used to
0671: * query for the registered content handler.
0672: *
0673: * @param ID the content handler application ID of the content
0674: * handler requested
0675: * @param exact <code>true</code> to require an exact match;
0676: * <code>false</code> to allow a registered content handler ID
0677: * to match a prefix of the requested ID
0678: *
0679: * @return the content handler that matches the ID,
0680: * otherwise <code>null</code>
0681: *
0682: * @exception NullPointerException if <code>ID</code> is
0683: * <code>null</code>
0684: */
0685: public ContentHandler forID(String ID, boolean exact) {
0686: return impl.forID(ID, exact);
0687: }
0688:
0689: /**
0690: * Gets the registered content handlers that could be used for
0691: * this Invocation. Only handlers accessible to the application
0692: * are considered. The values for ID, type, URL, and
0693: * action are used in the following order:
0694: * <ul>
0695: * <li>If the ID is non-null, then a candidate
0696: * handler is determined by the {@link #forID forID}
0697: * method with the parameter <tt>exact</tt> set to false.
0698: * The type and URL are ignored. If there is no handler that matches
0699: * the requested ID then a <tt>ContentHandlerException</tt>
0700: * is thrown.</li>
0701: *
0702: * <li>If the ID and type are <code>null</code> and
0703: * the URL is <code>non-null</code> and
0704: * if the protocol supports typing of content, then
0705: * the type is determined
0706: * as described in {@link Invocation#findType}.
0707: * If the type cannot be determined from the content,
0708: * the type is set to <code>null</code>.</li>
0709: *
0710: * <li>If the ID is null and type is non-null,
0711: * then the set of candidate handlers is determined from the
0712: * {@link #forType forType} method.
0713: * If there are no handlers that match the requested type
0714: * then a <tt>ContentHandlerException</tt> is thrown. </li>
0715: *
0716: * <li>If both the ID and type are <code>null</code> and
0717: * the URL is <code>non-null</code> and
0718: * if the protocol does not support typing of content
0719: * or the type was not available from the content,
0720: * then the set of candidate handlers
0721: * includes any handler with a suffix that matches the
0722: * end of the path component of the URL.
0723: * If there are no handlers that match a registered
0724: * suffix then a <tt>ContentHandlerException</tt> is thrown.</li>
0725: *
0726: * <li>If the ID, type, and URL are all null, the set of candidate
0727: * handlers includes all of the accessible handlers.</li>
0728: *
0729: * <li>If the action is non-null, the set of candidate handlers
0730: * is reduced to contain only handlers that support the
0731: * action.</li>
0732: *
0733: * <li>If the set of candidate handlers is empty
0734: * then a <tt>ContentHandlerException</tt> is thrown.</li>
0735: * </ul>
0736: * <p>
0737: * The calling thread blocks while the ID and type are being determined.
0738: * If a network access is needed there may be an associated delay.
0739: *
0740: * @param invocation the ID, type, action, and URL that
0741: * are needed to identify one or more content handlers;
0742: * must not be <code>null</code>
0743: * @return an array of the <code>ContentHandler</code>(s)
0744: * that could be used for this Invocation; MUST NOT be <code>null</code>;
0745: *
0746: * @exception IOException is thrown if access to the content fails
0747: * @exception ContentHandlerException is thrown with a reason of
0748: * <code>NO_REGISTERED_HANDLER</code> if
0749: * there is no registered content handler that
0750: * matches the requested ID, type, URL, and action
0751: *
0752: * @exception IllegalArgumentException is thrown if ID, type, URL,
0753: * and action are all <code>null</code> or
0754: * if the content is accessed via the URL and the URL is invalid
0755: * @exception NullPointerException is thrown if the
0756: * <code>invocation</code> is <code>null</code>
0757: * @exception SecurityException is thrown if access to the content
0758: * is not permitted
0759: */
0760: public ContentHandler[] findHandler(Invocation invocation)
0761: throws IOException, ContentHandlerException,
0762: SecurityException {
0763: return impl.findHandler(invocation.getInvocImpl());
0764: }
0765:
0766: /**
0767: * Checks the Invocation and uses the ID, type, URL, and action,
0768: * if present, to find a matching ContentHandler and queues this
0769: * request to it.
0770: * <p>
0771: * If the <code>previous</code> Invocation is <code>null</code>, then
0772: * a new transaction is created; otherwise, this
0773: * Invocation will use the same transaction as the
0774: * <code>previous</code> Invocation.
0775: * <p>
0776: * The status of this Invocation MUST be <code>INIT</code>.
0777: * If there is a previous Invocation, that Invocation MUST
0778: * have a status of <code>ACTIVE</code> and this Invocation MUST
0779: * require a response.
0780: * <p>
0781: * Candidate content handlers are found as described in
0782: * {@link #findHandler findHandler}. If any handlers are
0783: * found, one is selected for this Invocation.
0784: * The choice of content handler is implementation dependent.
0785: * <p>
0786: * A copy of the Invocation is made, the status is set to
0787: * <code>ACTIVE</code> and then queued to the
0788: * target content handler.
0789: * If the invoked content handler is not running, it MUST be started
0790: * as described in <a href="#execution">Invoking a Content Handler</a>.
0791: * <p>
0792: * The status of this Invocation is set to <code>WAITING</code>.
0793: * If there is a non-null <code>previous</code> Invocation,
0794: * its status is set to <code>HOLD</code>.
0795: * The <code>previous</code> Invocation is saved in the waiting
0796: * Invocation.
0797: * It can be retrieved by the <code>getPrevious</code> method.
0798: * <p>
0799: * The calling thread blocks while the content handler is being determined.
0800: * If a network access is needed, there may be an associated delay.
0801: *
0802: * @param invocation the Invocation containing the target ID, type, URL,
0803: * actions, arguments, and responseRequired parameters;
0804: * MUST NOT be <code>null</code>
0805: * @param previous a previous Invocation for this Invocation;
0806: * may be <code>null</code>
0807: *
0808: * @return <code>true</code> if the application MUST
0809: * voluntarily exit to allow the target content handler to be started;
0810: * <code>false</code> otherwise
0811: *
0812: * @exception IllegalArgumentException is thrown if:
0813: * <ul>
0814: * <li> the ID, type, URL, and action are all
0815: * <code>null</code>,</li>
0816: * <li> the argument array contains any <code>null</code>
0817: * references, or <li>
0818: * <li> the content is accessed via the URL and the URL is
0819: * invalid, or
0820: * <li> the <code>invocation.getResponseRequired</code>
0821: * method returns <code>false</code> and
0822: * <code>previous</code> is non-null</li>
0823: * </ul>
0824: * @exception IOException is thrown if access to the content fails
0825: * @exception ContentHandlerException is thrown with a reason of
0826: * <code>NO_REGISTERED_HANDLER</code> if
0827: * there is no registered content handler that
0828: * matches the requested ID, type, URL, and action
0829: *
0830: * @exception IllegalStateException is thrown if the status of this
0831: * Invocation is not <code>INIT</code> or if the status of the previous
0832: * Invocation, if any, is not <code>ACTIVE</code>
0833: * @exception NullPointerException is thrown if the
0834: * <code>invocation</code> is <code>null</code>
0835: * @exception SecurityException if access to the content is not permitted
0836: */
0837: public boolean invoke(Invocation invocation, Invocation previous)
0838: throws IllegalArgumentException, IOException,
0839: ContentHandlerException, SecurityException {
0840: if (invocation.getStatus() != Invocation.INIT) {
0841: throw new IllegalStateException();
0842: }
0843:
0844: if (previous != null
0845: && previous.getStatus() != Invocation.ACTIVE) {
0846: throw new IllegalStateException();
0847: }
0848:
0849: InvocationImpl invocImpl = invocation.getInvocImpl();
0850:
0851: InvocationImpl prevImpl = null;
0852: if (previous != null) {
0853: prevImpl = previous.getInvocImpl();
0854: }
0855:
0856: return impl.invoke(invocImpl, prevImpl);
0857: }
0858:
0859: /**
0860: * Checks the Invocation and uses the ID, type, URL, and action,
0861: * if present, to find a matching ContentHandler and queues this
0862: * request to it.
0863: * The behavior is identical to
0864: * <code>invoke(invocation, null)</code>.
0865: *
0866: * @param invocation the Invocation containing the target ID, type,
0867: * URL, action, arguments, and responseRequired parameters;
0868: * MUST NOT be <code>null</code>
0869: *
0870: * @return <code>true</code> if the application MUST
0871: * voluntarily exit to allow the target content handler to be started;
0872: * <code>false</code> otherwise
0873: *
0874: * @exception IllegalArgumentException is thrown if:
0875: * <ul>
0876: * <li> the ID, type, URL, and action are all
0877: * <code>null</code>, or </li>
0878: * <li> the content is accessed via the URL and the URL is
0879: * invalid, or
0880: * <li> the argument array contains any <code>null</code>
0881: * references</li>
0882: * </ul>
0883: * @exception IOException is thrown if access to the content fails
0884: * @exception ContentHandlerException is thrown with a reason of
0885: * <code>NO_REGISTERED_HANDLER</code> if
0886: * there is no registered content handler that
0887: * matches the requested ID, type, URL, and action
0888: *
0889: * @exception IllegalStateException is thrown if the status of this
0890: * Invocation is not <code>INIT</code>
0891: * @exception NullPointerException is thrown if the
0892: * <code>invocation</code> is <code>null</code>
0893: * @exception SecurityException if access to the content is not permitted
0894: */
0895: public boolean invoke(Invocation invocation)
0896: throws IllegalArgumentException, IOException,
0897: ContentHandlerException, SecurityException {
0898: return invoke(invocation, null);
0899: }
0900:
0901: /**
0902: * Reinvokes the Invocation and uses the ID, type, URL, and action
0903: * to find a matching ContentHandler and re-queues this request to
0904: * it. Reinvocation is used to delegate the handling of an active
0905: * Invocation to another content handler.
0906: * The processing of the Invocation instance is complete and the
0907: * status is set to <code>OK</code>. Responses to the
0908: * reinvocation will be queued to the original invoking
0909: * application, if a response is required.
0910: *
0911: * <p>
0912: * The status of this Invocation MUST be <code>ACTIVE</code>.
0913: * <p>
0914: * Candidate content handlers are found as described in
0915: * {@link #findHandler findHandler}. If any handlers are
0916: * found, one is selected for this Invocation.
0917: * The choice of content handler is implementation dependent.
0918: * <p>
0919: * The status of this Invocation is set to <code>OK</code>.
0920: * A copy of the Invocation is made, the status is set to
0921: * <code>ACTIVE</code>, and then queued to the
0922: * target content handler.
0923: * If the invoked content handler application is not running,
0924: * it MUST be started
0925: * as described in <a href="#execution">Invocation Processing</a>.
0926: *
0927: * <p>
0928: * The calling thread blocks while the content handler is being determined.
0929: * If a network access is needed there may be an associated delay.
0930: *
0931: * @param invocation an Invocation containing the target ID, type,
0932: * action, arguments, and responseRequired parameters;
0933: * MUST NOT be <code>null</code>
0934: *
0935: * @return <code>true</code> if the application MUST
0936: * voluntarily exit to allow the target content handler to be started;
0937: * <code>false</code> otherwise
0938: *
0939: * @exception IllegalArgumentException is thrown if:
0940: * <ul>
0941: * <li> the ID, type, and URL are all <code>null</code>, or </li>
0942: * <li> the content is accessed via the URL and the URL is
0943: * invalid, or
0944: * <li> the argument array contains any <code>null</code>
0945: * references</li>
0946: * </ul>
0947: * @exception IOException is thrown if access to the content fails
0948: * @exception ContentHandlerException is thrown with a reason of:
0949: * <code>NO_REGISTERED_HANDLER</code> if
0950: * there is no registered content handler that
0951: * matches the requested ID, type, URL, and action
0952: *
0953: * @exception IllegalStateException is thrown if the status of this
0954: * Invocation is not <code>ACTIVE</code>
0955: * @exception NullPointerException is thrown if the
0956: * <code>invocation</code> is <code>null</code>
0957: * @exception SecurityException if access to the content is not permitted
0958: */
0959: public boolean reinvoke(Invocation invocation)
0960: throws IllegalArgumentException, IOException,
0961: ContentHandlerException, SecurityException {
0962: if (invocation.getStatus() != Invocation.ACTIVE) {
0963: throw new IllegalStateException();
0964: }
0965:
0966: return impl.reinvoke(invocation.getInvocImpl());
0967: }
0968:
0969: /**
0970: * Gets the next Invocation response pending for this application.
0971: * If requested, the method waits until an Invocation response
0972: * is available.
0973: * The method can be unblocked with a call to
0974: * {@link #cancelGetResponse cancelGetResponse}.
0975: * The application can process the Invocation based on
0976: * its status. The status is one of
0977: * <code>OK</code>, <code>CANCELLED</code>, <code>ERROR</code>,
0978: * or <code>INITIATED</code>.
0979: * <p>
0980: * If the Invocation was invoked with
0981: * {@link #invoke(Invocation invocation, Invocation previous)},
0982: * the <code>getPrevious</code> method MUST return the
0983: * previous Invocation.
0984: * If the status of the previous Invocation is <code>HOLD</code>
0985: * then its status is restored to <code>ACTIVE</code>.
0986: *
0987: * <p>
0988: * If the original Invocation instance is reachable, then it
0989: * MUST be updated with the values from the response
0990: * and be returned to the application. If it is not
0991: * reachable, then a new instance is returned from
0992: * <code>getResponse</code> with the response values.
0993: *
0994: * @param wait <code>true</code> if the method
0995: * MUST wait for an Invocation if one is not available;
0996: * otherwise <code>false</code> if the method MUST NOT wait
0997: *
0998: * @return the next pending response Invocation or <code>null</code>
0999: * if the <code>wait</code> is false and no Invocation is available or
1000: * if cancelled with {@link #cancelGetResponse}
1001: * @see #invoke
1002: * @see #cancelGetResponse
1003: */
1004: public Invocation getResponse(boolean wait) {
1005: Invocation response = new Invocation();
1006: response = impl.getResponse(wait, response.getInvocImpl());
1007: return response;
1008: }
1009:
1010: /**
1011: * Cancels a pending <code>getResponse</code>.
1012: * This method will force a thread blocked in a call to the
1013: * <code>getResponse</code> method for this Registry instance
1014: * to return early.
1015: * If no thread is blocked; this call has no effect.
1016: */
1017: public void cancelGetResponse() {
1018: impl.cancelGetResponse();
1019: }
1020:
1021: /**
1022: * Sets the listener to be notified when a new response is
1023: * available for the application context. The request must
1024: * be retrieved using {@link #getResponse getResponse}.
1025: * If the listener is <code>non-null</code> and a response is
1026: * available, the listener MUST be notified.
1027: * <br>
1028: * Note that if <tt>getResponse</tt> is being called concurrently
1029: * with the listener then the listener may not be called because
1030: * the response has already been returned to the application.
1031: * The <tt>invocationResponseNotify</tt> is only used as a hint that
1032: * a response may be available.
1033: *
1034: * @param listener the listener to register;
1035: * <code>null</code> to remove the listener
1036: */
1037: public void setListener(ResponseListener listener) {
1038: impl.setListener(listener);
1039: }
1040:
1041: /**
1042: * Gets the content handler ID for the current application.
1043: * The ID uniquely identifies the content handler.
1044: * If the application is a content handler as returned from
1045: * {@link #getServer getServer} then the ID MUST be
1046: * the content handler ID returned from
1047: * {@link ContentHandlerServer#getID ContentHandlerServer.getID}.
1048: * Otherwise, the ID will be generated for the profile.
1049: * The package documentation
1050: * for "Content Handlers and the Mobile Information Device Profile"
1051: * defines the value for MIDP.
1052: * @return the ID; MUST NOT be <code>null</code>
1053: */
1054: public String getID() {
1055: return impl.getID();
1056: }
1057: }
|