| /* |
| * Copyright (c) 1997, 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. |
| * |
| * This Source Code may also be made available under the following Secondary |
| * Licenses when the conditions for such availability set forth in the |
| * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, |
| * version 2 with the GNU Classpath Exception, which is available at |
| * https://www.gnu.org/software/classpath/license.html. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 |
| */ |
| |
| package com.sun.gjc.util; |
| |
| import static java.util.logging.Level.FINEST; |
| |
| import java.io.IOException; |
| import java.io.Serializable; |
| import java.io.StringBufferInputStream; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| import java.security.PrivilegedActionException; |
| import java.security.PrivilegedExceptionAction; |
| import java.util.Enumeration; |
| import java.util.Properties; |
| import java.util.Vector; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| |
| import com.sun.enterprise.util.i18n.StringManager; |
| import com.sun.gjc.common.DataSourceObjectBuilder; |
| import com.sun.logging.LogDomains; |
| |
| import jakarta.resource.ResourceException; |
| |
| /** |
| * Execute the methods based on the parameters. |
| * |
| * @author Binod P.G |
| * @version 1.0, 02/07/23 |
| */ |
| public class MethodExecutor implements Serializable { |
| |
| private static final long serialVersionUID = 1L; |
| |
| private static Logger _logger = LogDomains.getLogger(MethodExecutor.class, LogDomains.RSR_LOGGER); |
| private static StringManager sm = StringManager.getManager(DataSourceObjectBuilder.class); |
| |
| private final static String newline = System.getProperty("line.separator"); |
| |
| /** |
| * Exceute a simple set Method. |
| * |
| * @param value Value to be set. |
| * @param method <code>Method</code> object. |
| * @param obj Object on which the method to be executed. |
| * @throws <code>ResourceException</code>, in case of the mismatch of parameter |
| * values or a security violation. |
| */ |
| public void runJavaBeanMethod(String value, Method method, Object obj) throws ResourceException { |
| if (value == null || value.trim().equals("")) { |
| return; |
| } |
| |
| Class[] parameters = method.getParameterTypes(); |
| if (parameters.length == 1) { |
| Object[] values = new Object[1]; |
| values[0] = convertType(parameters[0], value); |
| |
| final ResourceException[] exception = new ResourceException[1]; |
| AccessController.doPrivileged(new PrivilegedAction() { |
| public Object run() { |
| try { |
| method.setAccessible(true); |
| method.invoke(obj, values); |
| } catch (IllegalAccessException | InvocationTargetException | SecurityException iae) { |
| _logger.log(Level.SEVERE, "jdbc.exc_jb_val", value); |
| _logger.log(Level.SEVERE, "", iae); |
| String msg = sm.getString("me.access_denied", method.getName()); |
| exception[0] = new ResourceException(msg); |
| } catch (IllegalArgumentException ie) { |
| _logger.log(Level.SEVERE, "jdbc.exc_jb_val", value); |
| _logger.log(Level.SEVERE, "", ie); |
| String msg = sm.getString("me.illegal_args", method.getName()); |
| exception[0] = new ResourceException(msg); |
| } |
| return null; |
| } |
| }); |
| if (exception[0] != null) { |
| throw exception[0]; |
| } |
| } |
| } |
| |
| /** |
| * Executes the method. |
| * |
| * @param method <code>Method</code> object. |
| * @param obj Object on which the method to be executed. |
| * @param values Parameter values for executing the method. |
| * @throws <code>ResourceException</code>, in case of the mismatch of parameter |
| * values or a security violation. |
| */ |
| public void runMethod(Method method, Object obj, Vector values) throws ResourceException { |
| Class[] parameters = method.getParameterTypes(); |
| if (values.size() != parameters.length) { |
| return; |
| } |
| Object[] actualValues = new Object[parameters.length]; |
| for (int i = 0; i < parameters.length; i++) { |
| String val = (String) values.get(i); |
| if (val.trim().equals("NULL")) { |
| actualValues[i] = null; |
| } else { |
| actualValues[i] = convertType(parameters[i], val); |
| } |
| } |
| final ResourceException[] exception = new ResourceException[1]; |
| AccessController.doPrivileged(new PrivilegedAction() { |
| public Object run() { |
| try { |
| method.setAccessible(true); |
| method.invoke(obj, actualValues); |
| } catch (IllegalAccessException | InvocationTargetException | SecurityException iae) { |
| _logger.log(Level.SEVERE, "jdbc.exc_jb_val", values); |
| _logger.log(Level.SEVERE, "", iae); |
| String msg = sm.getString("me.access_denied", method.getName()); |
| exception[0] = new ResourceException(msg); |
| } catch (IllegalArgumentException ie) { |
| _logger.log(Level.SEVERE, "jdbc.exc_jb_val", values); |
| _logger.log(Level.SEVERE, "", ie); |
| String msg = sm.getString("me.illegal_args", method.getName()); |
| exception[0] = new ResourceException(msg); |
| } |
| return null; |
| } |
| }); |
| if (exception[0] != null) { |
| throw exception[0]; |
| } |
| } |
| |
| /** |
| * Converts the type from String to the Class type. |
| * |
| * @param type Class name to which the conversion is required. |
| * @param parameter String value to be converted. |
| * @return Converted value. |
| * @throws <code>ResourceException</code>, in case of the mismatch of parameter |
| * values or a security violation. |
| */ |
| private Object convertType(Class type, String parameter) throws ResourceException { |
| try { |
| String typeName = type.getName(); |
| if (typeName.equals("java.lang.String") || typeName.equals("java.lang.Object")) { |
| return parameter; |
| } |
| |
| if (typeName.equals("int") || typeName.equals("java.lang.Integer")) { |
| return Integer.valueOf(parameter); |
| } |
| |
| if (typeName.equals("short") || typeName.equals("java.lang.Short")) { |
| return Short.valueOf(parameter); |
| } |
| |
| if (typeName.equals("byte") || typeName.equals("java.lang.Byte")) { |
| return Byte.valueOf(parameter); |
| } |
| |
| if (typeName.equals("long") || typeName.equals("java.lang.Long")) { |
| return Long.valueOf(parameter); |
| } |
| |
| if (typeName.equals("float") || typeName.equals("java.lang.Float")) { |
| return Float.valueOf(parameter); |
| } |
| |
| if (typeName.equals("double") || typeName.equals("java.lang.Double")) { |
| return Double.valueOf(parameter); |
| } |
| |
| if (typeName.equals("java.math.BigDecimal")) { |
| return new java.math.BigDecimal(parameter); |
| } |
| |
| if (typeName.equals("java.math.BigInteger")) { |
| return new java.math.BigInteger(parameter); |
| } |
| |
| if (typeName.equals("boolean") || typeName.equals("java.lang.Boolean")) { |
| return Boolean.valueOf(parameter); |
| } |
| |
| if (typeName.equals("java.util.Properties")) { |
| Properties p = stringToProperties(parameter); |
| if (p != null) |
| return p; |
| } |
| |
| return parameter; |
| } catch (NumberFormatException nfe) { |
| _logger.log(Level.SEVERE, "jdbc.exc_nfe", parameter); |
| String msg = sm.getString("me.invalid_param", parameter); |
| throw new ResourceException(msg); |
| } |
| } |
| |
| public Object invokeMethod(Object object, String methodName, Class<?>[] valueTypes, Object... values) throws ResourceException { |
| Object returnValue = null; |
| Method actualMethod; |
| try { |
| actualMethod = object.getClass().getMethod(methodName, valueTypes); |
| } catch (NoSuchMethodException ex) { |
| throw new ResourceException(ex); |
| } catch (SecurityException ex) { |
| throw new ResourceException(ex); |
| } |
| if (actualMethod != null) { |
| try { |
| returnValue = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { |
| actualMethod.setAccessible(true); |
| return actualMethod.invoke(object, values); |
| }); |
| } catch (PrivilegedActionException e) { |
| if (e.getException() != null) { |
| throw new ResourceException(e.getException()); |
| } else { |
| throw new ResourceException(e); |
| } |
| } |
| } |
| return returnValue; |
| } |
| |
| private Properties stringToProperties(String parameter) { |
| if (parameter == null) |
| return null; |
| String s = parameter.trim(); |
| if (!((s.startsWith("(") && s.endsWith(")")))) { |
| return null; // not a "( .... )" syntax |
| } |
| s = s.substring(1, s.length() - 1); |
| s = s.replaceAll("(?<!\\\\),", newline); // , -> \n |
| s = s.replaceAll("\\\\,", ","); // escape-"," -> , |
| |
| Properties p = new Properties(); |
| Properties prop = new Properties(); |
| try { |
| p.load(new StringBufferInputStream(s)); |
| } catch (IOException ex) { |
| _logger.log(FINEST, "Parsing string to properties: {0}", ex.getMessage()); |
| return null; |
| } |
| |
| // cleanup trailing whitespace in value |
| for (Enumeration propKeys = p.propertyNames(); propKeys.hasMoreElements();) { |
| String tmpKey = (String) propKeys.nextElement(); |
| String tmpValue = p.getProperty(tmpKey); |
| // Trim spaces |
| tmpValue = tmpValue.trim(); |
| // Quoted string. |
| if (tmpValue.length() > 1 && tmpValue.startsWith("\"") && tmpValue.endsWith("\"")) { |
| tmpValue = tmpValue.substring(1, tmpValue.length() - 1); |
| } |
| prop.put(tmpKey, tmpValue); |
| } |
| |
| if (_logger.isLoggable(FINEST)) { |
| _logger.log(FINEST, "Parsing string to properties: {0}size:{1}", new Object[] { prop, prop.size() }); |
| } |
| |
| return prop; |
| } |
| } |