1 21 package oracle.toplink.essentials.internal.queryframework; 23 24 import java.security.AccessController ; 25 import java.security.PrivilegedActionException ; 26 import java.util.*; 27 import java.lang.reflect.*; 28 29 import oracle.toplink.essentials.exceptions.*; 30 import oracle.toplink.essentials.internal.ejb.cmp3.base.CMP3Policy; 31 import oracle.toplink.essentials.internal.helper.*; 32 import oracle.toplink.essentials.queryframework.DatabaseQuery; 33 import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper; 34 import oracle.toplink.essentials.internal.security.PrivilegedClassForName; 35 import oracle.toplink.essentials.internal.security.PrivilegedMethodInvoker; 36 import oracle.toplink.essentials.internal.security.PrivilegedGetValueFromField; 37 import oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl; 38 import oracle.toplink.essentials.internal.sessions.AbstractSession; 39 40 50 public class MapContainerPolicy extends InterfaceContainerPolicy { 51 protected String keyName; 52 protected String elementClassName; 53 protected Class elementClass; 54 protected transient Field keyField; 55 protected transient Method keyMethod; 56 57 61 public MapContainerPolicy() { 62 super(); 63 } 64 65 69 public MapContainerPolicy(Class containerClass) { 70 super(containerClass); 71 } 72 73 77 public MapContainerPolicy(String containerClassName) { 78 super(containerClassName); 79 } 80 81 85 public void prepare(DatabaseQuery query, AbstractSession session) throws QueryException { 86 if ((getElementClass() == null) && (query.getDescriptor() != null)) { 87 setElementClass(query.getDescriptor().getJavaClass()); 88 } 89 90 super.prepare(query, session); 91 } 92 93 97 public boolean addInto(Object key, Object element, Object container, AbstractSession session) { 98 Object wrapped = element; 99 100 if (hasElementDescriptor()) { 101 wrapped = getElementDescriptor().getObjectBuilder().wrapObject(element, session); 102 } 103 104 try { 105 if (key != null) { 106 return ((Map) container).put(key, wrapped) != null; 107 } else { 108 return ((Map) container).put(keyFrom(element, session), wrapped) != null; 109 } 110 } catch (ClassCastException ex1) { 111 throw QueryException.mapKeyNotComparable(element, container); 112 } 113 } 114 115 119 public void clear(Object container) { 120 try { 121 ((Map)container).clear(); 122 } catch (UnsupportedOperationException ex) { 123 throw QueryException.methodNotValid(container, "clear()"); 124 } 125 } 126 127 132 public boolean compareKeys(Object sourceValue, AbstractSession session) { 133 Object backUpVersion = null; 134 135 if (((UnitOfWorkImpl)session).isClassReadOnly(sourceValue.getClass())) { 136 backUpVersion = ((UnitOfWorkImpl)session).getOriginalVersionOfObject(sourceValue); 137 } else { 138 backUpVersion = ((UnitOfWorkImpl)session).getBackupClone(sourceValue); 139 } 140 141 return (keyFrom(backUpVersion, session).equals(keyFrom(sourceValue, session))); 142 } 143 144 149 protected boolean contains(Object element, Object container) { 150 return ((Map)container).containsValue(element); 151 } 152 153 160 public void convertClassNamesToClasses(ClassLoader classLoader){ 161 super.convertClassNamesToClasses(classLoader); 162 163 if (elementClassName == null){ 164 return; 165 } 166 167 try { 168 Class elementClass = null; 169 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 170 try { 171 elementClass = (Class )AccessController.doPrivileged(new PrivilegedClassForName(elementClassName, true, classLoader)); 172 } catch (PrivilegedActionException exception) { 173 throw ValidationException.classNotFoundWhileConvertingClassNames(containerClassName, exception.getException()); 174 } 175 } else { 176 elementClass = oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getClassForName(elementClassName, true, classLoader); 177 } 178 setElementClass(elementClass); 179 } catch (ClassNotFoundException exc){ 180 throw ValidationException.classNotFoundWhileConvertingClassNames(containerClassName, exc); 181 } 182 } 183 184 188 public Class getElementClass() { 189 return elementClass; 190 } 191 192 196 public String getElementClassName() { 197 return elementClassName; 198 } 199 200 203 public Class getInterfaceType() { 204 return ClassConstants.Map_Class; 205 } 206 207 212 public String getKeyName() { 213 return keyName; 214 } 215 216 220 public boolean isMapPolicy() { 221 return true; 222 } 223 224 228 public Object iteratorFor(Object container) { 229 return ((Map)container).values().iterator(); 230 } 231 232 236 public Object keyFrom(Object element, AbstractSession session) { 237 if (keyName != null && keyMethod == null && keyField == null) { 239 try { 240 keyMethod = Helper.getDeclaredMethod(elementClass, keyName, (Class []) null); 241 } catch (NoSuchMethodException ex) { 242 try { 243 keyField = Helper.getField(elementClass, keyName); 244 } catch (NoSuchFieldException e) { 245 throw ValidationException.mapKeyNotDeclaredInItemClass(keyName, elementClass); 246 } 247 } 248 } 249 250 Object keyElement = element; 251 252 if (hasElementDescriptor()) { 253 keyElement = getElementDescriptor().getObjectBuilder().unwrapObject(element, session); 254 } 255 256 if (keyMethod != null) { 257 try { 258 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 259 try { 260 return AccessController.doPrivileged(new PrivilegedMethodInvoker(keyMethod, keyElement, (Object [])null)); 261 } catch (PrivilegedActionException exception) { 262 Exception throwableException = exception.getException(); 263 if (throwableException instanceof IllegalAccessException ) { 264 throw QueryException.cannotAccessMethodOnObject(keyMethod, keyElement); 265 } else { 266 throw QueryException.calledMethodThrewException(keyMethod, keyElement, throwableException); 267 } 268 } 269 } else { 270 return PrivilegedAccessHelper.invokeMethod(keyMethod, keyElement, (Object [])null); 271 } 272 } catch (IllegalAccessException e) { 273 throw QueryException.cannotAccessMethodOnObject(keyMethod, keyElement); 274 } catch (InvocationTargetException exception) { 275 throw QueryException.calledMethodThrewException(keyMethod, keyElement, exception); 276 } 277 } else if (keyField != null) { 278 try { 279 if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ 280 try { 281 return AccessController.doPrivileged(new PrivilegedGetValueFromField(keyField, keyElement)); 282 } catch (PrivilegedActionException exception) { 283 throw QueryException.cannotAccessFieldOnObject(keyField, keyElement); 284 } 285 } else { 286 return oracle.toplink.essentials.internal.security.PrivilegedAccessHelper.getValueFromField(keyField, keyElement); 287 } 288 } catch (IllegalAccessException e) { 289 throw QueryException.cannotAccessFieldOnObject(keyField, keyElement); 290 } 291 } else { 292 return ((CMP3Policy) getElementDescriptor().getCMPPolicy()).createPrimaryKeyInstance(keyElement, session); 295 } 296 } 297 298 302 public boolean removeFrom(Object key, Object element, Object container, AbstractSession session) { 303 try { 304 Object returnValue = null; 305 if (key != null) { 306 returnValue = ((Map)container).remove(key); 307 } else { 308 returnValue = ((Map)container).remove(keyFrom(element, session)); 309 } 310 if (returnValue == null) { 311 return false; 312 } else { 313 return true; 314 } 315 } catch (UnsupportedOperationException ex) { 316 throw QueryException.methodNotValid(container, "remove(Object element)"); 317 } 318 } 319 320 324 public boolean removeFromWithIdentity(Object element, Object container, AbstractSession session) { 325 boolean found = false; 326 Vector knownKeys = new Vector(1); 327 try { 328 Iterator iterator = ((Map)container).keySet().iterator(); 329 while (iterator.hasNext()) { 330 Object key = iterator.next(); 331 if (((Map)container).get(key) == element) { 332 knownKeys.addElement(key); 333 found = true; 334 } 335 } 336 if (found) { 337 for (int index = 0; index < knownKeys.size(); ++index) { 338 ((Map)container).remove(knownKeys.elementAt(index)); 339 } 340 } 341 return found; 342 } catch (UnsupportedOperationException ex) { 343 throw QueryException.methodNotValid(container, "remove(Object element)"); 344 } 345 } 346 347 351 public void setElementClass(Class elementClass) { 352 if (elementClass != null) { 353 elementClassName = elementClass.getName(); 354 } 355 356 this.elementClass = elementClass; 357 } 358 359 363 public boolean isValidContainer(Object container) { 364 return container instanceof Map; 367 } 368 369 374 public void setKeyName(String keyName, String elementClassName) { 375 this.keyName = keyName; 378 this.elementClassName = elementClassName; 379 } 380 381 386 public void setKeyName(String keyName) { 387 this.keyName = keyName; 388 } 389 390 394 public int sizeFor(Object container) { 395 return ((Map)container).size(); 396 } 397 398 402 public void validateElementAndRehashIfRequired(Object sourceValue, Object targetMap, AbstractSession session, Object targetVersionOfSource) { 403 if (session.isUnitOfWork()) { 404 Object backupValue = ((UnitOfWorkImpl)session).getBackupClone(sourceValue); 406 if (!keyFrom(backupValue, session).equals(keyFrom(sourceValue, session))) { 407 removeFrom(backupValue, targetMap, session); 409 addInto(targetVersionOfSource, targetMap, session); 410 } 411 } 412 } 413 } 414 | Popular Tags |