001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.kernel.config.xstream;
017:
018: import java.io.IOException;
019: import java.util.ArrayList;
020: import java.util.Arrays;
021: import java.util.Collection;
022: import java.util.Collections;
023: import java.util.List;
024: import javax.xml.parsers.DocumentBuilder;
025: import javax.xml.parsers.DocumentBuilderFactory;
026: import javax.xml.parsers.ParserConfigurationException;
027:
028: import com.thoughtworks.xstream.XStream;
029: import com.thoughtworks.xstream.io.xml.DomReader;
030: import com.thoughtworks.xstream.io.xml.DomWriter;
031: import org.apache.geronimo.gbean.AbstractName;
032: import org.apache.geronimo.gbean.GBeanData;
033: import org.apache.geronimo.gbean.GBeanInfo;
034: import org.apache.geronimo.kernel.Naming;
035: import org.apache.geronimo.kernel.util.XmlUtil;
036: import org.apache.geronimo.kernel.config.InvalidConfigException;
037: import org.apache.geronimo.kernel.config.GBeanState;
038: import org.apache.geronimo.kernel.repository.Environment;
039: import org.w3c.dom.Document;
040: import org.w3c.dom.Element;
041:
042: /**
043: * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
044: */
045: public class XStreamGBeanState implements GBeanState {
046: /**
047: * GBeans contained in this configuration.
048: */
049: private final List gbeans = new ArrayList();
050:
051: /**
052: * The serialized form of the gbeans. Once this is set on more gbeans can be added.
053: */
054: private Element gbeanState;
055:
056: public XStreamGBeanState(Element gbeanState) {
057: this .gbeanState = gbeanState;
058: }
059:
060: public XStreamGBeanState(Collection gbeans) {
061: if (gbeans != null) {
062: this .gbeans.addAll(gbeans);
063: }
064: }
065:
066: public Element getGBeanState() throws IOException {
067: if (gbeanState == null) {
068: gbeanState = XStreamGBeanState.storeGBeans(gbeans);
069: gbeans.clear();
070: }
071: return gbeanState;
072: }
073:
074: public List getGBeans(ClassLoader classLoader)
075: throws InvalidConfigException {
076: if (gbeanState == null) {
077: return Collections.unmodifiableList(gbeans);
078: }
079: gbeans.addAll(XStreamGBeanState.loadGBeans(gbeanState,
080: classLoader));
081: return Collections.unmodifiableList(gbeans);
082: }
083:
084: public void addGBean(GBeanData gbeanData) {
085: if (gbeanState != null) {
086: throw new IllegalStateException(
087: "GBeans have been serialized, so no more GBeans can be added");
088: }
089:
090: gbeans.add(gbeanData);
091: }
092:
093: public GBeanData addGBean(String name, GBeanInfo gbeanInfo,
094: Naming naming, Environment environment) {
095: if (gbeanState != null) {
096: throw new IllegalStateException(
097: "GBeans have been serialized, so no more GBeans can be added");
098: }
099:
100: String j2eeType = gbeanInfo.getJ2eeType();
101: if (j2eeType == null)
102: j2eeType = "GBean";
103: AbstractName abstractName = naming.createRootName(environment
104: .getConfigId(), name, j2eeType);
105: GBeanData gBeanData = new GBeanData(abstractName, gbeanInfo);
106: addGBean(gBeanData);
107: return gBeanData;
108: }
109:
110: private static List loadGBeans(Element element,
111: ClassLoader classLoader) throws InvalidConfigException {
112: if (element != null) {
113: // Set the thread context classloader so deserializing classes can grab the cl from the thread
114: ClassLoader oldCl = Thread.currentThread()
115: .getContextClassLoader();
116: try {
117: Thread.currentThread().setContextClassLoader(
118: classLoader);
119:
120: DomReader reader = new DomReader(element);
121: XStream xstream = XStreamUtil.createXStream();
122: xstream.setClassLoader(classLoader);
123: Object o = xstream.unmarshal(reader);
124: GBeanData[] gbeanDatas = (GBeanData[]) o;
125: return Arrays.asList(gbeanDatas);
126: } catch (Exception e) {
127: throw new InvalidConfigException(
128: "Unable to load gbeans", e);
129: } finally {
130: Thread.currentThread().setContextClassLoader(oldCl);
131: }
132: }
133: return Collections.EMPTY_LIST;
134: }
135:
136: private static Element storeGBeans(List gbeans) throws IOException {
137: GBeanData[] gbeanDatas = (GBeanData[]) gbeans
138: .toArray(new GBeanData[gbeans.size()]);
139:
140: DocumentBuilderFactory documentBuilderFactory = XmlUtil
141: .newDocumentBuilderFactory();
142: DocumentBuilder documentBuilder = null;
143: try {
144: documentBuilder = documentBuilderFactory
145: .newDocumentBuilder();
146: } catch (ParserConfigurationException e) {
147: throw (IOException) new IOException("Cannot instantiate "
148: + Document.class.getName()).initCause(e);
149: }
150: Document document = documentBuilder.newDocument();
151: DomWriter writer = new DomWriter(document);
152:
153: XStream xstream = XStreamUtil.createXStream();
154: xstream.marshal(gbeanDatas, writer);
155:
156: // FileWriter w = new FileWriter("target/foo.xml");
157: // xstream.toXML(gbeanDatas, w);
158: // w.close();
159:
160: return document.getDocumentElement();
161: }
162: }
|