// *************************************************************************************************************************** | |
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * | |
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * | |
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * | |
// * with the License. You may obtain a copy of the License at * | |
// * * | |
// * http://www.apache.org/licenses/LICENSE-2.0 * | |
// * * | |
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * | |
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * | |
// * specific language governing permissions and limitations under the License. * | |
// *************************************************************************************************************************** | |
package org.apache.juneau.utils; | |
import java.io.*; | |
import java.lang.reflect.*; | |
import org.apache.juneau.json.*; | |
import org.apache.juneau.parser.*; | |
import org.apache.juneau.reflect.*; | |
/** | |
* Used to invoke methods on {@code Objects} using arguments in serialized form. | |
* | |
* <h5 class='section'>Example:</h5> | |
* <p class='bcode w800'> | |
* String s = <js>"foobar"</js>; | |
* String s2 = (String)<jk>new</jk> PojoIntrospector(s) | |
* .invoke(<js>"substring(int,int)"</js>, <js>"[3,6]"</js>); <jc>// "bar"</jc> | |
* </p> | |
*/ | |
public final class PojoIntrospector { | |
private final Object o; | |
private final ReaderParser p; | |
/** | |
* Constructor. | |
* | |
* @param o The object on which Java methods will be invoked. | |
* @param p The parser to use to parse the method arguments. | |
* If <jk>null</jk>, {@link JsonParser#DEFAULT} is used. | |
*/ | |
public PojoIntrospector(Object o, ReaderParser p) { | |
if (p == null) | |
p = JsonParser.DEFAULT; | |
this.o = o; | |
this.p = p; | |
} | |
/** | |
* Shortcut for calling <code><jk>new</jk> PojoIntrospector(o, <jk>null</jk>);</code> | |
* | |
* @param o The object on which Java methods will be invoked. | |
*/ | |
public PojoIntrospector(Object o) { | |
this(o, null); | |
} | |
/** | |
* Primary method. | |
* | |
* <p> | |
* Invokes the specified method on this bean. | |
* | |
* @param method The method being invoked. | |
* @param args | |
* The arguments to pass as parameters to the method. | |
* These will automatically be converted to the appropriate object type if possible. | |
* Can be <jk>null</jk> if method has no arguments. | |
* @return The object returned by the call to the method, or <jk>null</jk> if target object is <jk>null</jk>. | |
* @throws IllegalAccessException | |
* If the <c>Constructor</c> object enforces Java language access control and the underlying constructor is | |
* inaccessible. | |
* @throws IllegalArgumentException | |
* If one of the following occurs: | |
* <ul class='spaced-list'> | |
* <li> | |
* The number of actual and formal parameters differ. | |
* <li> | |
* An unwrapping conversion for primitive arguments fails. | |
* <li> | |
* A parameter value cannot be converted to the corresponding formal parameter type by a method invocation | |
* conversion. | |
* <li> | |
* The constructor pertains to an enum type. | |
* </ul> | |
* @throws InvocationTargetException If the underlying constructor throws an exception. | |
* @throws ParseException Malformed input encountered. | |
* @throws IOException Thrown by underlying stream. | |
*/ | |
public Object invokeMethod(Method method, Reader args) throws InvocationTargetException, IllegalArgumentException, | |
IllegalAccessException, ParseException, IOException { | |
if (o == null) | |
return null; | |
Object[] params = args == null ? null : p.parseArgs(args, method.getGenericParameterTypes()); | |
return method.invoke(o, params); | |
} | |
/** | |
* Convenience method for invoking argument from method signature (@see {@link MethodInfo#getSignature()}. | |
* | |
* @param method The method being invoked. | |
* @param args | |
* The arguments to pass as parameters to the method. | |
* These will automatically be converted to the appropriate object type if possible. | |
* Can be <jk>null</jk> if method has no arguments. | |
* @return The object returned by the call to the method, or <jk>null</jk> if target object is <jk>null</jk>. | |
* @throws NoSuchMethodException If method does not exist. | |
* @throws IllegalAccessException | |
* If the <c>Constructor</c> object enforces Java language access control and | |
* the underlying constructor is inaccessible. | |
* @throws IllegalArgumentException | |
* If one of the following occurs: | |
* <ul class='spaced-list'> | |
* <li> | |
* The number of actual and formal parameters differ. | |
* <li> | |
* An unwrapping conversion for primitive arguments fails. | |
* <li> | |
* A parameter value cannot be converted to the corresponding formal parameter type by a method invocation | |
* conversion. | |
* <li> | |
* The constructor pertains to an enum type. | |
* </ul> | |
* @throws InvocationTargetException If the underlying constructor throws an exception. | |
* @throws ParseException Malformed input encountered. | |
* @throws IOException Thrown by underlying stream. | |
*/ | |
public Object invokeMethod(String method, String args) throws NoSuchMethodException, IllegalArgumentException, | |
InvocationTargetException, IllegalAccessException, ParseException, IOException { | |
if (o == null) | |
return null; | |
Method m = p.getClassMeta(o.getClass()).getPublicMethods().get(method); | |
if (m == null) | |
throw new NoSuchMethodException(method); | |
return invokeMethod(m, args == null ? null : new StringReader(args)); | |
} | |
} |