001 /**
002 *
003 * Copyright 2004 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.gbean;
018
019 import java.io.Externalizable;
020 import java.io.IOException;
021 import java.io.ObjectInput;
022 import java.io.ObjectOutput;
023 import java.util.Collections;
024 import java.util.Comparator;
025 import java.util.HashMap;
026 import java.util.HashSet;
027 import java.util.Iterator;
028 import java.util.Map;
029 import java.util.Set;
030
031 /**
032 * @version $Rev: 471683 $ $Date: 2006-11-06 02:28:54 -0800 (Mon, 06 Nov 2006) $
033 */
034 public class GBeanData implements Externalizable {
035 private static final long serialVersionUID = -1012491431781444074L;
036
037 private Externalizable backwardExternalizables[] = new Externalizable[] {
038 new V0Externalizable(),
039 new V1Externalizable()
040 };
041
042 private GBeanInfo gbeanInfo;
043 private final Map attributes;
044 private final Map references;
045 private final Set dependencies;
046 private AbstractName abstractName;
047 private int priority;
048
049 public GBeanData() {
050 attributes = new HashMap();
051 references = new HashMap();
052 dependencies = new HashSet();
053 }
054
055 public GBeanData(GBeanInfo gbeanInfo) {
056 this();
057 setGBeanInfo(gbeanInfo);
058 }
059
060 public GBeanData(AbstractName abstractName, GBeanInfo gbeanInfo) {
061 this();
062 this.abstractName = abstractName;
063 setGBeanInfo(gbeanInfo);
064 }
065
066 public GBeanData(GBeanData gbeanData) {
067 setGBeanInfo(gbeanData.gbeanInfo);
068 attributes = new HashMap(gbeanData.attributes);
069 references = new HashMap(gbeanData.references);
070 dependencies = new HashSet(gbeanData.dependencies);
071 abstractName = gbeanData.abstractName;
072 }
073
074 public AbstractName getAbstractName() {
075 return abstractName;
076 }
077
078 public void setAbstractName(AbstractName abstractName) {
079 this.abstractName = abstractName;
080 }
081
082 public GBeanInfo getGBeanInfo() {
083 return gbeanInfo;
084 }
085
086 public void clearAttribute(String name) {
087 attributes.remove(name);
088 }
089
090 public void clearReference(String name) {
091 references.remove(name);
092 }
093
094 public void setGBeanInfo(GBeanInfo gbeanInfo) {
095 this.gbeanInfo = gbeanInfo;
096 if (gbeanInfo == null) {
097 priority = GBeanInfo.PRIORITY_NORMAL;
098 } else {
099 priority = gbeanInfo.getPriority();
100 }
101 }
102
103 public Map getAttributes() {
104 return new HashMap(attributes);
105 }
106
107 public Set getAttributeNames() {
108 return new HashSet(attributes.keySet());
109 }
110
111 public Object getAttribute(String name) {
112 return attributes.get(name);
113 }
114
115 public void setAttribute(String name, Object value) {
116 attributes.put(name, value);
117 }
118
119 public Map getReferences() {
120 return new HashMap(references);
121 }
122
123 public Set getReferencesNames() {
124 return new HashSet(references.keySet());
125 }
126
127 public ReferencePatterns getReferencePatterns(String name) {
128 return (ReferencePatterns) references.get(name);
129 }
130
131 public void setReferencePattern(String name, AbstractNameQuery pattern) {
132 setReferencePatterns(name, Collections.singleton(pattern));
133 }
134
135 public void setReferencePattern(String name, AbstractName abstractName) {
136 setReferencePatterns(name, new ReferencePatterns(abstractName));
137 }
138
139 public void setReferencePatterns(String name, Set patterns) {
140 setReferencePatterns(name, new ReferencePatterns(patterns));
141 }
142
143 public void setReferencePatterns(String name, ReferencePatterns patterns) {
144 references.put(name, patterns);
145 }
146
147 public Set getDependencies() {
148 return new HashSet(dependencies);
149 }
150
151 public void setDependencies(Set dependencies) {
152 this.dependencies.clear();
153 addDependencies(dependencies);
154 }
155
156 public void addDependencies(Set dependencies) {
157 for (Iterator iterator = dependencies.iterator(); iterator.hasNext();) {
158 Object dependency = iterator.next();
159 if (dependency instanceof AbstractName) {
160 AbstractName name = (AbstractName) dependency;
161 addDependency(name);
162 } else if (dependency instanceof AbstractNameQuery) {
163 AbstractNameQuery nameQuery = (AbstractNameQuery) dependency;
164 addDependency(nameQuery);
165 } else if (dependency instanceof ReferencePatterns) {
166 ReferencePatterns referencePatterns = (ReferencePatterns) dependency;
167 addDependency(referencePatterns);
168 } else {
169 throw new IllegalArgumentException("Unknown dependency type: " + dependency);
170 }
171 }
172 }
173
174 public void addDependency(ReferencePatterns dependency) {
175 this.dependencies.add(dependency);
176 }
177
178 public void addDependency(AbstractNameQuery refInfo) {
179 this.dependencies.add(new ReferencePatterns(refInfo));
180 }
181
182 public void addDependency(AbstractName dependency) {
183 this.dependencies.add(new ReferencePatterns(dependency));
184 }
185
186 public int getPriority() {
187 return priority;
188 }
189
190 public void setPriority(int priority) {
191 this.priority = priority;
192 }
193
194 public void writeExternal(ObjectOutput out) throws IOException {
195 // write version index
196 out.writeObject(new Integer(backwardExternalizables.length -1));
197
198 // write the gbean info
199 out.writeObject(gbeanInfo);
200
201 // write the abstract name
202 out.writeObject(abstractName);
203
204 // write the priority
205 out.writeInt(priority);
206
207 // write the attributes
208 out.writeInt(attributes.size());
209 for (Iterator iterator = attributes.entrySet().iterator(); iterator.hasNext();) {
210 Map.Entry entry = (Map.Entry) iterator.next();
211 String name = (String) entry.getKey();
212 Object value = entry.getValue();
213 try {
214 out.writeObject(name);
215 out.writeObject(value);
216 } catch (IOException e) {
217 throw (IOException) new IOException("Unable to write attribute: " + name + " in gbean: " + abstractName).initCause(e);
218 } catch (NoClassDefFoundError e) {
219 throw (IOException) new IOException("Unable to write attribute: " + name + " in gbean: " + abstractName).initCause(e);
220 }
221 }
222
223 // write the references
224 out.writeInt(references.size());
225 for (Iterator iterator = references.entrySet().iterator(); iterator.hasNext();) {
226 Map.Entry entry = (Map.Entry) iterator.next();
227 String name = (String) entry.getKey();
228 ReferencePatterns value = (ReferencePatterns) entry.getValue();
229 try {
230 out.writeObject(name);
231 out.writeObject(value);
232 } catch (IOException e) {
233 throw (IOException) new IOException("Unable to write reference pattern: " + name + " in gbean: " + abstractName).initCause(e);
234 }
235 }
236 //write the dependencies
237 out.writeInt(dependencies.size());
238 for (Iterator iterator = dependencies.iterator(); iterator.hasNext();) {
239 ReferencePatterns referencePatterns = (ReferencePatterns) iterator.next();
240 try {
241 out.writeObject(referencePatterns);
242 } catch (IOException e) {
243 throw (IOException) new IOException("Unable to write dependency pattern in gbean: " + abstractName).initCause(e);
244 }
245 }
246 }
247
248
249 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
250 Object opaque = in.readObject();
251 if (opaque instanceof Integer) {
252 backwardExternalizables[((Integer) opaque).intValue()].readExternal(in);
253 } else {
254 gbeanInfo = (GBeanInfo) opaque;
255 backwardExternalizables[0].readExternal(in);
256 }
257 }
258
259 /**
260 * Note: this comparator
261 * imposes orderings that are inconsistent with equals.
262 */
263 public static class PriorityComparator implements Comparator {
264
265 public int compare(Object o1, Object o2) {
266 if (o1 instanceof GBeanData && o2 instanceof GBeanData) {
267 return ((GBeanData)o1).priority - ((GBeanData)o2).priority;
268 }
269 return 0;
270 }
271 }
272
273 private class V0Externalizable implements Externalizable {
274
275 public void writeExternal(ObjectOutput out) throws IOException {
276 throw new UnsupportedOperationException();
277 }
278
279 public final void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
280 // read the gbean info
281 readGBeanInfo(in);
282
283 // read the abstract name
284 try {
285 abstractName = (AbstractName) in.readObject();
286 } catch (IOException e) {
287 throw (IOException) new IOException("Unable to deserialize AbstractName for GBeanData of type " + gbeanInfo.getClassName()).initCause(e);
288 }
289
290 readPriority(in);
291
292 try {
293 // read the attributes
294 int attributeCount = in.readInt();
295 for (int i = 0; i < attributeCount; i++) {
296 String attributeName = (String) in.readObject();
297 Object attributeValue;
298 try {
299 attributeValue = in.readObject();
300 } catch (ClassNotFoundException e) {
301 throw new ClassNotFoundException("Unable to find class used in GBeanData " + abstractName + ", attribute: " + attributeName, e);
302 } catch (IOException e) {
303 throw (IOException) new IOException("Unable to deserialize GBeanData " + abstractName + ", attribute: " + attributeName).initCause(e);
304 }
305 setAttribute(attributeName, attributeValue);
306 }
307
308 // read the references
309 int endpointCount = in.readInt();
310 for (int i = 0; i < endpointCount; i++) {
311 String referenceName = (String) in.readObject();
312 ReferencePatterns referencePattern;
313 try {
314 referencePattern = (ReferencePatterns) in.readObject();
315 } catch (ClassNotFoundException e) {
316 throw new ClassNotFoundException("Unable to find class used in GBeanData " + abstractName + ", reference: " + referenceName, e);
317 } catch (IOException e) {
318 throw (IOException) new IOException("Unable to deserialize GBeanData " + abstractName + ", reference: " + referenceName).initCause(e);
319 }
320 setReferencePatterns(referenceName, referencePattern);
321 }
322
323 //read the dependencies
324 int dependencyCount = in.readInt();
325 for (int i = 0; i < dependencyCount; i++) {
326 ReferencePatterns depdendencyPattern = (ReferencePatterns) in.readObject();
327 dependencies.add(depdendencyPattern);
328 }
329 } catch (IOException e) {
330 throw (IOException) new IOException("Unable to deserialize GBeanData " + abstractName).initCause(e);
331 } catch (ClassNotFoundException e) {
332 throw new ClassNotFoundException("Unable to find class used in GBeanData " + abstractName, e);
333 }
334 }
335
336 protected void readGBeanInfo(ObjectInput in) throws IOException, ClassNotFoundException {
337 }
338
339 protected void readPriority(ObjectInput in) throws IOException, ClassNotFoundException {
340 priority = GBeanInfo.PRIORITY_NORMAL;
341 }
342
343 }
344
345 private class V1Externalizable extends V0Externalizable {
346
347 public void writeExternal(ObjectOutput out) throws IOException {
348 throw new UnsupportedOperationException();
349 }
350
351 protected void readGBeanInfo(ObjectInput in) throws IOException, ClassNotFoundException {
352 gbeanInfo = (GBeanInfo) in.readObject();
353 }
354
355 protected void readPriority(ObjectInput in) throws IOException, ClassNotFoundException {
356 priority = in.readInt();
357 }
358
359 }
360
361 }
362