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 */ 017 package org.apache.geronimo.kernel.config.xstream; 018 019 import java.io.IOException; 020 import java.util.ArrayList; 021 import java.util.Arrays; 022 import java.util.Collection; 023 import java.util.Collections; 024 import java.util.List; 025 import javax.xml.parsers.DocumentBuilder; 026 import javax.xml.parsers.DocumentBuilderFactory; 027 import javax.xml.parsers.ParserConfigurationException; 028 029 import com.thoughtworks.xstream.XStream; 030 import com.thoughtworks.xstream.io.xml.DomReader; 031 import com.thoughtworks.xstream.io.xml.DomWriter; 032 import org.apache.geronimo.gbean.AbstractName; 033 import org.apache.geronimo.gbean.GBeanData; 034 import org.apache.geronimo.gbean.GBeanInfo; 035 import org.apache.geronimo.kernel.Naming; 036 import org.apache.geronimo.kernel.util.XmlUtil; 037 import org.apache.geronimo.kernel.config.InvalidConfigException; 038 import org.apache.geronimo.kernel.config.GBeanState; 039 import org.apache.geronimo.kernel.repository.Environment; 040 import org.w3c.dom.Document; 041 import org.w3c.dom.Element; 042 043 /** 044 * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $ 045 */ 046 public class XStreamGBeanState implements GBeanState { 047 /** 048 * GBeans contained in this configuration. 049 */ 050 private final List gbeans = new ArrayList(); 051 052 /** 053 * The serialized form of the gbeans. Once this is set on more gbeans can be added. 054 */ 055 private Element gbeanState; 056 057 public XStreamGBeanState(Element gbeanState) { 058 this.gbeanState = gbeanState; 059 } 060 061 public XStreamGBeanState(Collection gbeans) { 062 if (gbeans != null){ 063 this.gbeans.addAll(gbeans); 064 } 065 } 066 067 public Element getGBeanState() throws IOException { 068 if (gbeanState == null) { 069 gbeanState = XStreamGBeanState.storeGBeans(gbeans); 070 gbeans.clear(); 071 } 072 return gbeanState; 073 } 074 075 public List getGBeans(ClassLoader classLoader) throws InvalidConfigException { 076 if (gbeanState == null) { 077 return Collections.unmodifiableList(gbeans); 078 } 079 gbeans.addAll(XStreamGBeanState.loadGBeans(gbeanState, classLoader)); 080 return Collections.unmodifiableList(gbeans); 081 } 082 083 public void addGBean(GBeanData gbeanData) { 084 if (gbeanState != null) { 085 throw new IllegalStateException("GBeans have been serialized, so no more GBeans can be added"); 086 } 087 088 gbeans.add(gbeanData); 089 } 090 091 public GBeanData addGBean(String name, GBeanInfo gbeanInfo, Naming naming, Environment environment) { 092 if (gbeanState != null) { 093 throw new IllegalStateException("GBeans have been serialized, so no more GBeans can be added"); 094 } 095 096 String j2eeType = gbeanInfo.getJ2eeType(); 097 if (j2eeType == null) j2eeType = "GBean"; 098 AbstractName abstractName = naming.createRootName(environment.getConfigId(), name, j2eeType); 099 GBeanData gBeanData = new GBeanData(abstractName, gbeanInfo); 100 addGBean(gBeanData); 101 return gBeanData; 102 } 103 104 private static List loadGBeans(Element element, ClassLoader classLoader) throws InvalidConfigException { 105 if (element != null) { 106 // Set the thread context classloader so deserializing classes can grab the cl from the thread 107 ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); 108 try { 109 Thread.currentThread().setContextClassLoader(classLoader); 110 111 DomReader reader = new DomReader(element); 112 XStream xstream = XStreamUtil.createXStream(); 113 xstream.setClassLoader(classLoader); 114 Object o = xstream.unmarshal(reader); 115 GBeanData[] gbeanDatas = (GBeanData[]) o; 116 return Arrays.asList(gbeanDatas); 117 } catch (Exception e) { 118 throw new InvalidConfigException("Unable to load gbeans", e); 119 } finally { 120 Thread.currentThread().setContextClassLoader(oldCl); 121 } 122 } 123 return Collections.EMPTY_LIST; 124 } 125 126 private static Element storeGBeans(List gbeans) throws IOException { 127 GBeanData[] gbeanDatas = (GBeanData[]) gbeans.toArray(new GBeanData[gbeans.size()]); 128 129 DocumentBuilderFactory documentBuilderFactory = XmlUtil.newDocumentBuilderFactory(); 130 DocumentBuilder documentBuilder = null; 131 try { 132 documentBuilder = documentBuilderFactory.newDocumentBuilder(); 133 } catch (ParserConfigurationException e) { 134 throw (IOException)new IOException("Cannot instantiate " + Document.class.getName()).initCause(e); 135 } 136 Document document = documentBuilder.newDocument(); 137 DomWriter writer = new DomWriter(document); 138 139 XStream xstream = XStreamUtil.createXStream(); 140 xstream.marshal(gbeanDatas, writer); 141 142 // FileWriter w = new FileWriter("target/foo.xml"); 143 // xstream.toXML(gbeanDatas, w); 144 // w.close(); 145 146 return document.getDocumentElement(); 147 } 148 }