001 /** 002 * 003 * Copyright 2005 The Apache Software Foundation 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * 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 */ 017 package org.apache.geronimo.kernel.config; 018 019 import java.io.Serializable; 020 import java.io.IOException; 021 import java.io.ObjectInputStream; 022 import java.io.ByteArrayInputStream; 023 import java.io.EOFException; 024 import java.io.ByteArrayOutputStream; 025 import java.io.ObjectOutputStream; 026 import java.util.List; 027 import java.util.ArrayList; 028 import java.util.Collection; 029 import java.util.Collections; 030 import java.util.Iterator; 031 032 import org.apache.geronimo.gbean.GBeanData; 033 import org.apache.geronimo.gbean.GBeanInfo; 034 import org.apache.geronimo.gbean.AbstractName; 035 import org.apache.geronimo.kernel.Naming; 036 import org.apache.geronimo.kernel.ObjectInputStreamExt; 037 import org.apache.geronimo.kernel.repository.Environment; 038 039 /** 040 * @version $Rev: 410741 $ $Date: 2006-05-31 21:35:48 -0700 (Wed, 31 May 2006) $ 041 */ 042 public class SerializedGBeanState implements GBeanState, Serializable { 043 private static final long serialVersionUID = 6015138334529564307L; 044 045 /** 046 * GBeans contained in this configuration. 047 */ 048 private final List gbeans = new ArrayList(); 049 050 /** 051 * The serialized form of the gbeans. Once this is set on more gbeans can be added. 052 */ 053 private byte[] gbeanState; 054 055 public SerializedGBeanState(Collection gbeans) { 056 if (gbeans != null){ 057 this.gbeans.addAll(gbeans); 058 } 059 } 060 061 public List getGBeans(ClassLoader classLoader) 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("GBeans have been serialized, so no more GBeans can be added"); 072 } 073 074 gbeans.add(gbeanData); 075 } 076 077 public GBeanData addGBean(String name, GBeanInfo gbeanInfo, Naming naming, Environment environment) { 078 if (gbeanState != null) { 079 throw new IllegalStateException("GBeans have been serialized, so no more GBeans can be added"); 080 } 081 082 String j2eeType = gbeanInfo.getJ2eeType(); 083 if (j2eeType == null) j2eeType = "GBean"; 084 AbstractName abstractName = naming.createRootName(environment.getConfigId(), name, j2eeType); 085 GBeanData gBeanData = new GBeanData(abstractName, gbeanInfo); 086 addGBean(gBeanData); 087 return gBeanData; 088 } 089 090 private void writeObject(java.io.ObjectOutputStream stream) throws IOException { 091 if (gbeanState == null) { 092 gbeanState = storeGBeans(gbeans); 093 gbeans.clear(); 094 } 095 096 stream.defaultWriteObject(); 097 } 098 099 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 }