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;
017:
018: import java.io.Serializable;
019: import java.io.IOException;
020: import java.io.ObjectInputStream;
021: import java.io.ByteArrayInputStream;
022: import java.io.EOFException;
023: import java.io.ByteArrayOutputStream;
024: import java.io.ObjectOutputStream;
025: import java.util.List;
026: import java.util.ArrayList;
027: import java.util.Collection;
028: import java.util.Collections;
029: import java.util.Iterator;
030:
031: import org.apache.geronimo.gbean.GBeanData;
032: import org.apache.geronimo.gbean.GBeanInfo;
033: import org.apache.geronimo.gbean.AbstractName;
034: import org.apache.geronimo.kernel.Naming;
035: import org.apache.geronimo.kernel.ObjectInputStreamExt;
036: import org.apache.geronimo.kernel.repository.Environment;
037:
038: /**
039: * @version $Rev: 510752 $ $Date: 2007-02-22 17:27:16 -0800 (Thu, 22 Feb 2007) $
040: */
041: public class SerializedGBeanState implements GBeanState, Serializable {
042: private static final long serialVersionUID = 6015138334529564307L;
043:
044: /**
045: * GBeans contained in this configuration.
046: */
047: private final List gbeans = new ArrayList();
048:
049: /**
050: * The serialized form of the gbeans. Once this is set on more gbeans can be added.
051: */
052: private byte[] gbeanState;
053:
054: public SerializedGBeanState(Collection gbeans) {
055: if (gbeans != null) {
056: this .gbeans.addAll(gbeans);
057: }
058: }
059:
060: public List getGBeans(ClassLoader classLoader)
061: throws InvalidConfigException {
062: if (gbeanState == null) {
063: return Collections.unmodifiableList(gbeans);
064: }
065: gbeans.addAll(loadGBeans(gbeanState, classLoader));
066: return Collections.unmodifiableList(gbeans);
067: }
068:
069: public void addGBean(GBeanData gbeanData) {
070: if (gbeanState != null) {
071: throw new IllegalStateException(
072: "GBeans have been serialized, so no more GBeans can be added");
073: }
074:
075: gbeans.add(gbeanData);
076: }
077:
078: public GBeanData addGBean(String name, GBeanInfo gbeanInfo,
079: Naming naming, Environment environment) {
080: if (gbeanState != null) {
081: throw new IllegalStateException(
082: "GBeans have been serialized, so no more GBeans can be added");
083: }
084:
085: String j2eeType = gbeanInfo.getJ2eeType();
086: if (j2eeType == null)
087: j2eeType = "GBean";
088: AbstractName abstractName = naming.createRootName(environment
089: .getConfigId(), name, j2eeType);
090: GBeanData gBeanData = new GBeanData(abstractName, gbeanInfo);
091: addGBean(gBeanData);
092: return gBeanData;
093: }
094:
095: private void writeObject(java.io.ObjectOutputStream stream)
096: throws IOException {
097: if (gbeanState == null) {
098: gbeanState = storeGBeans(gbeans);
099: gbeans.clear();
100: }
101:
102: stream.defaultWriteObject();
103: }
104:
105: private static List loadGBeans(byte[] gbeanState,
106: ClassLoader classLoader) throws InvalidConfigException {
107: List gbeans = new ArrayList();
108: if (gbeanState != null && gbeanState.length > 0) {
109: // Set the thread context classloader so deserializing classes can grab the cl from the thread
110: ClassLoader oldCl = Thread.currentThread()
111: .getContextClassLoader();
112: try {
113: Thread.currentThread().setContextClassLoader(
114: classLoader);
115:
116: ObjectInputStream ois = new ObjectInputStreamExt(
117: new ByteArrayInputStream(gbeanState),
118: classLoader);
119: try {
120: while (true) {
121: GBeanData gbeanData = new GBeanData();
122: gbeanData.readExternal(ois);
123: gbeans.add(gbeanData);
124: }
125: } catch (EOFException e) {
126: // ok
127: } finally {
128: ois.close();
129: }
130: } catch (ClassNotFoundException e) {
131: throw new InvalidConfigException(
132: "Class not loadable in classloader: "
133: + classLoader, e);
134: } catch (NoClassDefFoundError e) {
135: throw new InvalidConfigException(
136: "Class not loadable in classloader: "
137: + classLoader, e);
138: } catch (Exception e) {
139: throw new InvalidConfigException(
140: "Unable to deserialize GBeanState in classloader: "
141: + classLoader, e);
142: } finally {
143: Thread.currentThread().setContextClassLoader(oldCl);
144: }
145: }
146: return gbeans;
147: }
148:
149: private static byte[] storeGBeans(List gbeans) throws IOException {
150: ByteArrayOutputStream baos = new ByteArrayOutputStream();
151: ObjectOutputStream oos;
152: try {
153: oos = new ObjectOutputStream(baos);
154: } catch (IOException e) {
155: throw (AssertionError) new AssertionError(
156: "Unable to initialize ObjectOutputStream")
157: .initCause(e);
158: }
159: for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) {
160: GBeanData gbeanData = (GBeanData) iterator.next();
161: try {
162: gbeanData.writeExternal(oos);
163: } catch (Exception e) {
164: throw (IOException) new IOException(
165: "Unable to serialize GBeanData for "
166: + gbeanData.getAbstractName())
167: .initCause(e);
168: }
169: }
170: try {
171: oos.flush();
172: } catch (IOException e) {
173: throw (AssertionError) new AssertionError(
174: "Unable to flush ObjectOutputStream").initCause(e);
175: }
176: return baos.toByteArray();
177: }
178: }
|