Source Code Cross Referenced for LocalizedEntryListFactory.java in  » Database-ORM » MMBase » org » mmbase » util » 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 » Database ORM » MMBase » org.mmbase.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:        This software is OSI Certified Open Source Software.
004:        OSI Certified is a certification mark of the Open Source Initiative.
005:
006:        The license (Mozilla version 1.0) can be read at the MMBase site.
007:        See http://www.MMBase.org/license
008:
009:         */
010:        package org.mmbase.util;
011:
012:        import java.util.*;
013:        import java.io.*;
014:        import org.w3c.dom.*;
015:        import org.mmbase.bridge.*;
016:        import org.mmbase.bridge.Node;
017:        import org.mmbase.bridge.util.Queries;
018:        import org.mmbase.bridge.util.xml.query.*;
019:        import org.mmbase.util.xml.DocumentSerializable;
020:        import org.mmbase.util.xml.DocumentReader;
021:        import org.mmbase.util.logging.*;
022:
023:        /**
024:         * These factories can produce Collections based on a Locale (The {@link #get} method is
025:         * essential). The other methods besides get are methods to define these lists. There are two ways
026:         * to add entries to the produced collections. The first one is to explicitely add them, using the
027:         * {@link #add} method. This gives precise control, and the collections can have different orders
028:         * for different languages. The size of the collections are always the same, so if for a certain
029:         * locale less entries are added, these are completed with the unused keys. If for a certain locale
030:         * <em>no</em> entries are added, it will behave itself like as the default locale of {@link
031:         * LocalizedString#getDefault}.
032:         *
033:         * It is also possible to add entire 'bundles'. For this use {@link #addBundle}. When a Collection instance
034:         * for a certain Locale is requested these informations are used to call {@link
035:         * SortedBundle#getResource}.
036:         *
037:         * It is possible to mix both methods, so having an enumeration partially defined by a bundle,
038:         * partially by explicit values, though this is not recommended.
039:         *
040:         * @author Michiel Meeuwissen
041:         * @version $Id: LocalizedEntryListFactory.java,v 1.48 2008/02/03 17:33:57 nklasens Exp $
042:         * @since MMBase-1.8
043:         */
044:        public class LocalizedEntryListFactory<C> implements  Serializable,
045:                Cloneable {
046:
047:            private static final Logger log = Logging
048:                    .getLoggerInstance(LocalizedEntryListFactory.class);
049:            private static final long serialVersionUID = 1L; // increase this if object serialization changes (which we shouldn't do!)
050:
051:            private int size = 0; // number of explicitely added keys
052:            private boolean usesCloud = false;
053:
054:            // we don't use interfaces here, because of Serializability
055:            private static class LocalizedEntry implements  Serializable,
056:                    PublicCloneable {
057:                private static final long serialVersionUID = 1L;
058:                ArrayList entries = new ArrayList(); //  List of Map.Entries, Bundles and DocumentSerializable's
059:                ArrayList<Serializable> unusedKeys = new ArrayList<Serializable>(); //  List of unused keys;
060:
061:                public Object clone() {
062:                    try {
063:                        LocalizedEntry clone = (LocalizedEntry) super .clone();
064:                        Iterator<PublicCloneable> i = clone.entries.iterator();
065:                        clone.entries = new ArrayList();
066:                        while (i.hasNext()) {
067:                            clone.entries.add(i.next().clone());
068:                        }
069:                        clone.unusedKeys = (ArrayList) unusedKeys.clone();
070:                        return clone;
071:                    } catch (CloneNotSupportedException cnse) {
072:                        log.error(cnse);
073:                        return new LocalizedEntry();
074:                    }
075:                }
076:
077:                public String toString() {
078:                    return "entries:" + entries + "uu:" + unusedKeys;
079:                }
080:            }
081:
082:            private HashMap<Locale, LocalizedEntry> localized = new HashMap<Locale, LocalizedEntry>();
083:            private ArrayList<Bundle> bundles = new ArrayList<Bundle>(); // contains all Bundles
084:            private ArrayList<Serializable> fallBack = new ArrayList<Serializable>(); // List of known keys, used as fallback, if nothing defined for a certain locale
085:
086:            private DocumentSerializable xml = null;
087:
088:            public LocalizedEntryListFactory() {
089:                localized.put(LocalizedString.getDefault(),
090:                        new LocalizedEntry());
091:            }
092:
093:            public boolean isEmpty() {
094:                return bundles.size() == 0 && fallBack.size() == 0
095:                        && !usesCloud;
096:            }
097:
098:            /**
099:             * Adds a value for a certain key and Locale
100:             * @return The created Map.Entry.
101:             */
102:            public Map.Entry<Serializable, Serializable> add(Locale locale,
103:                    Serializable key, Serializable value) {
104:                if (locale == null) {
105:                    locale = LocalizedString.getDefault();
106:                }
107:
108:                Entry<Serializable, Serializable> entry = new Entry(key, value);
109:                List<Serializable> unused = add(locale, entry);
110:                if (!fallBack.contains(key)) {
111:                    // this is an as yet unknown key.
112:                    size++;
113:                    fallBack.add(key);
114:                    for (Map.Entry<Locale, LocalizedEntry> e : localized
115:                            .entrySet()) {
116:                        if (!e.getKey().equals(locale)) {
117:                            LocalizedEntry loc = e.getValue();
118:                            loc.unusedKeys.add(key);
119:                        }
120:                    }
121:                }
122:                unused.remove(key);
123:                return entry;
124:            }
125:
126:            /**
127:             * Add entry to 'localized'
128:             * @param entry the object, which has not Locale support of itself (Entry, DocumentSerializable)
129:             * @param locale Can be <code>null</code> too, in which case the default locale is used
130:             * @return List of currently unused keys for this locale.
131:             */
132:
133:            protected List<Serializable> add(Locale locale, Object entry) {
134:                if (locale == null) {
135:                    locale = LocalizedString.getDefault();
136:                }
137:                LocalizedEntry local = localized.get(locale);
138:                if (local == null) {
139:                    Locale loc = locale;
140:                    loc = LocalizedString.degrade(loc, locale);
141:                    while (loc != null && local == null) {
142:                        local = localized.get(loc);
143:                        loc = LocalizedString.degrade(loc, locale);
144:                    }
145:                    if (local == null) {
146:                        local = new LocalizedEntry();
147:                        local.entries.addAll(bundles);
148:                        local.unusedKeys.addAll(fallBack);
149:                    } else {
150:                        local = (LocalizedEntry) local.clone();
151:                    }
152:                    localized.put(locale, local);
153:                }
154:
155:                // If this locale with variant is added but the parent locale was not yet in the map, then
156:                // we first add the parent locale.
157:                if (locale.getVariant() != null
158:                        && !"".equals(locale.getVariant())) {
159:                    Locale l = new Locale(locale.getLanguage(), locale
160:                            .getCountry());
161:                    if (!localized.containsKey(l)) {
162:                        add(l, entry);
163:                    }
164:                }
165:
166:                // If this locale with country is added, but the parent locale (only language) was not yet in
167:                // the map, we first add the parent language locale.
168:                if (locale.getCountry() != null
169:                        && !"".equals(locale.getCountry())) {
170:                    Locale l = new Locale(locale.getLanguage());
171:                    if (!localized.containsKey(l)) {
172:                        add(l, entry);
173:                    }
174:                }
175:                local.entries.add(entry);
176:                return local.unusedKeys;
177:            }
178:
179:            /**
180:             * Adds a bundle, to the (current) end of all maintained collections. Actually, only the
181:             * definition of the bundle is added, it is instantiated only later, when requested for a
182:             * specific locale.
183:             */
184:            public void addBundle(String baseName, ClassLoader classLoader,
185:                    Class constantsProvider, Class wrapper,
186:                    Comparator comparator) {
187:                Bundle b = new Bundle(baseName, classLoader, SortedBundle
188:                        .getConstantsProvider(constantsProvider), wrapper,
189:                        comparator);
190:                if (bundles.contains(b)) {
191:                    log.info("Adding bundle " + b + " for second time in " + b
192:                            + ", because " + Logging.stackTrace());
193:                }
194:                bundles.add(b);
195:                Iterator<LocalizedEntry> i = localized.values().iterator();
196:                if (!i.hasNext()) {
197:                    // adding very first localizedlist
198:                    Locale locale = LocalizedString.getDefault();
199:                    LocalizedEntry local = new LocalizedEntry();
200:                    local.entries.add(b);
201:                    local.unusedKeys.addAll(fallBack);
202:                } else
203:                    while (i.hasNext()) {
204:                        LocalizedEntry local = i.next();
205:                        local.entries.add(b);
206:                    }
207:            }
208:
209:            /**
210:             */
211:            public void addQuery(Locale locale, Document queryElement) {
212:                DocumentSerializable doc = new DocumentSerializable(
213:                        queryElement);
214:                add(locale, doc);
215:                usesCloud = true;
216:            }
217:
218:            /**
219:             * Defaulting version of {@link #get(Locale, Cloud)}. Using default anonymous cloud.
220:             */
221:            public List<Map.Entry<C, String>> get(final Locale locale) {
222:                return get(locale, usesCloud ? getCloud(locale) : null);
223:            }
224:
225:            protected Cloud getCloud(Locale locale) {
226:                CloudContext context = ContextProvider.getDefaultCloudContext();
227:                if (context.isUp()) {
228:                    try {
229:                        Cloud cloud = context.getCloud("mmbase", "class", null);
230:                        if (locale != null)
231:                            cloud.setLocale(locale);
232:                        return cloud;
233:                    } catch (SecurityException se) {
234:                        log.warn("" + se.getMessage());
235:                        try {
236:                            Cloud cloud = context.getCloud("mmbase");
237:                            if (locale != null && cloud != null)
238:                                cloud.setLocale(locale);
239:                            return cloud;
240:                        } catch (SecurityException se2) {
241:                            return null;
242:                        }
243:                    }
244:                } else {
245:                    return null;
246:                }
247:            }
248:
249:            /**
250:             * Returns a Collection of Map.Entries for the given Locale. The collection is kind of 'virtual',
251:             * it only reflects the underlying memory structures.
252:             * 
253:             * This collection does have a well defined iteration order.
254:             *
255:             * @param locale The locale of <code>null</code> for the default locale.
256:             * @param cloud  The cloud to use. Can be <code>null</code> if no queries added (see {@link #addQuery}).
257:             *               If Locale is <code>null</code>, but cloud isn't, the locale of the cloud is used.
258:             */
259:            public List<Map.Entry<C, String>> get(final Locale locale,
260:                    final Cloud cloud) {
261:                return new AbstractSequentialList<Map.Entry<C, String>>() {
262:
263:                    public int size() {
264:                        return LocalizedEntryListFactory.this .size(cloud);
265:                    }
266:
267:                    public ListIterator<Map.Entry<C, String>> listIterator(
268:                            final int index) {
269:                        return new ListIterator<Map.Entry<C, String>>() {
270:                            int i = -1;
271:                            Locale useLocale = locale;
272:                            Cloud useCloud = cloud;
273:
274:                            {
275:                                if (useLocale == null) {
276:                                    useLocale = useCloud != null ? useCloud
277:                                            .getLocale() : LocalizedString
278:                                            .getDefault();
279:                                }
280:                                log.debug("using locale " + useLocale);
281:                            }
282:                            private ChainedIterator iterator = new ChainedIterator();
283:                            private Iterator<Map.Entry<C, String>> subIterator = null;
284:                            private Map.Entry<C, String> next = null;
285:
286:                            {
287:                                Locale orgLocale = useLocale;
288:
289:                                LocalizedEntry loc = localized.get(useLocale);
290:                                while (loc == null && useLocale != null) {
291:                                    useLocale = LocalizedString.degrade(
292:                                            useLocale, orgLocale);
293:                                    if (log.isDebugEnabled()) {
294:                                        log.debug("Degraded to " + useLocale);
295:                                    }
296:                                    loc = localized.get(useLocale);
297:                                }
298:                                if (loc == null) {
299:                                    useLocale = orgLocale;
300:                                    loc = localized.get(LocalizedString
301:                                            .getDefault());
302:                                }
303:
304:                                if (loc == null) {
305:
306:                                    iterator.addIterator(bundles.iterator());
307:                                    iterator.addIterator(fallBack.iterator());
308:                                } else {
309:                                    iterator
310:                                            .addIterator(loc.entries.iterator());
311:                                    iterator.addIterator(loc.unusedKeys
312:                                            .iterator());
313:                                }
314:
315:                                findNext();
316:                                while (i < index)
317:                                    next();
318:                            }
319:
320:                            protected void findNext() {
321:                                next = null;
322:                                i++;
323:                                while (next == null && iterator.hasNext()) {
324:                                    Object candidate = iterator.next();
325:                                    if (candidate instanceof  Map.Entry) {
326:                                        next = (Map.Entry) candidate;
327:                                    } else if (candidate instanceof  Bundle) {
328:                                        subIterator = ((Bundle) candidate).get(
329:                                                useLocale).iterator();
330:                                        if (subIterator.hasNext()) {
331:                                            break;
332:                                        } else {
333:                                            subIterator = null;
334:                                        }
335:                                    } else if (candidate instanceof  DocumentSerializable) {
336:                                        Element element = ((DocumentSerializable) candidate)
337:                                                .getDocument()
338:                                                .getDocumentElement();
339:                                        try {
340:                                            if (useCloud == null) {
341:                                                useCloud = getCloud(useLocale);
342:                                                if (useCloud == null) {
343:                                                    if (log.isDebugEnabled()) {
344:                                                        log
345:                                                                .debug("Defined query for "
346:                                                                        + this 
347:                                                                        + " but no cloud provided. Skipping results.");
348:                                                    }
349:                                                    continue;
350:                                                }
351:                                            }
352:                                            Query query = QueryReader
353:                                                    .parseQuery(element,
354:                                                            useCloud, null).query;
355:                                            final org.mmbase.bridge.NodeList list = query
356:                                                    .getList();
357:                                            subIterator = new Iterator() {
358:                                                final NodeIterator nodeIterator = list
359:                                                        .nodeIterator();
360:
361:                                                public boolean hasNext() {
362:                                                    return nodeIterator
363:                                                            .hasNext();
364:                                                }
365:
366:                                                public Object next() {
367:                                                    org.mmbase.bridge.Node next = nodeIterator
368:                                                            .nextNode();
369:                                                    return new Entry<Node, FieldValue>(
370:                                                            next,
371:                                                            next
372:                                                                    .getFunctionValue(
373:                                                                            "gui",
374:                                                                            null));
375:                                                }
376:
377:                                                public void remove() {
378:                                                    throw new UnsupportedOperationException();
379:                                                }
380:                                            };
381:                                            if (subIterator.hasNext()) {
382:                                                break;
383:                                            } else {
384:                                                subIterator = null;
385:                                            }
386:                                        } catch (Exception e) {
387:                                            log.error(e.getMessage(), e);
388:                                        }
389:                                    } else {
390:                                        next = new Entry(candidate, candidate);
391:                                    }
392:                                }
393:                            }
394:
395:                            public boolean hasNext() {
396:                                return next != null || subIterator != null;
397:                            }
398:
399:                            public Map.Entry<C, String> next() {
400:                                Map.Entry<C, String> res;
401:                                if (subIterator != null) {
402:                                    res = subIterator.next();
403:                                    Object key = res.getKey();
404:                                    if (key != null
405:                                            && key instanceof  SortedBundle.ValueWrapper) {
406:                                        res = new Entry(
407:                                                ((SortedBundle.ValueWrapper) key)
408:                                                        .getKey(), res
409:                                                        .getValue());
410:                                    }
411:                                    if (!subIterator.hasNext()) {
412:                                        subIterator = null;
413:                                        findNext();
414:                                    }
415:                                } else {
416:                                    res = next;
417:                                    findNext();
418:                                }
419:                                return res;
420:                            }
421:
422:                            public int nextIndex() {
423:                                return i;
424:                            }
425:
426:                            public int previousIndex() {
427:                                return i - 1;
428:                            }
429:
430:                            public boolean hasPrevious() {
431:                                // TODO
432:                                throw new UnsupportedOperationException();
433:                            }
434:
435:                            public Map.Entry<C, String> previous() {
436:                                // TODO
437:                                throw new UnsupportedOperationException();
438:                            }
439:
440:                            // this is why we hate java:
441:
442:                            public void remove() {
443:                                throw new UnsupportedOperationException();
444:                            }
445:
446:                            public void add(Map.Entry<C, String> o) {
447:                                throw new UnsupportedOperationException();
448:                            }
449:
450:                            public void set(Map.Entry<C, String> o) {
451:                                throw new UnsupportedOperationException();
452:                            }
453:                        };
454:                    }
455:                };
456:            }
457:
458:            /**
459:             * The size of the collections returned by {@link #get}
460:             */
461:            public int size(Cloud cloud) {
462:                if (cloud == null)
463:                    cloud = getCloud(LocalizedString.getDefault());
464:                int queriesSize = size();
465:                Locale locale = cloud == null ? LocalizedString.getDefault()
466:                        : cloud.getLocale();
467:                LocalizedEntry localizedList = localized.get(locale);
468:                if (localizedList == null) {
469:                    locale = LocalizedString.getDefault();
470:                    localizedList = localized.get(locale);
471:                }
472:                if (localizedList != null) {
473:                    Iterator i = localizedList.entries.iterator();
474:                    while (i.hasNext()) {
475:                        Object o = i.next();
476:                        if (o instanceof  Bundle) {
477:                            // already in size();
478:                        } else if (o instanceof  DocumentSerializable) {
479:                            if (cloud == null) {
480:                                cloud = getCloud(null);
481:                                if (cloud == null) {
482:                                    log
483:                                            .debug("Found query but didn't provide cloud, skipping");
484:                                    continue;
485:                                }
486:                            }
487:                            Element element = ((DocumentSerializable) o)
488:                                    .getDocument().getDocumentElement();
489:                            try {
490:                                queriesSize += Queries
491:                                        .count(QueryReader.parseQuery(element,
492:                                                cloud, null).query);
493:                            } catch (Exception e) {
494:                                log.warn(e);
495:                            }
496:                        } else {
497:                            queriesSize++;
498:                        }
499:                    }
500:                    //queriesSize += localizedList.unusedKeys.size();
501:                }
502:
503:                return queriesSize;
504:            }
505:
506:            public int size() {
507:                int bundleSize = 0;
508:                Iterator i = bundles.iterator();
509:                while (i.hasNext()) {
510:                    Bundle b = (Bundle) i.next();
511:                    try {
512:                        bundleSize += b.get(null).size();
513:                    } catch (MissingResourceException mre) {
514:                        log.error(mre);
515:                    }
516:                }
517:                return size + bundleSize;
518:            }
519:
520:            public Object castKey(final Object key) {
521:                return castKey(key, null);
522:            }
523:
524:            /**
525:             * Since keys may be somehow wrapped, you can also 'unwrap' by this. If e.g. a constants
526:             * provider was used, that values can be indicated by the name of the constants and this method
527:             * casts to the value.
528:             */
529:            public Object castKey(final Object key, final Cloud cloud) {
530:                String string = null;
531:                Iterator<Bundle> i = bundles.iterator();
532:                if (i.hasNext()) {
533:                    string = Casting.toString(key);
534:                    while (i.hasNext()) {
535:                        Bundle b = i.next();
536:                        Class wrapper = b.wrapper;
537:                        Map<String, Object> constants = b.constantsProvider;
538:                        Object nk = SortedBundle.castKey(string, null,
539:                                constants, wrapper);
540:                        if (string != nk) {
541:                            if (log.isDebugEnabled()) {
542:                                log.debug("Cast " + key + " to " + nk);
543:                            }
544:                            return nk;
545:                        }
546:                    }
547:                }
548:                if (usesCloud && cloud != null) {
549:                    if (string == null)
550:                        string = Casting.toString(key);
551:                    if (cloud.hasNode(string)) {
552:                        return cloud.getNode(string);
553:                    }
554:                }
555:                return key;
556:
557:            }
558:
559:            public Object clone() {
560:                try {
561:                    LocalizedEntryListFactory clone = (LocalizedEntryListFactory) super 
562:                            .clone();
563:                    Iterator<Bundle> j = clone.bundles.iterator();
564:                    clone.bundles = new ArrayList<Bundle>();
565:                    while (j.hasNext()) {
566:                        clone.bundles.add((j.next().clone()));
567:                    }
568:                    Iterator<Map.Entry<Locale, LocalizedEntry>> i = clone.localized
569:                            .entrySet().iterator();
570:                    clone.localized = new HashMap();
571:                    while (i.hasNext()) {
572:                        Map.Entry<Locale, LocalizedEntry> entry = i.next();
573:                        clone.localized.put(entry.getKey(), (entry.getValue())
574:                                .clone());
575:                    }
576:                    clone.fallBack = (ArrayList) fallBack.clone();
577:                    return clone;
578:                } catch (Exception e) {
579:                    log.error(e.getMessage(), e);
580:                    return new LocalizedEntryListFactory();
581:                }
582:            }
583:
584:            /**
585:             * Clears all added keys, bundles and queries.
586:             */
587:            public void clear() {
588:                localized.clear();
589:                bundles.clear();
590:                fallBack.clear();
591:                usesCloud = false;
592:                size = 0;
593:            }
594:
595:            /**
596:             * Given a certain DOM parent element, it configures this LocalizedEntryListFactory with 
597:             * sub tags of type 'entry' and 'query'
598:             */
599:
600:            public void fillFromXml(final Element enumerationElement,
601:                    Class wrapperDefault) {
602:                xml = new DocumentSerializable(DocumentReader
603:                        .toDocument(enumerationElement));
604:                org.w3c.dom.NodeList childNodes = enumerationElement
605:                        .getElementsByTagName("query");
606:                for (int i = 0; i < childNodes.getLength(); i++) {
607:                    Element queryElement = (Element) childNodes.item(i);
608:                    Locale locale = LocalizedString.getLocale(queryElement);
609:                    addQuery(locale, DocumentReader.toDocument(queryElement));
610:                }
611:
612:                childNodes = enumerationElement.getElementsByTagName("entry");
613:                for (int i = 0; i < childNodes.getLength(); i++) {
614:                    Element entryElement = (Element) childNodes.item(i);
615:                    if (entryElement.hasAttribute("value")) {
616:                        String value = entryElement.getAttribute("value");
617:                        Locale locale = LocalizedString.getLocale(entryElement);
618:                        String display = entryElement.getAttribute("display");
619:                        if (display.equals(""))
620:                            display = value;
621:                        Object key = wrapperDefault != null ? Casting.toType(
622:                                wrapperDefault, null, value) : value;
623:                        if (key instanceof  Serializable) {
624:                            if (log.isDebugEnabled()) {
625:                                log.debug("Added " + key + "/" + display
626:                                        + " for " + locale);
627:                            }
628:                            add(locale, (Serializable) key, display);
629:                        } else {
630:                            log
631:                                    .error("key "
632:                                            + key
633:                                            + " for "
634:                                            + wrapperDefault
635:                                            + " is not serializable, cannot be added to entrylist factory.");
636:                        }
637:                    } else {
638:                        String resource = entryElement.getAttribute("basename");
639:                        if (!resource.equals("")) {
640:                            Comparator comparator = null;
641:                            Class wrapper = wrapperDefault;
642:                            if (wrapper != null
643:                                    && (!Comparable.class
644:                                            .isAssignableFrom(wrapper))
645:                                    && (!Boolean.class.equals(wrapper)) // in java < 1.5 Boolean is not comparable
646:                            ) {
647:                                wrapper = null;
648:                            }
649:
650:                            {
651:                                String sorterClass = entryElement
652:                                        .getAttribute("sorterclass");
653:                                if (!sorterClass.equals("")) {
654:                                    try {
655:                                        Class sorter = Class
656:                                                .forName(sorterClass);
657:                                        if (Comparator.class
658:                                                .isAssignableFrom(sorter)) {
659:                                            comparator = (Comparator) sorter
660:                                                    .newInstance();
661:                                        } else {
662:                                            wrapper = sorter;
663:                                        }
664:                                    } catch (Exception e) {
665:                                        log.error(e);
666:                                    }
667:                                }
668:                            }
669:                            Class constantsClass = null;
670:                            {
671:                                String javaConstants = entryElement
672:                                        .getAttribute("javaconstants");
673:                                if (!javaConstants.equals("")) {
674:                                    try {
675:                                        constantsClass = Class
676:                                                .forName(javaConstants);
677:                                    } catch (Exception e) {
678:                                        log.error(e);
679:                                    }
680:                                }
681:                            }
682:                            try {
683:                                addBundle(resource,
684:                                        getClass().getClassLoader(),
685:                                        constantsClass, wrapper, comparator);
686:                            } catch (MissingResourceException mre) {
687:                                log.error(mre);
688:                            }
689:                        } else {
690:                            throw new IllegalArgumentException(
691:                                    "no 'value' or 'basename' attribute on enumeration entry element");
692:                        }
693:                    }
694:                    if (log.isDebugEnabled()) {
695:                        log.debug("Found enumeration values now " + this );
696:                    }
697:                }
698:
699:            }
700:
701:            public Element toXml() {
702:                if (xml == null) {
703:                    // TODO: generate xml.
704:                    return null;
705:                } else {
706:                    return xml.getDocument().getDocumentElement();
707:                }
708:            }
709:
710:            public String toString() {
711:                return "(localized: " + localized + "bundles: " + bundles
712:                        + "fallBack: " + fallBack + ")";
713:            }
714:
715:            private static class Bundle implements  Serializable,
716:                    PublicCloneable {
717:                private static final long serialVersionUID = 1L; // increase this if object serialization changes (which we shouldn't do!)
718:
719:                private String resource;
720:                private ClassLoader classLoader;
721:                private HashMap<String, Object> constantsProvider;
722:                private Class wrapper;
723:                private Comparator comparator;
724:
725:                // implementation of serializable
726:                private void writeObject(ObjectOutputStream out)
727:                        throws IOException {
728:                    out.writeUTF(resource);
729:                    // dont'r write class-loader, it is not serializable
730:                    out.writeObject(constantsProvider);
731:                    out.writeObject(wrapper);
732:                    if (comparator instanceof  Serializable) {
733:                        out.writeObject(comparator);
734:                    } else {
735:                        out.writeObject((Comparator) null);
736:                    }
737:                }
738:
739:                // implementation of serializable
740:                private void readObject(ObjectInputStream in)
741:                        throws IOException, ClassNotFoundException {
742:                    resource = in.readUTF();
743:                    classLoader = getClass().getClassLoader();
744:                    constantsProvider = (HashMap) in.readObject();
745:                    wrapper = (Class) in.readObject();
746:                    comparator = (Comparator) in.readObject();
747:                }
748:
749:                Bundle(String r, ClassLoader cl, HashMap<String, Object> cp,
750:                        Class w, Comparator comp) {
751:                    resource = r;
752:                    classLoader = cl;
753:                    constantsProvider = cp;
754:                    wrapper = w;
755:                    comparator = comp;
756:                }
757:
758:                /**
759:                 * Collection of Map.Entry's
760:                 */
761:                Collection get(Locale loc) throws MissingResourceException {
762:                    try {
763:                        return SortedBundle.getResource(resource, loc,
764:                                classLoader, constantsProvider, wrapper,
765:                                comparator).entrySet();
766:                    } catch (IllegalArgumentException iae) {
767:                        log.error(iae);
768:                        return Collections.emptyList();
769:                    }
770:                }
771:
772:                public String toString() {
773:                    return resource + " " + constantsProvider + " " + wrapper
774:                            + " " + comparator;
775:                }
776:
777:                public boolean equals(Object o) {
778:                    if (o instanceof  Bundle) {
779:                        Bundle b = (Bundle) o;
780:                        return (resource == null ? b.resource == null
781:                                : resource.equals(b.resource))
782:                                && (classLoader == null ? b.classLoader == null
783:                                        : classLoader.equals(b.classLoader))
784:                                && (constantsProvider == null ? b.constantsProvider == null
785:                                        : constantsProvider
786:                                                .equals(b.constantsProvider))
787:                                && (wrapper == null ? b.wrapper == null
788:                                        : wrapper.equals(b.wrapper))
789:                                && (comparator == null ? b.comparator == null
790:                                        : comparator.equals(b.comparator));
791:
792:                    } else {
793:                        return false;
794:                    }
795:                }
796:
797:                public int hashCode() {
798:                    int result = 0;
799:                    result = HashCodeUtil.hashCode(result, resource);
800:                    result = HashCodeUtil.hashCode(result, classLoader);
801:                    result = HashCodeUtil.hashCode(result, constantsProvider);
802:                    result = HashCodeUtil.hashCode(result, wrapper);
803:                    result = HashCodeUtil.hashCode(result, comparator);
804:                    return result;
805:                }
806:
807:                public Object clone() {
808:                    log.debug("Cloning bundle " + this );
809:                    try {
810:                        Bundle clone = (Bundle) super .clone();
811:                        clone.constantsProvider = constantsProvider != null ? (HashMap<String, Object>) constantsProvider
812:                                .clone()
813:                                : null;
814:                        return clone;
815:                    } catch (Exception e) {
816:                        log.error(e.getMessage(), e);
817:                        return this ;
818:                    }
819:                }
820:
821:            }
822:
823:            /**
824:             * For testing only.
825:             */
826:            public static void main(String argv[]) {
827:                LocalizedEntryListFactory fact = new LocalizedEntryListFactory();
828:                String resource1 = "org.mmbase.datatypes.resources.boolean.onoff";
829:                String resource2 = "org.mmbase.datatypes.resources.boolean.yesno";
830:                Locale nl = new Locale("nl");
831:                Locale en = new Locale("en");
832:                Locale dk = new Locale("dk");
833:                Locale eo = new Locale("eo");
834:                fact.add(nl, "a", "hallo");
835:                System.out.println("nou " + fact);
836:                fact.add(new Locale("nl"), "b", "daag");
837:                fact.add(en, "b", "hello");
838:                fact.add(en, "a", "good bye");
839:                fact.addBundle(resource1, null, null, Boolean.class,
840:                        SortedBundle.NO_COMPARATOR);
841:                fact.add(nl, "c", "doegg");
842:                fact.add(dk, 5, "dk");
843:                fact.add(null, "e", "oi");
844:                fact.addBundle(resource2, null, null, String.class,
845:                        SortedBundle.NO_COMPARATOR);
846:
847:                System.out.println("size: " + fact.size() + " " + fact);
848:                System.out.println("en" + fact.get(en));
849:                System.out.println("nl" + fact.get(nl));
850:                System.out.println("dk" + fact.get(dk));
851:                System.out.println("eo" + fact.get(eo));
852:
853:                LocalizedEntryListFactory fact2 = new LocalizedEntryListFactory();
854:                fact2.addBundle("org.mmbase.datatypes.resources.states", null,
855:                        org.mmbase.module.builders.MMServers.class,
856:                        SortedBundle.NO_WRAPPER, SortedBundle.NO_COMPARATOR);
857:
858:                System.out.println("size: " + fact2.size());
859:                System.out.println("" + fact2.get(en));
860:                System.out.println("" + fact2.get(nl));
861:                Object error = fact2.castKey("ERROR", null);
862:                System.out.println("ERROR=" + error.getClass().getName() + " "
863:                        + error);
864:
865:            }
866:
867:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.