001: /*
002: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
003: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
004: */
005: package com.sun.portal.desktop.dp.xml;
006:
007: import org.w3c.dom.Element;
008: import org.w3c.dom.Document;
009:
010: import java.util.List;
011: import java.util.ArrayList;
012: import java.util.Map;
013: import java.util.Iterator;
014: import java.util.Set;
015: import java.io.InputStream;
016: import java.io.ByteArrayInputStream;
017:
018: import com.sun.portal.desktop.context.DPContext;
019: import com.sun.portal.desktop.context.DPUserContext;
020:
021: import com.sun.portal.desktop.dp.DPError;
022: import com.sun.portal.desktop.dp.DPChannel;
023: import com.sun.portal.desktop.dp.DPContainerChannel;
024: import com.sun.portal.desktop.dp.DPProperty;
025: import com.sun.portal.desktop.dp.DPPropertyHolder;
026: import com.sun.portal.desktop.dp.DPString;
027: import com.sun.portal.desktop.dp.DPCollection;
028: import com.sun.portal.desktop.dp.DPLocale;
029: import com.sun.portal.desktop.dp.DPReference;
030: import com.sun.portal.desktop.dp.DPTypes;
031: import com.sun.portal.desktop.dp.DPFactory;
032: import com.sun.portal.desktop.dp.DPRoot;
033: import com.sun.portal.desktop.dp.DPNode;
034: import com.sun.portal.desktop.dp.DPProperties;
035: import com.sun.portal.desktop.dp.DPConditionalProperties;
036: import com.sun.portal.desktop.dp.DPProvider;
037: import com.sun.portal.desktop.dp.DPSelected;
038: import com.sun.portal.desktop.dp.DPAvailable;
039:
040: /**
041: * This class gets and creates instances of DP objects.
042: *
043: * All XMLDP* objects are backed by a DOM element; they are simply
044: * wrappers for the DOM that impose certain semantics on particular
045: * types of DOM nodes.
046: *
047: * The get* methods add a wrapper around an already existing DOM node.
048: * They all require the DOM element to be passed in as an argument. If the
049: * DOM element does not match the type of the DP object being returned,
050: * then an exception is thrown.
051: *
052: * The create* methods create a new DOM element and add the wrapper.
053: *
054: */
055:
056: public class XMLDPFactory implements DPFactory, DPTypes, XMLDPTags {
057:
058: protected static XMLDPFactory factory = new XMLDPFactory();
059: protected static final char CHANNEL_NAME_SEPARATOR = DPNode.CHANNEL_NAME_SEPARATOR;
060:
061: public static XMLDPFactory getInstance() {
062: return factory;
063: }
064:
065: private XMLDPFactory() {
066: // nothing
067: }
068:
069: /**
070: * Get a DP root object wrapper for the given Element.
071: */
072:
073: public DPRoot getRoot(DPContext dpc, Element e) {
074: if (e.getTagName().equals(DISPLAYPROFILE_TAG)) {
075: return new XMLDPRoot(dpc, e);
076: } else {
077: throw new DPError(
078: "XMLDPFactory.getRoot(): not root node tagName="
079: + e.getTagName());
080: }
081: }
082:
083: /**
084: * Get a DP node object wrapper for the given Element.
085: *
086: * While the interface returned by this method is DPNode, the actual
087: * object is an instance of either DPRoot, DPChannel, or DPContainerChannel.
088: */
089:
090: public DPNode getNode(DPContext dpc, DPRoot r, Element e) {
091: String name = e.getAttribute(XMLDPAttrs.NAME_KEY);
092: if (name.indexOf(CHANNEL_NAME_SEPARATOR) != -1) {
093: throw new DPError(
094: "XMLDPFactory.getNode(): invalid character \""
095: + CHANNEL_NAME_SEPARATOR
096: + "\" found in the name=" + name);
097: }
098:
099: if (e.getTagName().equals(DISPLAYPROFILE_TAG)) {
100: return new XMLDPRoot(dpc, e);
101: } else if (e.getTagName().equals(CHANNEL_TAG)) {
102: return new XMLDPChannel(dpc, r, e);
103: } else if (e.getTagName().equals(CONTAINER_TAG)) {
104: return new XMLDPContainerChannel(dpc, r, e);
105: } else {
106: throw new DPError(
107: "XMLDPFactory.getNode(): unknown node type tagName="
108: + e.getTagName());
109: }
110: }
111:
112: /**
113: * Get a DP property holder wrapper for the given Element.
114: *
115: * While the interface returned by this method is a DPPropertyHolder,
116: * the actual object instance is either a DPRoot, DPChannel,
117: * DPContainerChannel, or a DPProvider.
118: */
119: public DPPropertyHolder getPropertyHolder(DPContext dpc, DPRoot r,
120: Element e) {
121: DPPropertyHolder dpph = null;
122:
123: if (e.getTagName().equals(PROVIDER_TAG)) {
124: dpph = getProvider(dpc, r, e);
125: } else {
126: dpph = getNode(dpc, r, e);
127: }
128:
129: return dpph;
130: }
131:
132: /**
133: * Get a DP property wrapper for the given Element.
134: *
135: * While the interface returned by this method is a DPProperty, the actual
136: * object instance returned is either a DPString, DPInteger, DPBoolean,
137: * DPLocale, DPProperties, DPConditionalProperties, or DPCollection.
138: */
139:
140: public DPProperty getProperty(DPContext dpc, DPRoot r, Element e) {
141: if (e.getTagName().equals(STRING_TAG)) {
142: return new XMLDPString(dpc, r, e);
143: } else if (e.getTagName().equals(REFERENCE_TAG)) {
144: return new XMLDPReference(dpc, r, e);
145: } else if (e.getTagName().equals(INTEGER_TAG)) {
146: return new XMLDPInteger(dpc, r, e);
147: } else if (e.getTagName().equals(BOOLEAN_TAG)) {
148: return new XMLDPBoolean(dpc, r, e);
149: } else if (e.getTagName().equals(COLLECTION_TAG)) {
150: return new XMLDPCollection(dpc, r, e);
151: } else if (e.getTagName().equals(LOCALE_TAG)) {
152: return new XMLDPLocale(dpc, r, e);
153: } else if (e.getTagName().equals(PROPERTIES_TAG)) {
154: return new XMLDPProperties(dpc, r, e);
155: } else if (e.getTagName().equals(CONDITIONALPROPERTIES_TAG)) {
156: return new XMLDPConditionalProperties(dpc, r, e);
157: } else {
158: throw new DPError(
159: "XMLDPFactory.getProperty(): unknown property type tagName="
160: + e.getTagName());
161: }
162: }
163:
164: /**
165: * Get a DP collection property wrapper for the given Element.
166: *
167: * This method with accept element types of Colletion, Selected, Available,
168: * Locale, Properties, or ConditionalProperties and will return an instance of
169: * DPCollection.
170: */
171:
172: public DPCollection getCollectionProperty(DPContext dpc, DPRoot r,
173: Element e) {
174: if (e.getTagName().equals(COLLECTION_TAG)
175: || e.getTagName().equals(LOCALE_TAG)
176: || e.getTagName().equals(SELECTED_TAG)
177: || e.getTagName().equals(AVAILABLE_TAG)
178: || e.getTagName().equals(PROPERTIES_TAG)
179: || e.getTagName().equals(CONDITIONALPROPERTIES_TAG)) {
180: return new XMLDPCollection(dpc, r, e);
181: } else {
182: throw new DPError(
183: "XMLDPFactory.getCollectionProperty(): unknown property type tagName="
184: + e.getTagName());
185: }
186: }
187:
188: /**
189: * Get a DP reference wrapper for the given Element.
190: */
191:
192: public DPReference getReference(DPContext dpc, DPRoot r, Element e) {
193: if (e.getTagName().equals(REFERENCE_TAG)) {
194: return new XMLDPReference(dpc, r, e);
195: } else {
196: throw new DPError(
197: "XMLDPFactory.getReference(): not a reference element tagName="
198: + e.getTagName());
199: }
200:
201: }
202:
203: /**
204: * Get a DP properties wrapper for the given Element.
205: */
206:
207: public DPProperties getProperties(DPContext dpc, DPRoot r, Element e) {
208: if (e.getTagName().equals(PROPERTIES_TAG)) {
209: return new XMLDPProperties(dpc, r, e);
210: } else {
211: throw new DPError(
212: "XMLDPFactory.getProperties(): not a properties element tagName="
213: + e.getTagName());
214: }
215:
216: }
217:
218: /**
219: * Get a DP conditionalproperties wrapper for the given Element.
220: */
221:
222: public DPConditionalProperties getConditionalProperties(
223: DPContext dpc, DPRoot r, Element e) {
224: if (e.getTagName().equals(CONDITIONALPROPERTIES_TAG)) {
225: return new XMLDPConditionalProperties(dpc, r, e);
226: } else {
227: throw new DPError(
228: "XMLDPFactory.getProperties(): not a conditionalproperties element tagName="
229: + e.getTagName());
230: }
231: }
232:
233: /**
234: * Get a DP selected wrapper for the given Element.
235: */
236:
237: public DPSelected getSelected(DPContext dpc, DPRoot r, Element e) {
238: if (e.getTagName().equals(SELECTED_TAG)) {
239: return new XMLDPSelected(dpc, r, e);
240: } else {
241: throw new DPError(
242: "XMLDPFactory.getSelected(): not a selected element tagName="
243: + e.getTagName());
244: }
245:
246: }
247:
248: /**
249: * Get a DP selected wrapper for the given Element.
250: */
251:
252: public DPAvailable getAvailable(DPContext dpc, DPRoot r, Element e) {
253: if (e.getTagName().equals(AVAILABLE_TAG)) {
254: return new XMLDPAvailable(dpc, r, e);
255: } else {
256: throw new DPError(
257: "XMLDPFactory.getAvailable(): not an available element tagName="
258: + e.getTagName());
259: }
260:
261: }
262:
263: /**
264: * Get a new DP channel wrapper for the given Element.
265: *
266: * Whiel the interface returned by this method is a DPChannel, the actual
267: * object instance returned is either a DPChannel or a DPContainerChannel.
268: */
269:
270: public DPChannel getChannel(DPContext dpc, DPRoot r, Element e) {
271: String name = e.getAttribute(XMLDPAttrs.NAME_KEY);
272: if (name.indexOf(CHANNEL_NAME_SEPARATOR) != -1) {
273: throw new DPError(
274: "XMLDPFactory.getchannel(): invalid character \""
275: + CHANNEL_NAME_SEPARATOR
276: + "\" found in the name=" + name);
277: }
278:
279: if (e.getTagName().equals(CHANNEL_TAG)) {
280: return new XMLDPChannel(dpc, r, e);
281: } else if (e.getTagName().equals(CONTAINER_TAG)) {
282: return new XMLDPContainerChannel(dpc, r, e);
283: } else {
284: throw new DPError(
285: "XMLDPFactory.getChannel(): unknown channel type tagName="
286: + e.getTagName());
287: }
288: }
289:
290: /**
291: * Get a new DP provider wrapper for the given Element.
292: */
293:
294: public DPProvider getProvider(DPContext dpc, DPRoot r, Element e) {
295: if (e.getTagName().equals(PROVIDER_TAG)) {
296: return new XMLDPProvider(dpc, r, e);
297: } else {
298: throw new DPError(
299: "XMLDPFactory.getProvider(): unknown provider type tagName="
300: + e.getTagName());
301: }
302: }
303:
304: /**
305: * Create a new DP property object.
306: *
307: * While the interface returned by this method is a DPProperty, the actual
308: * object instance returned depend on the type of the Object argument.
309: *
310: * <ul>
311: * <li>Object type String returns an instance of DPString
312: * <li>Object type Integer returns an instance of DPInteger
313: * <li>Object type Boolean returns an instance of DPBoolean
314: * <li>Object type List or Map returns an instance of DPCollection
315: * </ul>
316: *
317: * If the type of Object o is not a String, Integer, or Boolean
318: * then a DPString is returned, where the value is the value
319: * return from the object's toString() method.
320: */
321:
322: public DPProperty createProperty(DPContext dpc, DPRoot r,
323: Document d, String name, Object o) {
324: if (o instanceof String) {
325: return new XMLDPString(dpc, r, d, name, (String) o);
326: } else if (o instanceof Boolean) {
327: return new XMLDPBoolean(dpc, r, d, name, (Boolean) o);
328: } else if (o instanceof Integer) {
329: return new XMLDPInteger(dpc, r, d, name, (Integer) o);
330: } else if (o instanceof List) {
331: return new XMLDPCollection(dpc, r, d, name, (List) o);
332: } else if (o instanceof Map) {
333: return new XMLDPCollection(dpc, r, d, name, (Map) o);
334: } else {
335: return new XMLDPString(dpc, r, d, name, o.toString());
336: }
337: }
338:
339: /**
340: * Create a new unnamed DP property object.
341: *
342: * While the interface returned by this method is a DPProperty, the actual
343: * object instance returned depend on the type of the Object argument.
344: *
345: * <ul>
346: * <li>Object type String returns an instance of DPString
347: * <li>Object type Integer returns an instance of DPInteger
348: * <li>Object type Boolean returns an instance of DPBoolean
349: * </ul>
350: *
351: * If the type of Object o is not a String, Integer, or Boolean
352: * then a DPString is returned, where the value is the value
353: * return from the object's toString() method.
354: */
355:
356: public DPProperty createProperty(DPContext dpc, DPRoot r,
357: Document d, Object o) {
358: if (o instanceof String) {
359: return new XMLDPString(dpc, r, d, (String) o);
360: } else if (o instanceof Boolean) {
361: return new XMLDPBoolean(dpc, r, d, (Boolean) o);
362: } else if (o instanceof Integer) {
363: return new XMLDPInteger(dpc, r, d, (Integer) o);
364: } else {
365: return new XMLDPString(dpc, r, d, o.toString());
366: }
367: }
368:
369: /**
370: * Create a new DP reference object.
371: *
372: */
373:
374: public DPReference createReference(DPContext dpc, DPRoot r,
375: Document d, String ref) {
376: return new XMLDPReference(dpc, r, d, ref);
377: }
378:
379: public DPString createString(DPContext dpc, DPRoot r, Document d,
380: String name, String value) {
381: return new XMLDPString(dpc, r, d, name, value);
382: }
383:
384: /**
385: * Create a new, empty DP properties object.
386: */
387:
388: public DPProperties createProperties(DPContext dpc, DPRoot r,
389: Document d) {
390: return new XMLDPProperties(dpc, r, d);
391: }
392:
393: /**
394: * Create a new, empty DP conditional properties object.
395: */
396: public DPConditionalProperties createConditionalProperties(
397: DPContext dpc, DPRoot r, Document d, String type,
398: String value) {
399: return new XMLDPConditionalProperties(dpc, r, d, type, value);
400: }
401:
402: /**
403: * Create a new DP conditional properties object.
404: */
405: public DPConditionalProperties createConditionalProperties(
406: DPContext dpc, DPRoot r, Document d, String type,
407: String value, Map m) {
408: return new XMLDPConditionalProperties(dpc, r, d, type, value, m);
409: }
410:
411: /**
412: * Create a new, empty DP available object.
413: */
414:
415: public DPAvailable createAvailable(DPContext dpc, DPRoot r,
416: Document d) {
417: return new XMLDPAvailable(dpc, r, d);
418: }
419:
420: /**
421: * Create a new, empty DP selected object.
422: */
423:
424: public DPSelected createSelected(DPContext dpc, DPRoot r, Document d) {
425: return new XMLDPSelected(dpc, r, d);
426: }
427:
428: /**
429: * Create a new DP channel object.
430: *
431: * The new DP channel object has an empty properties bag.
432: */
433:
434: public DPChannel createChannel(DPContext dpc, DPRoot r, Document d,
435: String name, String providerName) {
436: if (name.indexOf(CHANNEL_NAME_SEPARATOR) != -1) {
437: throw new DPError(
438: "XMLDPFactory.getNode(): invalid character,\""
439: + CHANNEL_NAME_SEPARATOR
440: + "\" found in the name=" + name);
441: }
442:
443: return new XMLDPChannel(dpc, r, d, name, providerName);
444: }
445:
446: /**
447: * Create a new DP container channel object.
448: *
449: * The new DP container channel object has an empty properties bag.
450: */
451:
452: public DPContainerChannel createContainerChannel(DPContext dpc,
453: DPRoot r, Document d, String name, String providerName) {
454: if (name.indexOf(CHANNEL_NAME_SEPARATOR) != -1) {
455: throw new DPError(
456: "XMLDPFactory.getNode(): invalid character,\""
457: + CHANNEL_NAME_SEPARATOR
458: + "\" found in the name=" + name);
459: }
460:
461: return new XMLDPContainerChannel(dpc, r, d, name, providerName);
462: }
463:
464: /**
465: * Create a new DP provider object.
466: *
467: * The new DP provider object has an empty properties bag.
468: */
469:
470: public DPProvider createProvider(DPContext dpc, DPRoot r,
471: Document d, String name, String className,
472: int providerVersion) {
473: return new XMLDPProvider(dpc, r, d, name, className,
474: providerVersion);
475: }
476:
477: /**
478: * Create a new, empty DP locale object.
479: *
480: * @deprecated Use createConditionalProperties instead.
481: * @see #createConditionalProperties(DPContext, DPRoot, Document, String, String)
482: */
483: public DPLocale createLocale(DPContext dpc, DPRoot r, Document d,
484: String lang, String country, String variant) {
485: return new XMLDPLocale(dpc, r, d, lang, country, variant);
486: }
487:
488: /**
489: * Create a new DP locale object.
490: *
491: * @deprecated Use createConditionalProperties instead.
492: * @see #createConditionalProperties(DPContext, DPRoot, Document, String, String, Map)
493: */
494: public DPLocale createLocale(DPContext dpc, DPRoot r, Document d,
495: String lang, String country, String variant, Map m) {
496: return new XMLDPLocale(dpc, r, d, lang, country, variant, m);
497: }
498:
499: /**
500: * Create a new DP root object and optionally add merger root objects.
501: *
502: * The DP root object is created based on the user document read from
503: * the DPContext object (DPContext.getUserDocument()).
504: *
505: * If the merge argument is true, merger obejcts are added.
506: * The merger objects are based on the non-user documents
507: * read from DPContext object (DPContext.getDPDocuments()).
508: */
509:
510: public DPRoot createRoot(DPContext dpc, DPUserContext dpuc,
511: Map dpRoots, boolean merge) {
512: //
513: // first get the user doc
514: //
515:
516: byte[] userDoc = dpuc.getDPUserDocument();
517:
518: /*
519: dpc.debugError(
520: "XMLDPFactory.createRoot(): got user document=" + doc
521: );
522: */
523:
524: DPRoot dpr = null;
525:
526: if (userDoc == null || userDoc.length == 0) {
527: dpr = new XMLDPRoot(dpc);
528: } else {
529: ByteArrayInputStream s = new ByteArrayInputStream(userDoc);
530: dpr = new XMLDPRoot(dpc, s);
531: }
532:
533: //
534: // return user doc only
535: //
536: if (!merge) {
537: return dpr;
538: }
539:
540: //
541: // get the non-user documents
542: //
543: Set names = null;
544:
545: names = dpuc.getDPDocumentNames();
546:
547: //
548: // add non-user roots as mergers
549: //
550: return addMergers(dpc, dpr, names, dpRoots);
551: }
552:
553: /**
554: * Adds merger root objects to the given DP root.
555: */
556: public DPRoot addMergers(DPContext dpc, DPRoot dpr, Set names,
557: Map dpRoots) {
558: List mergers = new ArrayList();
559:
560: for (Iterator i = names.iterator(); i.hasNext();) {
561:
562: String name = (String) i.next();
563: DPRoot dprMerger = null;
564: if (dpRoots != null) {
565: dprMerger = (DPRoot) dpRoots.get(name);
566: }
567:
568: if (dprMerger == null) {
569: synchronized (this ) {
570: if (dpRoots != null) {
571: dprMerger = (DPRoot) dpRoots.get(name);
572: }
573:
574: if (dprMerger == null) {
575: String val = dpc.getDPDocument(name);
576: if (val == null || val.length() == 0) {
577: //
578: // this is not an error.
579: // it means that the document was not imported
580: // at the node name we are trying t fetch it from
581: //
582: continue;
583: }
584:
585: dprMerger = new XMLDPRoot(dpc, val);
586: if (dpRoots != null) {
587: dpRoots.put(name, dprMerger);
588: }
589:
590: }
591: }
592: }
593:
594: mergers.add(dprMerger);
595: }
596:
597: //
598: // add mergers in sorted order
599: //
600: dpr.addMergers(mergers);
601:
602: /*
603: dpc.debugError("XMLDPFactory.getRoot(): " +
604: ((XMLDPRoot)dpr).toDebugString());
605: */
606:
607: return dpr;
608: }
609:
610: /**
611: * Create a new, empty DP root object.
612: *
613: * No merge objects are added to the rturned DP root object.
614: */
615:
616: public DPRoot createRoot(DPContext dpc) {
617: DPRoot dpr = new XMLDPRoot(dpc);
618:
619: return dpr;
620: }
621:
622: /**
623: * Create a DP root object based on the given string.
624: * This method can be called only if the encoding in the xml header is "UTF-8"
625: * No merge objects are added to the returned DP root object.
626: *
627: * @param dpc The DPContext
628: * @param doc xml String
629: */
630: public DPRoot createRoot(DPContext dpc, String doc) {
631:
632: DPRoot dpr = null;
633:
634: if (doc == null) {
635: throw new DPError(
636: "XMLDPFactory.createRoot(): document was null");
637: } else {
638: dpr = new XMLDPRoot(dpc, doc);
639: }
640:
641: return dpr;
642: }
643:
644: /**
645: * Create a DP root object based on the given stream.
646: *
647: * No merge objects are added to the returned DP root object.
648: */
649: public DPRoot createRoot(DPContext dpc, InputStream xmlByteStream) {
650:
651: DPRoot dpr = null;
652:
653: if (xmlByteStream == null) {
654: throw new DPError(
655: "XMLDPFactory.createRoot(): document was null");
656: } else {
657: dpr = new XMLDPRoot(dpc, xmlByteStream);
658: }
659:
660: return dpr;
661: }
662:
663: public DPRoot createRoot(DPContext dpc, String baseName, Map dpRoots) {
664: DPRoot dpRoot = (DPRoot) dpRoots.get(baseName);
665: if (dpRoot == null) {
666: String dpText = dpc.getDPDocument(baseName);
667:
668: dpRoot = ((dpText != null) && (dpText.length() > 0)) ? createRoot(
669: dpc, dpText)
670: : createRoot(dpc);
671:
672: Set mergers = dpc.getDPDocumentNames(baseName);
673:
674: dpRoot = addMergers(dpc, dpRoot, mergers, dpRoots);
675: dpRoots.put(baseName, dpRoot);
676: }
677: //This is to make sure that returned dpRoot always has its mergers.
678: if (dpRoot.getMergers() == null
679: || dpRoot.getMergers().isEmpty()) {
680: Set mergers = dpc.getDPDocumentNames(baseName);
681: dpRoot = addMergers(dpc, dpRoot, mergers, dpRoots);
682: dpRoots.put(baseName, dpRoot);
683: }
684: return dpRoot;
685: }
686: }
|