1 22 package org.jboss.iiop.rmi; 23 24 import org.omg.CORBA.portable.IDLEntity ; 25 import org.omg.CORBA.portable.ValueBase ; 26 27 import java.rmi.Remote ; 28 29 import java.io.Serializable ; 30 import java.io.Externalizable ; 31 import java.io.ObjectStreamField ; 32 33 import java.util.ArrayList ; 34 import java.util.SortedSet ; 35 import java.util.TreeSet ; 36 import java.util.Comparator ; 37 38 import java.lang.reflect.Method ; 39 import java.lang.reflect.Field ; 40 import java.lang.reflect.Modifier ; 41 42 51 public class ValueAnalysis 52 extends ContainerAnalysis 53 { 54 56 58 60 private static final org.jboss.logging.Logger logger = 61 org.jboss.logging.Logger.getLogger(ValueAnalysis.class); 62 63 private static WorkCacheManager cache 64 = new WorkCacheManager(ValueAnalysis.class); 65 66 public static ValueAnalysis getValueAnalysis(Class cls) 67 throws RMIIIOPViolationException 68 { 69 return (ValueAnalysis)cache.getAnalysis(cls); 70 } 71 72 74 protected ValueAnalysis(Class cls) 75 { 76 super(cls); 77 logger.debug("ValueAnalysis(\""+cls.getName()+"\") entered."); 78 } 79 80 public String getIDLModuleName() 81 { 82 String result = super.getIDLModuleName(); 83 84 Class clazz = getCls(); 86 if (IDLEntity .class.isAssignableFrom(clazz) && ValueBase .class.isAssignableFrom(clazz) == false) 87 result = "::org::omg::boxedIDL" + result; 88 return result; 89 } 90 91 protected void doAnalyze() 92 throws RMIIIOPViolationException 93 { 94 super.doAnalyze(); 95 96 if (cls == String .class) 97 throw new IllegalArgumentException ( 98 "Cannot analyze java.lang.String here: It is a " + 99 "special case."); 101 if (cls == Class .class) 102 throw new IllegalArgumentException ( 103 "Cannot analyze java.lang.Class here: It is a " + 104 "special case."); 106 if (Remote .class.isAssignableFrom(cls)) 107 throw new RMIIIOPViolationException( 108 "Value type " + cls.getName() + 109 " cannot implement java.rmi.Remote.", "1.2.4"); 110 111 if (cls.getName().indexOf('$') != -1) 112 throw new RMIIIOPNotImplementedException( 113 "Class " + cls.getName() + " has a '$', like " + 114 "proxies or inner classes."); 115 116 externalizable = Externalizable .class.isAssignableFrom(cls); 117 118 if (!externalizable) { 119 Field spf = null; 121 try { 122 spf = cls.getField("serialPersistentFields"); 123 } catch (NoSuchFieldException ex) { 124 } 126 if (spf != null) { int mods = spf.getModifiers(); 128 if (!Modifier.isFinal(mods) || !Modifier.isStatic(mods) || 129 !Modifier.isPrivate(mods)) 130 spf = null; } 132 if (spf != null) { Class type = spf.getType(); 134 if (type.isArray()) { 135 type = type.getComponentType(); 136 if (type != ObjectStreamField .class) 137 spf = null; } else 139 spf = null; } 141 if (spf != null) { 142 144 try { 146 serialPersistentFields = (ObjectStreamField [])spf.get(null); 147 } catch (IllegalAccessException ex) { 148 throw new RuntimeException ("Unexpected IllegalException: " + 149 ex.toString()); 150 } 151 152 for (int i = 0; i < fields.length; ++i) { 154 if (fields[i] == spf) { 155 f_flags[i] |= F_SPFFIELD; 156 break; 157 } 158 } 159 } 160 161 Method wo = null; 163 try { 164 wo = cls.getMethod("writeObject", 165 new Class [] {java.io.OutputStream [].class} ); 166 } catch (NoSuchMethodException ex) { 167 } 169 if (wo != null) { if (wo.getReturnType() != Void.TYPE) 171 wo = null; } 173 if (wo != null) { int mods = spf.getModifiers(); 175 if (!Modifier.isPrivate(mods)) 176 wo = null; } 178 if (wo != null) { Class [] paramTypes = wo.getParameterTypes(); 180 if (paramTypes.length != 1) 181 wo = null; else if (paramTypes[0] != java.io.OutputStream .class) 183 wo = null; } 185 if (wo != null) { 186 hasWriteObjectMethod = true; 188 189 for (int i = 0; i < methods.length; ++i) { 191 if (methods[i] == wo) { 192 m_flags[i] |= M_WRITEOBJECT; 193 break; 194 } 195 } 196 } 197 } 198 199 SortedSet m = new TreeSet (new ValueMemberComparator()); 201 202 logger.debug("ValueAnalysis(\""+cls.getName()+"\"): " + 203 "fields.length="+fields.length); 204 for (int i = 0; i < fields.length; ++i) { 205 logger.debug("ValueAnalysis(\""+cls.getName()+"\"): " + 206 "Considering field["+i+"] \"" + fields[i].getName() + 207 "\"" + " f_flags=" + f_flags[i]); 208 if (f_flags[i] != 0) 209 continue; 211 int mods = fields[i].getModifiers(); 212 logger.debug("ValueAnalysis(\""+cls.getName()+"\"): mods=" + mods); 213 if (Modifier.isStatic(mods) || Modifier.isTransient(mods)) 214 continue; 216 ValueMemberAnalysis vma; 217 vma = new ValueMemberAnalysis(fields[i].getName(), 218 fields[i].getType(), 219 Modifier.isPublic(mods)); 220 m.add(vma); 221 } 222 223 members = new ValueMemberAnalysis[m.size()]; 224 members = (ValueMemberAnalysis[])m.toArray(members); 225 logger.debug("ValueAnalysis(\""+cls.getName()+"\") value member count: " 226 + members.length); 227 228 Class superClass = cls.getSuperclass(); 230 if (superClass == java.lang.Object .class) 231 superClass = null; 232 if (superClass == null) 233 superAnalysis = null; 234 else { 235 logger.debug("ValueAnalysis(\""+cls.getName()+"\"): superclass: " + 236 superClass.getName()); 237 superAnalysis = getValueAnalysis(superClass); 238 } 239 240 if (!Serializable .class.isAssignableFrom(cls)) 241 abstractValue = true; 242 243 fixupCaseNames(); 244 245 logger.debug("ValueAnalysis(\""+cls.getName()+"\") done."); 246 } 247 248 250 254 public ValueAnalysis getSuperAnalysis() 255 { 256 return superAnalysis; 257 } 258 259 262 public boolean isAbstractValue() 263 { 264 return abstractValue; 265 } 266 267 270 public boolean isCustom() 271 { 272 return externalizable || hasWriteObjectMethod; 273 } 274 275 278 public boolean isExternalizable() 279 { 280 return externalizable; 281 } 282 283 286 public ValueMemberAnalysis[] getMembers() 287 { 288 return (ValueMemberAnalysis[])members.clone(); 289 } 290 291 292 294 301 protected void analyzeAttributes() 302 throws RMIIIOPViolationException 303 { 304 attributes = new AttributeAnalysis[0]; 305 } 306 307 313 protected ArrayList getContainedEntries() 314 { 315 ArrayList ret = new ArrayList (constants.length + 316 attributes.length + 317 members.length); 318 319 for (int i = 0; i < constants.length; ++i) 320 ret.add(constants[i]); 321 for (int i = 0; i < attributes.length; ++i) 322 ret.add(attributes[i]); 323 for (int i = 0; i < members.length; ++i) 324 ret.add(members[i]); 325 326 return ret; 327 } 328 329 330 332 336 ValueAnalysis superAnalysis; 337 338 341 private boolean abstractValue = false; 342 343 346 private boolean externalizable = false; 347 348 351 private boolean hasWriteObjectMethod = false; 352 353 357 private ObjectStreamField [] serialPersistentFields; 358 359 362 private ValueMemberAnalysis[] members; 363 364 365 367 371 private static class ValueMemberComparator 372 implements Comparator 373 { 374 public int compare(Object o1, Object o2) 375 { 376 if (o1 == o2) 377 return 0; 378 379 ValueMemberAnalysis m1 = (ValueMemberAnalysis)o1; 380 ValueMemberAnalysis m2 = (ValueMemberAnalysis)o2; 381 382 boolean p1 = m1.getCls().isPrimitive(); 383 boolean p2 = m2.getCls().isPrimitive(); 384 385 if (p1 && !p2) 386 return -1; 387 if (!p1 && p2) 388 return 1; 389 390 return m1.getJavaName().compareTo(m2.getJavaName()); 391 } 392 } 393 } 394 | Popular Tags |