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.providers;
006:
007: import java.util.Map;
008: import java.util.Enumeration;
009: import java.util.HashMap;
010: import java.util.List;
011: import java.util.ArrayList;
012: import java.util.ResourceBundle;
013: import java.util.Locale;
014: import java.util.StringTokenizer;
015: import java.util.logging.Level;
016: import java.util.logging.LogRecord;
017: import java.util.logging.Logger;
018:
019: import java.lang.reflect.Method;
020:
021: import java.net.URL;
022: import java.net.MalformedURLException;
023:
024: import javax.servlet.ServletRequest;
025: import javax.servlet.http.HttpServletRequest;
026: import javax.servlet.http.HttpServletResponse;
027:
028: import com.sun.portal.desktop.DesktopRequest;
029: import com.sun.portal.desktop.RequestThreadLocalizer;
030:
031: import com.sun.portal.desktop.util.Integers;
032:
033: import com.sun.portal.providers.ProviderWidths;
034: import com.sun.portal.providers.ProviderEditTypes;
035: import com.sun.portal.providers.context.ProviderContext;
036: import com.sun.portal.providers.context.ProviderContextException;
037:
038: import com.sun.portal.desktop.context.ContextException;
039: import com.sun.portal.desktop.context.ProviderContextThreadLocalizer;
040: import com.sun.portal.log.common.PortalLogger;
041:
042: /**
043: * This class provides default implementations of methods in the Provider
044: * interface implemented using a ProviderContext object as the
045: * persistent store.
046: *
047: * <p>
048: * Developers who wish to implement a provider should extend this class
049: * or ProfileProviderAdapter.
050: * <p>
051: * The advantage of extending this class versus implementing the
052: * <code>Provider</code> interface directly
053: * is that you will maintain forward
054: * compatability as additions are made to the Provider API. Existing
055: * code will by default call the methods in this class. Eventually,
056: * code should be written to implement all of the methods in the
057: * <code>Provider</code> interface.
058: * <p>
059: * For method details, see the descriptions in the <code>Provider</code>
060: * interface.
061: *
062: * @see com.sun.portal.providers.context.ProviderContext
063: * @see com.sun.portal.providers.Provider
064: */
065:
066: public abstract class ProviderAdapter implements Provider,
067: ProviderWidths, ProviderEditTypes {
068:
069: private String name = null;
070: private ProviderContext context = null;
071:
072: private static Map widthMap = null;
073: private static Map editTypeMap = null;
074:
075: private static String HELP_URL = "helpURL";
076:
077: private Boolean presentableFromPA = null;
078: private final static String ADAPTER_CLASS = "com.sun.portal.providers.ProviderAdapter";
079:
080: private static Logger logger = PortalLogger
081: .getLogger(ProviderAdapter.class);
082: static {
083: widthMap = new HashMap();
084:
085: //
086: // pre-calc mapping of string width settings that
087: // are read from the DP to integer width
088: // types, so we do not need to do the string
089: // calc's each time ...
090: //
091: widthMap.put("thin", Integers.get(WIDTH_THIN));
092: widthMap.put("THIN", Integers.get(WIDTH_THIN));
093: widthMap.put("Thin", Integers.get(WIDTH_THIN));
094:
095: widthMap.put("thick", Integers.get(WIDTH_THICK));
096: widthMap.put("THICK", Integers.get(WIDTH_THICK));
097: widthMap.put("Thick", Integers.get(WIDTH_THICK));
098:
099: widthMap.put("full_top", Integers.get(WIDTH_FULL_TOP));
100: widthMap.put("FULL_TOP", Integers.get(WIDTH_FULL_TOP));
101: widthMap.put("Full_Top", Integers.get(WIDTH_FULL_TOP));
102:
103: widthMap.put("full_bottom", Integers.get(WIDTH_FULL_BOTTOM));
104: widthMap.put("FULL_BOTTOM", Integers.get(WIDTH_FULL_BOTTOM));
105: widthMap.put("Full_Bottom", Integers.get(WIDTH_FULL_BOTTOM));
106:
107: editTypeMap = new HashMap();
108:
109: editTypeMap.put("edit_subset", Integers.get(EDIT_SUBSET));
110: editTypeMap.put("EDIT_SUBSET", Integers.get(EDIT_SUBSET));
111: editTypeMap.put("Edit_Subset", Integers.get(EDIT_SUBSET));
112:
113: editTypeMap.put("edit_complete", Integers.get(EDIT_COMPLETE));
114: editTypeMap.put("EDIT_COMPLETE", Integers.get(EDIT_COMPLETE));
115: editTypeMap.put("Edit_Complete", Integers.get(EDIT_COMPLETE));
116:
117: }
118:
119: public void init(String n, HttpServletRequest req)
120: throws ProviderException {
121: name = n;
122:
123: //
124: // try to get the context object
125: //
126: context = getProviderContext(req);
127:
128: }
129:
130: /**
131: * Calls the getContent(<code>Map</code>) method in this object to provide backwards
132: * compatibility.
133: * <p>
134: * The implementation of this method provides backwards compatibility
135: * for providers that only implement the deprecated getContent(Map)
136: * method. It logs a warning informing the administrator that calling
137: * this method has performance implications, and that it should be
138: * re-implemented using the non-deprecated version of this method.
139: * <p>
140: * Each time this method is called, the HTTP parameter data in the request
141: * object must be converted to the Map form that is accepted by the
142: * getContent(Map) version of this method.
143: *
144: */
145: public StringBuffer getContent(HttpServletRequest request,
146: HttpServletResponse response) throws ProviderException {
147: if (logger.isLoggable(Level.WARNING)) {
148: String[] param = { "getContent(Map)", getName(),
149: "getContent(HttpServletRequest, HttpServletResponse)" };
150: logger.log(Level.WARNING, "PSDT_CSPP0001", param);
151: }
152:
153: Map parameterMap = getParameterMap(request);
154: return getContent(parameterMap);
155: }
156:
157: private static Map getParameterMap(ServletRequest req) {
158: Map parameterMap = null;
159: if (req instanceof DesktopRequest) {
160: parameterMap = ((DesktopRequest) req).getParameterMap();
161: } else {
162: parameterMap = new HashMap();
163: for (Enumeration e = req.getParameterNames(); e
164: .hasMoreElements();) {
165: String key = (String) e.nextElement();
166: String[] val = req.getParameterValues(key);
167: parameterMap.put(key, val);
168: }
169: }
170:
171: return parameterMap;
172: }
173:
174: /**
175: * This method has no effect.
176: *
177: * @return null, always.
178: *
179: * @deprecated Using this method has negative performance implications.
180: * Use getContent(HttpServletRequest, HttpServletResponse) instead.
181: *
182: */
183: public StringBuffer getContent(Map m) throws ProviderException {
184: return null;
185: }
186:
187: /**
188: * Calls the getEdit(Map) method in this object to provide backwards
189: * compatibility.
190: *
191: * The implementation of this method provides backwards compatibility
192: * for providers that only implement the deprecated getEdit(Map)
193: * method. It logs a warning informing the administrator that calling
194: * this method has performance implications, and that it should be
195: * re-implemented using the non-deprecated version of this method.
196: *
197: * Each time this method is called, the HTTP parameter data in the request
198: * object must be converted to the Map form that is accepted by the
199: * getEdit(Map) version of this method.
200: *
201: */
202: public StringBuffer getEdit(HttpServletRequest request,
203: HttpServletResponse response) throws ProviderException {
204: if (logger.isLoggable(Level.WARNING)) {
205: String[] params = {
206: "getEdit(Map)",
207: getName(),
208: "getContent(HttpServletRequest, HttpServletResponse)",
209: "Map" };
210: logger.log(Level.WARNING, "PSDT_CSPP0001", params);
211: }
212: Map parameterMap = getParameterMap(request);
213: return getEdit(parameterMap);
214: }
215:
216: /**
217: * This method has no effect.
218: *
219: * @return null, always.
220: *
221: * @deprecated Using this method has negative performance implications.
222: * Use getEdit(HttpServletRequest, HttpServletResponse) instead.
223: *
224: */
225: public StringBuffer getEdit(Map m) throws ProviderException {
226: return null;
227: }
228:
229: /**
230: * Gets the edit type for the channel. The edit type for
231: * a channel informs clients of the channel (such as a container channel)
232: * what sort of content to be returned for its edit view; either a
233: * fragment or a complete document.
234: *
235: * @return The edit type; either EDIT_COMPLETE or EDIT_SUBSET.
236: * @exception UnknownEditTypeException if an error occurs when getting the
237: * edit type of the channel.
238: * @see com.sun.portal.providers.ProviderEditTypes
239: */
240: public int getEditType() throws UnknownEditTypeException {
241: String val = null;
242: try {
243: ProviderContext pc = getProviderContext();
244: List clientAndLocaleFilters = pc
245: .getClientAndLocalePropertiesFilters();
246: val = pc.getStringProperty(getName(), "editType",
247: clientAndLocaleFilters);
248: } catch (ProviderContextException pce) {
249: throw new UnknownEditTypeException(
250: "ProviderAdapter.getEditType(): ", pce);
251: }
252: Integer type = (Integer) editTypeMap.get(val);
253:
254: if (type == null) {
255: throw new UnknownEditTypeException(
256: "ProviderAdapter.getEditType(): unknown edit type="
257: + val);
258: }
259:
260: return type.intValue();
261: }
262:
263: /**
264: * Calls the processEdit(Map) method in this object to provide backwards
265: * compatibility.
266: * <p>
267: * The implementation of this method provides backwards compatibility
268: * for providers that only implement the deprecated processEdit(Map)
269: * method. It logs a warning informing the administrator that calling
270: * this method has performance implications, and that it should be
271: * re-implemented using the non-deprecated version of this method.
272: * <p>
273: * Each time this method is called, the HTTP parameter data in the request
274: * object must be converted to the Map form that is accepted by the
275: * processEdit(Map) version of this method.
276: *
277: */
278: public URL processEdit(HttpServletRequest request,
279: HttpServletResponse response) throws ProviderException {
280:
281: if (logger.isLoggable(Level.INFO)) {
282: String[] param = { "processEdit (Map)", getName(),
283: "processEdit(HttpServletRequest, HttpServletRequest)" };
284: logger.log(Level.INFO, "PSDT_CSPP0001", param);
285: }
286:
287: Map parameterMap = getParameterMap(request);
288: return processEdit(parameterMap);
289: }
290:
291: /**
292: * This method has no effect.
293: *
294: * @deprecated Using this method has negative performance implications.
295: * Use processEdit(HttpServletRequest, HttpServletResponse) instead.
296: *
297: * @return null, always
298: */
299: public URL processEdit(Map m) throws ProviderException {
300: return null;
301: }
302:
303: /**
304: * Gets if the channel is editable. If a provider is editable, it is capable
305: * of providing an edit view to clients.
306: *
307: * @return <code>true</code> if the channel is editable, otherwise
308: * <code>false</code>.
309: * @exception ProviderException if error occurs when getting if the channel
310: * is editable.
311: */
312: public boolean isEditable() throws ProviderException {
313: try {
314: ProviderContext pc = getProviderContext();
315: List clientPropertyFilterList = pc
316: .getClientPropertiesFilters();
317:
318: return getProviderContext().getBooleanProperty(getName(),
319: "isEditable", clientPropertyFilterList);
320: } catch (ProviderContextException pce) {
321: throw new ProviderException(
322: "ProviderAdapter.isEditable(): ", pce);
323: }
324: }
325:
326: /**
327: *
328: * <p>Dictates whether the provider is presentable.
329: * <p>Searches for the key <code>genericHTML</code> with the value
330: * <code>true</code> on the client data for the session's client
331: * type and returns true.<br><br>
332: * If there is no such key, method will return <code>true</code> if
333: * the session's client type is named <code>genericHTML</code>.
334: * <p>In both cases, the content-type for the session's client type must
335: * equal <code>text/html</code> in order for the method to return true.
336: *
337: * @deprecated Replaced by isPresentable(HttpServletRequest)
338: *
339: * @return A boolean value dictating presentability
340: * @see com.sun.portal.providers.Provider#isPresentable
341: */
342:
343: public boolean isPresentable() {
344: if (logger.isLoggable(Level.WARNING)) {
345: String[] param = { "isPresentable ()", getName(),
346: "isPresentable(HttpServletRequest)" };
347: logger.log(Level.WARNING, "PSDT_CSPP0001", param);
348: }
349: return isPresentable(RequestThreadLocalizer.getRequest());
350: }
351:
352: private boolean isPresentableFromPA() {
353:
354: // To support backward compatibility.
355: // If a custom provider has implemented isPresentable() and if a
356: // new/old container is calling isPresentable(req) on the provider then
357: // the provider's isPresentable() will never be called and this will
358: // create compatibility problems. Hence, when isPresentable(req) method
359: // is called, a check will be made to makesure that isPresentable() is
360: // not implemented in the provider. If implemented, a warning is logged
361: // and the deprecated isPresentable() method in the provider is called .
362:
363: Method[] methods = this .getClass().getMethods();
364:
365: for (int i = 0; i < methods.length; i++) {
366: String methodName = methods[i].getName();
367: if (methodName.startsWith("isPresentable")
368: && methods[i].getParameterTypes().length == 0) {
369: String dcName = methods[i].getDeclaringClass()
370: .getName();
371: if (!dcName.equals(ADAPTER_CLASS)) {
372: if (logger.isLoggable(Level.WARNING)) {
373: String[] params = { "isPresentable()",
374: getName(),
375: "isPresentable(HttpServletRequest)" };
376: logger.log(Level.WARNING, "PSDT_CSPP0001",
377: params);
378: }
379: return false;
380: }
381: }
382: }
383: return true;
384: }
385:
386: /**
387: *
388: * <p>Dictates whether the provider is presentable.
389: * <p>Searches for the key <code>genericHTML</code> with the value
390: * <code>true</code> on the client data for the session's client
391: * type and returns true.<br><br>
392: * If there is no such key, method will return <code>true</code> if
393: * the session's client type is named <code>genericHTML</code>.
394: * <p>In both cases, the content-type for the session's client type must
395: * equal <code>text/html</code> in order for the method to return true.
396: *
397: * @param request An HttpServletRequest that contains
398: * the request the client made of the provider.
399: *
400: * @return A boolean value dictating presentability
401: * @see com.sun.portal.providers.Provider#isPresentable
402: */
403:
404: public boolean isPresentable(HttpServletRequest req) {
405:
406: if (presentableFromPA == null) {
407: if (isPresentableFromPA()) {
408: presentableFromPA = Boolean.TRUE;
409: } else {
410: presentableFromPA = Boolean.FALSE;
411: }
412: }
413:
414: if (!presentableFromPA.booleanValue()) {
415: // isPresentable() implemented in the provider, hence call
416: // that method.
417: return isPresentable();
418: }
419:
420: boolean genericHTML = true;
421: boolean htmlContent = true;
422: String defaultContentType = "text/html";
423:
424: try {
425: String property = getClientTypeProperty("genericHTML");
426: if (property != null) {
427: genericHTML = property.equals("true");
428: }
429: } catch (ProviderException pe) {
430: if (logger.isLoggable(Level.WARNING)) {
431: LogRecord rec = new LogRecord(Level.WARNING,
432: "PSDT_CSPP0002");
433: rec.setLoggerName(logger.getName());
434: String param[] = { "generic XML" };
435: rec.setParameters(param);
436: rec.setThrown(pe);
437: logger.log(rec);
438: }
439:
440: if (getProviderContext().getClientType() != null) {
441: genericHTML = getProviderContext().getClientType()
442: .equals("genericHTML");
443: }
444: }
445:
446: String val = getProviderContext().getContentType();
447: if (val != null) {
448: htmlContent = val.equals(defaultContentType);
449: }
450:
451: if (genericHTML && htmlContent) {
452: return true;
453: } else {
454: return false;
455: }
456: }
457:
458: /**
459: * Gets the title for the channel.
460: *
461: * @return A string title.
462: * @exception ProviderException if error occurs when getting the title for
463: * the channel.
464: */
465: public String getTitle() throws ProviderException {
466: try {
467: return getProviderContext().getStringProperty(getName(),
468: "title", true);
469: } catch (ProviderContextException pce) {
470: throw new ProviderException("ProviderAdapter.getTitle(): ",
471: pce);
472: }
473: }
474:
475: /**
476: * @return The name of the provider, as it was passed in to the init()
477: * method.
478: */
479: public String getName() {
480: return name;
481: }
482:
483: /**
484: * Gets the description for the channel.
485: *
486: * @return A string description.
487: * @exception ProviderException if error occurs when getting the description
488: * of the channel.
489: */
490: public String getDescription() throws ProviderException {
491: try {
492: return getProviderContext().getStringProperty(getName(),
493: "description", true);
494: } catch (ProviderContextException pce) {
495: throw new ProviderException(
496: "ProviderAdapter.getDescription(): ", pce);
497: }
498: }
499:
500: /**
501: * Gets the width for the channel that this is
502: * providing an environment for. The channel width is used as a
503: * suggestion to the container of the channel as to how much screen
504: * real estate it requires.
505: *
506: * @return The width; either WIDTH_THIN, WIDTH_THICK,
507: * WIDTH_FULL_TOP, or WIDTH_FULL_BOTTOM.
508: * @exception ProviderException If there was an error getting the width
509: * of the channel.
510: * @see com.sun.portal.providers.ProviderWidths
511: */
512: public int getWidth() throws ProviderException {
513: String val = null;
514: try {
515: val = getProviderContext().getStringProperty(getName(),
516: "width");
517: } catch (ProviderContextException pce) {
518: throw new ProviderException("ProviderAdapter.getWidth(): ",
519: pce);
520: }
521: Integer width = (Integer) widthMap.get(val);
522:
523: if (width == null) {
524: throw new ProviderException(
525: "ProviderAdapter.getWidth(): unknown width type="
526: + val);
527: }
528:
529: return width.intValue();
530: }
531:
532: /**
533: * Gets the named help URL for the channel that this object is
534: * providing an environment for.
535: *
536: * The request object parameter is included to facilitate implementations.
537: * It can be used to get the server name, port, and protocol. These can
538: * be used to transform a relative URL to absolute. It is not required
539: * that the request object be used as such.
540: *
541: * If the named help page is not supported, then the default help URL
542: * is returned (see <code>getHelp(HttpServletRequest)</code>).
543: *
544: * @param key Key name that maps to a help URL.
545: * @param req Request object containing information for building
546: * the URL.
547: * @return A URL object.
548: * @exception ProviderException If there was an error constructing the
549: * URL.
550: */
551: public URL getHelp(HttpServletRequest req, String key)
552: throws ProviderException {
553:
554: ProviderContext pc = getProviderContext();
555: String hu = null;
556: String locale = null;
557: String docroot = null;
558: try {
559: List clientPropertyFilterList = pc
560: .getClientAndLocalePropertiesFilters();
561: if (!pc.existsStringProperty(getName(), key,
562: clientPropertyFilterList)
563: && !key.equals(HELP_URL)) {
564: key = HELP_URL;
565: }
566: hu = pc.getStringProperty(getName(), key,
567: clientPropertyFilterList);
568:
569: // Check for an empty "helpURL" string, if so do not generate the
570: // help button for the channel.
571: if ((hu != null) && (hu.length() == 0)) {
572: return null;
573: }
574: locale = pc.getLocaleString();
575: docroot = pc.getStringProperty(getName(), "docroot");
576: } catch (ProviderContextException pce) {
577: throw new ProviderException("providerAdapter.getHelp(): ",
578: pce);
579: }
580:
581: URL helpURL = null;
582:
583: //
584: // avoid the MUE in the general case. this is not quite as
585: // robust as allowing the logic in new URL() to
586: // check if it's a abs or rel URL, but it avoid
587: // the overhead of having an exception in most cases.
588: //
589:
590: if (hu.indexOf("://") != -1) {
591: //
592: // looks like a abs url
593: //
594: try {
595: helpURL = new URL(hu);
596: } catch (MalformedURLException mfue) {
597: //
598: // string help url was no a well-formed url. try appending
599: // server and port (treat as a relative url)
600: //
601: String path = pc.getStaticContentPath() + docroot
602: + locale + "/" + hu;
603: try {
604: helpURL = getAbsURL(path, req);
605: } catch (MalformedURLException mue) {
606: throw new ProviderException(
607: "providerAdapter.getHelp(): ", mue);
608: }
609: }
610: } else {
611: //
612: // was not an abs URL, treat a relative
613: //
614: StringBuffer sb = new StringBuffer(pc
615: .getStaticContentPath());
616: sb.append(docroot);
617: if (!docroot.endsWith("/")) {
618: sb.append("/");
619: }
620: sb.append(hu);
621:
622: String path = sb.toString();
623: try {
624: helpURL = getAbsURL(path, req);
625: } catch (MalformedURLException mue) {
626: throw new ProviderException(
627: "providerAdapter.getHelp(): ", mue);
628: }
629: }
630:
631: return helpURL;
632: }
633:
634: /**
635: * Gets the default help URL for the channel that this object is providing an
636: * environment for. This method must return an absolute URL.
637: *
638: * The request object parameter is included to facilitate implementations.
639: * It can be used to get the server name, port, and protocol. These can
640: * be used to transform a relative URL to absolute. It is not required
641: * that the request object be used as such.
642: *
643: * @param req Request object containing information for building
644: * the URL.
645: * @return URL object that points to the channel's help page.
646: * @exception ProviderException If there was an error constructing the
647: * URL.
648: * @see #getHelp(HttpServletRequest)
649: */
650: public URL getHelp(HttpServletRequest req) throws ProviderException {
651: return getHelp(req, HELP_URL);
652: }
653:
654: private URL getAbsURL(String path, HttpServletRequest req)
655: throws MalformedURLException {
656: URL absURL = null;
657: StringBuffer b = new StringBuffer(128);
658:
659: b.append(getProviderContext().getRequestServer(req)).append(
660: path);
661:
662: absURL = new URL(b.toString());
663:
664: return absURL;
665: }
666:
667: /**
668: * Gets the refresh time for the channel. The refresh time for a channel
669: * is used to allow containers to implement caching of content
670: * for their contained channels. This value is used to indicate
671: * the validity of the cached content.
672: *
673: * @return >0, refresh time in number of seconds that a container should
674: * wait before expiring a content cache.
675: * 0, container should never cache channel's content.
676: * -1, container may cache channel's content indefinitely.
677: * @exception ProviderException If there was an error getting the refresh
678: * time for the channel.
679: */
680: public long getRefreshTime() throws ProviderException {
681: String refreshTime = null;
682: long time = 0;
683: try {
684: refreshTime = getProviderContext().getStringProperty(
685: getName(), "refreshTime");
686: } catch (ProviderContextException pce) {
687: throw new ProviderException(
688: "ProviderAdapter.getRefreshTime(): ", pce);
689: }
690: if (refreshTime != null && refreshTime.length() != 0) {
691: try {
692: time = Long.parseLong(refreshTime);
693: } catch (NumberFormatException nfe) {
694: if (logger.isLoggable(Level.WARNING)) {
695: LogRecord rec = new LogRecord(Level.WARNING,
696: "PSDT_CSPP0001");
697: rec.setLoggerName(logger.getName());
698: rec.setThrown(nfe);
699: String[] param = { "refresh time" };
700: rec.setParameters(param);
701: logger.log(rec);
702: }
703: time = 0;
704: }
705: } else {
706: time = 0;
707: }
708:
709: return time;
710: }
711:
712: /**
713: * This method has package-scope and is used here
714: * and in ProfileProviderAdapter
715: * for retrieving property values based on the session's clientType.
716: *
717: * @param propertyName
718: * client property name
719: * @return The client property value
720: * @exception ClientException
721: * When propertyName is null or when there was an exception
722: * getting the client property.
723: */
724:
725: String getClientTypeProperty(String propertyName)
726: throws ProviderException {
727: if (propertyName != null) {
728: return getProviderContext().getClientTypeProperty(
729: propertyName);
730: } else {
731: throw new ProviderException(
732: "ProviderAdapter.getClientProperty(): "
733: + "unable to read client property, propertyName is null");
734: }
735:
736: }
737:
738: /**
739: * Gets the <code>ProviderContext</code> for the provider.
740: *
741: * @return <code>ProviderContext</code>.
742: *
743: * @see com.sun.portal.providers.context.ProviderContext
744: *
745: */
746: public ProviderContext getProviderContext() {
747: return context;
748: }
749:
750: /**
751: * Gets a specified ResourceBundle file for the provider based on User's
752: * locale.
753: * <p>
754: * A provider can specify on-screen strings to be localized in a resource
755: * bundle file, as described in the Java <code>ResourceBundle</code> class.
756: *
757: * @param base a specified <code>ResourceBundle</code> name.
758: *
759: * @see java.util.ResourceBundle.
760: *
761: * @return <code>ResourceBundle</code>.
762: */
763: public ResourceBundle getResourceBundle(String base)
764: throws ProviderException {
765: Locale locale = null;
766: locale = getProviderContext().getLocale();
767: return ResourceBundle.getBundle(base, locale, getClass()
768: .getClassLoader());
769: }
770:
771: /**
772: * Gets the well-knowned ResourceBundle for the provider based on User's
773: * locale.
774: * <p>
775: * A provider can specify on-screen strings to be localized in a resource
776: * bundle file, as described in the Java <code>ResourceBundle</code> class.
777: * <p>
778: * The well-knowned name is the provider name.
779: *
780: * @return <code>ResourceBundle</code>.
781: */
782: public ResourceBundle getResourceBundle() throws ProviderException {
783: Locale locale = null;
784: String resource = null;
785: locale = getProviderContext().getLocale();
786: try {
787: resource = getProviderContext().getProviderName(getName());
788: } catch (ProviderContextException pce) {
789: throw new ProviderException(
790: "ProviderAdapter.getResourceBundle(): cannot get provider name",
791: pce);
792: }
793:
794: return ResourceBundle.getBundle(resource, locale, getClass()
795: .getClassLoader());
796: }
797:
798: private static ProviderContext getProviderContext(
799: HttpServletRequest req) throws ProviderException {
800: ProviderContext pc = ProviderContextThreadLocalizer.get();
801: if (pc == null) {
802: throw new ProviderException(
803: "ProviderAdapter.getProviderContext(): "
804: + "could not get provider context");
805: }
806:
807: return pc;
808: }
809:
810: //
811: // can be uncommented for advanced debugging
812: //
813:
814: /*
815: protected static void trace() {
816: try {
817: throw new Exception();
818: } catch (Exception e) {
819: debug.debugError("ProviderAdapter.trace(): printing trace:\n", e);
820: }
821: }
822: */
823: }
|