| /* |
| * Copyright (c) 1998, 2020 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.mappings.foundation.AbstractTransformationMapping; |
| import org.eclipse.persistence.sessions.Record; |
| import org.eclipse.persistence.sessions.Session; |
| |
| /** |
| * @version $Header: MethodBasedAttributeTransformer.java 18-sep-2006.14:33:54 gyorke Exp $ |
| * @author mmacivor |
| * @since release specific (what release of product did this appear in) |
| * This class is used to preserve the old method of doing Attribute 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 MethodBasedAttributeTransformer implements AttributeTransformer { |
| protected transient Method attributeTransformationMethod; |
| protected AbstractTransformationMapping mapping; |
| protected String methodName; |
| |
| public MethodBasedAttributeTransformer() { |
| } |
| |
| public MethodBasedAttributeTransformer(String methodName) { |
| this.methodName = methodName; |
| } |
| |
| public String getMethodName() { |
| return methodName; |
| } |
| |
| public void setMethodName(String name) { |
| methodName = name; |
| } |
| |
| public Method getAttributeTransformationMethod() { |
| return attributeTransformationMethod; |
| } |
| |
| public void setAttributeTransformationMethod(Method theMethod) { |
| attributeTransformationMethod = theMethod; |
| } |
| |
| /** |
| * INTERNAL: |
| * Initilizes the transformer. Looks up the transformation method on the |
| * domain class using reflection. This method can have either 1 or 2 parameters. |
| */ |
| @Override |
| public void initialize(AbstractTransformationMapping mapping) { |
| this.mapping = mapping; |
| final Class javaClass = this.mapping.getDescriptor().getJavaClass(); |
| try { |
| // look for the one-argument version with Record first |
| Class[] parameterTypes = new Class[1]; |
| parameterTypes[0] = ClassConstants.Record_Class; |
| attributeTransformationMethod = Helper.getDeclaredMethod(javaClass, methodName, parameterTypes); |
| } catch (NoSuchMethodException ex) { |
| try { |
| // if the one-argument version is not there, look for the two-argument version |
| Class[] parameterTypes = new Class[2]; |
| parameterTypes[0] = ClassConstants.Record_Class; |
| parameterTypes[1] = ClassConstants.PublicInterfaceSession_Class; |
| attributeTransformationMethod = Helper.getDeclaredMethod(javaClass, methodName, parameterTypes); |
| } catch (NoSuchMethodException ex2) { |
| try { |
| //now look for the 2 argument version using Record and sessions Session |
| Class[] parameterTypes = new Class[2]; |
| parameterTypes[0] = ClassConstants.Record_Class; |
| parameterTypes[1] = ClassConstants.SessionsSession_Class; |
| attributeTransformationMethod = Helper.getDeclaredMethod(javaClass, methodName, parameterTypes); |
| } catch (NoSuchMethodException ex3) { |
| throw DescriptorException.noSuchMethodOnInitializingAttributeMethod(this.mapping.getAttributeMethodName(), mapping, ex3); |
| } catch (SecurityException se) { |
| throw DescriptorException.securityOnInitializingAttributeMethod(this.mapping.getAttributeMethodName(), mapping, se); |
| } |
| } catch (SecurityException se) { |
| throw DescriptorException.securityOnInitializingAttributeMethod(this.mapping.getAttributeMethodName(), mapping, se); |
| } |
| } catch (SecurityException se) { |
| throw DescriptorException.securityOnInitializingAttributeMethod(this.mapping.getAttributeMethodName(), mapping, se); |
| } |
| if (attributeTransformationMethod.getReturnType() == ClassConstants.Void_Class) { |
| throw DescriptorException.returnTypeInGetAttributeAccessor(methodName, mapping); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Build the attribute value by invoking the user's transformation method. |
| */ |
| @Override |
| public Object buildAttributeValue(Record record, Object object, Session session) { |
| Class[] parameterTypes = null; |
| if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ |
| try{ |
| parameterTypes = AccessController.doPrivileged(new PrivilegedGetMethodParameterTypes(attributeTransformationMethod)); |
| }catch (PrivilegedActionException ex){ |
| throw (RuntimeException)ex.getCause(); |
| } |
| }else{ |
| parameterTypes = PrivilegedAccessHelper.getMethodParameterTypes(attributeTransformationMethod); |
| } |
| Object[] parameters = new Object[parameterTypes.length]; |
| parameters[0] = record; |
| if (parameters.length == 2) { |
| parameters[1] = session; |
| } |
| |
| try { |
| if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){ |
| try{ |
| return AccessController.doPrivileged(new PrivilegedMethodInvoker(attributeTransformationMethod, object, parameters)); |
| }catch (PrivilegedActionException ex){ |
| if (ex.getCause() instanceof IllegalArgumentException){ |
| throw (IllegalArgumentException) ex.getCause(); |
| } |
| if (ex.getCause() instanceof InvocationTargetException){ |
| throw (InvocationTargetException) ex.getCause(); |
| } |
| throw (RuntimeException) ex.getCause(); |
| } |
| }else { |
| return PrivilegedAccessHelper.invokeMethod(attributeTransformationMethod, object, parameters); |
| } |
| } catch (IllegalAccessException exception) { |
| throw DescriptorException.illegalAccessWhileInvokingAttributeMethod(mapping, exception); |
| } catch (IllegalArgumentException exception) { |
| throw DescriptorException.illegalArgumentWhileInvokingAttributeMethod(mapping, exception); |
| } catch (InvocationTargetException exception) { |
| throw DescriptorException.targetInvocationWhileInvokingAttributeMethod(mapping, exception); |
| } |
| } |
| } |