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: */package org.apache.geronimo.kernel.config.xstream;
017:
018: import java.util.Iterator;
019: import java.util.Map;
020: import java.util.Set;
021: import java.util.LinkedHashSet;
022: import java.util.LinkedHashMap;
023: import java.net.URI;
024:
025: import com.thoughtworks.xstream.converters.Converter;
026: import com.thoughtworks.xstream.converters.MarshallingContext;
027: import com.thoughtworks.xstream.converters.UnmarshallingContext;
028: import com.thoughtworks.xstream.converters.ConversionException;
029: import com.thoughtworks.xstream.io.HierarchicalStreamReader;
030: import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
031: import com.thoughtworks.xstream.mapper.Mapper;
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.gbean.ReferencePatterns;
036:
037: /**
038: * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
039: */
040: public class GBeanDataConverter implements Converter {
041: private final Mapper mapper;
042:
043: public GBeanDataConverter(Mapper mapper) {
044: this .mapper = mapper;
045: }
046:
047: public boolean canConvert(Class clazz) {
048: return GBeanData.class.isAssignableFrom(clazz);
049: }
050:
051: public void marshal(Object object, HierarchicalStreamWriter writer,
052: MarshallingContext marshallingContext) {
053: GBeanData gbeanData = (GBeanData) object;
054:
055: // name
056: AbstractName abstractName = gbeanData.getAbstractName();
057: if (abstractName != null) {
058: writer.addAttribute("name", abstractName.toString());
059: }
060:
061: // gbeanInfo
062: GBeanInfo gbeanInfo = gbeanData.getGBeanInfo();
063: String sourceClass = gbeanInfo.getSourceClass();
064: if (sourceClass != null) {
065: writer.addAttribute("sourceClass", sourceClass);
066: } else {
067: writer.startNode("gbean-info");
068: marshallingContext.convertAnother(gbeanInfo);
069: writer.endNode();
070: }
071:
072: // dependencies Set<ReferencePatterns>
073: Set dependencies = gbeanData.getDependencies();
074: for (Iterator iterator = dependencies.iterator(); iterator
075: .hasNext();) {
076: ReferencePatterns referencePatterns = (ReferencePatterns) iterator
077: .next();
078: writer.startNode("dependency");
079: marshallingContext.convertAnother(referencePatterns);
080: writer.endNode();
081: }
082:
083: // attributes Map<String, Object>
084: Map attributes = gbeanData.getAttributes();
085: for (Iterator iterator = attributes.entrySet().iterator(); iterator
086: .hasNext();) {
087: Map.Entry entry = (Map.Entry) iterator.next();
088: String attributeName = (String) entry.getKey();
089: Object attributeValue = entry.getValue();
090: if (attributeValue != null) {
091: writer.startNode("attribute");
092: writer.addAttribute("name", attributeName);
093:
094: writer.startNode(mapper.serializedClass(attributeValue
095: .getClass()));
096: marshallingContext.convertAnother(attributeValue);
097: writer.endNode();
098:
099: writer.endNode();
100: }
101: }
102: // references Map<String, ReferencePatterns>
103: Map references = gbeanData.getReferences();
104: for (Iterator iterator = references.entrySet().iterator(); iterator
105: .hasNext();) {
106: Map.Entry entry = (Map.Entry) iterator.next();
107: String referenceName = (String) entry.getKey();
108: ReferencePatterns referencePatterns = (ReferencePatterns) entry
109: .getValue();
110: writer.startNode("reference");
111: writer.addAttribute("name", referenceName);
112: marshallingContext.convertAnother(referencePatterns);
113: writer.endNode();
114: }
115: }
116:
117: public Object unmarshal(HierarchicalStreamReader reader,
118: UnmarshallingContext unmarshallingContext) {
119: ClassLoader classLoader = Thread.currentThread()
120: .getContextClassLoader();
121: if (classLoader == null) {
122: classLoader = this .getClass().getClassLoader();
123: }
124:
125: // name
126: String gbeanName = reader.getAttribute("name");
127: AbstractName abstractName = null;
128: if (gbeanName != null) {
129: abstractName = new AbstractName(URI.create(gbeanName));
130: }
131:
132: // gbeanInfo
133: GBeanInfo gbeanInfo = null;
134: String sourceClass = reader.getAttribute("sourceClass");
135: if (sourceClass != null) {
136: gbeanInfo = GBeanInfo
137: .getGBeanInfo(sourceClass, classLoader);
138: }
139:
140: Set dependencies = new LinkedHashSet();
141: Map attributes = new LinkedHashMap();
142: Map references = new LinkedHashMap();
143: while (reader.hasMoreChildren()) {
144: reader.moveDown();
145:
146: String nodeName = reader.getNodeName();
147: if (nodeName.equals("gbean-info")) {
148: if (gbeanInfo != null) {
149: throw new ConversionException(
150: "GBean info declared more than once in gbean "
151: + abstractName);
152: }
153: gbeanInfo = (GBeanInfo) unmarshallingContext
154: .convertAnother(reader, GBeanInfo.class);
155: } else if (nodeName.equals("dependency")) {
156: ReferencePatterns referencePatterns = (ReferencePatterns) unmarshallingContext
157: .convertAnother(reader, ReferencePatterns.class);
158: dependencies.add(referencePatterns);
159: } else if (nodeName.equals("attribute")) {
160: String attributeName = reader.getAttribute("name");
161:
162: reader.moveDown();
163: String classAttribute = reader.getAttribute(mapper
164: .attributeForImplementationClass());
165: Class type;
166: if (classAttribute == null) {
167: type = mapper.realClass(reader.getNodeName());
168: } else {
169: type = mapper.realClass(classAttribute);
170: }
171: Object attributeValue = unmarshallingContext
172: .convertAnother(reader, type);
173: reader.moveUp();
174:
175: attributes.put(attributeName, attributeValue);
176: } else if (nodeName.equals("reference")) {
177: String referenceName = reader.getAttribute("name");
178: ReferencePatterns referencePatterns = (ReferencePatterns) unmarshallingContext
179: .convertAnother(reader, ReferencePatterns.class);
180: references.put(referenceName, referencePatterns);
181: } else {
182: throw new ConversionException(
183: "Unknown nested node in GBean: " + nodeName);
184: }
185:
186: reader.moveUp();
187: }
188:
189: if (gbeanInfo == null) {
190: throw new ConversionException(
191: "GBean info not declared in gbean " + abstractName);
192: }
193:
194: GBeanData gbeanData = new GBeanData(abstractName, gbeanInfo);
195: gbeanData.setDependencies(dependencies);
196: for (Iterator iterator = attributes.entrySet().iterator(); iterator
197: .hasNext();) {
198: Map.Entry entry = (Map.Entry) iterator.next();
199: String attributeName = (String) entry.getKey();
200: Object attributeValue = entry.getValue();
201: gbeanData.setAttribute(attributeName, attributeValue);
202: }
203: for (Iterator iterator = references.entrySet().iterator(); iterator
204: .hasNext();) {
205: Map.Entry entry = (Map.Entry) iterator.next();
206: String referenceName = (String) entry.getKey();
207: ReferencePatterns referencePatterns = (ReferencePatterns) entry
208: .getValue();
209: gbeanData.setReferencePatterns(referenceName,
210: referencePatterns);
211: }
212:
213: return gbeanData;
214: }
215: }
|