FileDocCategorySizeDatePackage
InvocationStore.javaAPI DocphoneME MR2 API (J2ME)19137Wed May 02 18:00:44 BST 2007com.sun.midp.content

InvocationStore

public class InvocationStore extends Object
The store for pending Invocations. New Invocations are queued with {@link #put} method and retrieved with the {@link #get} method. The {@link #cancel} method is used to unblock calls to blocking {@link #get} methods.

Synchronization is performed by the native methods; access is serialized by the VM running in a single native thread and by NOT preempting native method calls. The native code uses the SNI ability to block a thread and unblock it at a later time. The implementation does not poll for requests but blocks, if requested, until it is unblocked.

Fields Summary
private static int
cancelCount
The count of cancel requests; access is not synchronized because it is only incrementes in one place and it does not matter if it is incremented once or twice. A new cancel has occurred if the value has been incremented since an operation was started.
private static final int
MODE_REQUEST
The mode for get to retrieve a new request.
private static final int
MODE_RESPONSE
The mode for get to retrieve a new response.
private static final int
MODE_CLEANUP
The mode for get to retrieve a new cleanup.
private static final int
MODE_LREQUEST
The mode for listen for new unmarked request.
private static final int
MODE_LRESPONSE
The mode for listen for a new unmarked response.
private static final int
MODE_TID
The mode for get to retreive byte tid.
private static final int
MODE_TID_NEXT
The mode to get the Invocation after tid.
private static final int
MODE_TID_PREV
The mode to get the Invocation before tid.
Constructors Summary
private InvocationStore()
Private constructor to prevent instance creation.


               
      
    
Methods Summary
static voidcancel()
Cancel a blocked {@link #get} or {@link #listen} method if it is blocked in the native code.

	cancelCount++;
	cancel0();
    
private static native voidcancel0()
Native method to unblock any threads that might be waiting for an invocation by way of having called {@link #get0}.

private static InvocationImplget(InvocationImpl invoc, int mode, boolean shouldBlock)
Get an InvocationImpl from the store using a MIDlet suiteId and classname. The mode controls whether getting an Invocation from the store removes it from the store.

param
invoc InvocationImpl to fill in with result
param
mode one of {@link #MODE_REQUEST}, {@link #MODE_RESPONSE}, or {@link #MODE_CLEANUP}, {@link #MODE_LREQUEST}, or {@link #MODE_LRESPONSE}, {@link #MODE_TID}.
param
shouldBlock true if the method should block waiting for an Invocation
return
InvocationImpl if any was found with the same MIDlet suiteId and classname if one was requested; null is returned if there is no matching Invocation

	String classname = invoc.classname;
	invoc.setArgs(null);
	invoc.setData(null);

	int s = 0;
	int oldCancelCount = cancelCount;
	while ((s = get0(invoc, invoc.suiteId, invoc.classname,
			 mode, shouldBlock)) != 1) {
	    if (s == -1) {
		/*
		 * Sizes of arguments and data buffers were insufficient
		 * reallocate and retry.
		 */
		invoc.setArgs(new String[invoc.argsLen]);
		invoc.setData(new byte[invoc.dataLen]);
		continue;
	    }
	    // Don't wait unless requested
	    if (!shouldBlock) {
		break;
	    }
	    // No matching request; retry unless cancelled
	    if (cancelCount > oldCancelCount) {
		// Was cancelled; s == 0 -> no Invocation
		break;
	    }
	}

	// Update the return if no invocation
	if (s == 0) {
	    invoc = null;
	}

	if (AppProxy.LOG_INFO) {
	    AppProxy.getCurrent().logInfo("Store get: " +
					  classname +
					  ", mode: " + mode +
					  ", " + invoc);
	}
        return invoc;
    
private static native intget0(InvocationImpl invoc, int suiteId, java.lang.String classname, int mode, boolean shouldBlock)
Native method to fill an available InvocationImpl with an available stored Invocation with the status (if non-zero), the suiteId, classname in the prototype InvocationImpl. Any InvocationImpl with a matching status, suite and class will be returned. Depending on the mode the stored invocation will be removed from the store.

param
invoc the Invocation containing the suiteId and classname to fill in with an available invocation.
param
suiteId the MIDletSuite ID to match
param
classname the classname to match
param
mode one of {@link #MODE_REQUEST}, {@link #MODE_RESPONSE}, or {@link #MODE_CLEANUP}
param
shouldBlock True if the method should block until an Invocation is available
return
1 if a matching invocation was found and returned in its entirety; zero if there was no matching invocation; -1 if the sizes of the arguments or parameter array were wrong
see
#get

static InvocationImplgetByTid(int tid, int relative)
Get an Invocation from the store based on its tid. The normal state transitions and dispositions are NOT performed. If TID == 0 then the first tid is used as the reference. If TID == 0 and relative == 0 then null is returned. This method never waits.

param
tid the tid to fetch
param
relative -1, 0, +1 to get previous, equal, or next
return
an InvocationImpl object if a matching tid was found; otherwise null

        InvocationImpl invoc = new InvocationImpl();
        int mode = MODE_TID;
        if (tid != 0) {
            if (relative < 0) {
                mode = MODE_TID_PREV;
            } else if (relative > 0) {
                mode = MODE_TID_NEXT;
            }
        }
        invoc.suiteId = MIDletSuite.UNUSED_SUITE_ID;
        invoc.classname = null;
        invoc.tid = tid;
        return get(invoc, mode, false);
    
static InvocationImplgetCleanup(int suiteId, java.lang.String classname)
Performs cleanup for a ContentHandler by suiteId and classname.

Any marked {@link #setCleanup} invocations still in the queue are handled based on status:

  • ACTIVE Invocations are returned from this method so they can be have the ERROR status set and so the invoking application relaunched.
  • INIT Invocations are requeued to the invoking application with ERROR status.
  • OK, CANCELLED, ERROR, or INITIATED Invocations are discrded.
  • HOLD status Invocations are retained pending completion of previous Invocation. TBD: Chained HOLDs...

param
suiteId the MIDletSuite ID
param
classname the classname
return
InvocationImpl if any was found with the same MIDlet suiteId and classname; null is returned if there is no matching Invocation

        InvocationImpl invoc = new InvocationImpl();
        invoc.suiteId = suiteId;
        invoc.classname = classname;

	return get(invoc, MODE_CLEANUP, false);
    
static InvocationImplgetRequest(int suiteId, java.lang.String classname, boolean shouldBlock)
Get a new InvocationImpl request from the store using a MIDlet suiteId and classname.

param
suiteId the MIDlet suiteId to search for, MUST not be null
param
classname to match, must not be null
param
shouldBlock true if the method should block waiting for an Invocation
return
InvocationImpl if any was found with the same MIDlet suiteId and classname with its status is set to ACTIVE; null is returned if there is no matching Invocation

        InvocationImpl invoc = new InvocationImpl();
        if (suiteId == MIDletSuite.UNUSED_SUITE_ID || classname == null) {
            throw new NullPointerException();
        }
        invoc.suiteId = suiteId;
        invoc.classname = classname;

        return get(invoc, MODE_REQUEST, shouldBlock);
    
static InvocationImplgetResponse(InvocationImpl invoc, int suiteId, java.lang.String classname, boolean shouldBlock)
Get a new InvocationImpl response from the store using a MIDlet suiteId and classname. The response is removed from the store.

param
invoc an InvocationImpl to fill with the response
param
suiteId the MIDletSuite ID
param
classname the classname
param
shouldBlock true if the method should block waiting for an Invocation
return
InvocationImpl if any was found with the same MIDlet suiteId and classname if one was requested; null is returned if there is no matching Invocation

        invoc.suiteId = suiteId;
        invoc.classname = classname;

	return get(invoc, MODE_RESPONSE, shouldBlock);
    
static booleanlisten(int suiteId, java.lang.String classname, boolean request, boolean shouldBlock)
Listen for a matching invocation. When a matching invocation is present, true is returned. Each Invocation instance is only returned once. After it has been returned once; it is ignored subsequently.

param
suiteId the MIDlet suiteId to search for, MUST not be null
param
classname to match, must not be null
param
request true to listen for a request; else a response
param
shouldBlock true if the method should block waiting for an Invocation
return
true if a matching invocation is present; false otherwise

        if (suiteId == MIDletSuite.UNUSED_SUITE_ID || classname == null) {
            throw new NullPointerException();
        }
        int mode = (request ? MODE_LREQUEST : MODE_LRESPONSE);
        boolean pending = false;

        int oldCancelCount = cancelCount;
        while ((pending = listen0(suiteId, classname,
                                  mode, shouldBlock)) == false &&
                                  shouldBlock) {
            // No pending request; retry unless cancelled
            if (cancelCount > oldCancelCount) {
                // Was cancelled; s == 0 -> no Invocation
                break;
            }
        }

        if (AppProxy.LOG_INFO) {
            AppProxy.getCurrent().logInfo("Store listen: " + classname +
                                          ", request: " + request +
                                          ", pending: " + pending);
        }
        return pending;
    
private static native booleanlisten0(int suiteId, java.lang.String classname, int mode, boolean shouldBlock)
Native method to listen for pending invocations with matching suite, classname, and status. Cancel() will also cause this method to return if blocked. Each Invocation will only be returned once to prevent multiple notifications.

param
suiteId the MIDletSuite ID to match
param
classname the classname to match
param
mode one of {@link #MODE_LREQUEST}, {@link #MODE_LRESPONSE}
param
shouldBlock true if the method should block until an Invocation is available
return
true if a matching invocation was found; otherwise false.
see
#get0

static voidput(InvocationImpl invoc)
Put a new Invocation into the store. It can be modified by {@link #setStatus}. The TID (transaction ID) is updated with a newly assigned value.

param
invoc an InvocationImpl instance with the members properly initialized.
see
#getRequest
see
#getResponse

        if (invoc.suiteId == MIDletSuite.UNUSED_SUITE_ID ||
                invoc.classname == null) {
            throw new NullPointerException();
        }
        put0(invoc);
	if (AppProxy.LOG_INFO) {
	    AppProxy.getCurrent().logInfo("Store put0: " + invoc);
	}
    
private static native voidput0(InvocationImpl invoc)
Native method to store a new Invocation. All of the fields of the InvocationImpl are stored.

param
invoc the InvocationImpl to store

static voidsetCleanup(int suiteId, java.lang.String classname, boolean cleanup)
Marks any existing invocations for the content handler. Any marked invocation will be modified by {@link #getCleanup}.

param
suiteId the suite to mark
param
classname the MIDlet within the suite
param
cleanup true to mark the Invocation for cleanup at exit

        if (AppProxy.LOG_INFO) {
            AppProxy.getCurrent().logInfo("Store setCleanup: " + classname +
                                          ": " + cleanup);
        }
        setCleanup0(suiteId, classname, cleanup);
    
private static native voidsetCleanup0(int suiteId, java.lang.String classname, boolean cleanup)
Sets the cleanup flag in matching Invocations. Any marked invocation will be modified by {@link #getCleanup}.

param
suiteId the MIDlet suiteId to search for, MUST not be null
param
classname to match, must not be null
param
cleanup true to mark the Invocation for cleanup at exit

static voidsetListenNotify(int suiteId, java.lang.String classname, boolean request)
Reset the flags for requests or responses that are pending. Once reset, any pending requests or responses will be returned when listen0 is called.

param
suiteId the MIDlet suiteId to search for, MUST not be null
param
classname to match, must not be null
param
request true to reset request notification flags; else reset response notification flags

        if (suiteId == MIDletSuite.UNUSED_SUITE_ID || classname == null) {
            throw new NullPointerException();
        }

        int mode = (request ? MODE_LREQUEST : MODE_LRESPONSE);
        setListenNotify0(suiteId, classname, mode);

        if (AppProxy.LOG_INFO) {
            AppProxy.getCurrent().logInfo("Store setListenNotify: " +
                                          classname +
                                          ", request: " + request);
        }
    
private static native voidsetListenNotify0(int suiteId, java.lang.String classname, int mode)
Native method to reset the listen notified state for pending invocations with matching suite, classname and status. Each Invocation will only be returned once to prevent multiple notifications.

param
suiteId the MIDletSuite ID to match
param
classname the classname to match
param
mode one of {@link #MODE_LREQUEST}, {@link #MODE_LRESPONSE} false to reset the notified state for responses
see
#listen0

static voidsetParams(InvocationImpl invoc)
Updates the parameters of the invocation in the native store. The ID, URL, type, action, arguments, and data are stored again in native.

param
invoc an InvocationImpl previously retrieved with get

	setParams0(invoc);
	if (AppProxy.LOG_INFO) {
	    AppProxy.getCurrent().logInfo("Store setParams0: " + invoc);
	}
    
private static native voidsetParams0(InvocationImpl invoc)
Updates the parameters of the invocation in the native store. The ID, URL, type, action, arguments, and data are stored again in native.

param
invoc an InvocationImpl previously retrieved with get

static voidsetStatus(InvocationImpl invoc)
Sets the status of an existing Invocation. If the status is OK, CANCELLED, ERROR, or INITIATED and a response is required then the invocation is requeued to the invoking application; if no response is required the request is discarded and the transaction id (tid) is set to zero.

param
invoc an InvocationImpl previously retrieved with get

	setStatus0(invoc);
	if (AppProxy.LOG_INFO) {
	    AppProxy.getCurrent().logInfo("Store setStatus0: " + invoc);
	}
    
private static native voidsetStatus0(InvocationImpl invoc)
Sets the status of an existing Invocation and handles response required behavior.

param
invoc an InvocationImpl previously retrieved with get.

static intsize()
Return the number of invocations in the native queue.

return
the number of invocations in the native queue

        return size0();
    
private static native intsize0()
Return the number of invocations in the native queue.

return
the number of invocations in the native queue