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