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