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