Source Code Cross Referenced for ContentHandlerImpl.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 javax.microedition.content.ContentHandler;
030:        import javax.microedition.content.ContentHandlerServer;
031:        import javax.microedition.content.RequestListener;
032:        import javax.microedition.content.ActionNameMap;
033:        import javax.microedition.content.Invocation;
034:
035:        import java.io.DataInputStream;
036:        import java.io.DataOutputStream;
037:
038:        /**
039:         * The internal structure of a registered content handler.
040:         */
041:        public class ContentHandlerImpl implements  ContentHandler {
042:
043:            /**
044:             * The content handler ID.
045:             * Lengths up to 256 characters MUST be supported.
046:             * The ID may be <code>null</code>.
047:             */
048:            String ID;
049:
050:            /**
051:             * The types that are supported by this content handler.
052:             * If there are no types registered, the this field MUST either be
053:             * <code>null</code> or refer to an empty array .
054:             */
055:            private String[] types;
056:
057:            /**
058:             * The suffixes of URLs that are supported by this content handler.
059:             * If there are no suffixes, then this field MUST be <code>null</code>.
060:             * The suffixes MUST include any and all punctuation. For example,
061:             * the string <code>".png"</code>.
062:             */
063:            private String[] suffixes;
064:
065:            /**
066:             * The actions that are supported by this content handler.
067:             * If there are no actions, then this field MSUT be <code>null</code>.
068:             */
069:            private String[] actions;
070:
071:            /**
072:             * The action names that are defined by this content handler.
073:             */
074:            ActionNameMap[] actionnames;
075:
076:            /** The sequence number of this instance; monotonic increasing. */
077:            final int seqno;
078:
079:            /** The next sequence number to assign. */
080:            private static int nextSeqno;
081:
082:            /**
083:             * The RequestListenerImpl; if a listener is set.
084:             */
085:            RequestListenerImpl listenerImpl;
086:
087:            /** Empty String array to return when needed. */
088:            public final static String[] ZERO_STRINGS = {};
089:
090:            /** Empty ActionNameMap to return when needed. */
091:            private final static ActionNameMap[] ZERO_ACTIONNAMES = new ActionNameMap[0];
092:
093:            /** Property name for the current locale. */
094:            private final static String LOCALE_PROP = "microedition.locale";
095:
096:            /**
097:             * The MIDlet suite storagename that contains the MIDlet.
098:             */
099:            int storageId;
100:
101:            /**
102:             * The Name from parsing the Property for the MIDlet
103:             * with this classname.
104:             */
105:            String appname;
106:
107:            /**
108:             * The Version parsed from MIDlet-Version attribute.
109:             */
110:            String version;
111:
112:            /**
113:             * The application class name that implements this content
114:             * handler.  Note: Only the application that registered the class
115:             * will see the classname; for other applications the value will be
116:             * <code>null</code>.
117:             */
118:            String classname;
119:
120:            /**
121:             * The authority that authenticated this ContentHandler.
122:             */
123:            String authority;
124:
125:            /**
126:             * The accessRestrictions for this ContentHandler.
127:             */
128:            private String[] accessRestricted;
129:
130:            /**
131:             * Indicates content handler registration method:
132:             * dynamic registration from the API, static registration from install
133:             * or native content handler.
134:             * Must be similar to enum in jsr211_registry.h
135:             */
136:            int registrationMethod;
137:
138:            /** Content handler statically registered during installation */
139:            final static int REGISTERED_STATIC = 0;
140:            /** Dynamically registered content handler via API */
141:            final static int REGISTERED_DYNAMIC = 1;
142:            /** Native platform content handler  */
143:            final static int REGISTERED_NATIVE = 2;
144:
145:            /** Count of requests retrieved via {@link #getRequest}. */
146:            int requestCalls;
147:
148:            /**
149:             * Instance is a registration or unregistration.
150:             * An unregistration needs only storageId and classname.
151:             */
152:            boolean removed;
153:
154:            /**
155:             * Construct a ContentHandlerImpl.
156:             * Verifies that all strings are non-null
157:             * @param types an array of types to register; may be
158:             *  <code>null</code>
159:             * @param suffixes an array of suffixes to register; may be
160:             *  <code>null</code>
161:             * @param actions an array of actions to register; may be
162:             *  <code>null</code>
163:             * @param actionnames an array of ActionNameMaps to register; may be
164:             *  <code>null</code>
165:             * @param ID the content handler ID; may be <code>null</code>
166:             * @param accessRestricted the  IDs of applications allowed access
167:             * @param auth application authority
168:             *
169:             * @exception NullPointerException if any types, suffixes,
170:             *   actions, actionnames array element is null
171:             *
172:             * @exception IllegalArgumentException is thrown if any of
173:             *   the types, suffix, or action strings have a
174:             *   length of zero or
175:             *   if the ID has a length of zero or contains any
176:             *        control character or space (U+0000-U+00020)
177:             */
178:            ContentHandlerImpl(String[] types, String[] suffixes,
179:                    String[] actions, ActionNameMap[] actionnames, String ID,
180:                    String[] accessRestricted, String auth) {
181:                this ();
182:
183:                // Verify consistency between actions and ActionNameMaps
184:                if (actionnames != null && actionnames.length > 0) {
185:                    if (actions == null) {
186:                        throw new IllegalArgumentException("no actions");
187:                    }
188:                    int len = actions.length;
189:                    for (int i = 0; i < actionnames.length; i++) {
190:                        // Verify the actions are the same
191:                        ActionNameMap map = actionnames[i];
192:                        if (len != map.size()) {
193:                            throw new IllegalArgumentException(
194:                                    "actions not identical");
195:                        }
196:
197:                        for (int j = 0; j < len; j++) {
198:                            if (!actions[j].equals(map.getAction(j))) {
199:                                throw new IllegalArgumentException(
200:                                        "actions not identical");
201:                            }
202:                        }
203:
204:                        /*
205:                         * Verify the locale of this ActionNameMap is not the same
206:                         * as any previous ActionNameMap.
207:                         */
208:                        for (int j = 0; j < i; j++) {
209:                            if (map.getLocale().equals(
210:                                    actionnames[j].getLocale())) {
211:                                throw new IllegalArgumentException(
212:                                        "duplicate locale");
213:                            }
214:                        }
215:                    }
216:                }
217:
218:                // Check the ID for invalid characters (controls or space)
219:                if (ID != null) {
220:                    int len = ID.length();
221:                    if (len == 0) {
222:                        throw new IllegalArgumentException("invalid ID");
223:                    }
224:                    for (int i = 0; i < ID.length(); i++) {
225:                        if (ID.charAt(i) <= 0x0020) {
226:                            throw new IllegalArgumentException("invalid ID");
227:                        }
228:                    }
229:                    this .ID = ID;
230:                }
231:                this .types = copy(types);
232:                this .suffixes = copy(suffixes);
233:                this .actions = copy(actions);
234:                this .actionnames = copy(actionnames);
235:                this .accessRestricted = copy(accessRestricted);
236:                this .authority = auth;
237:            }
238:
239:            /**
240:             * Initialize a new instance with the same information.
241:             * @param handler another ContentHandlerImpl
242:             * @see javax.microedition.content.ContentHandlerServerImpl
243:             */
244:            protected ContentHandlerImpl(ContentHandlerImpl handler) {
245:                this ();
246:                types = handler.types;
247:                suffixes = handler.suffixes;
248:                ID = handler.ID;
249:                accessRestricted = handler.accessRestricted;
250:                actions = handler.actions;
251:                actionnames = handler.actionnames;
252:                listenerImpl = handler.listenerImpl;
253:                storageId = handler.storageId;
254:                classname = handler.classname;
255:                version = handler.version;
256:                registrationMethod = handler.registrationMethod;
257:                requestCalls = handler.requestCalls;
258:                authority = handler.authority;
259:                appname = handler.appname;
260:            }
261:
262:            /**
263:             * Constructor used to read handlers.
264:             */
265:            ContentHandlerImpl() {
266:                seqno = nextSeqno++;
267:            }
268:
269:            /**
270:             * Checks that all of the string references are non-null
271:             * and not zero length.  If either the argument is null or
272:             * is an empty array the default ZERO length string array is used.
273:             *
274:             * @param strings array to check for null and length == 0
275:             * @return a non-null array of strings; an empty array replaces null
276:             * @exception NullPointerException if any string ref is null
277:             * @exception IllegalArgumentException if any string
278:             * has length == 0
279:             */
280:            public static String[] copy(String[] strings) {
281:                if (strings != null && strings.length > 0) {
282:                    String[] copy = new String[strings.length];
283:                    for (int i = 0; i < strings.length; i++) {
284:                        if (strings[i].length() == 0) {
285:                            throw new IllegalArgumentException(
286:                                    "string length is 0");
287:                        }
288:                        copy[i] = strings[i];
289:
290:                    }
291:                    return strings;
292:                } else {
293:                    return ZERO_STRINGS;
294:                }
295:            }
296:
297:            /**
298:             * Checks that all of the actionname references are non-null.
299:             *
300:             * @param actionnames array to check for null and length == 0
301:             * @return a non-null array of actionnames; an empty array replaces null
302:             * @exception NullPointerException if any string ref is null
303:             */
304:            private static ActionNameMap[] copy(ActionNameMap[] actionnames) {
305:                if (actionnames != null && actionnames.length > 0) {
306:                    ActionNameMap[] copy = new ActionNameMap[actionnames.length];
307:                    for (int i = 0; i < actionnames.length; i++) {
308:                        // Check for null
309:                        if (actionnames[i] == null) {
310:                            throw new NullPointerException();
311:                        }
312:                        copy[i] = actionnames[i];
313:                    }
314:                    return copy;
315:                } else {
316:                    return ZERO_ACTIONNAMES;
317:                }
318:            }
319:
320:            /**
321:             * Copy an array of ContentHandlers making a new ContentHandler
322:             * for each ContentHandler.  Make copies of any mutiple object.
323:             * @param handlers the array of handlers duplicate
324:             * @return the new array of content handlers
325:             */
326:            public static ContentHandler[] copy(ContentHandler[] handlers) {
327:                ContentHandler[] h = new ContentHandler[handlers.length];
328:                for (int i = 0; i < handlers.length; i++) {
329:                    h[i] = handlers[i];
330:                }
331:                return h;
332:            }
333:
334:            /**
335:             * Get the nth type supported by the content handler.
336:             * @param index the index into the types
337:             * @return the nth type
338:             * @exception IndexOutOfBounds if index is less than zero or
339:             *     greater than or equal to the value of the
340:             *     {@link #getTypeCount getTypeCount} method.
341:             */
342:            public String getType(int index) {
343:                return get(index, getTypes());
344:            }
345:
346:            /**
347:             * Get the number of types supported by the content handler.
348:             *
349:             * @return the number of types
350:             */
351:            public int getTypeCount() {
352:                return getTypes().length;
353:            }
354:
355:            /**
356:             * Get types supported by the content handler.
357:             *
358:             * @return array of types supported
359:             */
360:            String[] getTypes() {
361:                if (types == null) {
362:                    types = RegistryStore.getArrayField(ID,
363:                            RegistryStore.FIELD_TYPES);
364:                }
365:                return types;
366:            }
367:
368:            /**
369:             * Determine if a type is supported by the content handler.
370:             *
371:             * @param type the type to check for
372:             * @return <code>true</code> if the type is supported;
373:             *  <code>false</code> otherwise
374:             * @exception NullPointerException if <code>type</code>
375:             * is <code>null</code>
376:             */
377:            public boolean hasType(String type) {
378:                return has(type, getTypes(), true);
379:            }
380:
381:            /**
382:             * Get the nth suffix supported by the content handler.
383:             * @param index the index into the suffixes
384:             * @return the nth suffix
385:             * @exception IndexOutOfBounds if index is less than zero or
386:             *     greater than or equal to the value of the
387:             *     {@link #getSuffixCount getSuffixCount} method.
388:             */
389:            public String getSuffix(int index) {
390:                return get(index, getSuffixes());
391:            }
392:
393:            /**
394:             * Get the number of suffixes supported by the content handler.
395:             *
396:             * @return the number of suffixes
397:             */
398:            public int getSuffixCount() {
399:                return getSuffixes().length;
400:            }
401:
402:            /**
403:             * Determine if a suffix is supported by the content handler.
404:             *
405:             * @param suffix the suffix to check for
406:             * @return <code>true</code> if the suffix is supported;
407:             *  <code>false</code> otherwise
408:             * @exception NullPointerException if <code>suffix</code>
409:             * is <code>null</code>
410:             */
411:            public boolean hasSuffix(String suffix) {
412:                return has(suffix, getSuffixes(), true);
413:            }
414:
415:            /**
416:             * Get suffixes supported by the content handler.
417:             *
418:             * @return array of suffixes supported
419:             */
420:            String[] getSuffixes() {
421:                if (suffixes == null) {
422:                    suffixes = RegistryStore.getArrayField(ID,
423:                            RegistryStore.FIELD_SUFFIXES);
424:                }
425:                return suffixes;
426:            }
427:
428:            /**
429:             * Get the nth action supported by the content handler.
430:             * @param index the index into the actions
431:             * @return the nth action
432:             * @exception IndexOutOfBounds if index is less than zero or
433:             *     greater than or equal to the value of the
434:             *     {@link #getActionCount getActionCount} method.
435:             */
436:            public String getAction(int index) {
437:                return get(index, getActions());
438:            }
439:
440:            /**
441:             * Get the number of actions supported by the content handler.
442:             *
443:             * @return the number of actions
444:             */
445:            public int getActionCount() {
446:                return getActions().length;
447:            }
448:
449:            /**
450:             * Determine if a action is supported by the content handler.
451:             *
452:             * @param action the action to check for
453:             * @return <code>true</code> if the action is supported;
454:             *  <code>false</code> otherwise
455:             * @exception NullPointerException if <code>action</code>
456:             * is <code>null</code>
457:             */
458:            public boolean hasAction(String action) {
459:                return has(action, getActions(), false);
460:            }
461:
462:            /**
463:             * Get actions supported by the content handler.
464:             *
465:             * @return array of actions supported
466:             */
467:            String[] getActions() {
468:                if (actions == null) {
469:                    actions = RegistryStore.getArrayField(ID,
470:                            RegistryStore.FIELD_ACTIONS);
471:                }
472:                return actions;
473:            }
474:
475:            /**
476:             * Gets the value at index in the string array.
477:             * @param index of the value
478:             * @param strings array of strings to get from
479:             * @return string at index.
480:             * @exception IndexOutOfBounds if index is less than zero or
481:             *     greater than or equal length of the array.
482:             */
483:            private String get(int index, String[] strings) {
484:                if (index < 0 || index >= strings.length) {
485:                    throw new IndexOutOfBoundsException();
486:                }
487:                return strings[index];
488:            }
489:
490:            /**
491:             * Determines if the string is in the array.
492:             * @param string to locate
493:             * @param strings array of strings to get from
494:             * @param ignoreCase true to ignore case in matching
495:             * @return <code>true</code> if the value is found
496:             * @exception NullPointerException if <code>string</code>
497:             * is <code>null</code>
498:             */
499:            private boolean has(String string, String[] strings,
500:                    boolean ignoreCase) {
501:                int len = string.length(); // Throw NPE if null
502:                for (int i = 0; i < strings.length; i++) {
503:                    if (strings[i].length() == len
504:                            && string.regionMatches(ignoreCase, 0, strings[i],
505:                                    0, len)) {
506:                        return true;
507:                    }
508:                }
509:                return false;
510:            }
511:
512:            /**
513:             * Get the mapping of actions to action names for the current
514:             * locale supported by this content handler. The behavior is
515:             * the same as invoking {@link #getActionNameMap} with the current
516:             * locale.
517:             *
518:             * @return an ActionNameMap; if there is no map available for the
519:             *  current locale, then it MUST be <code>null</code>
520:             */
521:            public ActionNameMap getActionNameMap() {
522:                String locale = System.getProperty(LOCALE_PROP);
523:                return (locale == null) ? null : getActionNameMap(locale);
524:            }
525:
526:            /**
527:             * Get the mapping of actions to action names for the requested
528:             * locale supported by this content handler.
529:             * The locale is matched against the available locales.
530:             * If a match is found it is used.  If an exact match is
531:             * not found, then the locale string is shortened and retried
532:             * if either of the "_" or "-" delimiters is present.
533:             * The locale is shortened by retaining only the characters up to
534:             * but not including the last occurence of the delimiter
535:             * (either "_" or "-").
536:             * The shortening and matching is repeated as long as the string
537:             * contains one of the delimiters.
538:             * Effectively, this will try the full locale and then try
539:             * without the variant or country code, if they were present.
540:             *
541:             * @param locale for which to find an ActionNameMap;
542:             *   MUST NOT be <code>null</code>
543:             * @return an ActionNameMap; if there is no map available for the
544:             *  locale, then it MUST be <code>null</code>
545:             * @exception NullPointerException if the locale is <code>null</code>
546:             */
547:            public ActionNameMap getActionNameMap(String locale) {
548:                while (locale.length() > 0) {
549:                    for (int i = 0; i < getActionNames().length; i++) {
550:                        if (locale.equals(getActionNames()[i].getLocale())) {
551:                            return getActionNames()[i];
552:                        }
553:                    }
554:                    int lastdash = locale.lastIndexOf('-');
555:                    if (lastdash < 0) {
556:                        break;
557:                    }
558:                    locale = locale.substring(0, lastdash);
559:                }
560:                return null;
561:            }
562:
563:            /**
564:             * Gets the number of action name maps supported by the content handler.
565:             *
566:             * @return the number of action name maps
567:             */
568:            public int getActionNameMapCount() {
569:                return getActionNames().length;
570:            }
571:
572:            /**
573:             * Gets the n<sup>th</sup> ActionNameMap supported by the
574:             * content handler.
575:             * @param index the index of the locale
576:             * @return the n<sup>th</sup> ActionNameMap
577:             *
578:             * @exception IndexOutOfBoundsException if index is less than zero or
579:             *     greater than or equal to the value of the
580:             *     {@link #getActionNameMapCount getActionNameMapCount} method.
581:             */
582:            public ActionNameMap getActionNameMap(int index) {
583:                if (index < 0 || index >= getActionNames().length) {
584:                    throw new IndexOutOfBoundsException();
585:                }
586:                return getActionNames()[index];
587:            }
588:
589:            /**
590:             * Get actions names for the content handler.
591:             *
592:             * @return array of actions names
593:             */
594:            private ActionNameMap[] getActionNames() {
595:                if (actionnames == null) {
596:                    String[] locales = RegistryStore.getArrayField(ID,
597:                            RegistryStore.FIELD_LOCALES);
598:                    String[] names = RegistryStore.getArrayField(ID,
599:                            RegistryStore.FIELD_ACTION_MAP);
600:
601:                    actionnames = new ActionNameMap[locales.length];
602:                    for (int index = 0; index < locales.length; index++) {
603:                        String[] temp = new String[getActions().length];
604:
605:                        System.arraycopy(names, index * getActions().length,
606:                                temp, 0, getActions().length);
607:
608:                        actionnames[index] = new ActionNameMap(getActions(),
609:                                temp, locales[index]);
610:                    }
611:                }
612:                return actionnames;
613:            }
614:
615:            /**
616:             * Returns the name used to present this content handler to a user.
617:             * The value is extracted from the normal installation information
618:             * about the content handler application.
619:             *
620:             * @return the user-friendly name of the application;
621:             * it MUST NOT be <code>null</code>
622:             */
623:            public String getAppName() {
624:                loadAppData();
625:                return appname;
626:            }
627:
628:            /**
629:             * Gets the version number of this content handler.
630:             * The value is extracted from the normal installation information
631:             * about the content handler application.
632:             * @return the version number of the application;
633:             * MAY be <code>null</code>
634:             */
635:            public String getVersion() {
636:                loadAppData();
637:                return version;
638:            }
639:
640:            /**
641:             * Get the content handler ID.  The ID uniquely identifies the
642:             * application which contains the content handler.
643:             * After registration and for every registered handler,
644:             * the ID MUST NOT be <code>null</code>.
645:             * @return the ID; MUST NOT be <code>null</code> unless the
646:             *  ContentHandler is not registered.
647:             */
648:            public String getID() {
649:                return ID;
650:            }
651:
652:            /**
653:             * Gets the name of the authority that authorized this application.
654:             * This value MUST be <code>null</code> unless the device has been
655:             * able to authenticate this application.
656:             * If <code>non-null</code>, it is the string identifiying the
657:             * authority.  For example,
658:             * if the application was a signed MIDlet, then this is the
659:             * "subject" of the certificate used to sign the application.
660:             * <p>The format of the authority for X.509 certificates is defined
661:             * by the MIDP Printable Representation of X.509 Distinguished
662:             * Names as defined in class
663:             * <code>javax.microedition.pki.Certificate</code>. </p>
664:             *
665:             * @return the authority; may be <code>null</code>
666:             */
667:            public String getAuthority() {
668:                loadAppData();
669:                return authority;
670:            }
671:
672:            /**
673:             * Initializes fields retrieved from AppProxy 'by-demand'.
674:             */
675:            private void loadAppData() {
676:                if (appname == null) {
677:                    try {
678:                        AppProxy app = AppProxy.getCurrent().forApp(storageId,
679:                                classname);
680:                        appname = app.getApplicationName();
681:                        version = app.getVersion();
682:                        authority = app.getAuthority();
683:                    } catch (Throwable t) {
684:                    }
685:                    if (appname == null) {
686:                        appname = "";
687:                    }
688:                }
689:            }
690:
691:            /**
692:             * Gets the n<sup>th</sup> ID of an application or content handler
693:             * allowed access to this content handler.
694:             * The ID returned for each index must be the equal to the ID
695:             * at the same index in the <tt>accessAllowed</tt> array passed to
696:             * {@link javax.microedition.content.Registry#register Registry.register}.
697:             *
698:             * @param index the index of the ID
699:             * @return the n<sup>th</sup> ID
700:             * @exception IndexOutOfBoundsException if index is less than zero or
701:             *     greater than or equal to the value of the
702:             *     {@link #accessAllowedCount accessAllowedCount} method.
703:             */
704:            public String getAccessAllowed(int index) {
705:                return get(index, getAccessRestricted());
706:            }
707:
708:            /**
709:             * Gets the number of IDs allowed access by the content handler.
710:             * The number of IDs must be equal to the length of the array
711:             * of accessRestricted passed to
712:             * {@link javax.microedition.content.Registry#register Registry.register}.
713:             * If the number of IDs is zero then all applications and
714:             * content handlers are allowed access.
715:             *
716:             * @return the number of accessRestricteds
717:             */
718:            public int accessAllowedCount() {
719:                return getAccessRestricted().length;
720:            }
721:
722:            /**
723:             * Determines if an ID MUST be allowed access by the content handler.
724:             * Access MUST be allowed if the ID has a prefix that exactly matches
725:             * any of the IDs returned by {@link #getAccessAllowed}.
726:             * The prefix comparison is equivalent to
727:             * <code>java.lang.String.startsWith</code>.
728:             *
729:             * @param ID the ID for which to check access
730:             * @return <code>true</code> if access MUST be allowed by the
731:             *  content handler;
732:             *  <code>false</code> otherwise
733:             * @exception NullPointerException if <code>accessRestricted</code>
734:             * is <code>null</code>
735:             */
736:            public boolean isAccessAllowed(String ID) {
737:                ID.length(); // check for null
738:                if (getAccessRestricted().length == 0) {
739:                    return true;
740:                }
741:                for (int i = 0; i < getAccessRestricted().length; i++) {
742:                    if (ID.startsWith(getAccessRestricted()[i])) {
743:                        return true;
744:                    }
745:                }
746:                return false;
747:            }
748:
749:            /**
750:             * Get accesses for the content handler.
751:             *
752:             * @return array of allowed class names
753:             */
754:            private String[] getAccessRestricted() {
755:                if (accessRestricted == null) {
756:                    accessRestricted = RegistryStore.getArrayField(ID,
757:                            RegistryStore.FIELD_ACCESSES);
758:                }
759:                return accessRestricted;
760:            }
761:
762:            /**
763:             * Gets the next Invocation request pending for this
764:             * ContentHandlerServer.
765:             * The method can be unblocked with a call to
766:             * {@link #cancelGetRequest cancelGetRequest}.
767:             * The application should process the Invocation as
768:             * a request to perform the <code>action</code> on the content.
769:             *
770:             * @param wait <code>true</code> if the method must wait for
771:             * for an Invocation if one is not available;
772:             * <code>false</code> if the method MUST NOT wait.
773:             * @param invocation an Invocation instance that will delegate to
774:             * the result; if any
775:             * @return the next pending Invocation or <code>null</code>
776:             *  if no Invocation is available; <code>null</code>
777:             *  if cancelled with {@link #cancelGetRequest cancelGetRequest}
778:             * @see javax.microedition.content.Registry#invoke
779:             * @see javax.microedition.content.ContentHandlerServer#finish
780:             */
781:            public InvocationImpl getRequest(boolean wait, Invocation invocation) {
782:                // Application has tried to get a request; reset cleanup flags on all
783:                if (requestCalls == 0) {
784:                    InvocationStore.setCleanup(storageId, classname, false);
785:                }
786:                requestCalls++;
787:
788:                InvocationImpl invoc = InvocationStore.getRequest(storageId,
789:                        classname, wait);
790:                if (invoc != null) {
791:                    // Keep track of number of requests delivered to the application
792:                    AppProxy.requestForeground(invoc.invokingSuiteId,
793:                            invoc.invokingClassname, invoc.suiteId,
794:                            invoc.classname);
795:                    invoc.invocation = invocation;
796:                }
797:                return invoc;
798:            }
799:
800:            /**
801:             * Cancel a pending <code>getRequest</code>.
802:             * This method will force a Thread blocked in a call to the
803:             * <code>getRequest</code> method for the same application
804:             * context to return early.
805:             * If no Thread is blocked; this call has no effect.
806:             */
807:            public void cancelGetRequest() {
808:                InvocationStore.cancel();
809:            }
810:
811:            /**
812:             * Finish this Invocation and set the status for the response.
813:             * The <code>finish</code> method may only be called when this
814:             * Invocation
815:             * has a status of <code>ACTIVE</code> or <code>HOLD</code>.
816:             * <p>
817:             * The content handler may modify the URL, type, action, or
818:             * arguments before invoking <code>finish</code>.
819:             * If the method {@link Invocation#getResponseRequired} returns
820:             * <code>true</code> then the modified
821:             * values MUST be returned to the invoking application.
822:             *
823:             * @param invoc the Invocation to finish
824:             * @param status the new status of the Invocation. This MUST be either
825:             *         <code>OK</code> or <code>CANCELLED</code>.
826:             *
827:             * @return <code>true</code> if the MIDlet suite MUST
828:             *   voluntarily exit before the response can be returned to the
829:             *   invoking application
830:             *
831:             * @exception IllegalArgumentException if the new
832:             *   <code>status</code> of the Invocation
833:             *    is not <code>OK</code> or <code>CANCELLED</code>
834:             * @exception IllegalStateException if the current
835:             *   <code>status</code> of the
836:             *   Invocation is not <code>ACTIVE</code> or <code>HOLD</code>
837:             * @exception NullPointerException if the invocation is <code>null</code>
838:             */
839:            protected boolean finish(InvocationImpl invoc, int status) {
840:                int currst = invoc.getStatus();
841:                if (currst != Invocation.ACTIVE && currst != Invocation.HOLD) {
842:                    throw new IllegalStateException("Status already set");
843:                }
844:                // If ACTIVE or HOLD it must be an InvocationImpl
845:                return invoc.finish(status);
846:            }
847:
848:            /**
849:             * Set the listener to be notified when a new request is
850:             * available for this content handler.  The request MUST
851:             * be retrieved using {@link #getRequest}.
852:             *
853:             * @param listener the listener to register;
854:             *   <code>null</code> to remove the listener.
855:             */
856:            public void setListener(RequestListener listener) {
857:                synchronized (this ) {
858:                    if (listener != null || listenerImpl != null) {
859:                        // Create or update the active listener thread
860:                        if (listenerImpl == null) {
861:                            listenerImpl = new RequestListenerImpl(this ,
862:                                    listener);
863:                        } else {
864:                            listenerImpl.setListener(listener);
865:                        }
866:
867:                        // If the listener thread no longer needed; clear it
868:                        if (listener == null) {
869:                            listenerImpl = null;
870:                        }
871:                    }
872:                }
873:            }
874:
875:            /**
876:             * Notify the request listener of a pending request.
877:             * Overridden by subclass.
878:             */
879:            protected void requestNotify() {
880:            }
881:
882:            /**
883:             * Compare two ContentHandlerImpl's for equality.
884:             * Classname, storageID, and seqno must match.
885:             * @param other another ContentHandlerImpl
886:             * @return true if the other handler is for the same class,
887:             * storageID, and seqno.
888:             */
889:            boolean equals(ContentHandlerImpl other) {
890:                return seqno == other.seqno && storageId == other.storageId
891:                        && classname.equals(other.classname);
892:            }
893:
894:            /**
895:             * Debug routine to print the values.
896:             * @return a string with the details
897:             */
898:            public String toString() {
899:                if (AppProxy.LOG_INFO) {
900:                    StringBuffer sb = new StringBuffer(80);
901:                    sb.append("CH:");
902:                    sb.append(" classname: ");
903:                    sb.append(classname);
904:                    sb.append(", removed: ");
905:                    sb.append(removed);
906:                    sb.append(", flag: ");
907:                    sb.append(registrationMethod);
908:                    sb.append(", types: ");
909:                    toString(sb, types);
910:                    sb.append(", ID: ");
911:                    sb.append(ID);
912:                    sb.append(", suffixes: ");
913:                    toString(sb, suffixes);
914:                    sb.append(", actions: ");
915:                    toString(sb, actions);
916:                    sb.append(", access: ");
917:                    toString(sb, accessRestricted);
918:                    sb.append(", suiteID: ");
919:                    sb.append(storageId);
920:                    sb.append(", authority: ");
921:                    sb.append(authority);
922:                    sb.append(", appname: ");
923:                    sb.append(appname);
924:                    return sb.toString();
925:                } else {
926:                    return super .toString();
927:                }
928:            }
929:
930:            /**
931:             * Append all of the strings inthe array to the string buffer.
932:             * @param sb a StringBuffer to append to
933:             * @param strings an array of strings.
934:             */
935:            private void toString(StringBuffer sb, String[] strings) {
936:                if (strings == null) {
937:                    sb.append("null");
938:                    return;
939:                }
940:                for (int i = 0; i < strings.length; i++) {
941:                    if (i > 0) {
942:                        sb.append(':');
943:                    }
944:                    sb.append(strings[i]);
945:                }
946:            }
947:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.