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;
18
19 import java.io.Serializable;
20 import java.io.IOException;
21 import java.io.ObjectInputStream;
22 import java.io.ByteArrayInputStream;
23 import java.io.EOFException;
24 import java.io.ByteArrayOutputStream;
25 import java.io.ObjectOutputStream;
26 import java.util.List;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Iterator;
31
32 import org.apache.geronimo.gbean.GBeanData;
33 import org.apache.geronimo.gbean.GBeanInfo;
34 import org.apache.geronimo.gbean.AbstractName;
35 import org.apache.geronimo.kernel.Naming;
36 import org.apache.geronimo.kernel.ObjectInputStreamExt;
37 import org.apache.geronimo.kernel.repository.Environment;
38
39 /**
40 * @version $Rev: 410741 $ $Date: 2006-05-31 21:35:48 -0700 (Wed, 31 May 2006) $
41 */
42 public class SerializedGBeanState implements GBeanState, Serializable {
43 private static final long serialVersionUID = 6015138334529564307L;
44
45 /**
46 * GBeans contained in this configuration.
47 */
48 private final List gbeans = new ArrayList();
49
50 /**
51 * The serialized form of the gbeans. Once this is set on more gbeans can be added.
52 */
53 private byte[] gbeanState;
54
55 public SerializedGBeanState(Collection gbeans) {
56 if (gbeans != null){
57 this.gbeans.addAll(gbeans);
58 }
59 }
60
61 public List getGBeans(ClassLoader classLoader) throws InvalidConfigException {
62 if (gbeanState == null) {
63 return Collections.unmodifiableList(gbeans);
64 }
65 gbeans.addAll(loadGBeans(gbeanState, classLoader));
66 return Collections.unmodifiableList(gbeans);
67 }
68
69 public void addGBean(GBeanData gbeanData) {
70 if (gbeanState != null) {
71 throw new IllegalStateException("GBeans have been serialized, so no more GBeans can be added");
72 }
73
74 gbeans.add(gbeanData);
75 }
76
77 public GBeanData addGBean(String name, GBeanInfo gbeanInfo, Naming naming, Environment environment) {
78 if (gbeanState != null) {
79 throw new IllegalStateException("GBeans have been serialized, so no more GBeans can be added");
80 }
81
82 String j2eeType = gbeanInfo.getJ2eeType();
83 if (j2eeType == null) j2eeType = "GBean";
84 AbstractName abstractName = naming.createRootName(environment.getConfigId(), name, j2eeType);
85 GBeanData gBeanData = new GBeanData(abstractName, gbeanInfo);
86 addGBean(gBeanData);
87 return gBeanData;
88 }
89
90 private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
91 if (gbeanState == null) {
92 gbeanState = storeGBeans(gbeans);
93 gbeans.clear();
94 }
95
96 stream.defaultWriteObject();
97 }
98
99 private static List loadGBeans(byte[] gbeanState, ClassLoader classLoader) throws InvalidConfigException {
100 List gbeans = new ArrayList();
101 if (gbeanState != null && gbeanState.length > 0) {
102
103 ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
104 try {
105 Thread.currentThread().setContextClassLoader(classLoader);
106
107 ObjectInputStream ois = new ObjectInputStreamExt(new ByteArrayInputStream(gbeanState), classLoader);
108 try {
109 while (true) {
110 GBeanData gbeanData = new GBeanData();
111 gbeanData.readExternal(ois);
112 gbeans.add(gbeanData);
113 }
114 } catch (EOFException e) {
115
116 } finally {
117 ois.close();
118 }
119 } catch (Exception e) {
120 throw new InvalidConfigException("Unable to deserialize GBeanState", e);
121 } finally {
122 Thread.currentThread().setContextClassLoader(oldCl);
123 }
124 }
125 return gbeans;
126 }
127
128 private static byte[] storeGBeans(List gbeans) throws IOException {
129 ByteArrayOutputStream baos = new ByteArrayOutputStream();
130 ObjectOutputStream oos;
131 try {
132 oos = new ObjectOutputStream(baos);
133 } catch (IOException e) {
134 throw (AssertionError) new AssertionError("Unable to initialize ObjectOutputStream").initCause(e);
135 }
136 for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) {
137 GBeanData gbeanData = (GBeanData) iterator.next();
138 try {
139 gbeanData.writeExternal(oos);
140 } catch (Exception e) {
141 throw (IOException) new IOException("Unable to serialize GBeanData for " + gbeanData.getAbstractName()).initCause(e);
142 }
143 }
144 try {
145 oos.flush();
146 } catch (IOException e) {
147 throw (AssertionError) new AssertionError("Unable to flush ObjectOutputStream").initCause(e);
148 }
149 return baos.toByteArray();
150 }
151 }