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;
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             // Set the thread context classloader so deserializing classes can grab the cl from the thread
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                     // ok
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 }