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