KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > system > metadata > ServiceMetaDataParser


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2006, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.system.metadata;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.List JavaDoc;
26
27 import javax.management.ObjectName JavaDoc;
28
29 import org.jboss.dependency.spi.ControllerMode;
30 import org.jboss.dependency.spi.ControllerState;
31 import org.jboss.deployment.DeploymentException;
32 import org.jboss.logging.Logger;
33 import org.jboss.util.StringPropertyReplacer;
34 import org.w3c.dom.Attr JavaDoc;
35 import org.w3c.dom.Element JavaDoc;
36 import org.w3c.dom.Node JavaDoc;
37 import org.w3c.dom.NodeList JavaDoc;
38 import org.w3c.dom.Text JavaDoc;
39
40 /**
41  * ServiceMetaDataParser
42  *
43  * This class is based on the old ServiceConfigurator/Creator.
44  *
45  * @author <a HREF="mailto:marc@jboss.org">Marc Fleury</a>
46  * @author <a HREF="mailto:hiram@jboss.org">Hiram Chirino</a>
47  * @author <a HREF="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
48  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
49  * @author <a HREF="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
50  * @author <a HREF="adrian@jboss.com">Adrian Brock</a>
51  * @version $Revision: 1.1 $
52  */

53 public class ServiceMetaDataParser
54 {
55    /** The log */
56    private static final Logger log = Logger.getLogger(ServiceMetaDataParser.class);
57    
58    /** The element config */
59    private Element JavaDoc config;
60
61    /** The mode */
62    private ControllerMode serverMode;
63    
64    /**
65     * Create a new service meta data parser
66     *
67     * @param config the xml config
68     */

69    public ServiceMetaDataParser(Element JavaDoc config)
70    {
71       if (config == null)
72          throw new IllegalArgumentException JavaDoc("Null config");
73       
74       this.config = config;
75    }
76
77    /**
78     * Parse the xml
79     *
80     * @return the list of service meta data
81     * @throws DeploymentException for any error
82     */

83    public List JavaDoc<ServiceMetaData> parse() throws DeploymentException
84    {
85       List JavaDoc<ServiceMetaData> services = new ArrayList JavaDoc<ServiceMetaData>();
86       
87       try
88       {
89          String JavaDoc tagName = config.getTagName();
90          if ("mbean".equals(tagName))
91             internalParse(services, config, true);
92          else
93          {
94             if ("server".equals(tagName))
95                parseServer(config);
96
97             NodeList JavaDoc nl = config.getChildNodes();
98
99             for (int i = 0; i < nl.getLength(); ++i)
100             {
101                if (nl.item(i).getNodeType() == Node.ELEMENT_NODE)
102                {
103                   Element JavaDoc element = (Element JavaDoc) nl.item(i);
104                   if ("mbean".equals(element.getTagName()))
105                   {
106                      Element JavaDoc mbean = (Element JavaDoc) nl.item(i);
107                      internalParse(services, mbean, true);
108                   }
109                }
110             }
111          }
112       }
113       catch (Throwable JavaDoc t)
114       {
115          DeploymentException.rethrowAsDeploymentException("Unable to parse service configuration", t);
116       }
117       
118       return services;
119    }
120
121    /**
122     * Parse the server element
123     *
124     * @param serverElement the server element
125     * @throws Exception for any error
126     */

127    private void parseServer(Element JavaDoc serverElement) throws Exception JavaDoc
128    {
129       String JavaDoc modeString = serverElement.getAttribute("mode");
130       if (modeString != null)
131       {
132          modeString = modeString.trim();
133          if (modeString.length() != 0)
134             serverMode = new ControllerMode(modeString);
135       }
136    }
137
138    /**
139     * Internal parse
140     *
141     * @param services the list of service meta data
142     * @param mbeanElement the mbean configuration
143     * @param replace whether to replace system properties
144     * @return the ObjectName of the parsed mbean
145     * @throws Exception for any error
146     */

147    private ObjectName JavaDoc internalParse(List JavaDoc<ServiceMetaData> services, Element JavaDoc mbeanElement, boolean replace) throws Exception JavaDoc
148    {
149       ServiceMetaData service = new ServiceMetaData();
150
151       ObjectName JavaDoc mbeanName = parseObjectName(mbeanElement, replace);
152       service.setObjectName(mbeanName);
153       
154       String JavaDoc code = parseCode(mbeanName, mbeanElement);
155       service.setCode(code);
156       
157       ControllerMode mode = parseMode(mbeanName, mbeanElement);
158       if (mode == null)
159          mode = serverMode;
160       service.setMode(mode);
161
162       ServiceConstructorMetaData constructor = parseConstructor(mbeanName, mbeanElement, replace);
163       service.setConstructor(constructor);
164       
165       String JavaDoc interfaceName = parseInterface(mbeanName, mbeanElement);
166       service.setInterfaceName(interfaceName);
167       
168       String JavaDoc xmbeandd = parseXMBeanDD(mbeanName, mbeanElement);
169       service.setXMBeanDD(xmbeandd);
170
171       String JavaDoc xmbeanCode = parseXMBeanCode(mbeanName, mbeanElement);
172       service.setXMBeanCode(xmbeanCode);
173       
174       if (xmbeandd != null && xmbeandd.length() == 0)
175       {
176          Element JavaDoc xmbeanDescriptor = parseXMBeanDescriptor(mbeanName, mbeanElement);
177          service.setXMBeanDescriptor(xmbeanDescriptor);
178       }
179       
180       List JavaDoc<ServiceAttributeMetaData> attributes = new ArrayList JavaDoc<ServiceAttributeMetaData>();
181       List JavaDoc<ServiceDependencyMetaData> dependencies = new ArrayList JavaDoc<ServiceDependencyMetaData>();
182
183       NodeList JavaDoc attrs = mbeanElement.getChildNodes();
184       for (int j = 0; j < attrs.getLength(); j++)
185       {
186          // skip over non-element nodes
187
if (attrs.item(j).getNodeType() != Node.ELEMENT_NODE)
188             continue;
189
190          Element JavaDoc element = (Element JavaDoc) attrs.item(j);
191
192          boolean replaceAttribute = true;
193
194          // Set attributes
195
if (element.getTagName().equals("attribute"))
196          {
197             String JavaDoc attributeName = element.getAttribute("name");
198             if (attributeName == null)
199                throw new DeploymentException("No attribute name for " + mbeanName);
200             boolean trim = true;
201             String JavaDoc replaceAttr = element.getAttribute("replace");
202             if (replaceAttr.length() > 0)
203                replaceAttribute = Boolean.valueOf(replaceAttr).booleanValue();
204             String JavaDoc trimAttr = element.getAttribute("trim");
205             if (trimAttr.length() > 0)
206                trim = Boolean.valueOf(trimAttr).booleanValue();
207             String JavaDoc serialDataType = element.getAttribute("serialDataType");
208
209             if (element.hasChildNodes())
210             {
211                // Unmarshall the attribute value based on the serialDataType
212
ServiceValueMetaData value = null;
213                if (serialDataType.equals("javaBean"))
214                {
215                   value = new ServiceJavaBeanValueMetaData(element);
216                }
217                else if (serialDataType.equals("jbxb"))
218                {
219                   value = new ServiceJBXBValueMetaData(element);
220                }
221                else
222                {
223                   NodeList JavaDoc nl = element.getChildNodes();
224                   for (int i = 0; i < nl.getLength(); i++)
225                   {
226                      Node JavaDoc n = nl.item(i);
227                      if (n.getNodeType() == Node.ELEMENT_NODE)
228                      {
229                         Element JavaDoc el = (Element JavaDoc) n;
230                         String JavaDoc tagName = el.getTagName();
231                         if ("inject".equals(tagName))
232                         {
233                            String JavaDoc dependency = el.getAttribute("bean");
234                            String JavaDoc property = null;
235                            Attr JavaDoc attr = el.getAttributeNode("property");
236                            if (attr != null)
237                               property = attr.getValue();
238                            ControllerState requiredState = ControllerState.INSTALLED;
239                            attr = el.getAttributeNode("state");
240                            if (attr != null)
241                               requiredState = new ControllerState(attr.getValue());
242                            value = new ServiceInjectionValueMetaData(dependency, property, requiredState);
243                         }
244                         else
245                         {
246                            value = new ServiceElementValueMetaData((Element JavaDoc) n);
247                         }
248                         break;
249                      }
250                   }
251                   if (value == null)
252                      value = new ServiceTextValueMetaData(getElementTextContent(element, trim, replaceAttribute));
253                }
254                
255                ServiceAttributeMetaData attribute = new ServiceAttributeMetaData();
256                attribute.setName(attributeName);
257                attribute.setReplace(replaceAttribute);
258                attribute.setTrim(trim);
259                attribute.setValue(value);
260                attributes.add(attribute);
261             }
262          }
263          else if (element.getTagName().equals("depends"))
264          {
265             String JavaDoc mbeanRefName = element.getAttribute("optional-attribute-name");
266             if ("".equals(mbeanRefName))
267                mbeanRefName = null;
268             else
269                mbeanRefName = StringPropertyReplacer.replaceProperties(mbeanRefName);
270
271             String JavaDoc proxyType = element.getAttribute("proxy-type");
272             if ("".equals(proxyType))
273                proxyType = null;
274             else
275                proxyType = StringPropertyReplacer.replaceProperties(proxyType);
276
277             // Get the mbeanRef value
278
String JavaDoc dependsObjectName = processDependency(mbeanName, mbeanRefName, element, services, replace);
279
280             if (mbeanRefName != null)
281             {
282                ServiceValueMetaData value = new ServiceDependencyValueMetaData(dependsObjectName, proxyType);
283                ServiceAttributeMetaData attribute = new ServiceAttributeMetaData();
284                attribute.setName(mbeanRefName);
285                attribute.setValue(value);
286                attributes.add(attribute);
287             }
288             else
289             {
290                ServiceDependencyMetaData dependency = new ServiceDependencyMetaData();
291                dependency.setIDependOn(dependsObjectName);
292                dependencies.add(dependency);
293             }
294          }
295          else if (element.getTagName().equals("depends-list"))
296          {
297             String JavaDoc dependsListName = element.getAttribute("optional-attribute-name");
298             if ("".equals(dependsListName))
299                dependsListName = null;
300
301             NodeList JavaDoc dependsList = element.getChildNodes();
302             ArrayList JavaDoc<String JavaDoc> dependsListNames = new ArrayList JavaDoc<String JavaDoc>();
303             for (int l = 0; l < dependsList.getLength(); ++l)
304             {
305                if (dependsList.item(l).getNodeType() != Node.ELEMENT_NODE)
306                   continue;
307
308                Element JavaDoc dependsElement = (Element JavaDoc) dependsList.item(l);
309                if (dependsElement.getTagName().equals("depends-list-element"))
310                {
311                   // Get the depends value
312
String JavaDoc dependsObjectName = processDependency(mbeanName, dependsListName, dependsElement, services, replace);
313                   if (dependsListNames.contains(dependsObjectName) == false)
314                      dependsListNames.add(dependsObjectName);
315
316                   if (dependsListName == null)
317                   {
318                      ServiceDependencyMetaData dependency = new ServiceDependencyMetaData();
319                      dependency.setIDependOn(dependsObjectName);
320                      dependencies.add(dependency);
321                   }
322                }
323             }
324             if (dependsListName != null)
325             {
326                ServiceValueMetaData value = new ServiceDependencyListValueMetaData(dependsListNames);
327                ServiceAttributeMetaData attribute = new ServiceAttributeMetaData();
328                attribute.setName(dependsListName);
329                attribute.setValue(value);
330                attributes.add(attribute);
331             }
332          }
333       }
334       
335       service.setAttributes(attributes);
336       service.setDependencies(dependencies);
337       
338       services.add(service);
339       
340       return mbeanName;
341    }
342
343    /**
344     * Parse an object name from the given element attribute 'name'.
345     *
346     * @param mbeanElement the element to parse name from.
347     * @return the ObjectName
348     * @throws Exception for any error
349     */

350    private ObjectName JavaDoc parseObjectName(final Element JavaDoc mbeanElement, boolean replace) throws Exception JavaDoc
351    {
352       String JavaDoc name = mbeanElement.getAttribute("name");
353
354       if (name == null || name.trim().length() == 0)
355          throw new DeploymentException("Missing or empty 'name' attribute for mbean.");
356
357       if (replace)
358          name = StringPropertyReplacer.replaceProperties(name);
359
360       return new ObjectName JavaDoc(name);
361    }
362
363    /**
364     * Parse a class name from the given element attribute 'code'.
365     *
366     * @param name the mbean name
367     * @param mbeanElement the element to parse name from.
368     * @return the class name
369     * @throws Exception for any error
370     */

371    private String JavaDoc parseCode(final ObjectName JavaDoc name, final Element JavaDoc mbeanElement) throws Exception JavaDoc
372    {
373       return mbeanElement.getAttribute("code");
374    }
375
376    /**
377     * Parse the mode
378     *
379     * @param name the mbean name
380     * @param mbeanElement the element to parse name from.
381     * @return the mode
382     * @throws Exception for any error
383     */

384    private ControllerMode parseMode(final ObjectName JavaDoc name, final Element JavaDoc mbeanElement) throws Exception JavaDoc
385    {
386       String JavaDoc modeString = mbeanElement.getAttribute("mode");
387       if (modeString == null)
388          return null;
389       modeString = modeString.trim();
390       if (modeString.length() == 0)
391          return null;
392       return new ControllerMode(modeString);
393    }
394
395    /**
396     * Parse the constructor element of the given element
397     *
398     * @param name the mbean name
399     * @param mbeanElement the element to parse name from.
400     * @param replace whether to replace system properties
401     * @return the constructor meta data
402     * @throws Exception for any error
403     */

404    private ServiceConstructorMetaData parseConstructor(final ObjectName JavaDoc name, final Element JavaDoc mbeanElement, boolean replace) throws Exception JavaDoc
405    {
406       ServiceConstructorMetaData result = new ServiceConstructorMetaData();
407
408       NodeList JavaDoc list = mbeanElement.getElementsByTagName("constructor");
409       if (list.getLength() > 1 && list.item(0).getParentNode() == mbeanElement)
410          throw new DeploymentException("only one <constructor> element may be defined for " + name);
411       
412       if (list.getLength() == 1)
413       {
414          Element JavaDoc element = (Element JavaDoc) list.item(0);
415
416          // get all of the "arg" elements
417
list = element.getElementsByTagName("arg");
418          int length = list.getLength();
419          String JavaDoc[] params = new String JavaDoc[length];
420          String JavaDoc[] signature = new String JavaDoc[length];
421
422          // decode the values into params & signature
423
for (int j=0; j<length; ++j)
424          {
425             Element JavaDoc arg = (Element JavaDoc)list.item(j);
426             String JavaDoc typeName = null;
427             Attr JavaDoc attr = arg.getAttributeNode("type");
428             if (attr != null)
429                typeName = attr.getValue();
430             String JavaDoc value = null;
431             attr = arg.getAttributeNode("value");
432             if (attr != null)
433                value = attr.getValue();
434             signature[j] = typeName;
435             params[j] = value;
436          }
437          
438          result.setParams(params);
439          result.setSignature(signature);
440       }
441
442       return result;
443    }
444
445    /**
446     * Parse the interface name from the given element attribute 'interface'.
447     *
448     * @param name the mbean name
449     * @param mbeanElement the element to parse name from.
450     * @return the class name
451     * @throws Exception for any error
452     */

453    private String JavaDoc parseInterface(final ObjectName JavaDoc name, final Element JavaDoc mbeanElement) throws Exception JavaDoc
454    {
455       Attr JavaDoc attr = mbeanElement.getAttributeNode("interface");
456       if (attr != null)
457          return attr.getValue();
458       else
459          return null;
460    }
461
462    /**
463     * Parse the xmbean dds from the given element attribute 'xmbean-dd'.
464     *
465     * @param name the mbean name
466     * @param mbeanElement the element to parse name from.
467     * @return the xmbean dds location
468     * @throws Exception for any error
469     */

470    private String JavaDoc parseXMBeanDD(final ObjectName JavaDoc name, final Element JavaDoc mbeanElement) throws Exception JavaDoc
471    {
472       Attr JavaDoc attr = mbeanElement.getAttributeNode("xmbean-dd");
473       if (attr != null)
474          return attr.getValue();
475       else
476          return null;
477    }
478
479    /**
480     * Parse the xmbean code from the given element attribute 'xmbean-code'.
481     *
482     * @param name the mbean name
483     * @param mbeanElement the element to parse name from.
484     * @return the xmbean code
485     * @throws Exception for any error
486     */

487    private String JavaDoc parseXMBeanCode(final ObjectName JavaDoc name, final Element JavaDoc mbeanElement) throws Exception JavaDoc
488    {
489       Attr JavaDoc attr = mbeanElement.getAttributeNode("xmbean-code");
490       if (attr != null)
491          return attr.getValue();
492       else
493          return ServiceMetaData.XMBEAN_CODE;
494    }
495
496    /**
497     * Parse the xmbean descriptor.
498     *
499     * @param name the mbean name
500     * @param mbeanElement the element to parse name from.
501     * @return the xmbean descriptor
502     * @throws Exception for any error
503     */

504    private Element JavaDoc parseXMBeanDescriptor(final ObjectName JavaDoc name, final Element JavaDoc mbeanElement) throws Exception JavaDoc
505    {
506       NodeList JavaDoc mbeans = mbeanElement.getElementsByTagName("xmbean");
507       if (mbeans.getLength() == 0)
508          throw new DeploymentException("No nested mbean element given for xmbean for " + name);
509       return (Element JavaDoc) mbeans.item(0);
510    }
511
512    /**
513     * Process a dependency
514     *
515     * @param mbeanName the surronding mbean
516     * @param attributeName the attribute name
517     * @param element the element
518     * @param services the list of services
519     * @param replace whether to replace properties
520     * @return the dependent object name
521     * @throws Exception for any error
522     */

523    private String JavaDoc processDependency(ObjectName JavaDoc mbeanName, String JavaDoc attributeName, Element JavaDoc element, List JavaDoc<ServiceMetaData> services, boolean replace) throws Exception JavaDoc
524    {
525       String JavaDoc dependsObjectName = null;
526       
527       NodeList JavaDoc nl = element.getChildNodes();
528       for (int i = 0; i < nl.getLength(); i++)
529       {
530          Node JavaDoc childNode = nl.item(i);
531          if (childNode.getNodeType() == Node.ELEMENT_NODE)
532          {
533             Element JavaDoc child = (Element JavaDoc) childNode;
534             String JavaDoc tagName = child.getTagName();
535             if ("mbean".equals(tagName))
536             {
537                dependsObjectName = internalParse(services, child, replace).getCanonicalName();
538                break;
539             }
540             else
541             {
542                if (attributeName != null)
543                   log.warn("Non mbean child <" + tagName + "/> in depends tag for " + mbeanName + " attribute: " + attributeName);
544                else
545                   log.warn("Non mbean child <" + tagName + "/> in depends tag for " + mbeanName);
546             }
547          }
548       }
549
550       if (dependsObjectName == null)
551          dependsObjectName = getElementTextContent(element, true, replace);
552
553       return dependsObjectName;
554    }
555
556    /**
557     * Get an elements text content
558     *
559     * @param element the element
560     * @param trim whether to trim
561     * @param replace whetehr to replace properties
562     * @return the concatentation of the text nodes
563     * @throws Exception for any error
564     */

565    public static String JavaDoc getElementTextContent(Element JavaDoc element, boolean trim, boolean replace) throws Exception JavaDoc
566    {
567       NodeList JavaDoc nl = element.getChildNodes();
568       String JavaDoc attributeText = "";
569       for (int i = 0; i < nl.getLength(); i++)
570       {
571          Node JavaDoc n = nl.item(i);
572          if (n instanceof Text JavaDoc)
573          {
574             attributeText += ((Text JavaDoc) n).getData();
575          }
576       }
577       if (trim)
578          attributeText = attributeText.trim();
579       if (replace)
580          attributeText = StringPropertyReplacer.replaceProperties(attributeText);
581       return attributeText;
582    }
583 }
584
Popular Tags