⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 propertyinjector.java

📁 一套java版本的搜索引擎源码
💻 JAVA
字号:
/** * 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.lucene.gdata.server.registry.configuration;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;import java.util.Set;import java.util.Map.Entry;import org.apache.lucene.gdata.utils.ReflectionUtils;/** * PropertyInjector is used to set member variables / properties of classes via * <i>setter</i> methods using the * {@link org.apache.lucene.gdata.server.registry.configuration.ComponentConfiguration} * class. * <p> * To populate a object with properties from a ComponentConfiguration instance * the class or a superclass of the object to populate has to provide at least * one setter method with a single parameter. The object to populate is set via * the {@link PropertyInjector#setTargetObject} method. The class of the object * will be analyzed for setter methods having a "set" prefix in their method * name. If one of the found setter methods is annotated with * {@link org.apache.lucene.gdata.server.registry.configuration.Requiered} this * property is interpreted as a mandatory property. Mandatory properties must be * available in the provided ComponentConfiguration, if not the injection will * fail.<br> * The * {@link org.apache.lucene.gdata.server.registry.configuration.ComponentConfiguration} * contains key / value pairs where the key must match the signature of the * setter method without the 'set' prefix and must begin with a lower case * character. <span>Key<code>bufferSize</code> does match a method signature * of <code>setBufferSize</code></span> The type of the parameter will be * reflected via the Reflection API and instantiated with the given value if * possible. * </p> * <p> * Setter methods without a <code>Required</code> annotation will be set if * the property is present in the ComponentConfiguration * </p> * <p>This class does not support overloaded setter methods.</p> * @author Simon Willnauer * @see org.apache.lucene.gdata.server.registry.configuration.Requiered * @see org.apache.lucene.gdata.server.registry.configuration.ComponentConfiguration */public class PropertyInjector {    private static final String SETTER_PREFIX = "set";    private Class targetClass;    private Object target;    private Map<String, Method> requieredProperties = new HashMap<String, Method>();    private Map<String, Method> optionalProperties = new HashMap<String, Method>();    /**     * Sets the object to be populated with the properties provided in the ComponentConfiguration.     * @param o - the object to populate     */    public void setTargetObject(final Object o) {        if (o == null)            throw new IllegalArgumentException("TargetObject must not be null");        this.target = o;        this.targetClass = o.getClass();        try {            registerProperties(this.targetClass);        } catch (Exception e) {            throw new InjectionException("can access field -- "                    + e.getMessage(), e);        }        if (this.requieredProperties.isEmpty()                && this.optionalProperties.isEmpty())            throw new InjectionException(                    "Given type has no public setter methods -- "                            + o.getClass().getName());    }    protected int getRequiredSize() {        return this.requieredProperties.size();    }    protected int getOptionalSize() {        return this.optionalProperties.size();    }    private void registerProperties(final Class clazz)            throws SecurityException, NoSuchFieldException {        if (clazz == null)            return;        Method[] methodes = clazz.getMethods();        for (int i = 0; i < methodes.length; i++) {            if (methodes[i].getName()                    .startsWith(PropertyInjector.SETTER_PREFIX)) {                String methodName = methodes[i].getName();                String fieldName = getFieldName(methodName);                if (methodes[i].getAnnotation(Requiered.class) != null)                    this.requieredProperties.put(fieldName, methodes[i]);                else                    this.optionalProperties.put(fieldName, methodes[i]);            }        }        registerProperties(clazz.getSuperclass());    }    private String getFieldName(final String setterMethodName) {        // remove 'set' prefix --> first char as lowerCase        String retVal = setterMethodName.substring(3);        String firstLetter = retVal.substring(0, 1);        retVal = retVal.replaceFirst(firstLetter, firstLetter.toLowerCase());        return retVal;    }    /**     * Injects the properties stored in the <code>ComponentConfiguration</code>     * to the corresponding methods of the target object     * @param bean - configuration bean containing all properties to set.     *      */    public void injectProperties(final ComponentConfiguration bean) {        if (bean == null)            throw new IllegalArgumentException("bean must not be null");        if (this.target == null)            throw new IllegalStateException("target is not set -- null");        Set<Entry<String, Method>> requiered = this.requieredProperties                .entrySet();        // set required properties        for (Entry<String, Method> entry : requiered) {            if (!bean.contains(entry.getKey()))                throw new InjectionException(                        "Required property can not be set -- value not in configuration bean; Property: "                                + entry.getKey()                                + "for class "                                + this.targetClass.getName());            populate(bean, entry);        }        Set<Entry<String, Method>> optinal = this.optionalProperties.entrySet();        // set optional properties        for (Entry<String, Method> entry : optinal) {            if (bean.contains(entry.getKey()))                populate(bean, entry);        }    }    private void populate(ComponentConfiguration bean,            Entry<String, Method> entry) {        String value = bean.get(entry.getKey());        Method m = entry.getValue();        Class<?>[] parameterTypes = m.getParameterTypes();        if (parameterTypes.length > 1)            throw new InjectionException("Setter has more than one parameter "                    + m.getName() + " -- can not invoke method -- ");        Object parameter = null;        try {            parameter = createObject(value, parameterTypes[0]);        } catch (InjectionException e) {            throw new InjectionException(                    "parameter object creation failed for method "                            + m.getName() + " in class: "                            + this.targetClass.getName(), e);        }        // only setters with one parameter are supported        Object[] parameters = { parameter };        try {            m.invoke(this.target, parameters);        } catch (Exception e) {            throw new InjectionException("Can not set value of type "                    + value.getClass().getName()                    + " -- can not invoke method -- " + e.getMessage(), e);        }    }    private Object createObject(String s, Class<?> clazz) {        try {            // if class is requested use s as fully qualified class name            if (clazz == Class.class)                return Class.forName(s);            // check for primitive type            if (clazz.isPrimitive())                clazz = ReflectionUtils.getPrimitiveWrapper(clazz);            boolean defaultConst = false;            boolean stringConst = false;            Constructor[] constructors = clazz.getConstructors();            if (constructors.length == 0)                defaultConst = true;            for (int i = 0; i < constructors.length; i++) {                if (constructors[i].getParameterTypes().length == 0) {                    defaultConst = true;                    continue;                }                if (constructors[i].getParameterTypes().length == 1                        && constructors[i].getParameterTypes()[0]                                .equals(String.class))                    stringConst = true;            }            /*             * if there is a string constructor use the string as a parameter             */            if (stringConst) {                Constructor constructor = clazz                        .getConstructor(new Class[] { String.class });                return constructor.newInstance(new Object[] { s });            }            /*             * if no string const. but a default const. -- use the string as a             * class name             */            if (defaultConst)                return Class.forName(s).newInstance();            throw new InjectionException(                    "Parameter can not be created -- no default or String constructor found for class "                            + clazz.getName());        } catch (Exception e) {            throw new InjectionException("can not create object for setter", e);        }    }    /**     * Sets all members to their default values and clears the internal used     * {@link Map} instances     *      * @see Map#clear()     */    public void clear() {        this.target = null;        this.targetClass = null;        this.optionalProperties.clear();        this.requieredProperties.clear();    }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -