View Javadoc

1   // 
2   // Copyright (c) 2003-2005, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J. 
3   // All rights reserved. 
4   // 
5   // Redistribution and use in source and binary forms, with or without modification,  
6   // are permitted provided that the following conditions are met: 
7   //  
8   // * Redistributions of source code must retain the above copyright notice,  
9   //	 this list of conditions and the following disclaimer. 
10  // * Redistributions in binary form must reproduce the above copyright notice,  
11  //	 this list of conditions and the following disclaimer in the documentation  
12  //	 and/or other materials provided with the distribution. 
13  // * Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.  
14  //	 nor the names of its contributors may be used to endorse or promote products  
15  //	 derived from this software without specific prior written permission. 
16  // 
17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  
18  // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  
19  // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
20  // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  
21  // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  
22  // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
23  // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
24  // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  
25  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  
26  // POSSIBILITY OF SUCH DAMAGE. 
27  // 
28  package org.objectledge.configuration;
29  
30  import java.util.ArrayList;
31  import java.util.Collections;
32  import java.util.Iterator;
33  import java.util.LinkedList;
34  import java.util.List;
35  
36  import javax.xml.parsers.SAXParserFactory;
37  
38  import org.objectledge.ComponentInitializationError;
39  import org.xml.sax.Attributes;
40  import org.xml.sax.InputSource;
41  import org.xml.sax.SAXException;
42  import org.xml.sax.XMLReader;
43  import org.xml.sax.helpers.DefaultHandler;
44  
45  /***
46   * Provides information about components deployed in the system and their configuration. 
47   *
48   * @author <a href="mailto:rafal@caltha.pl">Rafal Krzewski</a>
49   * @version $Id: ConfigurationInspector.java,v 1.5 2006/02/08 18:20:11 zwierzem Exp $
50   */
51  public class ConfigurationInspector
52  {
53      private final ConfigurationFactory configurationFactory;
54  
55      private final SAXParserFactory parserFactory;
56  
57      /***
58       * Creates new ConfigurationViewer instance.
59       * 
60       * @param configurationFactoryArg the configuration factory.
61       */
62      public ConfigurationInspector(ConfigurationFactory configurationFactoryArg)
63      {
64          this.configurationFactory = configurationFactoryArg;
65          try
66          {
67              parserFactory = SAXParserFactory.newInstance();
68              parserFactory.setNamespaceAware(true);
69          }
70          catch(Exception e)
71          {
72              throw new ComponentInitializationError(e);
73          }
74      }
75  
76      /***
77       * Returns the configuration desctiptors for all components present in the system.
78       * 
79       * @return the configuration desctiptors for all components present in the system.
80       */
81      public List<ComponentConfiguration> getComponentConfigurations()
82      {
83          List<ComponentConfiguration> list = new ArrayList<ComponentConfiguration>();
84          InputSource composition = configurationFactory.getCompositionSource();
85          try
86          {
87              XMLReader reader = parserFactory.newSAXParser().getXMLReader();
88              reader.setContentHandler(new CompositionHandler(list));
89              reader.parse(composition);
90          }
91          catch(Exception e)
92          {
93              throw new RuntimeException("composition parsing failed", e);
94          }
95          
96          return list;
97      }    
98      
99      List<String> getComponentConfig(String key)
100     {
101         if(!configurationFactory.hasConfig(key))
102         {
103             return Collections.emptyList();
104         }
105         List<String> entries = new ArrayList<String>();
106         InputSource config = configurationFactory.getRawConfigurationSource(key);
107         try
108         {
109             XMLReader reader = parserFactory.newSAXParser().getXMLReader();
110             reader.setContentHandler(new ConfigurationHandler(entries));
111             reader.parse(config);
112         }
113         catch(Exception e)
114         {
115             throw new RuntimeException("composition parsing failed", e);
116         }
117         
118         return entries;
119     }
120     
121     /***
122      * Describes a component's configuration.
123      */
124     public class ComponentConfiguration
125     {
126         /*** Key of the component. */
127         private final String componentKey;
128         
129         /*** Component implementation class. */
130         private final String componentClass;
131         
132         /*** Component's constructor parameters. */
133         private final List<String> parameters;
134         
135         /*** Component's configuration entries. */
136         private final List<String> config;
137         
138         /***
139          * Creates new ComponentConfiguration instance.
140          * 
141          * @param componentKeyArg component's key.
142          * @param componentClassArg component's configuration class.
143          * @param parametersArg component's constructor parameter list.
144          * @param configArg component's configuration entries.
145          */
146         public ComponentConfiguration(final String componentKeyArg, final String componentClassArg,
147             final List<String> parametersArg, final List<String> configArg)
148         {
149             componentKey = componentKeyArg;
150             componentClass = componentClassArg;
151             parameters = parametersArg;
152             config = configArg;
153         }
154 
155         /***
156          * Returns the componentClass.
157          *
158          * @return the componentClass.
159          */
160         public String getComponentClass()
161         {
162             return componentClass;
163         }
164 
165         /***
166          * Returns the componentKey.
167          *
168          * @return the componentKey.
169          */
170         public String getComponentKey()
171         {
172             return componentKey;
173         }
174 
175         /***
176          * Returns the config.
177          *
178          * @return the config.
179          */
180         public List<String> getConfig()
181         {
182             return config;
183         }
184 
185         /***
186          * Returns the parameters.
187          *
188          * @return the parameters.
189          */
190         public List<String> getParameters()
191         {
192             return parameters;
193         }
194     }
195     
196     /***
197      * A SAX2 DocumentHandler for parsing the composition file.
198      */
199     private class CompositionHandler 
200         extends DefaultHandler
201     {
202         private final List<ComponentConfiguration> list;
203 
204         public CompositionHandler(List<ComponentConfiguration> listArg)
205         {
206             this.list = listArg;
207         }
208         
209         /***
210          * {@inheritDoc}
211          */
212         public void startElement(String uri, String localName, String qName, Attributes attributes)
213             throws SAXException
214         {
215             if(localName.equals("component"))
216             {
217                 String key = null;
218                 boolean classKey = false;
219                 if(attributes.getValue("key") != null)
220                 {
221                     key = attributes.getValue("key");
222                 }
223                 if(key == null && attributes.getValue("class-key") != null)
224                 {
225                     key = attributes.getValue("class-key");
226                     classKey = true;
227                 }
228                 if(key == null && attributes.getValue("anon") != null)
229                 {
230                     key = "anon";
231                 }
232                 if(key == null)
233                 {
234                     key = attributes.getValue("class");
235                     classKey = true;
236                 }
237                 String impl = attributes.getValue("class");
238                 
239                 List<String> params = Collections.emptyList();
240                 List<String> config = getComponentConfig(key);
241                 list.add(new ComponentConfiguration((classKey ? "class " : "") + key, impl, params, 
242                     config));
243              }
244         }
245     }
246 
247     /***
248      * 
249      * 
250      *
251      * @author <a href="mailto:rafal@caltha.pl">Rafal Krzewski</a>
252      * @version $Id: ConfigurationInspector.java,v 1.5 2006/02/08 18:20:11 zwierzem Exp $
253      */
254     private class ConfigurationHandler 
255         extends DefaultHandler
256     {
257         private final List<String> entries;
258         
259         private final StringBuilder buff = new StringBuilder();
260         
261         private final StringBuilder charContent = new StringBuilder();
262         
263         private final LinkedList<String> elementStack = new LinkedList<String>();
264         
265         public ConfigurationHandler(List<String> entriesArg)
266         {
267             entries = entriesArg;
268         }
269         
270         /***
271          * {@inheritDoc}
272          */
273         public void characters(char[] ch, int start, int length)
274             throws SAXException
275         {
276             String s = new String(ch, start, length);
277             if(s.trim().length() > 0)
278             {
279                 charContent.append(s);
280             }
281         }
282 
283         /***
284          * {@inheritDoc}
285          */
286         public void startElement(String uri, String localName, String qName, Attributes attributes)
287             throws SAXException
288         {
289             elementStack.add(localName);
290             if(attributes.getLength() > 0)
291             {
292                 String elementPath = getElementPath();
293                 for(int i = 0; i < attributes.getLength(); i++)
294                 {
295                     buff.append(elementPath);
296                     buff.append('.');
297                     buff.append(attributes.getQName(i));
298                     buff.append(" = ");
299                     buff.append(attributes.getValue(i));
300                     commitEntry();
301                 }
302             }
303         }
304 
305         /***
306          * {@inheritDoc}
307          */
308         public void endElement(String uri, String localName, String qName)
309             throws SAXException
310         {
311             if(charContent.length() > 0)
312             {
313                 buff.append(getElementPath());
314                 buff.append(" = ");
315                 buff.append(charContent.toString().trim());
316                 commitEntry();
317                 charContent.setLength(0);
318             }
319             elementStack.removeLast();
320         }
321         
322         private String getElementPath()
323         {
324             StringBuilder pathBuff = new StringBuilder();
325             for(Iterator<String> element = elementStack.iterator(); element.hasNext();)
326             {
327                 pathBuff.append(element.next());
328                 if(element.hasNext())
329                 {
330                     pathBuff.append('/');
331                 }
332             }
333             return pathBuff.toString();
334         }
335         
336         private void commitEntry()
337         {
338             entries.add(buff.toString());
339             buff.setLength(0);
340         }
341     }
342 }