KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > util > Encode


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.util;
11
12 import java.util.*;
13
14
15 import org.mmbase.util.logging.Logger;
16 import org.mmbase.util.logging.Logging;
17 import org.mmbase.util.transformers.*;
18
19
20 /**
21  *
22  * Class to convert from/to a string (byte[]) from/to a encoded string (byte[])
23  *
24  * Supported encodings are at this moment:
25  * <ul>
26  * <li>BASE64</li>
27  * <li>HEX</li>
28  * <li>ESCAPE_XML</li>
29  * <li>ESCAPE_HTML</li>
30  * <li>ESCAPE_HTML_ATTRIBUTE</li>
31  * <li>ESCAPE_WML</li>
32  * <li>ESCAPE_WML_ATTRIBUTE</li>
33  * <li>ESCAPE_URL</li>
34  * <li>ESCAPE_URL_PARAM</li>
35  * <li>ESCAPE_SINGLE_QUOTE</li>
36  * </ul>
37  *
38  * A list of supported encodings can be gotten by java
39  * org.mmbase.util.Encode, and you add your own encodings by calling
40  * the static function 'register' of this class.
41  *
42  * Usage:
43  * <pre>
44  * Encode encoder = new Encode("ESCAPE_XML");
45  * System.out.println( encoder.decode( encoder.encode("& \" < >") ) );
46  * </pre>
47  *
48  * @rename Encoder
49  * @author Eduard Witteveen
50  * @author Michiel Meeuwissen
51  * @version $Id: Encode.java,v 1.27 2006/07/19 11:07:17 johannes Exp $
52  **/

