001/* 
002 * JKNIV, utils - Helper utilities for jdk code.
003 * 
004 * Copyright (C) 2017, the original author or authors.
005 *
006 * This library is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 2.1 of the License.
010 * 
011 * This library is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 * Lesser General Public License for more details.
015 * 
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with this library; if not, write to the Free Software Foundation, Inc., 
018 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
019 */
020package net.sf.jkniv.reflect.beans;
021
022import java.lang.annotation.Annotation;
023import java.lang.reflect.Field;
024import java.lang.reflect.Method;
025import java.util.List;
026
027import net.sf.jkniv.exception.HandleableException;
028import net.sf.jkniv.reflect.ReflectionException;
029
030/**
031 * Utility interface to work with object reflection
032 * 
033 * @author Alisson Gomes
034 *
035 * @param <T> Type of class to be instanced
036 */
037public interface ObjectProxy<T>
038{
039    /**
040     * Arguments to build object using contructor
041     * @param constructorArgs argument values
042     */
043    void setConstructorArgs(Object... constructorArgs);
044    
045    /**
046     * Sequential type arguments from constructor 
047     * @param contructorTypes type of arguments
048     * @throws net.sf.jkniv.reflect.ReflectionException if some type is null
049     */
050    void setConstructorTypes(Class<?>... contructorTypes);
051    
052    /**
053     * build a new instance using constructor with arguments types or default
054     * @return a new instance of object, throws exception if an instance already exists
055     * @throws net.sf.jkniv.reflect.ReflectionException if an instance already exists
056     */
057    T newInstance();
058    
059    /**
060     * check if instance exists
061     * @return {@code true} when instance exists, {@code false} otherwise
062     */
063    boolean hasInstance();
064    
065    boolean isInstanceof(Class<?> clazz);
066    
067    /**
068     * check if class has a {@code methodName} to be invoked.
069     * @param methodName complete method name like {@code isDeleted}, {@code setName}...
070     * @return {@code true} when the class has the name, {@code false} otherwise
071     */
072    boolean hasMethod(String methodName);
073    
074    T getInstance();
075    
076    Class<T> getTargetClass();
077    
078    Object invoke(String methodName, Object... args); 
079
080    Object invoke(Method method, Object... args); 
081
082    /**
083     * copy all data from properties started with {@code get} or {@code is} to instance of this proxy
084     * @param o origin object data
085     * @return instance of object from proxy with the data from {@code o}
086     * @throws net.sf.jkniv.reflect.ReflectionException when some wrong occurs
087     */
088    T from(Object o);
089
090    /**
091     * merge all data from properties started with {@code get} or {@code is} to instance of this proxy
092     * @param o origin object data
093     * @return instance of object from proxy with the data from {@code o}
094     * @throws net.sf.jkniv.reflect.ReflectionException when some wrong occurs
095     */
096    T merge(Object o);
097
098    /**
099     * When the proxy catch a Exception to handler by {@code ReflectionException}
100     * a mute rule is used to not throw the exception. 
101     * @param ex exception class type
102     * @return this instance
103     */
104    ObjectProxy<T> mute(Class<? extends Exception> ex);
105    
106    /**
107     * check if this proxy class has {@code annotation}
108     * @param annotation name of annotation
109     * @return {@code true} when the class has this annotation, {@code false} otherwise
110     */
111    boolean hasAnnotation(String annotation);
112
113    /**
114     * check if this proxy class has {@code annotation}
115     * @param annotation name of annotation
116     * @return {@code true} when the class has this annotation, {@code false} otherwise
117     */
118    boolean hasAnnotation(Class<? extends Annotation> annotation);
119
120    /**
121     * Retrieve all public methods annotated with {@code annotation}
122     * @param annotation looked for
123     * @return a list of all public methods annotated with {@code annotation} or empty list otherwise.
124     */
125    List<Method> getMethodsAnnotatedWith(final Class<? extends Annotation> annotation);
126
127    /**
128     * check if this proxy class has {@code annotation} for a method name
129     * @param <T> generic type to return
130     * @param annotation name of the annotation
131     * @param methodName name of the method
132     * @param paramTypes type of parameters
133     * @return the Annotation instance or {@code null} if not found
134     * @throws ReflectionException when the {@code methodName} not exists
135     */
136    <T extends Annotation> T getAnnotationMethod(Class<? extends Annotation> annotation, String methodName, Class<?>... paramTypes);
137
138    /**
139     * check if this proxy class has {@code annotation} for a method name
140     * @param <T> generic type to return
141     * @param annotation name of the annotation
142     * @param fieldName attribute name
143     * @return the Annotation instance or {@code null} if not found
144     * @throws ReflectionException when the {@code attributeName} not exists
145     */
146    <T extends Annotation> T getAnnotationField(Class<? extends Annotation> annotation, String fieldName);
147
148    /**
149     * get the {@link Field} declared by the class or sub-class represented by this proxy
150     * @param name field to looking for
151     * @return the Field instance or {@code null} if not found
152     */
153    Field getDeclaredField(String name);
154    
155    /**
156     * get the {@link Method} declared by the class or sub-class represented by this proxy
157     * @param name method to looking for
158     * @return the Method instance or {@code null} if not found
159     */
160    Method getDeclaredMethod(String name);
161    
162    ObjectProxy<T> with(HandleableException handle);
163    
164    void register(TranslateType cast, Class type);
165}