001package org.maltparser.core.feature.system;
002
003import java.lang.reflect.Constructor;
004import java.lang.reflect.InvocationTargetException;
005
006import org.maltparser.core.exception.MaltChainedException;
007import org.maltparser.core.feature.FeatureException;
008import org.maltparser.core.feature.FeatureRegistry;
009import org.maltparser.core.feature.function.Function;
010/**
011 *  
012 *
013 * @author Johan Hall
014**/
015public class FunctionDescription {
016        private final String name;
017        private final Class<?> functionClass;
018        private final boolean hasSubfunctions;
019        private final boolean hasFactory;
020
021        public FunctionDescription(String _name, Class<?> _functionClass, boolean _hasSubfunctions, boolean _hasFactory) {
022                this.name = _name;
023                this.functionClass = _functionClass;
024                this.hasSubfunctions = _hasSubfunctions;
025                this.hasFactory = _hasFactory;
026        }
027        
028        public Function newFunction(FeatureRegistry registry) throws MaltChainedException {
029                if (hasFactory) {
030//                      for (Class<?> c : registry.keySet()) {
031//                              try {
032//                                      c.asSubclass(functionClass);
033//                              } catch (ClassCastException e) {
034//                                      continue;
035//                              }
036//                              return ((AbstractFeatureFactory)registry.get(c)).makeFunction(name);
037//                      }
038//                      return null;
039                        return registry.getFactory(functionClass).makeFunction(name, registry);
040                }
041                Constructor<?>[] constructors = functionClass.getConstructors();
042                if (constructors.length == 0) {
043                        try {
044                                return (Function)functionClass.newInstance();
045                        } catch (InstantiationException e) {
046                                throw new FeatureException("The function '"+functionClass.getName()+"' cannot be initialized. ", e);
047                        } catch (IllegalAccessException e) {
048                                throw new FeatureException("The function '"+functionClass.getName()+"' cannot be initialized. ", e);
049                        }
050                }
051                Class<?>[] params = constructors[0].getParameterTypes();
052                if (params.length == 0) {
053                        try {
054                                return (Function)functionClass.newInstance();
055                        } catch (InstantiationException e) {
056                                throw new FeatureException("The function '"+functionClass.getName()+"' cannot be initialized. ", e);
057                        } catch (IllegalAccessException e) {
058                                throw new FeatureException("The function '"+functionClass.getName()+"' cannot be initialized. ", e);
059                        }
060                }
061                Object[] arguments = new Object[params.length];
062                for (int i = 0; i < params.length; i++) {
063                        if (hasSubfunctions && params[i] == java.lang.String.class) {
064                                arguments[i] = name;
065                        } else {
066                                arguments[i] = registry.get(params[i]);
067                                if (arguments[i] == null) {
068                                        return null;
069                                }
070                        }
071                }
072                try {
073                        return (Function)constructors[0].newInstance(arguments);
074                } catch (InstantiationException e) {
075                        throw new FeatureException("The function '"+functionClass.getName()+"' cannot be initialized. ", e);
076                } catch (IllegalAccessException e) {
077                        throw new FeatureException("The function '"+functionClass.getName()+"' cannot be initialized. ", e);
078                } catch (InvocationTargetException e) {
079                        throw new FeatureException("The function '"+functionClass.getName()+"' cannot be initialized. ", e);
080                }
081        }
082        
083        public String getName() {
084                return name;
085        }
086
087        public Class<?> getFunctionClass() {
088                return functionClass;
089        }
090
091        public boolean isHasSubfunctions() {
092                return hasSubfunctions;
093        }
094
095        public boolean isHasFactory() {
096                return hasFactory;
097        }
098
099        public boolean equals(Object obj) {
100                if (this == obj)
101                        return true;
102                if (obj == null)
103                        return false;
104                if (getClass() != obj.getClass())
105                        return false;
106                if (!(name.equalsIgnoreCase(((FunctionDescription)obj).getName()))) {
107                        return false;
108                } else if (!(functionClass.equals(((FunctionDescription)obj).getFunctionClass()))) {
109                        return false;
110                }
111                return true;
112        }
113
114        public String toString() {
115                final StringBuilder sb = new StringBuilder();
116                sb.append(name);
117                sb.append("->");
118                sb.append(functionClass.getName());
119                return sb.toString();
120        }
121}