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   * @author Philipp Bracher
68   * @version $Id: ConfigUtil.java 32667 2010-03-13 00:37:06Z gjoseph $
69   *
70   */
71  public class ConfigUtil {
72      private static final Logger log = LoggerFactory.getLogger(ConfigUtil.class);
73  
74      /**
75       * EntityResolver using a Map to resources
76       * @author Philipp Bracher
77       * @version $Id: ConfigUtil.java 32667 2010-03-13 00:37:06Z gjoseph $
78       *
79       */
80      public static final class MapDTDEntityResolver implements EntityResolver {
81  
82          private final Map<String, String> dtds;
83  
84          public MapDTDEntityResolver(Map<String, String> dtds) {
85              this.dtds = dtds;
86          }
87  
88          public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
89              String key = StringUtils.substringAfterLast(systemId, "/");
90              if (dtds.containsKey(key)) {
91                  Class<? extends MapDTDEntityResolver> clazz = getClass();
92                  InputStream in = clazz.getResourceAsStream(dtds.get(key));
93                  if (in == null) {
94                      log.error("Could not find [" + systemId + "]. Used ["
95                          + clazz.getClassLoader()
96                          + "] class loader in the search.");
97                      return null;
98                  } else {
99                      return new InputSource(in);
100                 }
101             } else {
102                 return null;
103             }
104         }
105     }
106 
107     public static String getTokenizedConfigFile(String fileName) throws IOException {
108         final InputStream stream = getConfigFile(fileName);
109         if (stream == null) {
110             throw new IOException("Can't load file: " + fileName);
111         }
112         return replaceTokens(stream);
113     }
114 
115     /**
116      * Try to get the file. Get it first in the file system, then from the resources
117      * @param fileName
118      * @return the input stream
119      * @deprecated since 4.0 - use getTokenizedConfigFile
120      */
121     public static InputStream getConfigFile(String fileName) {
122         File file = new File(Path.getAppRootDir(), fileName);
123         InputStream stream;
124         // relative to webapp root
125         if (file.exists()) {
126             URL url;
127             try {
128                 url = new URL("file:" + file.getAbsolutePath()); //$NON-NLS-1$
129             }
130             catch (MalformedURLException e) {
131                 log.error("Unable to read config file from [" + fileName + "], got a MalformedURLException: ", e);
132                 return null;
133             }
134             try {
135                 stream = url.openStream();
136             }
137             catch (IOException e) {
138                 log.error("Unable to read config file from [" + fileName + "], got a IOException ", e);
139                 return null;
140             }
141             return stream;
142         }
143 
144         // try it directly
145         file = new File(fileName);
146         if(file.exists()) {
147             try {
148                 stream = new FileInputStream(file);
149             }
150             catch (FileNotFoundException e) {
151                 log.error("Unable to read config file from [" + fileName + "], got a FileNotFoundException ", e);
152                 return null;
153             }
154             return stream;
155         }
156         // try resources
157         try {
158             return ClasspathResourcesUtil.getStream(fileName);
159         } catch (IOException e) {
160             log.error("Unable to read config file from the resources [" + fileName + "]", e);
161         }
162 
163         return null;
164     }
165 
166     /**
167      * Read the stream and replace tokens.
168      * @deprecated since 4.0 - use getTokenizedConfigFile
169      */
170     public static String replaceTokens(InputStream stream) throws IOException {
171         final String config = IOUtils.toString(stream);
172         IOUtils.closeQuietly(stream);
173         return replaceTokens(config);
174     }
175 
176     /**
177      * Replace tokens in a string.
178      * @param config
179      * @return
180      * @throws IOException
181      */
182     public static String replaceTokens(String config) throws IOException {
183         for (Iterator iter = SystemProperty.getProperties().keySet().iterator(); iter.hasNext();) {
184             String key = (String) iter.next();
185             config = StringUtils.replace(config, "${" + key + "}", SystemProperty.getProperty(key, ""));
186         }
187         return config;
188     }
189 
190     /**
191      * Convert the string to an DOM Document.
192      * @deprecated since 4.0 - not used
193      */
194     public static Document string2DOM(String xml) throws ParserConfigurationException, SAXException, IOException {
195         return string2DOM(xml, Collections.EMPTY_MAP);
196     }
197 
198     /**
199      * Convert the string to a JDOM Document.
200      */
201     public static org.jdom.Document string2JDOM(String xml) throws JDOMException, IOException{
202         return string2JDOM(xml, Collections.EMPTY_MAP);
203     }
204 
205     /**
206      * Uses a map to find the dtds in the resources.
207      * @deprecated since 4.0 - not used
208      */
209     public static org.jdom.Document string2JDOM(String xml, final Map dtds) throws JDOMException, IOException{
210         SAXBuilder builder = new SAXBuilder();
211         builder.setEntityResolver(new MapDTDEntityResolver(dtds));
212         return builder.build(IOUtils.toInputStream(xml));
213     }
214 
215     /**
216      * Uses a map to find dtds in the resources.
217      * @param xml
218      * @param dtds
219      * @return
220      * @throws ParserConfigurationException
221      * @throws SAXException
222      * @throws IOException
223      */
224     public static Document string2DOM(String xml, final Map<String, String> dtds) throws ParserConfigurationException, SAXException, IOException {
225         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
226         dbf.setValidating(true);
227         DocumentBuilder builder;
228         builder = dbf.newDocumentBuilder();
229         builder.setEntityResolver(new MapDTDEntityResolver(dtds));
230         return builder.parse(IOUtils.toInputStream(xml));
231     }
232 
233 }