blob: 785a92f21702f4520232813a2a56c57bd70b5214 [file] [log] [blame]
// ***************************************************************************************************************************
// * 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));
}
}