All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.lib.digester3.AbstractMethodRule Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.3.0
Show newest version
package com.feilong.lib.digester3;

/*
 * 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.
 */

import static java.lang.String.format;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;

import com.feilong.lib.beanutils.MethodUtils;

/**
 * Abstract implementation for {@link com.feilong.lib.digester3.SetNextRule},
 * {@link com.feilong.lib.digester3.SetRootRule} and {@link com.feilong.lib.digester3.SetTopRule} rules.
 *
 * @since 3.0
 */
public abstract class AbstractMethodRule extends Rule{

    /** The Constant log. */
    private static final Logger LOGGER        = LoggerFactory.getLogger(AbstractMethodRule.class);

    //---------------------------------------------------------------

    /**
     * The method name to call on the parent object.
     */
    protected String            methodName    = null;

    /**
     * The Java class name of the parameter type expected by the method.
     */
    protected String            paramTypeName = null;

    /**
     * The Java class name of the parameter type expected by the method.
     */
    protected Class          paramType;

    /**
     * Should we use exact matching. Default is no.
     */
    protected boolean           useExactMatch = false;

    /**
     * Should this rule be invoked when {@link #begin(String, String, Attributes)} (true)
     * or {@link #end(String, String)} (false) methods are invoked, false by default.
     */
    protected boolean           fireOnBegin   = false;

    /**
     * Construct a "set next" rule with the specified method name. The method's argument type is assumed to be the class
     * of the child object.
     * 
     * @param methodName
     *            Method name of the parent method to call
     */
    public AbstractMethodRule(String methodName){
        this(methodName, (String) null);
    }

    /**
     * Construct a "set next" rule with the specified method name.
     * 
     * @param methodName
     *            Method name of the parent method to call
     * @param paramType
     *            Java class of the parent method's argument (if you wish to use a primitive type, specify the
     *            corresonding Java wrapper class instead, such as java.lang.Boolean for a
     *            boolean parameter)
     */
    public AbstractMethodRule(String methodName, Class paramType){
        this(methodName, paramType.getName());
        this.paramType = paramType;
    }

    /**
     * Construct a "set next" rule with the specified method name.
     * 
     * @param methodName
     *            Method name of the parent method to call
     * @param paramTypeName
     *            Java class of the parent method's argument (if you wish to use a primitive type, specify the
     *            corresonding Java wrapper class instead, such as java.lang.Boolean for a
     *            boolean parameter)
     */
    public AbstractMethodRule(String methodName, String paramTypeName){
        this.methodName = methodName;
        this.paramTypeName = paramTypeName;
    }

    /**
     * 

* Is exact matching being used. *

*

* This rule uses org.apache.commons.beanutils.MethodUtils to introspect the relevent objects so that * the right method can be called. Originally, MethodUtils.invokeExactMethod was used. This matches * methods very strictly and so may not find a matching method when one exists. This is still the behaviour when * exact matching is enabled. *

*

* When exact matching is disabled, MethodUtils.invokeMethod is used. This method finds more methods * but is less precise when there are several methods with correct signatures. So, if you want to choose an exact * signature you might need to enable this property. *

*

* The default setting is to disable exact matches. *

* * @return true if exact matching is enabled * @since Digester Release 1.1.1 */ public boolean isExactMatch(){ return useExactMatch; } /** * Sets this rule be invoked when {@link #begin(String, String, Attributes)} (true) * or {@link #end(String, String)} (false) methods are invoked, false by default. * * @param fireOnBegin * flag to mark this rule be invoked when {@link #begin(String, String, Attributes)} (true) * or {@link #end(String, String)} (false) methods are invoked, false by default. */ public void setFireOnBegin(boolean fireOnBegin){ this.fireOnBegin = fireOnBegin; } /** * Returns the flag this rule be invoked when {@link #begin(String, String, Attributes)} (true) * or {@link #end(String, String)} (false) methods are invoked, false by default. * * @return the flag this rule be invoked when {@link #begin(String, String, Attributes)} (true) * or {@link #end(String, String)} (false) methods are invoked, false by default. */ public boolean isFireOnBegin(){ return fireOnBegin; } /** *

* Set whether exact matching is enabled. *

*

* See {@link #isExactMatch()}. *

* * @param useExactMatch * should this rule use exact method matching * @since Digester Release 1.1.1 */ public void setExactMatch(boolean useExactMatch){ this.useExactMatch = useExactMatch; } /** * {@inheritDoc} */ @Override public void begin(String namespace,String name,Attributes attributes) throws Exception{ if (fireOnBegin){ invoke(); } } /** * {@inheritDoc} */ @Override public void end(String namespace,String name) throws Exception{ if (!fireOnBegin){ invoke(); } } /** * Just performs the method execution. * * @throws Exception * if any error occurs. */ private void invoke() throws Exception{ // Identify the objects to be used Object child = getChild(); Object parent = getParent(); if (LOGGER.isDebugEnabled()){ if (parent == null){ LOGGER.debug( format( "[%s]{%s} Call [NULL PARENT].%s(%s)", getClass().getSimpleName(), getDigester().getMatch(), methodName, child)); }else{ LOGGER.debug( format( "[%s]{%s} Call %s.%s(%s)", getClass().getSimpleName(), getDigester().getMatch(), parent.getClass().getName(), methodName, child)); } } // Call the specified method Class paramTypes[] = new Class[1]; if (paramType != null){ paramTypes[0] = getDigester().getClassLoader().loadClass(paramTypeName); }else{ paramTypes[0] = child.getClass(); } if (useExactMatch){ MethodUtils.invokeExactMethod(parent, methodName, new Object[] { child }, paramTypes); }else{ MethodUtils.invokeMethod(parent, methodName, new Object[] { child }, paramTypes); } } /** * Returns the argument object of method has to be invoked. * * @return the argument object of method has to be invoked. */ protected abstract Object getChild(); /** * Returns the target object of method has to be invoked. * * @return the target object of method has to be invoked. */ protected abstract Object getParent(); /** * {@inheritDoc} */ @Override public final String toString(){ return format( "%s[methodName=%s, paramType=%s, paramTypeName=%s, useExactMatch=%s, fireOnBegin=%s]", getClass().getSimpleName(), methodName, paramType, paramTypeName, useExactMatch, fireOnBegin); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy