org.eclipse.persistence.mappings.transformers.MethodBasedFieldTransformer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.persistence.core Show documentation
Show all versions of org.eclipse.persistence.core Show documentation
EclipseLink build based upon Git transaction ecdf3c32c4
/*
* Copyright (c) 1998, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.mappings.transformers;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetMethodParameterTypes;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping;
/**
* @version $Header: MethodBasedFieldTransformer.java 18-sep-2006.16:20:59 gyorke Exp $
* @author mmacivor
* @since 10
* This class is used to preserve the old method of doing Field Transformations
* on a transformation mapping. It is used internally when the older API is used on
* a TransformationMapping, and handles doing invocations on the user's domain class
*/
public class MethodBasedFieldTransformer implements FieldTransformer {
protected transient Method fieldTransformationMethod;
protected String methodName;
protected AbstractTransformationMapping mapping;
public MethodBasedFieldTransformer(String methodName) {
this.methodName = methodName;
}
public void initialize(AbstractTransformationMapping mapping) {
this.mapping = mapping;
final Class javaClass = this.mapping.getDescriptor().getJavaClass();
try {
// look for the zero-argument version first
fieldTransformationMethod = Helper.getDeclaredMethod(javaClass, methodName, new Class[0]);
} catch (NoSuchMethodException ex) {
try {
// if the zero-argument version is not there, look for the one-argument version
Class[] methodParameterTypes = new Class[1];
methodParameterTypes[0] = ClassConstants.PublicInterfaceSession_Class;
fieldTransformationMethod = Helper.getDeclaredMethod(javaClass, methodName, methodParameterTypes);
} catch (NoSuchMethodException ex2) {
try {
//if the one-argument version is absent, try with sessions.Session
Class[] methodParameterTypes = new Class[1];
methodParameterTypes[0] = ClassConstants.SessionsSession_Class;
fieldTransformationMethod = Helper.getDeclaredMethod(javaClass, methodName, methodParameterTypes);
} catch (NoSuchMethodException exception) {
throw DescriptorException.noSuchMethodWhileConvertingToMethod(methodName, this.mapping, exception);
} catch (SecurityException exception) {
throw DescriptorException.securityWhileConvertingToMethod(methodName, this.mapping, exception);
}
} catch (SecurityException exception) {
throw DescriptorException.securityWhileConvertingToMethod(methodName, this.mapping, exception);
}
} catch (SecurityException exception) {
throw DescriptorException.securityWhileConvertingToMethod(methodName, this.mapping, exception);
}
}
/**
* Return the Java class type of the field value.
* This uses the method return type.
*/
public Class getFieldType() {
if (this.fieldTransformationMethod != null) {
return this.fieldTransformationMethod.getReturnType();
}
return null;
}
public Object buildFieldValue(Object object, String fieldName, Session session) {
Class[] parameterTypes = null;
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try{
parameterTypes = AccessController.doPrivileged(new PrivilegedGetMethodParameterTypes(fieldTransformationMethod));
}catch (PrivilegedActionException ex){
throw (RuntimeException) ex.getCause();
}
}else{
parameterTypes = PrivilegedAccessHelper.getMethodParameterTypes(fieldTransformationMethod);
}
Object[] parameters = new Object[parameterTypes.length];
if (parameters.length == 1) {
parameters[0] = session;
}
try {
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
try{
return AccessController.doPrivileged(new PrivilegedMethodInvoker(fieldTransformationMethod, object, parameters));
}catch (PrivilegedActionException ex){
if (ex.getCause() instanceof IllegalAccessException){
throw (IllegalAccessException) ex.getCause();
}
if (ex.getCause() instanceof InvocationTargetException){
throw (InvocationTargetException) ex.getCause();
}
throw (RuntimeException) ex.getCause();
}
}else{
return PrivilegedAccessHelper.invokeMethod(fieldTransformationMethod, object, parameters);
}
} catch (IllegalAccessException exception) {
throw DescriptorException.illegalAccessWhileInvokingFieldToMethod(fieldTransformationMethod.getName(), mapping, exception);
} catch (IllegalArgumentException exception) {
throw DescriptorException.illegalArgumentWhileInvokingFieldToMethod(fieldTransformationMethod.getName(), mapping, exception);
} catch (InvocationTargetException exception) {
throw DescriptorException.targetInvocationWhileInvokingFieldToMethod(fieldTransformationMethod.getName(), mapping, exception);
}
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String name) {
methodName = name;
}
}