/** * PUBLIC: * Set this mapping to use Proxy Indirection. * * Proxy Indirection uses the <CODE>Proxy</CODE> and <CODE>InvocationHandler</CODE> features * of JDK 1.3 to provide "transparent indirection" for 1:1 relationships. In order to use Proxy * Indirection: * * <UL> * <LI>The target class must implement at least one public interface * <LI>The attribute on the source class must be typed as that public interface * <LI>get() and set() methods for the attribute must use the interface * </UL> * * With this policy, proxy objects are returned during object creation. When a message other than * <CODE>toString</CODE> is called on the proxy the real object data is retrieved from the database. * * @param targetInterfaces The interfaces that the target class implements. The attribute must be typed * as one of these interfaces. */ public void useProxyIndirection(Class[] targetInterfaces) { setIndirectionPolicy(new ProxyIndirectionPolicy(targetInterfaces)); }
/** * INTERNAL: * Verify that the parameter type of the attribute's set method is correct for the indirection policy. If it is * incorrect, add an exception to the integrity checker. In this case, the parameter type must be a * public interface. */ public void validateSetMethodParameterType(Class parameterType, IntegrityChecker checker) throws DescriptorException { if (!isValidType(parameterType)) { checker.handleError(DescriptorException.invalidSetMethodParameterTypeForProxyIndirection(parameterType, targetInterfaces, getMapping())); } }
/** * ADVANCED: * Return the descriptor specified for the object's class. * If the passed Object is null, null will be returned. */ public ClassDescriptor getDescriptor(Object domainObject) { if (domainObject == null) { return null; } //Bug#3947714 Check and trigger the proxy here if (this.project.hasProxyIndirection()) { return getDescriptor(ProxyIndirectionPolicy.getValueFromProxy(domainObject).getClass()); } return getDescriptor(domainObject.getClass()); }
/** * INTERNAL: * Replace the client value holder with the server value holder after copying some of the settings from * the client value holder. */ public void mergeRemoteValueHolder(Object clientSideDomainObject, Object serverSideDomainObject, MergeManager mergeManager) { getMapping().setAttributeValueInObject(clientSideDomainObject, serverSideDomainObject); }
/** * INTERNAL: * Initialize the state of mapping. */ @Override public void preInitialize(AbstractSession session) throws DescriptorException { super.preInitialize(session); //Bug#4251902 Make Proxy Indirection writable and readable to deployment xml. If ProxyIndirectionPolicy does not //have any targetInterfaces, build a new set. if ((this.indirectionPolicy instanceof ProxyIndirectionPolicy) && !((ProxyIndirectionPolicy)this.indirectionPolicy).hasTargetInterfaces()) { useProxyIndirection(); } }
/** * INTERNAL: * Return the value to be stored in the object's attribute. * This value is determined by invoking the appropriate method on the object and passing it the * row and session. */ public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) { ValueHolderInterface valueHolder = new TransformerBasedValueHolder(this.getTransformationMapping().getAttributeTransformer(), object, row, session); return ProxyIndirectionHandler.newProxyInstance(object.getClass(), targetInterfaces, valueHolder); }
/** * INTERNAL: * Return the value to be stored in the object's attribute. * This value is determined by the batch query. * * NOTE: Currently not supported anyway. */ public Object valueFromBatchQuery(ReadQuery batchQuery, AbstractRecord row, ObjectLevelReadQuery originalQuery, CacheKey parentCacheKey) { Object object; try { // Need an instance of the implementing class ClassDescriptor d = originalQuery.getDescriptor(); if (d.isDescriptorForInterface()) { d = originalQuery.getDescriptor().getInterfacePolicy().getChildDescriptors().get(0); } if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ object = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(d.getJavaClass())); }else{ object = PrivilegedAccessHelper.newInstanceFromClass(d.getJavaClass()); } } catch (Exception e) { //org.eclipse.persistence.internal.helper.Helper.toDo("*** Should probably throw some sort of TopLink exception here. ***"); e.printStackTrace(); return null; } ValueHolderInterface valueHolder = new BatchValueHolder(batchQuery, row, this.getForeignReferenceMapping(), originalQuery, parentCacheKey); return ProxyIndirectionHandler.newProxyInstance(object.getClass(), targetInterfaces, valueHolder); }
/** * INTERNAL: * Set the "real" value of the attribute to attributeValue. */ public void setRealAttributeValueInObject(Object target, Object attributeValue) { this.getMapping().setAttributeValueInObject(target, attributeValue); }
/** * INTERNAL: * Initialize the state of mapping. */ @Override public void preInitialize(AbstractSession session) throws DescriptorException { super.preInitialize(session); //Bug#4251902 Make Proxy Indirection writable and readable to deployment xml. If ProxyIndirectionPolicy does not //have any targetInterfaces, build a new set. if ((this.indirectionPolicy instanceof ProxyIndirectionPolicy) && !((ProxyIndirectionPolicy)this.indirectionPolicy).hasTargetInterfaces()) { useProxyIndirection(); } }
/** * INTERNAL: * Return the value to be stored in the object's attribute. * This value is determined by invoking the appropriate method on the object and passing it the * row and session. */ public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) { ValueHolderInterface valueHolder = new TransformerBasedValueHolder(this.getTransformationMapping().getAttributeTransformer(), object, row, session); return ProxyIndirectionHandler.newProxyInstance(object.getClass(), targetInterfaces, valueHolder); }
/** * INTERNAL: * Return the value to be stored in the object's attribute. * This value is determined by the batch query. * * NOTE: Currently not supported anyway. */ public Object valueFromBatchQuery(ReadQuery batchQuery, AbstractRecord row, ObjectLevelReadQuery originalQuery, CacheKey parentCacheKey) { Object object; try { // Need an instance of the implementing class ClassDescriptor d = originalQuery.getDescriptor(); if (d.isDescriptorForInterface()) { d = originalQuery.getDescriptor().getInterfacePolicy().getChildDescriptors().get(0); } if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ object = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(d.getJavaClass())); }else{ object = PrivilegedAccessHelper.newInstanceFromClass(d.getJavaClass()); } } catch (Exception e) { //org.eclipse.persistence.internal.helper.Helper.toDo("*** Should probably throw some sort of TopLink exception here. ***"); e.printStackTrace(); return null; } ValueHolderInterface valueHolder = new BatchValueHolder(batchQuery, row, this.getForeignReferenceMapping(), originalQuery, parentCacheKey); return ProxyIndirectionHandler.newProxyInstance(object.getClass(), targetInterfaces, valueHolder); }
/** * INTERNAL: * Verify that attribute type is correct for the indirection policy. If it is incorrect, add an exception to the * integrity checker. In this case, the attribute type must be contained in targetInterfaces. */ public void validateDeclaredAttributeType(Class attributeType, IntegrityChecker checker) throws DescriptorException { if (!isValidType(attributeType)) { checker.handleError(DescriptorException.invalidAttributeTypeForProxyIndirection(attributeType, targetInterfaces, getMapping())); } }
/** * INTERNAL: * Set the "real" value of the attribute to attributeValue. */ public void setRealAttributeValueInObject(Object target, Object attributeValue) { this.getMapping().setAttributeValueInObject(target, attributeValue); }
/** * ADVANCED: * Return the descriptor specified for the object's class. * If the passed Object is null, null will be returned. */ public ClassDescriptor getDescriptor(Object domainObject) { if (domainObject == null) { return null; } //Bug#3947714 Check and trigger the proxy here if (this.project.hasProxyIndirection()) { return getDescriptor(ProxyIndirectionPolicy.getValueFromProxy(domainObject).getClass()); } return getDescriptor(domainObject.getClass()); }
/** * PUBLIC: * Set this mapping to use Proxy Indirection. * * Proxy Indirection uses the <CODE>Proxy</CODE> and <CODE>InvocationHandler</CODE> features * of JDK 1.3 to provide "transparent indirection" for 1:1 relationships. In order to use Proxy * Indirection:<P> * * <UL> * <LI>The target class must implement at least one public interface * <LI>The attribute on the source class must be typed as that public interface * <LI>get() and set() methods for the attribute must use the interface * </UL> * * With this policy, proxy objects are returned during object creation. When a message other than * <CODE>toString</CODE> is called on the proxy the real object data is retrieved from the database. * * @param proxyInterfaces The interfaces that the target class implements. The attribute must be typed * as one of these interfaces. */ public void useProxyIndirection(Class[] targetInterfaces) { setIndirectionPolicy(new ProxyIndirectionPolicy(targetInterfaces)); }
/** * INTERNAL: * Initialize the state of mapping. */ public void preInitialize(AbstractSession session) throws DescriptorException { super.preInitialize(session); //Bug#4251902 Make Proxy Indirection writable and readable to deployment xml. If ProxyIndirectionPolicy does not //have any targetInterfaces, build a new set. if ((this.indirectionPolicy instanceof ProxyIndirectionPolicy) && !((ProxyIndirectionPolicy)this.indirectionPolicy).hasTargetInterfaces()) { useProxyIndirection(); } }
/** * INTERNAL: * Return the value to be stored in the object's attribute. * This value is determined by invoking the appropriate method on the object and passing it the * row and session. */ public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) { ValueHolderInterface valueHolder = new TransformerBasedValueHolder(this.getTransformationMapping().getAttributeTransformer(), object, row, session); return ProxyIndirectionHandler.newProxyInstance(object.getClass(), targetInterfaces, valueHolder); }
/** * INTERNAL: * Return the value to be stored in the object's attribute. * This value is determined by the batch query. * * NOTE: Currently not supported anyway. */ public Object valueFromBatchQuery(ReadQuery batchQuery, AbstractRecord row, ObjectLevelReadQuery originalQuery) { Object object; try { // Need an instance of the implementing class ClassDescriptor d = originalQuery.getDescriptor(); if (d.isDescriptorForInterface()) { d = (ClassDescriptor)originalQuery.getDescriptor().getInterfacePolicy().getChildDescriptors().firstElement(); } if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ object = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass(d.getJavaClass())); }else{ object = PrivilegedAccessHelper.newInstanceFromClass(d.getJavaClass()); } } catch (Exception e) { //org.eclipse.persistence.internal.helper.Helper.toDo("*** Should probably throw some sort of TopLink exception here. ***"); e.printStackTrace(); return null; } ValueHolderInterface valueHolder = new BatchValueHolder(batchQuery, row, this.getForeignReferenceMapping(), originalQuery); return ProxyIndirectionHandler.newProxyInstance(object.getClass(), targetInterfaces, valueHolder); }
/** * INTERNAL: * Verify that attribute type is correct for the indirection policy. If it is incorrect, add an exception to the * integrity checker. In this case, the attribute type must be contained in targetInterfaces. */ public void validateDeclaredAttributeType(Class attributeType, IntegrityChecker checker) throws DescriptorException { if (!isValidType(attributeType)) { checker.handleError(DescriptorException.invalidAttributeTypeForProxyIndirection(attributeType, targetInterfaces, getMapping())); } }
/** * INTERNAL: * Replace the client value holder with the server value holder after copying some of the settings from * the client value holder. */ public void mergeRemoteValueHolder(Object clientSideDomainObject, Object serverSideDomainObject, MergeManager mergeManager) { getMapping().setAttributeValueInObject(clientSideDomainObject, serverSideDomainObject); }