001    /*
002      Copyright (C) 2001-2004 Renaud Pawlak, Laurent Martelli
003      
004      This program is free software; you can redistribute it and/or modify
005      it under the terms of the GNU Lesser General Public License as
006      published by the Free Software Foundation; either version 2 of the
007      License, or (at your option) any later version.
008    
009      This program is distributed in the hope that it will be useful,
010      but WITHOUT ANY WARRANTY; without even the implied warranty of
011      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012      GNU Lesser General Public License for more details.
013    
014      You should have received a copy of the GNU Lesser General Public License
015      along with this program; if not, write to the Free Software
016      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
017    
018    package org.objectweb.jac.core.rtti;
019    
020    
021    import java.lang.NoSuchMethodException;
022    import java.lang.reflect.Constructor;
023    import java.lang.reflect.InvocationTargetException;
024    import org.apache.log4j.Logger;
025    import org.objectweb.jac.util.WrappedThrowableException;
026    
027    /**
028     * This class defines a meta item that corresponds to the
029     * <code>java.lang.reflect.Constructor</code> meta element.<p>
030     *
031     * @author Laurent Martelli
032     * @author Renaud Pawlak
033     */
034    
035    public class ConstructorItem extends AbstractMethodItem {
036        static Logger logger = Logger.getLogger("rtti.method");
037    
038        /**
039         * Transforms a constructor items array into a constructors array
040         * containing the <code>java.lang.reflect</code> constructors
041         * wrapped by the constructor items.<p>
042         *
043         * @param constructorItems the Constructor items
044         * @return the actual Constructors in <code>java.lang.reflect</code> */
045    
046        public static Constructor[] toConstructors( ConstructorItem[] constructorItems ) {
047            Constructor[] res = new Constructor[constructorItems.length];
048            for ( int i = 0; i < constructorItems.length; i++ ) {
049                if ( constructorItems[i] == null ) {
050                    res[i] = null;
051                } else {
052                    res[i] = constructorItems[i].getActualConstructor();
053                }
054            }
055            return res;
056        }
057    
058       
059        /**
060         * Default contructor to create a new constructor item object.<p>
061         *
062         * @param delegate the <code>java.lang.reflect.Constructor</code> actual
063         * meta item */
064    
065        public ConstructorItem(Constructor delegate, ClassItem parent) 
066            throws InvalidDelegateException 
067        {
068            super(delegate,parent);
069            try {
070                delegate.getDeclaringClass().getDeclaredMethod(
071                    "_org_"+NamingConventions.getShortClassName(delegate.getDeclaringClass()),
072                    delegate.getParameterTypes());
073            } catch(NoSuchMethodException e) {
074                //Log.warning("No _org_ method found for "+this);
075            }
076        }
077    
078        /**
079         * Get the constructor represented by this constructor item.<p>
080         *
081         * @return the actual constructor
082         */
083    
084        public Constructor getActualConstructor() {
085            return (Constructor) delegate;
086        }
087    
088        public String getName() {
089            return NamingConventions.getShortConstructorName(this);
090        }
091    
092        public Class getType() {
093            return getParent().getType();
094        }
095    
096        /**
097         * Creates a new instance of the class item that is parent of this
098         * constructor item.
099         *
100         * @param params the parameters needed by this constructor (see the
101         * types)
102         * @see #getParameterTypes() */
103    
104        public Object newInstance(Object [] params) 
105            throws InstantiationException, IllegalAccessException, InvocationTargetException 
106        {
107            return getActualConstructor().newInstance(params);
108        }
109    
110        /**
111         * A nice way to construct a new instance when the constructor does
112         * not take any arguements (it throws an exception if it is not the
113         * case).
114         *
115         * @see #getParameterTypes() */
116    
117        public Object newInstance() 
118            throws InstantiationException, IllegalAccessException, InvocationTargetException 
119        {
120            if (getClassItem().isAbstract())
121                throw new InstantiationException("Cannot instantiate abstract class "+getClassItem());
122            return getType().newInstance();
123        }
124    
125        public Object invoke(Object substance, Object[] params) {
126            try {
127                return newInstance(params);
128            } catch (Exception e) {
129                logger.info("Failed to invoke "+this,e);
130                throw new WrappedThrowableException(e);
131            }
132        }
133    
134        public Class[] getParameterTypes() {
135            return ((Constructor)delegate).getParameterTypes();
136        }
137    
138        public String toString() {
139            if (delegate!=null)
140                return getFullName();
141            else 
142                return "???";
143        }
144    
145        public String getFullName() {
146            String ret = NamingConventions.getShortConstructorName(this) + "(";
147            Class[] pts = getParameterTypes();
148            for ( int i = 0; i < pts.length; i++ ) {
149                ret = ret + NamingConventions.getStandardClassName(pts[i]);
150                if ( i < pts.length - 1 ) ret = ret + ",";
151            }
152            ret = ret + ")";
153            return ret;
154        }
155    
156        public final boolean isAdder() {
157            return false;
158        }   
159        public final CollectionItem[] getAddedCollections() {
160            return CollectionItem.emptyArray;
161        }
162        public final CollectionItem[] getRemovedCollections() {
163            return CollectionItem.emptyArray;
164        }
165    
166        public final boolean isSetter() { return false; }
167        public final boolean isRemover() { return false; }   
168        public final boolean isAccessor() { return false; }
169        public final boolean isWriter() { return false; }
170        public final boolean isGetter() { return false; }
171    
172        public final boolean isFieldGetter() { return false; }
173        public final boolean isFieldSetter() { return false; }
174    
175        public final boolean isReferenceGetter() { return false; }
176        public final boolean isReferenceSetter() { return false; }
177        public final boolean isReferenceAccessor() { return false; }
178    
179        public final boolean isCollectionGetter() { return false; }
180        public final boolean isCollectionSetter() { return false; }
181        public final boolean isCollectionAccessor() { return false; }
182    
183        public final FieldItem getSetField() {
184            return null;
185        }
186       
187    }// ConstructorItem