View Javadoc

1   /**
2    *
3    * Copyright 2005 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  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  package org.apache.geronimo.kernel.config.xstream;
18  
19  import java.io.IOException;
20  import java.util.ArrayList;
21  import java.util.Arrays;
22  import java.util.Collection;
23  import java.util.Collections;
24  import java.util.List;
25  import javax.xml.parsers.DocumentBuilder;
26  import javax.xml.parsers.DocumentBuilderFactory;
27  import javax.xml.parsers.ParserConfigurationException;
28  
29  import com.thoughtworks.xstream.XStream;
30  import com.thoughtworks.xstream.io.xml.DomReader;
31  import com.thoughtworks.xstream.io.xml.DomWriter;
32  import org.apache.geronimo.gbean.AbstractName;
33  import org.apache.geronimo.gbean.GBeanData;
34  import org.apache.geronimo.gbean.GBeanInfo;
35  import org.apache.geronimo.kernel.Naming;
36  import org.apache.geronimo.kernel.util.XmlUtil;
37  import org.apache.geronimo.kernel.config.InvalidConfigException;
38  import org.apache.geronimo.kernel.config.GBeanState;
39  import org.apache.geronimo.kernel.repository.Environment;
40  import org.w3c.dom.Document;
41  import org.w3c.dom.Element;
42  
43  /**
44   * @version $Rev: 428843 $ $Date: 2006-08-04 11:43:59 -0700 (Fri, 04 Aug 2006) $
45   */
46  public class XStreamGBeanState implements GBeanState {
47      /**
48       * GBeans contained in this configuration.
49       */
50      private final List gbeans = new ArrayList();
51  
52      /**
53       * The serialized form of the gbeans.  Once this is set on more gbeans can be added.
54       */
55      private Element gbeanState;
56  
57      public XStreamGBeanState(Element gbeanState) {
58          this.gbeanState = gbeanState;
59      }
60  
61      public XStreamGBeanState(Collection gbeans) {
62          if (gbeans != null){
63              this.gbeans.addAll(gbeans);
64          }
65      }
66  
67      public Element getGBeanState() throws IOException {
68          if (gbeanState == null) {
69              gbeanState = XStreamGBeanState.storeGBeans(gbeans);
70              gbeans.clear();
71          }
72          return gbeanState;
73      }
74  
75      public List getGBeans(ClassLoader classLoader) throws InvalidConfigException {
76          if (gbeanState == null) {
77              return Collections.unmodifiableList(gbeans);
78          }
79          gbeans.addAll(XStreamGBeanState.loadGBeans(gbeanState, classLoader));
80          return Collections.unmodifiableList(gbeans);
81      }
82  
83      public void addGBean(GBeanData gbeanData) {
84          if (gbeanState != null) {
85              throw new IllegalStateException("GBeans have been serialized, so no more GBeans can be added");
86          }
87  
88          gbeans.add(gbeanData);
89      }
90  
91      public GBeanData addGBean(String name, GBeanInfo gbeanInfo, Naming naming, Environment environment) {
92          if (gbeanState != null) {
93              throw new IllegalStateException("GBeans have been serialized, so no more GBeans can be added");
94          }
95  
96          String j2eeType = gbeanInfo.getJ2eeType();
97          if (j2eeType == null) j2eeType = "GBean";
98          AbstractName abstractName = naming.createRootName(environment.getConfigId(), name, j2eeType);
99          GBeanData gBeanData = new GBeanData(abstractName, gbeanInfo);
100         addGBean(gBeanData);
101         return gBeanData;
102     }
103 
104     private static List loadGBeans(Element element, ClassLoader classLoader) throws InvalidConfigException {
105         if (element != null) {
106             // Set the thread context classloader so deserializing classes can grab the cl from the thread
107             ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
108             try {
109                 Thread.currentThread().setContextClassLoader(classLoader);
110 
111                 DomReader reader = new DomReader(element);
112                 XStream xstream = XStreamUtil.createXStream();
113                 xstream.setClassLoader(classLoader);
114                 Object o = xstream.unmarshal(reader);
115                 GBeanData[] gbeanDatas = (GBeanData[]) o;
116                 return Arrays.asList(gbeanDatas);
117             } catch (Exception e) {
118                 throw new InvalidConfigException("Unable to load gbeans", e);
119             } finally {
120                 Thread.currentThread().setContextClassLoader(oldCl);
121             }
122         }
123         return Collections.EMPTY_LIST;
124     }
125 
126     private static Element storeGBeans(List gbeans) throws IOException {
127         GBeanData[] gbeanDatas = (GBeanData[]) gbeans.toArray(new GBeanData[gbeans.size()]);
128 
129         DocumentBuilderFactory documentBuilderFactory = XmlUtil.newDocumentBuilderFactory();
130         DocumentBuilder documentBuilder = null;
131         try {
132             documentBuilder = documentBuilderFactory.newDocumentBuilder();
133         } catch (ParserConfigurationException e) {
134             throw (IOException)new IOException("Cannot instantiate " + Document.class.getName()).initCause(e);
135         }
136         Document document = documentBuilder.newDocument();
137         DomWriter writer = new DomWriter(document);
138 
139         XStream xstream = XStreamUtil.createXStream();
140         xstream.marshal(gbeanDatas, writer);
141 
142 //        FileWriter w = new FileWriter("target/foo.xml");
143 //        xstream.toXML(gbeanDatas, w);
144 //        w.close();
145 
146         return document.getDocumentElement();
147     }
148 }