Source Code Cross Referenced for InvocationStore.java in  » 6.0-JDK-Modules » j2me » com » sun » midp » content » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » com.sun.midp.content 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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 com.sun.midp.content;
028:
029:        import com.sun.midp.midlet.MIDletSuite;
030:
031:        /**
032:         * The store for pending Invocations.
033:         * New Invocations are queued with {@link #put} method and
034:         * retrieved with the {@link #get} method. The {@link #cancel}
035:         * method is used to unblock calls to blocking {@link #get} methods.
036:         * <p>
037:         * Synchronization is performed by the native methods; access
038:         * is serialized by the VM running in a single native thread and
039:         * by NOT preempting native method calls.
040:         * The native code uses the SNI ability to block a thread and
041:         * unblock it at a later time. The implementation does not poll for
042:         * requests but blocks, if requested, until it is unblocked.
043:         */
044:        class InvocationStore {
045:
046:            /**
047:             * The count of cancel requests; access is not synchronized because
048:             * it is only incrementes in one place and it does not matter if it is
049:             * incremented once or twice.  A new cancel has occurred if
050:             * the value has been incremented since an operation was started.
051:             */
052:            private static int cancelCount;
053:
054:            /** The mode for get to retrieve a new request. */
055:            private static final int MODE_REQUEST = 0;
056:
057:            /** The mode for get to retrieve a new response. */
058:            private static final int MODE_RESPONSE = 1;
059:
060:            /** The mode for get to retrieve a new cleanup. */
061:            private static final int MODE_CLEANUP = 2;
062:
063:            /** The mode for listen for new unmarked request. */
064:            private static final int MODE_LREQUEST = 3;
065:
066:            /** The mode for listen for a new unmarked response. */
067:            private static final int MODE_LRESPONSE = 4;
068:
069:            /** The mode for get to retrieve a new ACTIVE, HOLD, or WAITING request. */
070:            // private static final int MODE_PENDING = 5;
071:            /** The mode for get to retreive byte <code>tid</code>. */
072:            private static final int MODE_TID = 6;
073:
074:            /** The mode to get the Invocation after <code>tid</code>. */
075:            private static final int MODE_TID_NEXT = 7;
076:
077:            /** The mode to get the Invocation before <code>tid</code>. */
078:            private static final int MODE_TID_PREV = 8;
079:
080:            /**
081:             * Private constructor to prevent instance creation.
082:             */
083:            private InvocationStore() {
084:            }
085:
086:            /**
087:             * Put a new Invocation into the store.
088:             * It can be modified by {@link #setStatus}.
089:             * The TID (transaction ID) is updated with a newly assigned value.
090:             *
091:             * @param invoc an InvocationImpl instance with the members properly
092:             *  initialized.
093:             * @see #getRequest
094:             * @see #getResponse
095:             */
096:            static void put(InvocationImpl invoc) {
097:                if (invoc.suiteId == MIDletSuite.UNUSED_SUITE_ID
098:                        || invoc.classname == null) {
099:                    throw new NullPointerException();
100:                }
101:                put0(invoc);
102:                if (AppProxy.LOG_INFO) {
103:                    AppProxy.getCurrent().logInfo("Store put0: " + invoc);
104:                }
105:            }
106:
107:            /**
108:             * Get a new InvocationImpl request from the store using a MIDlet
109:             * suiteId and classname.
110:             *
111:             * @param suiteId the MIDlet suiteId to search for,
112:             *  MUST not be <code>null</code>
113:             * @param classname to match, must not be null
114:             * @param shouldBlock true if the method should block
115:             *      waiting for an Invocation
116:             *
117:             * @return <code>InvocationImpl</code> if any was found with
118:             *  the same MIDlet suiteId and classname with
119:             *  its status is set to ACTIVE;
120:             *  <code>null</code> is returned if there is no matching Invocation
121:             */
122:            static InvocationImpl getRequest(int suiteId, String classname,
123:                    boolean shouldBlock) {
124:                InvocationImpl invoc = new InvocationImpl();
125:                if (suiteId == MIDletSuite.UNUSED_SUITE_ID || classname == null) {
126:                    throw new NullPointerException();
127:                }
128:                invoc.suiteId = suiteId;
129:                invoc.classname = classname;
130:
131:                return get(invoc, MODE_REQUEST, shouldBlock);
132:            }
133:
134:            /**
135:             * Get a new InvocationImpl response from the store using a
136:             * MIDlet suiteId and classname.
137:             * The response is removed from the store.
138:             *
139:             * @param invoc an InvocationImpl to fill with the response
140:             * @param suiteId the MIDletSuite ID
141:             * @param classname the classname
142:             * @param shouldBlock true if the method should block
143:             *      waiting for an Invocation
144:             *
145:             * @return <code>InvocationImpl</code> if any was found with
146:             *  the same MIDlet suiteId and classname if one was requested;
147:             *  <code>null</code> is returned if there is no matching Invocation
148:             */
149:            static InvocationImpl getResponse(InvocationImpl invoc,
150:                    int suiteId, String classname, boolean shouldBlock) {
151:                invoc.suiteId = suiteId;
152:                invoc.classname = classname;
153:
154:                return get(invoc, MODE_RESPONSE, shouldBlock);
155:            }
156:
157:            /**
158:             * Performs cleanup for a ContentHandler
159:             * by suiteId and classname.
160:             * <p>
161:             * Any marked {@link #setCleanup} invocations still in the queue
162:             * are handled based on status:
163:             * <UL>
164:             * <li>ACTIVE Invocations are returned from this method
165:             *    so they can be have the ERROR status set and so the
166:             *    invoking application relaunched.</li>
167:             * <li>INIT Invocations are requeued to the invoking application
168:             *    with ERROR status. </li>
169:             * <li>OK, CANCELLED, ERROR, or INITIATED Invocations are
170:             *    discrded.</li>
171:             * <li>HOLD status Invocations are retained pending
172:             *    completion of previous Invocation.  TBD: Chained HOLDs...</li>
173:             * </ul>
174:             *
175:             * @param suiteId the MIDletSuite ID
176:             * @param classname the classname
177:             *
178:             * @return <code>InvocationImpl</code> if any was found with
179:             *  the same MIDlet suiteId and classname;
180:             *  <code>null</code> is returned if there is no matching Invocation
181:             */
182:            static InvocationImpl getCleanup(int suiteId, String classname) {
183:                InvocationImpl invoc = new InvocationImpl();
184:                invoc.suiteId = suiteId;
185:                invoc.classname = classname;
186:
187:                return get(invoc, MODE_CLEANUP, false);
188:            }
189:
190:            /**
191:             * Get an Invocation from the store based on its <code>tid</code>.
192:             * The normal state transitions and dispositions are NOT performed.
193:             * If TID == 0 then the first tid is used as the reference.
194:             * If TID == 0 and relative == 0 then null is returned.
195:             * This method never waits.
196:             *
197:             * @param tid the <code>tid</code> to fetch
198:             * @param relative -1, 0, +1 to get previous, equal, or next
199:             * @return an InvocationImpl object if a matching tid was found;
200:             *  otherwise <code>null</code>
201:             */
202:            static InvocationImpl getByTid(int tid, int relative) {
203:                InvocationImpl invoc = new InvocationImpl();
204:                int mode = MODE_TID;
205:                if (tid != 0) {
206:                    if (relative < 0) {
207:                        mode = MODE_TID_PREV;
208:                    } else if (relative > 0) {
209:                        mode = MODE_TID_NEXT;
210:                    }
211:                }
212:                invoc.suiteId = MIDletSuite.UNUSED_SUITE_ID;
213:                invoc.classname = null;
214:                invoc.tid = tid;
215:                return get(invoc, mode, false);
216:            }
217:
218:            /**
219:             * Get an InvocationImpl from the store using a MIDlet suiteId
220:             * and classname.
221:             * The mode controls whether getting an Invocation
222:             * from the store removes it from the store.
223:             *
224:             * @param invoc InvocationImpl to fill in with result
225:             * @param mode one of {@link #MODE_REQUEST}, {@link #MODE_RESPONSE},
226:             *    or {@link #MODE_CLEANUP}, {@link #MODE_LREQUEST},
227:             *    or {@link #MODE_LRESPONSE}, {@link #MODE_TID}.
228:             * @param shouldBlock true if the method should block
229:             *      waiting for an Invocation
230:             *
231:             * @return <code>InvocationImpl</code> if any was found with
232:             *  the same MIDlet suiteId and classname if one was requested;
233:             *  <code>null</code> is returned if there is no matching Invocation
234:             */
235:            private static InvocationImpl get(InvocationImpl invoc, int mode,
236:                    boolean shouldBlock) {
237:                String classname = invoc.classname;
238:                invoc.setArgs(null);
239:                invoc.setData(null);
240:
241:                int s = 0;
242:                int oldCancelCount = cancelCount;
243:                while ((s = get0(invoc, invoc.suiteId, invoc.classname, mode,
244:                        shouldBlock)) != 1) {
245:                    if (s == -1) {
246:                        /*
247:                         * Sizes of arguments and data buffers were insufficient
248:                         * reallocate and retry.
249:                         */
250:                        invoc.setArgs(new String[invoc.argsLen]);
251:                        invoc.setData(new byte[invoc.dataLen]);
252:                        continue;
253:                    }
254:                    // Don't wait unless requested
255:                    if (!shouldBlock) {
256:                        break;
257:                    }
258:                    // No matching request; retry unless cancelled
259:                    if (cancelCount > oldCancelCount) {
260:                        // Was cancelled; s == 0 -> no Invocation
261:                        break;
262:                    }
263:                }
264:
265:                // Update the return if no invocation
266:                if (s == 0) {
267:                    invoc = null;
268:                }
269:
270:                if (AppProxy.LOG_INFO) {
271:                    AppProxy.getCurrent().logInfo(
272:                            "Store get: " + classname + ", mode: " + mode
273:                                    + ", " + invoc);
274:                }
275:                return invoc;
276:            }
277:
278:            /**
279:             * Sets the status of an existing Invocation.
280:             * If the status is OK, CANCELLED, ERROR, or INITIATED
281:             * and a response is required then the invocation is
282:             * requeued to the invoking application; if no response
283:             * is required the request is discarded and the transaction id (tid)
284:             * is set to zero.
285:             *
286:             * @param invoc an InvocationImpl previously retrieved with get
287:             */
288:            static void setStatus(InvocationImpl invoc) {
289:                setStatus0(invoc);
290:                if (AppProxy.LOG_INFO) {
291:                    AppProxy.getCurrent().logInfo("Store setStatus0: " + invoc);
292:                }
293:            }
294:
295:            /**
296:             * Updates the parameters of the invocation in the native store.
297:             * The ID, URL, type, action, arguments, and data are
298:             * stored again in native.
299:             *
300:             * @param invoc an InvocationImpl previously retrieved with get
301:             */
302:            static void setParams(InvocationImpl invoc) {
303:                setParams0(invoc);
304:                if (AppProxy.LOG_INFO) {
305:                    AppProxy.getCurrent().logInfo("Store setParams0: " + invoc);
306:                }
307:            }
308:
309:            /**
310:             * Listen for a matching invocation.
311:             * When a matching invocation is present, true is returned.
312:             * Each Invocation instance is only returned once.
313:             * After it has been returned once; it is ignored subsequently.
314:             *
315:             * @param suiteId the MIDlet suiteId to search for,
316:             *  MUST not be <code>null</code>
317:             * @param classname to match, must not be null
318:             * @param request true to listen for a request; else a response
319:             * @param shouldBlock true if the method should block
320:             *      waiting for an Invocation
321:             *
322:             * @return true if a matching invocation is present; false otherwise
323:             */
324:            static boolean listen(int suiteId, String classname,
325:                    boolean request, boolean shouldBlock) {
326:                if (suiteId == MIDletSuite.UNUSED_SUITE_ID || classname == null) {
327:                    throw new NullPointerException();
328:                }
329:                int mode = (request ? MODE_LREQUEST : MODE_LRESPONSE);
330:                boolean pending = false;
331:
332:                int oldCancelCount = cancelCount;
333:                while ((pending = listen0(suiteId, classname, mode, shouldBlock)) == false
334:                        && shouldBlock) {
335:                    // No pending request; retry unless cancelled
336:                    if (cancelCount > oldCancelCount) {
337:                        // Was cancelled; s == 0 -> no Invocation
338:                        break;
339:                    }
340:                }
341:
342:                if (AppProxy.LOG_INFO) {
343:                    AppProxy.getCurrent().logInfo(
344:                            "Store listen: " + classname + ", request: "
345:                                    + request + ", pending: " + pending);
346:                }
347:                return pending;
348:            }
349:
350:            /**
351:             * Reset the flags for requests or responses that are pending.
352:             * Once reset, any pending requests or responses will be
353:             * returned when listen0 is called.
354:             *
355:             * @param suiteId the MIDlet suiteId to search for,
356:             *  MUST not be <code>null</code>
357:             * @param classname to match, must not be null
358:             * @param request true to reset request notification flags;
359:             *   else reset response notification flags
360:             */
361:            static void setListenNotify(int suiteId, String classname,
362:                    boolean request) {
363:                if (suiteId == MIDletSuite.UNUSED_SUITE_ID || classname == null) {
364:                    throw new NullPointerException();
365:                }
366:
367:                int mode = (request ? MODE_LREQUEST : MODE_LRESPONSE);
368:                setListenNotify0(suiteId, classname, mode);
369:
370:                if (AppProxy.LOG_INFO) {
371:                    AppProxy.getCurrent().logInfo(
372:                            "Store setListenNotify: " + classname
373:                                    + ", request: " + request);
374:                }
375:            }
376:
377:            /**
378:             * Cancel a blocked {@link #get}  or {@link #listen}
379:             * method if it is blocked in the native code.
380:             */
381:            static void cancel() {
382:                cancelCount++;
383:                cancel0();
384:            }
385:
386:            /**
387:             * Marks any existing invocations for the content handler.
388:             * Any marked invocation will be modified by {@link #getCleanup}.
389:             *
390:             * @param suiteId the suite to mark
391:             * @param classname the MIDlet within the suite
392:             * @param cleanup <code>true</code> to mark the Invocation for
393:             *   cleanup at exit
394:             */
395:
396:            static void setCleanup(int suiteId, String classname,
397:                    boolean cleanup) {
398:                if (AppProxy.LOG_INFO) {
399:                    AppProxy.getCurrent().logInfo(
400:                            "Store setCleanup: " + classname + ": " + cleanup);
401:                }
402:                setCleanup0(suiteId, classname, cleanup);
403:            }
404:
405:            /**
406:             * Return the number of invocations in the native queue.
407:             * @return the number of invocations in the native queue
408:             */
409:            static int size() {
410:                return size0();
411:            }
412:
413:            /**
414:             * Native method to store a new Invocation.
415:             * All of the fields of the InvocationImpl are stored.
416:             * @param invoc the InvocationImpl to store
417:             */
418:            private static native void put0(InvocationImpl invoc);
419:
420:            /**
421:             * Native method to fill an available InvocationImpl with an
422:             * available stored Invocation with the status (if non-zero),
423:             * the suiteId, classname in the prototype InvocationImpl.
424:             * Any InvocationImpl with a matching status, suite and
425:             * class will be returned.
426:             * Depending on the mode the stored invocation will be removed
427:             * from the store.
428:             * @param invoc the Invocation containing the suiteId and
429:             *  classname to fill in with an available invocation.
430:             * @param suiteId the MIDletSuite ID to match
431:             * @param classname the classname to match
432:             * @param mode one of {@link #MODE_REQUEST}, {@link #MODE_RESPONSE},
433:             *    or {@link #MODE_CLEANUP}
434:             * @param shouldBlock True if the method should block until an
435:             *    Invocation is available
436:             * @return 1 if a matching invocation was found and returned
437:             *    in its entirety; zero if there was no matching invocation;
438:             *    -1 if the sizes of the arguments or parameter array were wrong
439:             * @see #get
440:             */
441:            private static native int get0(InvocationImpl invoc, int suiteId,
442:                    String classname, int mode, boolean shouldBlock);
443:
444:            /**
445:             * Sets the status of an existing Invocation
446:             * and handles response required behavior.
447:             *
448:             * @param invoc an InvocationImpl previously retrieved with get.
449:             */
450:            private static native void setStatus0(InvocationImpl invoc);
451:
452:            /**
453:             * Updates the parameters of the invocation in the native store.
454:             * The ID, URL, type, action, arguments, and data are
455:             * stored again in native.
456:             *
457:             * @param invoc an InvocationImpl previously retrieved with get
458:             */
459:            private static native void setParams0(InvocationImpl invoc);
460:
461:            /**
462:             * Native method to listen for pending invocations with
463:             * matching suite, classname, and status. Cancel() will
464:             * also cause this method to return if blocked.
465:             * Each Invocation will only be returned once to prevent
466:             * multiple notifications.
467:             *
468:             * @param suiteId the MIDletSuite ID to match
469:             * @param classname the classname to match
470:             * @param mode one of {@link #MODE_LREQUEST}, {@link #MODE_LRESPONSE}
471:             * @param shouldBlock true if the method should block until an
472:             *     Invocation is available
473:             * @return true if a matching invocation was found; otherwise false.
474:             * @see #get0
475:             */
476:            private static native boolean listen0(int suiteId,
477:                    String classname, int mode, boolean shouldBlock);
478:
479:            /**
480:             * Native method to reset the listen notified state for pending
481:             * invocations with matching suite, classname and status.
482:             * Each Invocation will only be returned once to prevent
483:             * multiple notifications.
484:             *
485:             * @param suiteId the MIDletSuite ID to match
486:             * @param classname the classname to match
487:             * @param mode one of {@link #MODE_LREQUEST}, {@link #MODE_LRESPONSE}
488:             *   <code>false</code> to reset the notified state for responses
489:             * @see #listen0
490:             */
491:            private static native void setListenNotify0(int suiteId,
492:                    String classname, int mode);
493:
494:            /**
495:             * Native method to unblock any threads that might be
496:             * waiting for an invocation by way of having called
497:             * {@link #get0}.
498:             *
499:             */
500:            private static native void cancel0();
501:
502:            /**
503:             * Sets the cleanup flag in matching Invocations.
504:             * Any marked invocation will be modified by {@link #getCleanup}.
505:             *
506:             * @param suiteId the MIDlet suiteId to search for,
507:             *  MUST not be <code>null</code>
508:             * @param classname to match, must not be null
509:             * @param cleanup <code>true</code> to mark the Invocation for
510:             *  cleanup at exit
511:             */
512:            private static native void setCleanup0(int suiteId,
513:                    String classname, boolean cleanup);
514:
515:            /**
516:             * Return the number of invocations in the native queue.
517:             * @return the number of invocations in the native queue
518:             */
519:            private static native int size0();
520:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.