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.xstream;
18
19 import java.util.Iterator;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.LinkedHashSet;
23 import java.util.LinkedHashMap;
24 import java.net.URI;
25
26 import com.thoughtworks.xstream.converters.Converter;
27 import com.thoughtworks.xstream.converters.MarshallingContext;
28 import com.thoughtworks.xstream.converters.UnmarshallingContext;
29 import com.thoughtworks.xstream.converters.ConversionException;
30 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
31 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
32 import com.thoughtworks.xstream.mapper.Mapper;
33 import org.apache.geronimo.gbean.AbstractName;
34 import org.apache.geronimo.gbean.GBeanData;
35 import org.apache.geronimo.gbean.GBeanInfo;
36 import org.apache.geronimo.gbean.ReferencePatterns;
37
38 /**
39 * @version $Rev: 410741 $ $Date: 2006-05-31 21:35:48 -0700 (Wed, 31 May 2006) $
40 */
41 public class GBeanDataConverter implements Converter {
42 private final Mapper mapper;
43
44 public GBeanDataConverter(Mapper mapper) {
45 this.mapper = mapper;
46 }
47
48 public boolean canConvert(Class clazz) {
49 return GBeanData.class.isAssignableFrom(clazz);
50 }
51
52 public void marshal(Object object, HierarchicalStreamWriter writer, MarshallingContext marshallingContext) {
53 GBeanData gbeanData = (GBeanData) object;
54
55
56 AbstractName abstractName = gbeanData.getAbstractName();
57 if (abstractName != null) {
58 writer.addAttribute("name", abstractName.toString());
59 }
60
61
62 GBeanInfo gbeanInfo = gbeanData.getGBeanInfo();
63 String sourceClass = gbeanInfo.getSourceClass();
64 if (sourceClass != null) {
65 writer.addAttribute("sourceClass", sourceClass);
66 } else {
67 writer.startNode("gbean-info");
68 marshallingContext.convertAnother(gbeanInfo);
69 writer.endNode();
70 }
71
72
73 Set dependencies = gbeanData.getDependencies();
74 for (Iterator iterator = dependencies.iterator(); iterator.hasNext();) {
75 ReferencePatterns referencePatterns = (ReferencePatterns) iterator.next();
76 writer.startNode("dependency");
77 marshallingContext.convertAnother(referencePatterns);
78 writer.endNode();
79 }
80
81
82 Map attributes = gbeanData.getAttributes();
83 for (Iterator iterator = attributes.entrySet().iterator(); iterator.hasNext();) {
84 Map.Entry entry = (Map.Entry) iterator.next();
85 String attributeName = (String) entry.getKey();
86 Object attributeValue = entry.getValue();
87 if (attributeValue != null) {
88 writer.startNode("attribute");
89 writer.addAttribute("name", attributeName);
90
91 writer.startNode(mapper.serializedClass(attributeValue.getClass()));
92 marshallingContext.convertAnother(attributeValue);
93 writer.endNode();
94
95 writer.endNode();
96 }
97 }
98
99 Map references = gbeanData.getReferences();
100 for (Iterator iterator = references.entrySet().iterator(); iterator.hasNext();) {
101 Map.Entry entry = (Map.Entry) iterator.next();
102 String referenceName = (String) entry.getKey();
103 ReferencePatterns referencePatterns = (ReferencePatterns) entry.getValue();
104 writer.startNode("reference");
105 writer.addAttribute("name", referenceName);
106 marshallingContext.convertAnother(referencePatterns);
107 writer.endNode();
108 }
109 }
110
111 public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext unmarshallingContext) {
112 ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
113 if (classLoader == null) {
114 classLoader = this.getClass().getClassLoader();
115 }
116
117
118 String gbeanName = reader.getAttribute("name");
119 AbstractName abstractName = null;
120 if (gbeanName != null) {
121 abstractName = new AbstractName(URI.create(gbeanName));
122 }
123
124
125 GBeanInfo gbeanInfo = null;
126 String sourceClass = reader.getAttribute("sourceClass");
127 if (sourceClass != null) {
128 gbeanInfo = GBeanInfo.getGBeanInfo(sourceClass, classLoader);
129 }
130
131 Set dependencies = new LinkedHashSet();
132 Map attributes = new LinkedHashMap();
133 Map references = new LinkedHashMap();
134 while (reader.hasMoreChildren()) {
135 reader.moveDown();
136
137 String nodeName = reader.getNodeName();
138 if (nodeName.equals("gbean-info")) {
139 if (gbeanInfo != null) {
140 throw new ConversionException("GBean info declared more than once in gbean " + abstractName);
141 }
142 gbeanInfo = (GBeanInfo) unmarshallingContext.convertAnother(reader, GBeanInfo.class);
143 } else if (nodeName.equals("dependency")) {
144 ReferencePatterns referencePatterns = (ReferencePatterns) unmarshallingContext.convertAnother(reader, ReferencePatterns.class);
145 dependencies.add(referencePatterns);
146 } else if (nodeName.equals("attribute")) {
147 String attributeName = reader.getAttribute("name");
148
149 reader.moveDown();
150 String classAttribute = reader.getAttribute(mapper.attributeForImplementationClass());
151 Class type;
152 if (classAttribute == null) {
153 type = mapper.realClass(reader.getNodeName());
154 } else {
155 type = mapper.realClass(classAttribute);
156 }
157 Object attributeValue = unmarshallingContext.convertAnother(reader, type);
158 reader.moveUp();
159
160 attributes.put(attributeName, attributeValue);
161 } else if (nodeName.equals("reference")) {
162 String referenceName = reader.getAttribute("name");
163 ReferencePatterns referencePatterns = (ReferencePatterns) unmarshallingContext.convertAnother(reader, ReferencePatterns.class);
164 references.put(referenceName, referencePatterns);
165 } else {
166 throw new ConversionException("Unknown nested node in GBean: " + nodeName);
167 }
168
169 reader.moveUp();
170 }
171
172 if (gbeanInfo == null) {
173 throw new ConversionException("GBean info not declared in gbean " + abstractName);
174 }
175
176 GBeanData gbeanData = new GBeanData(abstractName, gbeanInfo);
177 gbeanData.setDependencies(dependencies);
178 for (Iterator iterator = attributes.entrySet().iterator(); iterator.hasNext();) {
179 Map.Entry entry = (Map.Entry) iterator.next();
180 String attributeName = (String) entry.getKey();
181 Object attributeValue = entry.getValue();
182 gbeanData.setAttribute(attributeName, attributeValue);
183 }
184 for (Iterator iterator = references.entrySet().iterator(); iterator.hasNext();) {
185 Map.Entry entry = (Map.Entry) iterator.next();
186 String referenceName = (String) entry.getKey();
187 ReferencePatterns referencePatterns = (ReferencePatterns) entry.getValue();
188 gbeanData.setReferencePatterns(referenceName, referencePatterns);
189 }
190
191 return gbeanData;
192 }
193 }