View Javadoc

1   /**
2    * This file Copyright (c) 2003-2010 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.cms.util;
35  
36  import info.magnolia.cms.core.SystemProperty;
37  import info.magnolia.cms.core.Path;
38  
39  import java.io.File;
40  import java.io.FileInputStream;
41  import java.io.FileNotFoundException;
42  import java.io.IOException;
43  import java.io.InputStream;
44  import java.net.MalformedURLException;
45  import java.net.URL;
46  import java.util.Collections;
47  import java.util.Iterator;
48  import java.util.Map;
49  
50  import javax.xml.parsers.DocumentBuilder;
51  import javax.xml.parsers.DocumentBuilderFactory;
52  import javax.xml.parsers.ParserConfigurationException;
53  
54  import org.apache.commons.io.IOUtils;
55  import org.apache.commons.lang.StringUtils;
56  import org.jdom.JDOMException;
57  import org.jdom.input.SAXBuilder;
58  import org.slf4j.Logger;
59  import org.slf4j.LoggerFactory;
60  import org.w3c.dom.Document;
61  import org.xml.sax.EntityResolver;
62  import org.xml.sax.InputSource;
63  import org.xml.sax.SAXException;
64  
65  /**
66   * Util used to process config files.
67   * @version $Id: ConfigUtil.java 36903 2010-09-02 16:01:20Z pbaerfuss $
68   *
69   */
70  public class ConfigUtil {
71      private static final Logger log = LoggerFactory.getLogger(ConfigUtil.class);
72  
73      /**
74       * EntityResolver using a Map to resources.
75       * @version $Id: ConfigUtil.java 36903 2010-09-02 16:01:20Z pbaerfuss $
76       *
77       */
78      public static final class MapDTDEntityResolver implements EntityResolver {
79  
80          private final Map<String, String> dtds;
81  
82          public MapDTDEntityResolver(Map<String, String> dtds) {
83              this.dtds = dtds;
84          }
85  
86          public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
87              String key = StringUtils.substringAfterLast(systemId, "/");
88              if (dtds.containsKey(key)) {
89                  Class<? extends MapDTDEntityResolver> clazz = getClass();
90                  InputStream in = clazz.getResourceAsStream(dtds.get(key));
91                  if (in == null) {
92                      log.error("Could not find [" + systemId + "]. Used ["
93                          + clazz.getClassLoader()
94                          + "] class loader in the search.");
95                      return null;
96                  } else {
97                      return new InputSource(in);
98                  }
99              } else {
100                 return null;
101             }
102         }
103     }
104 
105     public static String getTokenizedConfigFile(String fileName) throws IOException {
106         final InputStream stream = getConfigFile(fileName);
107         if (stream == null) {
108             throw new IOException("Can't load file: " + fileName);
109         }
110         return replaceTokens(stream);
111     }
112 
113     /**
114      * Try to get the file. Get it first in the file system, then from the resources
115      * @param fileName
116      * @return the input stream
117      * @deprecated since 4.0 - use getTokenizedConfigFile
118      */
119     public static InputStream getConfigFile(String fileName) {
120         File file = new File(Path.getAppRootDir(), fileName);
121         InputStream stream;
122         // relative to webapp root
123         if (file.exists()) {
124             URL url;
125             try {
126                 url = new URL("file:" + file.getAbsolutePath()); //$NON-NLS-1$
127             }
128             catch (MalformedURLException e) {
129                 log.error("Unable to read config file from [" + fileName + "], got a MalformedURLException: ", e);
130                 return null;
131             }
132             try {
133                 stream = url.openStream();
134             }
135             catch (IOException e) {
136                 log.error("Unable to read config file from [" + fileName + "], got a IOException ", e);
137                 return null;
138             }
139             return stream;
140         }
141 
142         // try it directly
143         file = new File(fileName);
144         if(file.exists()) {
145             try {
146                 stream = new FileInputStream(file);
147             }
148             catch (FileNotFoundException e) {
149                 log.error("Unable to read config file from [" + fileName + "], got a FileNotFoundException ", e);
150                 return null;
151             }
152             return stream;
153         }
154         // try resources
155         try {
156             return ClasspathResourcesUtil.getStream(fileName);
157         } catch (IOException e) {
158             log.error("Unable to read config file from the resources [" + fileName + "]", e);
159         }
160 
161         return null;
162     }
163 
164     /**
165      * Read the stream and replace tokens.
166      * @deprecated since 4.0 - use getTokenizedConfigFile
167      */
168     public static String replaceTokens(InputStream stream) throws IOException {
169         final String config = IOUtils.toString(stream);
170         IOUtils.closeQuietly(stream);
171         return replaceTokens(config);
172     }
173 
174     /**
175      * Replace tokens in a string.
176      * @param config
177      * @return
178      * @throws IOException
179      */
180     public static String replaceTokens(String config) throws IOException {
181         for (Iterator iter = SystemProperty.getProperties().keySet().iterator(); iter.hasNext();) {
182             String key = (String) iter.next();
183             config = StringUtils.replace(config, "${" + key + "}", SystemProperty.getProperty(key, ""));
184         }
185         return config;
186     }
187 
188     /**
189      * Convert the string to an DOM Document.
190      * @deprecated since 4.0 - not used
191      */
192     public static Document string2DOM(String xml) throws ParserConfigurationException, SAXException, IOException {
193         return string2DOM(xml, Collections.EMPTY_MAP);
194     }
195 
196     /**
197      * Convert the string to a JDOM Document.
198      */
199     public static org.jdom.Document string2JDOM(String xml) throws JDOMException, IOException{
200         return string2JDOM(xml, Collections.EMPTY_MAP);
201     }
202 
203     /**
204      * Uses a map to find the dtds in the resources.
205      * @deprecated since 4.0 - not used
206      */
207     public static org.jdom.Document string2JDOM(String xml, final Map dtds) throws JDOMException, IOException{
208         SAXBuilder builder = new SAXBuilder();
209         builder.setEntityResolver(new MapDTDEntityResolver(dtds));
210         return builder.build(IOUtils.toInputStream(xml));
211     }
212 
213     /**
214      * Uses a map to find dtds in the resources.
215      * @param xml
216      * @param dtds
217      * @return
218      * @throws ParserConfigurationException
219      * @throws SAXException
220      * @throws IOException
221      */
222     public static Document string2DOM(String xml, final Map<String, String> dtds) throws ParserConfigurationException, SAXException, IOException {
223         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
224         dbf.setValidating(true);
225         DocumentBuilder builder;
226         builder = dbf.newDocumentBuilder();
227         builder.setEntityResolver(new MapDTDEntityResolver(dtds));
228         return builder.parse(IOUtils.toInputStream(xml));
229     }
230 
231 }