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