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.encode;
006:
007: import java.util.Map;
008: import java.util.HashMap;
009: import java.util.Collections;
010:
011: import com.sun.portal.desktop.context.DesktopAppContextThreadLocalizer;
012: import com.sun.portal.desktop.context.DesktopAppContext;
013:
014: /**
015: * This class provides a device-unaware means of encoding markup and
016: * other text. It is the front end for an encoder SPI, allowing different
017: * encoding schemes to be plugged in to the system.
018: * <br><br>
019: * To decode text, use the <code>Decoder</code> class.
020: * <br><br>
021: * The pluggable components used by this class are called
022: * type encoders. A type encoder is a class that implements
023: * the simple <code>TypeEncoder</code> interface.
024: * <br><br>
025: * For cases where the encoding type is fixed and does not
026: * change with the markup type, the four static type encoders
027: * may be used: <code>XML_ENCODER, HTML_ENCODER, FORMNAME_ENCODER,</code>
028: * and <code>COOKIE_ENCODER</code>.
029: * <br><br>
030: * When the encoding type is dependent on the accessing client device,
031: * use the <code>get()</code> or <code>encode()</code> methods. These
032: * methods accept a string type encoder class name and return an
033: * instance of that type encoder or use that type encoder to perform
034: * encoding, respectively. The argument <code>encoderClassName</code>
035: * to these methods should be dynamically varied based on the client
036: * device type. This class does not care how the mapping from client
037: * device type to encode class name happens, but here is an example
038: * of how it might be done. Using client type properties, associate
039: * a new client type property, "encoderClassName" with each client
040: * device type. The type encoder class specified by the class name should
041: * implement encoding that is proper for the associated device type.
042: * Use this client type property as an arugment to either the
043: * <code>get()</code> or <code>encode()</code> methods. For example:
044: * <br><br>
045: * <code>
046: * String unencoded = "<this><is><a><test>";<br>
047: * String encoderClassName = providerContext.getEncoderClassName();<br>
048: * String encoded = Encoder.encode(encoderClassName, unencoded);<br>
049: * </code>
050: * <br><br>
051: * To add a new type encoder to the system, do the following:
052: * <ul>
053: * <li> Author a class that implements the <code>TypeEncoder</code>
054: * interface.
055: * <li> Add the class to the web container's class path.
056: * </ul>
057: * Now, the new type encoder may be referenced by naming its
058: * class name in either of the two methods in this class. Going
059: * by the above example usage, client type properties can be
060: * modified to include the new class name as a value of the
061: * encoderClassName client type property.
062: * <br><br>
063: * The public methods and members in this class are static. This class
064: * may not be instantiated.
065: *
066: * @see com.sun.portal.providers.context.ProviderContext#getEncoderClassName
067: * @see com.sun.portal.desktop.encode.TypeEncoder
068: * @see com.sun.portal.desktop.encode.Decoder
069: */
070:
071: public class Encoder {
072: private static Map encoders = Collections
073: .synchronizedMap(new HashMap());
074: //private static DesktopAppContext dac = DesktopAppContextThreadLocalizer.get();
075:
076: /**
077: * XML type encoder.
078: */
079: public static TypeEncoder XML_ENCODER = null;
080:
081: /**
082: * HTML type encoder.
083: */
084: public static TypeEncoder HTML_ENCODER = null;
085:
086: /**
087: * Form name type encoder.
088: */
089: public static TypeEncoder FORMNAME_ENCODER = null;
090:
091: /**
092: * Cookie type encoder.
093: */
094: public static TypeEncoder COOKIE_ENCODER = null;
095:
096: static {
097: try {
098: XML_ENCODER = get(EncoderClassNames.ENCODER_XML);
099: HTML_ENCODER = get(EncoderClassNames.ENCODER_HTML);
100: FORMNAME_ENCODER = get(EncoderClassNames.ENCODER_FORMNAME);
101: COOKIE_ENCODER = get(EncoderClassNames.ENCODER_COOKIE);
102: } catch (EncoderException ee) {
103: throw new EncoderError(
104: "Encoder.<init>: error initializing standard encoder types",
105: ee);
106: }
107: }
108:
109: private Encoder() {
110: }
111:
112: /**
113: * Gets an instance for the named type encoder.
114: *
115: * @param encoderClassName a <code>String</code> value indicating
116: * the type encoder class name. The named class must implement
117: * the <code>TypeEncoder</code> interface.
118: * @return a <code>TypeEncoder</code> value, the type encoder instance.
119: * @exception EncoderException if there is an error instantiating the
120: * type encoder object.
121: */
122: public static TypeEncoder get(String encoderClassName)
123: throws EncoderException {
124: TypeEncoder encoder = (TypeEncoder) encoders
125: .get(encoderClassName);
126: if (encoder == null) {
127: try {
128: encoder = (TypeEncoder) Class.forName(encoderClassName)
129: .newInstance();
130: } catch (ClassNotFoundException cnfe) {
131: throw new EncoderException("Encoder.encode()", cnfe);
132: } catch (InstantiationException ie) {
133: throw new EncoderException("Encoder.encode()", ie);
134: } catch (IllegalAccessException iae) {
135: throw new EncoderException("Encoder.encode()", iae);
136: }
137: encoders.put(encoderClassName, encoder);
138: //dac.debugError("Encoder.get(): got new type encoder for encoderClassName=" + encoderClassName);
139: } else {
140: //dac.debugError("Encoder.get(): using existing type encoder for encoderClassName=" + encoderClassName);
141: }
142:
143: return encoder;
144: }
145:
146: /**
147: * Encodes text with the named type encoder. This method is a
148: * convenience wrapper for calling <code>get()</code> and
149: * <code>TypeEncoder.encode()</code>.
150: *
151: * @param encoderClassName a <code>String</code> value indicating
152: * the type encoder class name. The named class must implement
153: * the <code>TypeEncoder</code> interface.
154: * @param text a <code>String</code> value, the text to be
155: * encoded.
156: * @return a <code>String</code> value, the encoded text.
157: * @exception EncoderException if an error occurs instantiating the named
158: * type encoder.
159: */
160: public static String encode(String encoderClassName, String text)
161: throws EncoderException {
162: TypeEncoder encoder = get(encoderClassName);
163: return encoder.encode(text);
164: }
165: }
|