53 public class Encode {
54
55     private static Logger log;
56
57     private Transformer trans; // the instance of the object doing the actual work.
58

59     private static Map encodings; // string -> Config, all encoding are registered in this.
60
private static Set registered = new HashSet(); // in this is remembered which classes were registered, to avoid registering them more than once.
61

62     static {
63         log = Logging.getLoggerInstance(Encode.class);
64         encodings = new HashMap();
65
66         // a few Encoding are avaible by default:
67
try {
68             register("org.mmbase.util.transformers.MD5");
69             register("org.mmbase.util.transformers.Base64");
70             register("org.mmbase.util.transformers.Hex");
71             register("org.mmbase.util.transformers.Xml");
72             register("org.mmbase.util.transformers.Url");
73             register("org.mmbase.util.transformers.Sql");
74             register("org.mmbase.util.transformers.XmlField");
75             register("org.mmbase.util.transformers.LinkFinder");
76             register("org.mmbase.util.transformers.Censor");
77             register("org.mmbase.util.transformers.Rot13");
78             register("org.mmbase.util.transformers.Rot5");
79             register("org.mmbase.util.transformers.UnicodeEscaper");
80         } catch (IllegalArgumentException JavaDoc e) {
81             log.warn("", e);
82         }
83     }
84
85     /**
86      * Created a encode instance of a certain type of encoding. It
87      * will instantiate the right class, and configure it. This
88      * instantion will be used when you call 'encode' or 'decode'
89      * members later.
90      *
91      * @param encoding a string that describes which encoding should be used.
92      */

93     public Encode(String JavaDoc encoding) {
94         if (encodings.containsKey(encoding.toUpperCase())) { // it must be known.
95
Config e = (Config)encodings.get(encoding.toUpperCase()); // get the info.
96
try {
97                 trans = (Transformer) e.clazz.newInstance();
98             } catch (InstantiationException JavaDoc ex) {
99                 throw new IllegalArgumentException JavaDoc("encoding: '" + encoding + "' could not be instantiated");
100             } catch (IllegalAccessException JavaDoc ex) {
101             }
102             if (trans instanceof ConfigurableTransformer) {
103                 ((ConfigurableTransformer) trans).configure(e.config);
104             }
105         } else {
106             throw new IllegalArgumentException JavaDoc("encoding: '" + encoding + "' unknown" + encodings.keySet());
107         }
108
109     }
110
111     /**
112      * @since MMBase-1.8
113      */

114     public Transformer getTransformer() {
115         return trans;
116     }
117
118
119     /**
120      * Add new transformation types. Feed it with a class name (which
121      * must implement Transformer)
122      *
123      * @param clazz a class name.
124      */

125     public static void register(String JavaDoc clazz) {
126         if (! registered.contains(clazz)) { // if already registered, do nothing.
127
log.service("registering encode class " + clazz);
128             try {
129                 Class JavaDoc atrans = Class.forName(clazz);
130                 if(Transformer.class.isAssignableFrom(atrans)) { // make sure it is of the right type.
131
if (ConfigurableTransformer.class.isAssignableFrom(atrans)) {
132                         log.debug("A configurable transformer");
133                         // Instantiate it, just once, to call the method 'transformers'
134
// In this way we find out what this class can do.
135
ConfigurableTransformer transformer = (ConfigurableTransformer) atrans.newInstance();
136                         Map newencodings = transformer.transformers();
137                         encodings.putAll(newencodings); // add them all to our encodings.
138
} else {
139                         log.debug("Non configurable");
140                         Transformer transformer = (Transformer) atrans.newInstance();
141                         encodings.put(transformer.toString().toUpperCase(), new Config(atrans, -1, "Transformer: " + clazz));
142                     }
143                     // TODO, perhaps there should be a check here, to make sure that no two classes use the
144
// same string to identify a transformation.
145

146                 } else {
147                     throw new IllegalArgumentException JavaDoc("The class " + clazz + " does not implement " + Transformer.class.getName());
148                 }
149             } catch (ClassNotFoundException JavaDoc e) {
150                 throw new IllegalArgumentException JavaDoc(e.toString());
151             } catch (Exception JavaDoc e) { // yeah, yeah, it can throw a lot more.
152
// TODO perhaps make better distinction between exceptions...
153
throw new IllegalArgumentException JavaDoc(e.toString());
154             }
155             registered.add(clazz);
156         }
157     }
158
159     /**
160      * This function will encode a given string to it's encoded
161      * variant. It is static, it will make a temporary instance of
162      * the Transformer class. If you need to encode alot, it is
163      * better to use new Encode first.
164      *
165      *
166      * @param encoding a string that describes which encoding should be used.
167      * @param toEncode a string which is the value which should be encoded.
168      * This can also be a byte[].
169      *
170      * @return a string which is the encoded representation of toEncode
171      * with the given encoding
172      **/

173     public static String JavaDoc encode(String JavaDoc encoding, String JavaDoc toEncode) {
174         Encode e = new Encode(encoding);
175         return e.encode(toEncode);
176     }
177
178
179     public static String JavaDoc encode(String JavaDoc encoding, byte[] bytes) {
180         Encode e = new Encode(encoding);
181         return e.encode(bytes);
182     }
183
184
185     /**
186      * This function will decode a given string to it's decoded variant.
187      * @see #encode
188      * @param encoding a string that describes which decoding should be used.
189      * @param toDecode a string which is the value which should be encoded.
190      * @return a string which is the encoded representation of toEncode
191      * with the given encoding
192      **/

193
194     public static String JavaDoc decode(String JavaDoc encoding, String JavaDoc toDecode) {
195         Encode e = new Encode(encoding);
196         return e.decode(toDecode);
197     }
198     
199     public static byte[] decodeBytes(String JavaDoc encoding, String JavaDoc toDecode) {
200         Encode e = new Encode(encoding);
201         return e.decodeBytes(toDecode);
202     }
203
204
205     /**
206      * This function will encode a given string to it's encoded variant.
207      * @param toEncode A string which is the value which should be encoded.
208                             If the transformer does transform bytes, then first getBytes is done on the String.
209      *
210      * @return a string which is the encoded representation of toEncode
211      * with the given encoding
212      **/

213     public String JavaDoc encode(String JavaDoc toEncode) {
214         if (isByteToCharEncoder()) {
215             return ((ByteToCharTransformer)trans).transform(toEncode.getBytes());
216         } else {
217             return ((CharTransformer)trans).transform(toEncode);
218         }
219     }
220     /**
221      * Encodes a byte array.
222      *
223      * @return a string;;
224      */

225     public String JavaDoc encode(byte[] bytes) {
226         return ((ByteToCharTransformer)trans).transform(bytes);
227     }
228
229     /**
230      * This function will decode a given string to it's decoded variant
231      * @param toDecode a string which is the value which should be encoded.
232      * @return a string which is the encoded representation of toEncode
233      * with the given encoding
234      **/

235     public String JavaDoc decode(String JavaDoc toDecode) {
236         if (isByteToCharEncoder()) {
237             return new String JavaDoc(((ByteToCharTransformer)trans).transformBack(toDecode));
238         } else {
239             return ((CharTransformer)trans).transformBack(toDecode);
240         }
241     }
242     public byte[] decodeBytes(String JavaDoc toDecode) {
243         if (isByteToCharEncoder()) {
244             return ((ByteToCharTransformer)trans).transformBack(toDecode);
245         } else {
246             return ((CharTransformer)trans).transformBack(toDecode).getBytes();
247         }
248     }
249     /**
250      * All the currently known encodings.
251      *
252      * @return Set of Strings containing the names of the registered encodings.
253      */

254
255     public static Set possibleEncodings() {
256         return encodings.keySet();
257     }
258     
259     /**
260      * Checks if a certain string represents a known transformation.
261      *
262      */

263     public static boolean isEncoding(String JavaDoc e) {
264         return encodings.containsKey(e.toUpperCase());
265     }
266     /**
267      * Checks if the transformation is between two Strings.
268      */

269     public boolean isCharEncoder() {
270         return trans instanceof org.mmbase.util.transformers.CharTransformer;
271     }
272     /**
273      * Checks if the transformations makes from byte[] String.
274      */

275     public boolean isByteToCharEncoder() {
276         return trans instanceof org.mmbase.util.transformers.ByteToCharTransformer;
277     }
278     /**
279      * Returns the encoding
280      *
281      * @return An String representing the coding that is currently used.
282      */

283     public String JavaDoc getEncoding() {
284         return trans.toString();
285     }
286     /**
287      * Invocation of the class from the commandline for testing.
288      */

289     public static void main(String JavaDoc[] argv) {
290         try {
291             org.mmbase.module.core.MMBaseContext.init(System.getProperty("mmbase.config"), false);
292         } catch (Throwable JavaDoc e) {
293             System.err.println("Could not intialize mmbase context, proceeding without it: " + e.getMessage());
294         }
295         String JavaDoc coding = null;
296         boolean decode = false;
297         String JavaDoc string = null;
298
299         { // read arguments.
300
int cur = 0;
301             while (cur < argv.length) {
302                 if ("-decode".equals(argv[cur])) {
303                     decode = true;
304                 } else if ("-encode".equals(argv[cur])) {
305                 } else if ("-class".equals(argv[cur])) {
306                     register(argv[++cur]);
307                 } else {
308                     if (coding == null) {
309                         coding = argv[cur];
310                         if (! isEncoding(coding)) {
311                             throw new RuntimeException JavaDoc (coding + " is not a known coding");
312                         }
313                     } else if (argv[cur].charAt(0) == '-') {
314                         throw new RuntimeException JavaDoc ("unknown option " + argv[cur]);
315                     } else {
316                         if (string == null) string = "";
317                         string += " " + argv[cur];
318                     }
319                 }
320                 cur++;
321             }
322         }
323
324         if (coding == null) { // supply help
325
System.out.println("org.mmbase.util.Encode main is for testing purposes only\n");
326             System.out.println(" use: java -Dmmbase.config=... org.mmbase.util.Encode [-class <classname> [-class ..]] [-encode|-decode] <coding> [string]\n\n");
327             System.out.println("On default it encodes and gets the string from STDIN\n\n");
328             System.out.println("possible decoding are");
329             List v = new ArrayList(possibleEncodings());
330             java.util.Collections.sort(v);
331             Iterator i = v.iterator();
332             while (i.hasNext()) {
333                 String JavaDoc enc = (String JavaDoc)i.next();
334                 System.out.println(enc + " " + ((Config)encodings.get(enc)).info);
335             }
336         } else {
337
338             if (string == null) {
339                 // put STDIN in the string.
340
string = "";
341                 try {
342                     java.io.BufferedReader JavaDoc stdinReader = new java.io.BufferedReader JavaDoc(new java.io.InputStreamReader JavaDoc(System.in));
343                     String JavaDoc line = stdinReader.readLine();
344                     while (line != null) {
345                             string += line + "\n";
346                             line = stdinReader.readLine();
347                     }
348                     log.service("----------------");
349                 } catch (java.io.IOException JavaDoc e) {
350                     System.err.println(e.toString());
351                 }
352             }
353
354             // do the job:
355
if (decode) {
356                 System.out.println(new String JavaDoc(decodeBytes(coding, string)));
357                 // decode bytes, then also byte decoding go ok... (I think).
358
} else {
359                 System.out.println(encode(coding, string));
360             }
361         }
362     }
363 }
364
Popular Tags