1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5 *
6 * The contents of this file are subject to the terms of either the GNU
7 * General Public License Version 2 only ("GPL") or the Common Development
8 * and Distribution License("CDDL") (collectively, the "License"). You
9 * may not use this file except in compliance with the License. You can obtain
10 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
11 * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
12 * language governing permissions and limitations under the License.
13 *
14 * When distributing the software, include this License Header Notice in each
15 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
16 * Sun designates this particular file as subject to the "Classpath" exception
17 * as provided by Sun in the GPL Version 2 section of the License file that
18 * accompanied this code. If applicable, add the following below the License
19 * Header, with the fields enclosed by brackets [] replaced by your own
20 * identifying information: "Portions Copyrighted [year]
21 * [name of copyright owner]"
22 *
23 * Contributor(s):
24 *
25 * If you wish your version of this file to be governed by only the CDDL or
26 * only the GPL Version 2, indicate your decision by adding "[Contributor]
27 * elects to include this software in this distribution under the [CDDL or GPL
28 * Version 2] license." If you don't indicate a single choice of license, a
29 * recipient has the option to distribute your version of this file under
30 * either the CDDL, the GPL Version 2 or to extend the choice of license to
31 * its licensees as provided above. However, if you add GPL Version 2 code
32 * and therefore, elected the GPL Version 2 license, then the option applies
33 * only if the new code is made subject to such option by the copyright
34 * holder.
35 */
36
37 /*
38 * @(#)MailcapCommandMap.java 1.42 07/05/14
39 */
40
41
42 package javax.activation;
43
44 import java.util;
45 import java.io;
46 import java.net;
47 import com.sun.activation.registries.MailcapFile;
48 import com.sun.activation.registries.LogSupport;
49
50 /**
51 * MailcapCommandMap extends the CommandMap
52 * abstract class. It implements a CommandMap whose configuration
53 * is based on mailcap files
54 * (<A HREF="http://www.ietf.org/rfc/rfc1524.txt">RFC 1524</A>).
55 * The MailcapCommandMap can be configured both programmatically
56 * and via configuration files.
57 * <p>
58 * <b>Mailcap file search order:</b><p>
59 * The MailcapCommandMap looks in various places in the user's
60 * system for mailcap file entries. When requests are made
61 * to search for commands in the MailcapCommandMap, it searches
62 * mailcap files in the following order:
63 * <p>
64 * <ol>
65 * <li> Programatically added entries to the MailcapCommandMap instance.
66 * <li> The file <code>.mailcap</code> in the user's home directory.
67 * <li> The file <<i>java.home</i>><code>/lib/mailcap</code>.
68 * <li> The file or resources named <code>META-INF/mailcap</code>.
69 * <li> The file or resource named <code>META-INF/mailcap.default</code>
70 * (usually found only in the <code>activation.jar</code> file).
71 * </ol>
72 * <p>
73 * <b>Mailcap file format:</b><p>
74 *
75 * Mailcap files must conform to the mailcap
76 * file specification (RFC 1524, <i>A User Agent Configuration Mechanism
77 * For Multimedia Mail Format Information</i>).
78 * The file format consists of entries corresponding to
79 * particular MIME types. In general, the specification
80 * specifies <i>applications</i> for clients to use when they
81 * themselves cannot operate on the specified MIME type. The
82 * MailcapCommandMap extends this specification by using a parameter mechanism
83 * in mailcap files that allows JavaBeans(tm) components to be specified as
84 * corresponding to particular commands for a MIME type.<p>
85 *
86 * When a mailcap file is
87 * parsed, the MailcapCommandMap recognizes certain parameter signatures,
88 * specifically those parameter names that begin with <code>x-java-</code>.
89 * The MailcapCommandMap uses this signature to find
90 * command entries for inclusion into its registries.
91 * Parameter names with the form <code>x-java-<name></code>
92 * are read by the MailcapCommandMap as identifying a command
93 * with the name <i>name</i>. When the <i>name</i> is <code>
94 * content-handler</code> the MailcapCommandMap recognizes the class
95 * signified by this parameter as a <i>DataContentHandler</i>.
96 * All other commands are handled generically regardless of command
97 * name. The command implementation is specified by a fully qualified
98 * class name of a JavaBean(tm) component. For example; a command for viewing
99 * some data can be specified as: <code>x-java-view=com.foo.ViewBean</code>.<p>
100 *
101 * When the command name is <code>fallback-entry</code>, the value of
102 * the command may be <code>true</code> or <code>false</code>. An
103 * entry for a MIME type that includes a parameter of
104 * <code>x-java-fallback-entry=true</code> defines fallback commands
105 * for that MIME type that will only be used if no non-fallback entry
106 * can be found. For example, an entry of the form <code>text/*; ;
107 * x-java-fallback-entry=true; x-java-view=com.sun.TextViewer</code>
108 * specifies a view command to be used for any text MIME type. This
109 * view command would only be used if a non-fallback view command for
110 * the MIME type could not be found.<p>
111 *
112 * MailcapCommandMap aware mailcap files have the
113 * following general form:<p>
114 * <code>
115 * # Comments begin with a '#' and continue to the end of the line.<br>
116 * <mime type>; ; <parameter list><br>
117 * # Where a parameter list consists of one or more parameters,<br>
118 * # where parameters look like: x-java-view=com.sun.TextViewer<br>
119 * # and a parameter list looks like: <br>
120 * text/plain; ; x-java-view=com.sun.TextViewer; x-java-edit=com.sun.TextEdit
121 * <br>
122 * # Note that mailcap entries that do not contain 'x-java' parameters<br>
123 * # and comply to RFC 1524 are simply ignored:<br>
124 * image/gif; /usr/dt/bin/sdtimage %s<br>
125 *
126 * </code>
127 * <p>
128 *
129 * @author Bart Calder
130 * @author Bill Shannon
131 */
132
133 public class MailcapCommandMap extends CommandMap {
134 /*
135 * We manage a collection of databases, searched in order.
136 * The default database is shared between all instances
137 * of this class.
138 * XXX - Can we safely share more databases between instances?
139 */
140 private static MailcapFile defDB = null;
141 private MailcapFile[] DB;
142 private static final int PROG = 0; // programmatically added entries
143
144 /**
145 * The default Constructor.
146 */
147 public MailcapCommandMap() {
148 super();
149 List dbv = new ArrayList(5); // usually 5 or less databases
150 MailcapFile mf = null;
151 dbv.add(null); // place holder for PROG entry
152
153 LogSupport.log("MailcapCommandMap: load HOME");
154 try {
155 String user_home = System.getProperty("user.home");
156
157 if (user_home != null) {
158 String path = user_home + File.separator + ".mailcap";
159 mf = loadFile(path);
160 if (mf != null)
161 dbv.add(mf);
162 }
163 } catch (SecurityException ex) {}
164
165 LogSupport.log("MailcapCommandMap: load SYS");
166 try {
167 // check system's home
168 String system_mailcap = System.getProperty("java.home") +
169 File.separator + "lib" + File.separator + "mailcap";
170 mf = loadFile(system_mailcap);
171 if (mf != null)
172 dbv.add(mf);
173 } catch (SecurityException ex) {}
174
175 LogSupport.log("MailcapCommandMap: load JAR");
176 // load from the app's jar file
177 loadAllResources(dbv, "META-INF/mailcap");
178
179 LogSupport.log("MailcapCommandMap: load DEF");
180 synchronized (MailcapCommandMap.class) {
181 // see if another instance has created this yet.
182 if (defDB == null)
183 defDB = loadResource("/META-INF/mailcap.default");
184 }
185
186 if (defDB != null)
187 dbv.add(defDB);
188
189 DB = new MailcapFile[dbv.size()];
190 DB = (MailcapFile[])dbv.toArray(DB);
191 }
192
193 /**
194 * Load from the named resource.
195 */
196 private MailcapFile loadResource(String name) {
197 InputStream clis = null;
198 try {
199 clis = SecuritySupport.getResourceAsStream(this.getClass(), name);
200 if (clis != null) {
201 MailcapFile mf = new MailcapFile(clis);
202 if (LogSupport.isLoggable())
203 LogSupport.log("MailcapCommandMap: successfully loaded " +
204 "mailcap file: " + name);
205 return mf;
206 } else {
207 if (LogSupport.isLoggable())
208 LogSupport.log("MailcapCommandMap: not loading " +
209 "mailcap file: " + name);
210 }
211 } catch (IOException e) {
212 if (LogSupport.isLoggable())
213 LogSupport.log("MailcapCommandMap: can't load " + name, e);
214 } catch (SecurityException sex) {
215 if (LogSupport.isLoggable())
216 LogSupport.log("MailcapCommandMap: can't load " + name, sex);
217 } finally {
218 try {
219 if (clis != null)
220 clis.close();
221 } catch (IOException ex) { } // ignore it
222 }
223 return null;
224 }
225
226 /**
227 * Load all of the named resource.
228 */
229 private void loadAllResources(List v, String name) {
230 boolean anyLoaded = false;
231 try {
232 URL[] urls;
233 ClassLoader cld = null;
234 // First try the "application's" class loader.
235 cld = SecuritySupport.getContextClassLoader();
236 if (cld == null)
237 cld = this.getClass().getClassLoader();
238 if (cld != null)
239 urls = SecuritySupport.getResources(cld, name);
240 else
241 urls = SecuritySupport.getSystemResources(name);
242 if (urls != null) {
243 if (LogSupport.isLoggable())
244 LogSupport.log("MailcapCommandMap: getResources");
245 for (int i = 0; i < urls.length; i++) {
246 URL url = urls[i];
247 InputStream clis = null;
248 if (LogSupport.isLoggable())
249 LogSupport.log("MailcapCommandMap: URL " + url);
250 try {
251 clis = SecuritySupport.openStream(url);
252 if (clis != null) {
253 v.add(new MailcapFile(clis));
254 anyLoaded = true;
255 if (LogSupport.isLoggable())
256 LogSupport.log("MailcapCommandMap: " +
257 "successfully loaded " +
258 "mailcap file from URL: " +
259 url);
260 } else {
261 if (LogSupport.isLoggable())
262 LogSupport.log("MailcapCommandMap: " +
263 "not loading mailcap " +
264 "file from URL: " + url);
265 }
266 } catch (IOException ioex) {
267 if (LogSupport.isLoggable())
268 LogSupport.log("MailcapCommandMap: can't load " +
269 url, ioex);
270 } catch (SecurityException sex) {
271 if (LogSupport.isLoggable())
272 LogSupport.log("MailcapCommandMap: can't load " +
273 url, sex);
274 } finally {
275 try {
276 if (clis != null)
277 clis.close();
278 } catch (IOException cex) { }
279 }
280 }
281 }
282 } catch (Exception ex) {
283 if (LogSupport.isLoggable())
284 LogSupport.log("MailcapCommandMap: can't load " + name, ex);
285 }
286
287 // if failed to load anything, fall back to old technique, just in case
288 if (!anyLoaded) {
289 if (LogSupport.isLoggable())
290 LogSupport.log("MailcapCommandMap: !anyLoaded");
291 MailcapFile mf = loadResource("/" + name);
292 if (mf != null)
293 v.add(mf);
294 }
295 }
296
297 /**
298 * Load from the named file.
299 */
300 private MailcapFile loadFile(String name) {
301 MailcapFile mtf = null;
302
303 try {
304 mtf = new MailcapFile(name);
305 } catch (IOException e) {
306 // e.printStackTrace();
307 }
308 return mtf;
309 }
310
311 /**
312 * Constructor that allows the caller to specify the path
313 * of a <i>mailcap</i> file.
314 *
315 * @param fileName The name of the <i>mailcap</i> file to open
316 * @exception IOException if the file can't be accessed
317 */
318 public MailcapCommandMap(String fileName) throws IOException {
319 this();
320
321 if (LogSupport.isLoggable())
322 LogSupport.log("MailcapCommandMap: load PROG from " + fileName);
323 if (DB[PROG] == null) {
324 DB[PROG] = new MailcapFile(fileName);
325 }
326 }
327
328
329 /**
330 * Constructor that allows the caller to specify an <i>InputStream</i>
331 * containing a mailcap file.
332 *
333 * @param is InputStream of the <i>mailcap</i> file to open
334 */
335 public MailcapCommandMap(InputStream is) {
336 this();
337
338 LogSupport.log("MailcapCommandMap: load PROG");
339 if (DB[PROG] == null) {
340 try {
341 DB[PROG] = new MailcapFile(is);
342 } catch (IOException ex) {
343 // XXX - should throw it
344 }
345 }
346 }
347
348 /**
349 * Get the preferred command list for a MIME Type. The MailcapCommandMap
350 * searches the mailcap files as described above under
351 * <i>Mailcap file search order</i>.<p>
352 *
353 * The result of the search is a proper subset of available
354 * commands in all mailcap files known to this instance of
355 * MailcapCommandMap. The first entry for a particular command
356 * is considered the preferred command.
357 *
358 * @param mimeType the MIME type
359 * @return the CommandInfo objects representing the preferred commands.
360 */
361 public synchronized CommandInfo[] getPreferredCommands(String mimeType) {
362 List cmdList = new ArrayList();
363 if (mimeType != null)
364 mimeType = mimeType.toLowerCase(Locale.ENGLISH);
365
366 for (int i = 0; i < DB.length; i++) {
367 if (DB[i] == null)
368 continue;
369 Map cmdMap = DB[i].getMailcapList(mimeType);
370 if (cmdMap != null)
371 appendPrefCmdsToList(cmdMap, cmdList);
372 }
373
374 // now add the fallback commands
375 for (int i = 0; i < DB.length; i++) {
376 if (DB[i] == null)
377 continue;
378 Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
379 if (cmdMap != null)
380 appendPrefCmdsToList(cmdMap, cmdList);
381 }
382
383 CommandInfo[] cmdInfos = new CommandInfo[cmdList.size()];
384 cmdInfos = (CommandInfo[])cmdList.toArray(cmdInfos);
385
386 return cmdInfos;
387 }
388
389 /**
390 * Put the commands that are in the hash table, into the list.
391 */
392 private void appendPrefCmdsToList(Map cmdHash, List cmdList) {
393 Iterator verb_enum = cmdHash.keySet().iterator();
394
395 while (verb_enum.hasNext()) {
396 String verb = (String)verb_enum.next();
397 if (!checkForVerb(cmdList, verb)) {
398 List cmdList2 = (List)cmdHash.get(verb); // get the list
399 String className = (String)cmdList2.get(0);
400 cmdList.add(new CommandInfo(verb, className));
401 }
402 }
403 }
404
405 /**
406 * Check the cmdList to see if this command exists, return
407 * true if the verb is there.
408 */
409 private boolean checkForVerb(List cmdList, String verb) {
410 Iterator ee = cmdList.iterator();
411 while (ee.hasNext()) {
412 String enum_verb =
413 (String)((CommandInfo)ee.next()).getCommandName();
414 if (enum_verb.equals(verb))
415 return true;
416 }
417 return false;
418 }
419
420 /**
421 * Get all the available commands in all mailcap files known to
422 * this instance of MailcapCommandMap for this MIME type.
423 *
424 * @param mimeType the MIME type
425 * @return the CommandInfo objects representing all the commands.
426 */
427 public synchronized CommandInfo[] getAllCommands(String mimeType) {
428 List cmdList = new ArrayList();
429 if (mimeType != null)
430 mimeType = mimeType.toLowerCase(Locale.ENGLISH);
431
432 for (int i = 0; i < DB.length; i++) {
433 if (DB[i] == null)
434 continue;
435 Map cmdMap = DB[i].getMailcapList(mimeType);
436 if (cmdMap != null)
437 appendCmdsToList(cmdMap, cmdList);
438 }
439
440 // now add the fallback commands
441 for (int i = 0; i < DB.length; i++) {
442 if (DB[i] == null)
443 continue;
444 Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
445 if (cmdMap != null)
446 appendCmdsToList(cmdMap, cmdList);
447 }
448
449 CommandInfo[] cmdInfos = new CommandInfo[cmdList.size()];
450 cmdInfos = (CommandInfo[])cmdList.toArray(cmdInfos);
451
452 return cmdInfos;
453 }
454
455 /**
456 * Put the commands that are in the hash table, into the list.
457 */
458 private void appendCmdsToList(Map typeHash, List cmdList) {
459 Iterator verb_enum = typeHash.keySet().iterator();
460
461 while (verb_enum.hasNext()) {
462 String verb = (String)verb_enum.next();
463 List cmdList2 = (List)typeHash.get(verb);
464 Iterator cmd_enum = ((List)cmdList2).iterator();
465
466 while (cmd_enum.hasNext()) {
467 String cmd = (String)cmd_enum.next();
468 cmdList.add(new CommandInfo(verb, cmd));
469 // cmdList.add(0, new CommandInfo(verb, cmd));
470 }
471 }
472 }
473
474 /**
475 * Get the command corresponding to <code>cmdName</code> for the MIME type.
476 *
477 * @param mimeType the MIME type
478 * @param cmdName the command name
479 * @return the CommandInfo object corresponding to the command.
480 */
481 public synchronized CommandInfo getCommand(String mimeType,
482 String cmdName) {
483 if (mimeType != null)
484 mimeType = mimeType.toLowerCase(Locale.ENGLISH);
485
486 for (int i = 0; i < DB.length; i++) {
487 if (DB[i] == null)
488 continue;
489 Map cmdMap = DB[i].getMailcapList(mimeType);
490 if (cmdMap != null) {
491 // get the cmd list for the cmd
492 List v = (List)cmdMap.get(cmdName);
493 if (v != null) {
494 String cmdClassName = (String)v.get(0);
495
496 if (cmdClassName != null)
497 return new CommandInfo(cmdName, cmdClassName);
498 }
499 }
500 }
501
502 // now try the fallback list
503 for (int i = 0; i < DB.length; i++) {
504 if (DB[i] == null)
505 continue;
506 Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
507 if (cmdMap != null) {
508 // get the cmd list for the cmd
509 List v = (List)cmdMap.get(cmdName);
510 if (v != null) {
511 String cmdClassName = (String)v.get(0);
512
513 if (cmdClassName != null)
514 return new CommandInfo(cmdName, cmdClassName);
515 }
516 }
517 }
518 return null;
519 }
520
521 /**
522 * Add entries to the registry. Programmatically
523 * added entries are searched before other entries.<p>
524 *
525 * The string that is passed in should be in mailcap
526 * format.
527 *
528 * @param mail_cap a correctly formatted mailcap string
529 */
530 public synchronized void addMailcap(String mail_cap) {
531 // check to see if one exists
532 LogSupport.log("MailcapCommandMap: add to PROG");
533 if (DB[PROG] == null)
534 DB[PROG] = new MailcapFile();
535
536 DB[PROG].appendToMailcap(mail_cap);
537 }
538
539 /**
540 * Return the DataContentHandler for the specified MIME type.
541 *
542 * @param mimeType the MIME type
543 * @return the DataContentHandler
544 */
545 public synchronized DataContentHandler createDataContentHandler(
546 String mimeType) {
547 if (LogSupport.isLoggable())
548 LogSupport.log(
549 "MailcapCommandMap: createDataContentHandler for " + mimeType);
550 if (mimeType != null)
551 mimeType = mimeType.toLowerCase(Locale.ENGLISH);
552
553 for (int i = 0; i < DB.length; i++) {
554 if (DB[i] == null)
555 continue;
556 if (LogSupport.isLoggable())
557 LogSupport.log(" search DB #" + i);
558 Map cmdMap = DB[i].getMailcapList(mimeType);
559 if (cmdMap != null) {
560 List v = (List)cmdMap.get("content-handler");
561 if (v != null) {
562 String name = (String)v.get(0);
563 DataContentHandler dch = getDataContentHandler(name);
564 if (dch != null)
565 return dch;
566 }
567 }
568 }
569
570 // now try the fallback entries
571 for (int i = 0; i < DB.length; i++) {
572 if (DB[i] == null)
573 continue;
574 if (LogSupport.isLoggable())
575 LogSupport.log(" search fallback DB #" + i);
576 Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
577 if (cmdMap != null) {
578 List v = (List)cmdMap.get("content-handler");
579 if (v != null) {
580 String name = (String)v.get(0);
581 DataContentHandler dch = getDataContentHandler(name);
582 if (dch != null)
583 return dch;
584 }
585 }
586 }
587 return null;
588 }
589
590 private DataContentHandler getDataContentHandler(String name) {
591 if (LogSupport.isLoggable())
592 LogSupport.log(" got content-handler");
593 if (LogSupport.isLoggable())
594 LogSupport.log(" class " + name);
595 try {
596 ClassLoader cld = null;
597 // First try the "application's" class loader.
598 cld = SecuritySupport.getContextClassLoader();
599 if (cld == null)
600 cld = this.getClass().getClassLoader();
601 Class cl = null;
602 try {
603 cl = cld.loadClass(name);
604 } catch (Exception ex) {
605 // if anything goes wrong, do it the old way
606 cl = Class.forName(name);
607 }
608 if (cl != null) // XXX - always true?
609 return (DataContentHandler)cl.newInstance();
610 } catch (IllegalAccessException e) {
611 if (LogSupport.isLoggable())
612 LogSupport.log("Can't load DCH " + name, e);
613 } catch (ClassNotFoundException e) {
614 if (LogSupport.isLoggable())
615 LogSupport.log("Can't load DCH " + name, e);
616 } catch (InstantiationException e) {
617 if (LogSupport.isLoggable())
618 LogSupport.log("Can't load DCH " + name, e);
619 }
620 return null;
621 }
622
623 /**
624 * Get all the MIME types known to this command map.
625 *
626 * @return array of MIME types as strings
627 * @since JAF 1.1
628 */
629 public synchronized String[] getMimeTypes() {
630 List mtList = new ArrayList();
631
632 for (int i = 0; i < DB.length; i++) {
633 if (DB[i] == null)
634 continue;
635 String[] ts = DB[i].getMimeTypes();
636 if (ts != null) {
637 for (int j = 0; j < ts.length; j++) {
638 // eliminate duplicates
639 if (!mtList.contains(ts[j]))
640 mtList.add(ts[j]);
641 }
642 }
643 }
644
645 String[] mts = new String[mtList.size()];
646 mts = (String[])mtList.toArray(mts);
647
648 return mts;
649 }
650
651 /**
652 * Get the native commands for the given MIME type.
653 * Returns an array of strings where each string is
654 * an entire mailcap file entry. The application
655 * will need to parse the entry to extract the actual
656 * command as well as any attributes it needs. See
657 * <A HREF="http://www.ietf.org/rfc/rfc1524.txt">RFC 1524</A>
658 * for details of the mailcap entry syntax. Only mailcap
659 * entries that specify a view command for the specified
660 * MIME type are returned.
661 *
662 * @return array of native command entries
663 * @since JAF 1.1
664 */
665 public synchronized String[] getNativeCommands(String mimeType) {
666 List cmdList = new ArrayList();
667 if (mimeType != null)
668 mimeType = mimeType.toLowerCase(Locale.ENGLISH);
669
670 for (int i = 0; i < DB.length; i++) {
671 if (DB[i] == null)
672 continue;
673 String[] cmds = DB[i].getNativeCommands(mimeType);
674 if (cmds != null) {
675 for (int j = 0; j < cmds.length; j++) {
676 // eliminate duplicates
677 if (!cmdList.contains(cmds[j]))
678 cmdList.add(cmds[j]);
679 }
680 }
681 }
682
683 String[] cmds = new String[cmdList.size()];
684 cmds = (String[])cmdList.toArray(cmds);
685
686 return cmds;
687 }
688
689 /**
690 * for debugging...
691 *
692 public static void main(String[] argv) throws Exception {
693 MailcapCommandMap map = new MailcapCommandMap();
694 CommandInfo[] cmdInfo;
695
696 cmdInfo = map.getPreferredCommands(argv[0]);
697 System.out.println("Preferred Commands:");
698 for (int i = 0; i < cmdInfo.length; i++)
699 System.out.println("Command " + cmdInfo[i].getCommandName() + " [" +
700 cmdInfo[i].getCommandClass() + "]");
701 cmdInfo = map.getAllCommands(argv[0]);
702 System.out.println();
703 System.out.println("All Commands:");
704 for (int i = 0; i < cmdInfo.length; i++)
705 System.out.println("Command " + cmdInfo[i].getCommandName() + " [" +
706 cmdInfo[i].getCommandClass() + "]");
707 DataContentHandler dch = map.createDataContentHandler(argv[0]);
708 if (dch != null)
709 System.out.println("DataContentHandler " +
710 dch.getClass().toString());
711 System.exit(0);
712 }
713 */
714 }