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.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          // name
56          AbstractName abstractName = gbeanData.getAbstractName();
57          if (abstractName != null) {
58              writer.addAttribute("name", abstractName.toString());
59          }
60  
61          // gbeanInfo
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          // dependencies Set<ReferencePatterns>
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          // attributes Map<String, Object>
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          // references Map<String, ReferencePatterns>
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         // name
118         String gbeanName = reader.getAttribute("name");
119         AbstractName abstractName = null;
120         if (gbeanName != null) {
121             abstractName = new AbstractName(URI.create(gbeanName));
122         }
123 
124         // gbeanInfo
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 }