2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * $Id: ClayXmlParser.java 464373 2006-10-16 04:21:54Z rahul $
20   */
21  package org.apache.shale.clay.config;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.net.URL;
26  
27  import org.apache.commons.digester.Digester;
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.shale.clay.config.beans.ComponentConfigBean;
31  import org.apache.shale.clay.config.beans.ConfigBean;
32  import org.apache.shale.util.Messages;
33  import org.xml.sax.InputSource;
34  import org.xml.sax.SAXException;
35  
36  
37  /***
38   * <p>This class loads the configuration files defining page fragments and
39   * caches a graph of beans in application scope. The location of the default
40   * configuration file is located at <code>Globals.DEFAULT_CLAY_CONFIG_FILE</code>.
41   * A comma value list of names can be supplied as a  initialization parameter in
42   * the web deployment descriptor using the parameter name
43   * <code>Globals.CLAY_CONFIG_FILES</code>.
44   * </p>
45   */
46  
47  
48  public class ClayXmlParser  implements ClayConfigParser {
49  
50      /***
51       * <p>The {@link ComponentConfigBean} is the container holding all of the
52       * component metadata definitions read for the configuration files.
53       * </p>
54       */
55      private ConfigBean config = null;
56  
57      /***
58       * <p>The <code>Digester</code> makes short work of materalizing a XML document
59       * into an object graph using simple binding rules.
60       * </p>
61       */
62      private Digester digester;
63  
64      /***
65       * <p>Commons logging utility object static instance.</p>
66       */
67      private static Log log;
68      static {
69          log = LogFactory.getLog(org.apache.shale.clay.config.ClayXmlParser.class);
70      }
71  
72      /***
73       * @return config {@link ConfigBean} instance of the component metadata container
74       */
75      public ConfigBean getConfig() {
76          return config;
77      }
78      /***
79       * @param config {@link ConfigBean} instance of the component metadata container
80       */
81      public void setConfig(ConfigBean config) {
82          this.config = config;
83      }
84  
85      /***
86       * <p>Message resources for this class.</p>
87       */
88      private static Messages messages = new Messages("org.apache.shale.clay.Bundle",
89              ClayConfigureListener.class.getClassLoader());
90  
91      /***
92       * <p>A static array of local DTD's to validate the digested documents against when not
93       * connected to the internet.
94       * </p>
95       */
96      private Object[] registrations = {
97          new String[] {"-//Apache Software Foundation//DTD Shale Clay View Configuration 1.0//EN",
98                        "/META-INF/clay-config_1_0.dtd"}};
99  
100     /***
101      * <p>Loads a configuration file from a <code>url</code>.  The
102      * input stream is identifed by the <code>watchDogName</code>.</p>
103      *
104      * @param configURL url of the target configuration file
105      * @param watchDogName an id used to group files that need to be reloaded together
106      * @throws IOException raised by the digester processing the configUrl
107      * @throws SAXException raised by the digester processing the XML config file
108      */
109     public void loadConfigFile(URL configURL, String watchDogName) throws IOException, SAXException {
110 
111         if (digester == null) {
112             digester = new Digester();
113             digester.setLogger(log);
114             digester.setValidating(true);
115             digester.setUseContextClassLoader(true);
116 
117             // Register our local copy of the DTDs that we can find
118             for (int i = 0; i < registrations.length; i++) {
119                 URL url = this.getClass().getResource(((String[]) registrations[i])[1]);
120                 if (url != null) {
121                     digester.register(((String[]) registrations[i])[0], url.toString());
122                 }
123             }
124 
125             configureRules();
126             digester.push(config);
127         } else {
128             digester.clear();
129             digester.push(config);
130         }
131 
132         InputStream in = null;
133         InputSource inputSource = null;
134         try {
135             in = configURL.openStream();
136             inputSource = new InputSource(configURL.toExternalForm());
137             inputSource.setByteStream(in);
138             digester.parse(inputSource);
139         } finally {
140            if (in != null) {
141               in.close();
142            }
143         }
144         inputSource = null;
145 
146     }
147 
148         /***
149          * <p>This method is called once to register the object binding rules with
150          * the <code>Digester</code> instance.
151          *</p>
152          */
153         protected void configureRules() {
154 
155             if (log.isInfoEnabled()) {
156                 log.info(messages.getMessage("parser.load.rules"));
157             }
158 
159             if (getConfig() instanceof ComponentConfigBean) {
160                 if (((ComponentConfigBean) getConfig()).isDesigntime()) {
161                     digester.addBeanPropertySetter("*/description", "description");
162                 }
163             }
164 
165             digester.addObjectCreate(
166                     "*/attributes/set",
167                     org.apache.shale.clay.config.beans.AttributeBean.class);
168             digester.addSetProperties("*/attributes/set");
169             digester.addSetNext(
170                     "*/attributes/set",
171                     "addAttribute",
172                     "org.apache.shale.clay.config.beans.AttributeBean");
173 
174             digester.addObjectCreate(
175                     "*/symbols/set",
176                     org.apache.shale.clay.config.beans.SymbolBean.class);
177             digester.addSetProperties("*/symbols/set");
178             digester.addSetNext(
179                     "*/symbols/set",
180                     "addSymbol",
181                     "org.apache.shale.clay.config.beans.SymbolBean");
182 
183             digester.addObjectCreate(
184                     "*/valueChangeListener",
185                     org.apache.shale.clay.config.beans.ValueChangeListenerBean.class);
186             digester.addSetProperties(
187                     "*/valueChangeListener");
188             digester.addSetNext(
189                     "*/valueChangeListener",
190                     "addValueChangeListener",
191                     "org.apache.shale.clay.config.beans.ValueChangeListenerBean");
192 
193             digester.addObjectCreate(
194                     "*/actionListener",
195                     org.apache.shale.clay.config.beans.ActionListenerBean.class);
196             digester.addSetProperties("*/actionListener");
197             digester.addSetNext(
198                     "*/actionListener",
199                     "addActionListener",
200                     "org.apache.shale.clay.config.beans.ActionListenerBean");
201 
202             digester.addObjectCreate(
203                     "*/validator",
204                     org.apache.shale.clay.config.beans.ValidatorBean.class);
205             digester.addSetProperties("*/validator");
206             digester.addSetNext(
207                     "*/validator",
208                     "addValidator",
209                     "org.apache.shale.clay.config.beans.ValidatorBean");
210 
211             digester.addObjectCreate(
212                     "*/converter",
213                     org.apache.shale.clay.config.beans.ConverterBean.class);
214             digester.addSetProperties("*/converter");
215             digester.addSetNext(
216                     "*/converter",
217                     "addConverter",
218                     "org.apache.shale.clay.config.beans.ConverterBean");
219 
220             digester.addObjectCreate(
221                     "*/element",
222                     org.apache.shale.clay.config.beans.ElementBean.class);
223             digester.addSetProperties("*/element");
224             digester.addSetNext(
225                     "*/element",
226                     "addChild",
227                     "org.apache.shale.clay.config.beans.ElementBean");
228 
229             digester.addObjectCreate(
230                     "view/component",
231                     org.apache.shale.clay.config.beans.ComponentBean.class);
232             digester.addSetProperties("view/component");
233             digester.addSetNext(
234                     "view/component",
235                     "addChild",
236                     "org.apache.shale.clay.config.beans.ComponentBean");
237 
238         }
239 }
240