View Javadoc

1   /*
2    * $Id: MuleDtdResolver.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.config;
12  
13  import org.mule.util.IOUtils;
14  import org.mule.util.StringUtils;
15  
16  import java.io.IOException;
17  import java.io.InputStream;
18  
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  import org.xml.sax.EntityResolver;
22  import org.xml.sax.InputSource;
23  import org.xml.sax.SAXException;
24  
25  /**
26   * <code>MuleDtdResolver</code> attempts to locate the mule-configuration.dtd on
27   * the classpath, regardless of the DOCTYPE declaration. If the DTD is not found, it
28   * defaults to trying to download it using the systemId. <p/> This resolver is
29   * responsible for associating an XSL document if any with the DTD. It also allows
30   * for a delegate Entity resolver and delegate XSL. This allows Configuration
31   * builders to mix Mule Xml configuration with other document based configuration and
32   * apply transformers to each of the configuration types (if necessary) before
33   * constucting a Mule instance. <p/> Note that its up to the Configuration builder
34   * implementation to do the actual transformations this Resolver simply associates
35   * XSL resources with DTDs.
36   */
37  public class MuleDtdResolver implements EntityResolver
38  {
39      /**
40       * logger used by this class
41       */
42      protected static final Log logger = LogFactory.getLog(MuleDtdResolver.class);
43  
44      public static final String DEFAULT_MULE_DTD = "mule-configuration.dtd";
45  //    private String dtdName = null;
46  
47      // Maybe the dtd should go in the META-INF??
48      private static final String SEARCH_PATH = "";
49  
50      private EntityResolver delegate;
51      private String xsl;
52      private static String currentXsl;
53  
54      public MuleDtdResolver()
55      {
56          this(DEFAULT_MULE_DTD);
57      }
58  
59      public MuleDtdResolver(String dtdName)
60      {
61          this(dtdName, null, null);
62      }
63  
64      public MuleDtdResolver(String dtdName, String xsl)
65      {
66          this(dtdName, xsl, null);
67      }
68  
69      public MuleDtdResolver(String dtdName, EntityResolver delegate)
70      {
71          this(dtdName, null, delegate);
72      }
73  
74      public MuleDtdResolver(String dtdName, String xsl, EntityResolver delegate)
75      {
76  //        this.dtdName = dtdName;
77          this.delegate = delegate;
78          this.xsl = xsl;
79          if (logger.isDebugEnabled())
80          {
81              StringBuffer buffer = new StringBuffer();
82              buffer.append("Created Mule Dtd Resolver: ");
83              buffer.append("dtd=").append(dtdName).append(", ");
84              buffer.append("xsl=").append(xsl).append(", ");
85              buffer.append("delegate resolver=").append(delegate).append(", ");
86              logger.debug(buffer.toString());
87          }
88      }
89  
90      public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException
91      {
92          logger.debug("Trying to resolve XML entity with public ID: " + publicId + " and system ID: "
93                       + systemId);
94  
95          InputSource source = null;
96          currentXsl = null;
97          if (delegate != null)
98          {
99              source = delegate.resolveEntity(publicId, systemId);
100         }
101         if ((source == null) && StringUtils.isNotBlank(systemId) && systemId.endsWith(".dtd"))
102         {
103             String[] tokens = systemId.split("/");
104             String dtdFile = tokens[tokens.length - 1];
105             logger.debug("Looking on classpath for " + SEARCH_PATH + dtdFile);
106 
107             InputStream is = IOUtils.getResourceAsStream(SEARCH_PATH + dtdFile, getClass(), /* tryAsFile */
108                 true, /* tryAsUrl */false);
109             if (is != null)
110             {
111                 source = new InputSource(is);
112                 source.setPublicId(publicId);
113                 source.setSystemId(systemId);
114                 logger.debug("Found on classpath mule DTD: " + systemId);
115                 currentXsl = xsl;
116                 return source;
117             }
118             logger.debug("Could not find dtd resource on classpath: " + SEARCH_PATH + dtdFile);
119         }
120         return source;
121     }
122 
123     public String getXslForDtd()
124     {
125         return currentXsl;
126     }
127 }