Package org.apache.felix.scr.impl.helper

Source Code of org.apache.felix.scr.impl.helper.BindMethod

/*
* 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.felix.scr.impl.helper;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.felix.scr.impl.Activator;
import org.apache.felix.scr.impl.manager.ComponentContextImpl;
import org.apache.felix.scr.impl.manager.RefPair;
import org.apache.felix.scr.impl.metadata.DSVersion;
import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
import org.apache.felix.scr.impl.metadata.ReferenceMetadata.ReferenceScope;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceObjects;
import org.osgi.framework.ServiceReference;
import org.osgi.service.log.LogService;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;


/**
* Component method to be invoked on service (un)binding.
*/
public class BindMethod extends BaseMethod<BindParameters>
{

    private static final Class<?> OBJECT_CLASS = Object.class;
   
    protected static final Class<?> SERVICE_REFERENCE_CLASS = ServiceReference.class;
    private static final Class<?> SERVICE_OBJECTS_CLASS;
   
    static {
        Class<?> serviceObjectsClass = null;
        try {
            serviceObjectsClass = ServiceObjects.class;
        }
        catch (Throwable t)
        {
            //can't load class
        }
        SERVICE_OBJECTS_CLASS = serviceObjectsClass;
    }

    private final String m_referenceClassName;
   
    private final ReferenceMetadata.ReferenceScope m_referenceScope;

    private enum ParamType {
        serviceReference,
        serviceObjects,
        serviceType,
        map
    }
   
    //initialized for cases where there is no method.
    private volatile List<ParamType> m_paramTypes = Collections.emptyList();


    public BindMethod( final String methodName,
            final Class<?> componentClass, final String referenceClassName, final DSVersion dsVersion, final boolean configurableServiceProperties, ReferenceScope referenceScope )
    {
        super( methodName, componentClass, dsVersion, configurableServiceProperties );
        m_referenceClassName = referenceClassName;
        m_referenceScope = referenceScope;
    }


    /**
     * Finds the method named in the {@link #m_methodName} field in the given
     * <code>targetClass</code>. If the target class has no acceptable method
     * the class hierarchy is traversed until a method is found or the root
     * of the class hierarchy is reached without finding a method.
     *
     *
     * @param targetClass The class in which to look for the method
     * @param acceptPrivate <code>true</code> if private methods should be
     *      considered.
     * @param acceptPackage <code>true</code> if package private methods should
     *      be considered.
     * @param logger
     * @return The requested method or <code>null</code> if no acceptable method
     *      can be found in the target class or any super class.
     * @throws InvocationTargetException If an unexpected Throwable is caught
     *      trying to find the requested method.
     */
    protected Method doFindMethod( Class<?> targetClass, boolean acceptPrivate, boolean acceptPackage, SimpleLogger logger )
        throws SuitableMethodNotAccessibleException, InvocationTargetException
    {
        /* 112.3.1 The method is searched for using the following priority
         1 - ServiceReference single parameter
         2 - ServiceObjects single parameter (DS 1.3+ only)
         3 - Service object single parameter
         4 - Service interface assignment compatible single parameter
         5 - two parameters, first the type of or assignment compatible with the service, the second Map (DS 1.1, 1.2 only)
         6 - one or more parameters of types ServiceReference, ServiceObjects, interface type, or assignment compatible to interface type, in any order. (DS 1.3+ only)
         */

        // flag indicating a suitable but inaccessible method has been found
        boolean suitableMethodNotAccessible = false;

        if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
        {
            logger.log( LogService.LOG_DEBUG,
                "doFindMethod: Looking for method " + targetClass.getName() + "." + getMethodName(), null );
        }

        // Case 1 - Service reference parameter
        Method method;
        try
        {
            method = getServiceReferenceMethod( targetClass, acceptPrivate, acceptPackage, logger );
            if ( method != null )
            {
                if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
                {
                    logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
                }
                m_paramTypes = Collections.singletonList(ParamType.serviceReference);
                return method;
            }
        }
        catch ( SuitableMethodNotAccessibleException ex )
        {
            suitableMethodNotAccessible = true;
        }

        //case 2 ServiceObjects parameter
        try
        {
            method = getServiceObjectsMethod( targetClass, acceptPrivate, acceptPackage, logger );
            if ( method != null )
            {
                if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
                {
                    logger.log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
                }
                m_paramTypes = Collections.singletonList(ParamType.serviceObjects);
                return method;
            }
        }
        catch ( SuitableMethodNotAccessibleException ex )
        {
            suitableMethodNotAccessible = true;
        }

        // for further methods we need the class of the service object
        final Class<?> parameterClass = getParameterClass( targetClass, logger );
        if ( parameterClass != null )
        {

            if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
            {
                logger.log(
                    LogService.LOG_DEBUG,
                    "doFindMethod: No method taking ServiceReference found, checking method taking "
                        + parameterClass.getName(), null );
            }

            // Case 2 - Service object parameter
            try
            {
                method = getServiceObjectMethod( targetClass, parameterClass, acceptPrivate, acceptPackage, logger );
                if ( method != null )
                {
                    m_paramTypes = Collections.singletonList(ParamType.serviceType);
                    return method;
                }
            }
            catch ( SuitableMethodNotAccessibleException ex )
            {
                suitableMethodNotAccessible = true;
            }

            // Case 3 - Service interface assignement compatible methods
            try
            {
                method = getServiceObjectAssignableMethod( targetClass, parameterClass, acceptPrivate, acceptPackage, logger );
                if ( method != null )
                {
                    m_paramTypes = Collections.singletonList(ParamType.serviceType);
                    return method;
                }
            }
            catch ( SuitableMethodNotAccessibleException ex )
            {
                suitableMethodNotAccessible = true;
            }

            // signatures taking a map are only supported starting with DS 1.1
            if ( getDSVersion().isDS11() && !getDSVersion().isDS13() )
            {

                // Case 4 - same as case 2, but + Map param (DS 1.1 only)
                try
                {
                    method = getServiceObjectWithMapMethod( targetClass, parameterClass, acceptPrivate, acceptPackage, logger );
                    if ( method != null )
                    {
                        List<ParamType> paramTypes = new ArrayList<ParamType>(2);
                        paramTypes.add(ParamType.serviceType);
                        paramTypes.add(ParamType.map);
                        m_paramTypes = paramTypes;
                        return method;
                    }
                }
                catch ( SuitableMethodNotAccessibleException ex )
                {
                    suitableMethodNotAccessible = true;
                }

                // Case 5 - same as case 3, but + Map param (DS 1.1 only)
                try
                {
                    method = getServiceObjectAssignableWithMapMethod( targetClass, parameterClass, acceptPrivate,
                        acceptPackage );
                    if ( method != null )
                    {
                        List<ParamType> paramTypes = new ArrayList<ParamType>(2);
                        paramTypes.add(ParamType.serviceType);
                        paramTypes.add(ParamType.map);
                        m_paramTypes = paramTypes;
                        return method;
                    }
                }
                catch ( SuitableMethodNotAccessibleException ex )
                {
                    suitableMethodNotAccessible = true;
                }

            }
            if ( getDSVersion().isDS13() )
            {
                for (Method m: targetClass.getDeclaredMethods())
                {
                    if (getMethodName().equals(m.getName())) {
                        Class<?>[] parameterTypes = m.getParameterTypes();
                        boolean matches = true;
                        boolean specialMatch = true;
                        List<ParamType> paramTypes = new ArrayList<ParamType>(parameterTypes.length);
                        for (Class<?> paramType: parameterTypes) {
                            if (paramType == SERVICE_REFERENCE_CLASS)
                            {
                                if (specialMatch && parameterClass == SERVICE_REFERENCE_CLASS)
                                {
                                    specialMatch = false;
                                    paramTypes.add(ParamType.serviceType);
                                }
                                else
                                {
                                    paramTypes.add(ParamType.serviceReference);
                                }
                            }
                            else if (paramType == SERVICE_OBJECTS_CLASS)
                            {
                                if (specialMatch && parameterClass == SERVICE_OBJECTS_CLASS)
                                {
                                    specialMatch = false;
                                    paramTypes.add(ParamType.serviceType);
                                }
                                else
                                {
                                    paramTypes.add(ParamType.serviceObjects);
                                }
                            }
                            else if (paramType == Map.class)
                            {
                                if (specialMatch && parameterClass == Map.class)
                                {
                                    specialMatch = false;
                                    paramTypes.add(ParamType.serviceType);
                                }
                                else
                                {
                                    paramTypes.add(ParamType.map);
                                }
                            }
                            else if (paramType.isAssignableFrom( parameterClass ) )
                            {
                                paramTypes.add(ParamType.serviceType);
                            }
                            else
                            {
                                matches = false;
                                break;
                            }
                        }
                        if (matches)
                        {
                            if ( accept( m, acceptPrivate, acceptPackage, returnValue() ) )
                            {
                                m_paramTypes = paramTypes;
                                return m;
                            }
                            suitableMethodNotAccessible = true;
                        }
                    }
                }
            }
        }
        else if ( logger.isLogEnabled( LogService.LOG_WARNING ) )
        {
            logger.log(
                LogService.LOG_WARNING,
                "doFindMethod: Cannot check for methods taking parameter class " + m_referenceClassName + ": "
                    + targetClass.getName() + " does not see it", null );
        }

        // if at least one suitable method could be found but none of
        // the suitable methods are accessible, we have to terminate
        if ( suitableMethodNotAccessible )
        {
            logger.log( LogService.LOG_ERROR,
                "doFindMethod: Suitable but non-accessible method found in class {0}", new Object[]
                    { targetClass.getName() }, null );
            throw new SuitableMethodNotAccessibleException();
        }

        // no method found
        return null;
    }


    /**
     * Returns the class object representing the class of the service reference
     * named by the {@link #m_referenceClassName} field. The class loader of
     * the <code>targetClass</code> is used to load the service class.
     * <p>
     * It may well be possible, that the classloader of the target class cannot
     * see the service object class, for example if the service reference is
     * inherited from a component class of another bundle.
     *
     * @return The class object for the referred to service or <code>null</code>
     *      if the class loader of the <code>targetClass</code> cannot see that
     *      class.
     */
    private Class<?> getParameterClass( final Class<?> targetClass, SimpleLogger logger )
    {
        if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
        {
            logger.log(
                LogService.LOG_DEBUG,
                "getParameterClass: Looking for interface class {0} through loader of {1}",
                    new Object[] {m_referenceClassName, targetClass.getName()}, null );
        }

        try
        {
            // need the class loader of the target class, which may be the
            // system classloader, which case getClassLoader may retur null
            ClassLoader loader = targetClass.getClassLoader();
            if ( loader == null )
            {
                loader = ClassLoader.getSystemClassLoader();
            }

            final Class<?> referenceClass = loader.loadClass( m_referenceClassName );
            if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
            {
                logger.log( LogService.LOG_DEBUG,
                    "getParameterClass: Found class {0}", new Object[] {referenceClass.getName()}, null );
            }
            return referenceClass;
        }
        catch ( ClassNotFoundException cnfe )
        {
            // if we can't load the class, perhaps the method is declared in a
            // super class so we try this class next
        }

        if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
        {
            logger.log( LogService.LOG_DEBUG,
                "getParameterClass: Not found through component class, using PackageAdmin service", null );
        }

        // try to load the class with the help of the PackageAdmin service
        PackageAdmin pa = ( PackageAdmin ) Activator.getPackageAdmin();
        if ( pa != null )
        {
            final String referenceClassPackage = m_referenceClassName.substring( 0, m_referenceClassName
                .lastIndexOf( '.' ) );
            ExportedPackage[] pkg = pa.getExportedPackages( referenceClassPackage );
            if ( pkg != null )
            {
                for ( int i = 0; i < pkg.length; i++ )
                {
                    try
                    {
                        if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
                        {
                            logger.log(
                                LogService.LOG_DEBUG,
                                "getParameterClass: Checking Bundle {0}/{1}",
                                    new Object[] {pkg[i].getExportingBundle().getSymbolicName(), pkg[i].getExportingBundle().getBundleId()}, null );
                        }

                        Class<?> referenceClass = pkg[i].getExportingBundle().loadClass( m_referenceClassName );
                        if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
                        {
                            logger.log( LogService.LOG_DEBUG,
                                    "getParameterClass: Found class {0}", new Object[] {referenceClass.getName()}, null );
                        }
                        return referenceClass;
                    }
                    catch ( ClassNotFoundException cnfe )
                    {
                        // exported package does not provide the interface !!!!
                    }
                }
            }
            else if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
            {
                logger.log( LogService.LOG_DEBUG,
                    "getParameterClass: No bundles exporting package {0} found", new Object[] {referenceClassPackage}, null );
            }
        }
        else if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
        {
            logger.log( LogService.LOG_DEBUG,
                "getParameterClass: PackageAdmin service not available, cannot find class", null );
        }

        // class cannot be found, neither through the component nor from an
        // export, so we fall back to assuming Object
        if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
        {
            logger.log( LogService.LOG_DEBUG,
                "getParameterClass: No class found, falling back to class Object", null );
        }
        return OBJECT_CLASS;
    }


    /**
     * Returns a method taking a single <code>ServiceReference</code> object
     * as a parameter or <code>null</code> if no such method exists.
     *
     *
     * @param targetClass The class in which to look for the method. Only this
     *      class is searched for the method.
     * @param acceptPrivate <code>true</code> if private methods should be
     *      considered.
     * @param acceptPackage <code>true</code> if package private methods should
     *      be considered.
     * @param logger
     * @return The requested method or <code>null</code> if no acceptable method
     *      can be found in the target class.
     * @throws SuitableMethodNotAccessibleException If a suitable method was
     *      found which is not accessible
     * @throws InvocationTargetException If an unexpected Throwable is caught
     *      trying to find the requested method.
     */
    private Method getServiceReferenceMethod( final Class<?> targetClass, boolean acceptPrivate, boolean acceptPackage, SimpleLogger logger )
        throws SuitableMethodNotAccessibleException, InvocationTargetException
    {
        return getMethod( targetClass, getMethodName(), new Class[]
            { SERVICE_REFERENCE_CLASS }, acceptPrivate, acceptPackage, logger );
    }

    private Method getServiceObjectsMethod( final Class<?> targetClass, boolean acceptPrivate, boolean acceptPackage, SimpleLogger logger )
        throws SuitableMethodNotAccessibleException, InvocationTargetException
    {
        if ( m_referenceScope == ReferenceMetadata.ReferenceScope.prototype )
        {
            return getMethod(targetClass, getMethodName(),
                new Class[] { SERVICE_OBJECTS_CLASS }, acceptPrivate, acceptPackage,
                logger);
        }
        return null;
    }


    /**
     * Returns a method taking a single parameter of the exact type declared
     * for the service reference or <code>null</code> if no such method exists.
     *
     *
     * @param targetClass The class in which to look for the method. Only this
     *      class is searched for the method.
     * @param acceptPrivate <code>true</code> if private methods should be
     *      considered.
     * @param acceptPackage <code>true</code> if package private methods should
     *      be considered.
     * @param logger
     * @return The requested method or <code>null</code> if no acceptable method
     *      can be found in the target class.
     * @throws SuitableMethodNotAccessibleException If a suitable method was
     *      found which is not accessible
     * @throws InvocationTargetException If an unexpected Throwable is caught
     *      trying to find the requested method.
     */
    private Method getServiceObjectMethod( final Class<?> targetClass, final Class<?> parameterClass, boolean acceptPrivate,
            boolean acceptPackage, SimpleLogger logger ) throws SuitableMethodNotAccessibleException, InvocationTargetException
    {
        return getMethod( targetClass, getMethodName(), new Class[]
            { parameterClass }, acceptPrivate, acceptPackage, logger );
    }


    /**
     * Returns a method taking a single object whose type is assignment
     * compatible with the declared service type or <code>null</code> if no
     * such method exists.
     *
     *
     * @param targetClass The class in which to look for the method. Only this
     *      class is searched for the method.
     * @param acceptPrivate <code>true</code> if private methods should be
     *      considered.
     * @param acceptPackage <code>true</code> if package private methods should
     *      be considered.
     * @param logger
     * @return The requested method or <code>null</code> if no acceptable method
     *      can be found in the target class.
     * @throws SuitableMethodNotAccessibleException If a suitable method was
     *      found which is not accessible
     */
    private Method getServiceObjectAssignableMethod( final Class<?> targetClass, final Class<?> parameterClass,
            boolean acceptPrivate, boolean acceptPackage, SimpleLogger logger ) throws SuitableMethodNotAccessibleException
    {
        // Get all potential bind methods
        Method candidateBindMethods[] = targetClass.getDeclaredMethods();
        boolean suitableNotAccessible = false;

        if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
        {
            logger.log(
                LogService.LOG_DEBUG,
                "getServiceObjectAssignableMethod: Checking " + candidateBindMethods.length
                    + " declared method in class " + targetClass.getName(), null );
        }

        // Iterate over them
        for ( int i = 0; i < candidateBindMethods.length; i++ )
        {
            Method method = candidateBindMethods[i];
            if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
            {
                logger.log( LogService.LOG_DEBUG, "getServiceObjectAssignableMethod: Checking " + method, null );
            }

            // Get the parameters for the current method
            Class[] parameters = method.getParameterTypes();

            // Select only the methods that receive a single
            // parameter
            // and a matching name
            if ( parameters.length == 1 && method.getName().equals( getMethodName() ) )
            {

                if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
                {
                    logger.log( LogService.LOG_DEBUG, "getServiceObjectAssignableMethod: Considering " + method, null );
                }

                // Get the parameter type
                final Class<?> theParameter = parameters[0];

                // Check if the parameter type is ServiceReference
                // or is assignable from the type specified by the
                // reference's interface attribute
                if ( theParameter.isAssignableFrom( parameterClass ) )
                {
                    if ( accept( method, acceptPrivate, acceptPackage, false ) )
                    {
                        return method;
                    }

                    // suitable method is not accessible, flag for exception
                    suitableNotAccessible = true;
                }
                else if ( logger.isLogEnabled( LogService.LOG_DEBUG ) )
                {
                    logger.log(
                        LogService.LOG_DEBUG,
                        "getServiceObjectAssignableMethod: Parameter failure: Required " + theParameter + "; actual "
                            + parameterClass.getName(), null );
                }

            }
        }

        // if one or more suitable methods which are not accessible is/are
        // found an exception is thrown
        if ( suitableNotAccessible )
        {
            throw new SuitableMethodNotAccessibleException();
        }

        // no method with assignment compatible argument found
        return null;
    }


    /**
     * Returns a method taking two parameters, the first being of the exact
     * type declared for the service reference and the second being a
     * <code>Map</code> or <code>null</code> if no such method exists.
     *
     *
     * @param targetClass The class in which to look for the method. Only this
     *      class is searched for the method.
     * @param acceptPrivate <code>true</code> if private methods should be
     *      considered.
     * @param acceptPackage <code>true</code> if package private methods should
     *      be considered.
     * @param logger
     * @return The requested method or <code>null</code> if no acceptable method
     *      can be found in the target class.
     * @throws SuitableMethodNotAccessibleException If a suitable method was
     *      found which is not accessible
     * @throws InvocationTargetException If an unexpected Throwable is caught
     *      trying to find the requested method.
     */
    private Method getServiceObjectWithMapMethod( final Class<?> targetClass, final Class<?> parameterClass,
            boolean acceptPrivate, boolean acceptPackage, SimpleLogger logger ) throws SuitableMethodNotAccessibleException,
        InvocationTargetException
    {
        return getMethod( targetClass, getMethodName(), new Class[]
            { parameterClass, MAP_CLASS }, acceptPrivate, acceptPackage, logger );
    }


    /**
     * Returns a method taking two parameters, the first being an object
     * whose type is assignment compatible with the declared service type and
     * the second being a <code>Map</code> or <code>null</code> if no such
     * method exists.
     *
     * @param targetClass The class in which to look for the method. Only this
     *      class is searched for the method.
     * @param acceptPrivate <code>true</code> if private methods should be
     *      considered.
     * @param acceptPackage <code>true</code> if package private methods should
     *      be considered.
     * @return The requested method or <code>null</code> if no acceptable method
     *      can be found in the target class.
     * @throws SuitableMethodNotAccessibleException If a suitable method was
     *      found which is not accessible
     */
    private Method getServiceObjectAssignableWithMapMethod( final Class<?> targetClass, final Class<?> parameterClass,
        boolean acceptPrivate, boolean acceptPackage ) throws SuitableMethodNotAccessibleException
    {
        // Get all potential bind methods
        Method candidateBindMethods[] = targetClass.getDeclaredMethods();
        boolean suitableNotAccessible = false;

        // Iterate over them
        for ( int i = 0; i < candidateBindMethods.length; i++ )
        {
            final Method method = candidateBindMethods[i];
            final Class[] parameters = method.getParameterTypes();
            if ( parameters.length == 2 && method.getName().equals( getMethodName() ) )
            {

                // parameters must be refclass,map
                if ( parameters[0].isAssignableFrom( parameterClass ) && parameters[1] == MAP_CLASS )
                {
                    if ( accept( method, acceptPrivate, acceptPackage, false ) )
                    {
                        return method;
                    }

                    // suitable method is not accessible, flag for exception
                    suitableNotAccessible = true;
                }
            }
        }

        // if one or more suitable methods which are not accessible is/are
        // found an exception is thrown
        if ( suitableNotAccessible )
        {
            throw new SuitableMethodNotAccessibleException();
        }

        // no method with assignment compatible argument found
        return null;
    }

    public <S, T> boolean getServiceObject( ComponentContextImpl<S> key, RefPair<S, T> refPair, BundleContext context, SimpleLogger logger )
    {
        //??? this resolves which we need.... better way?
        if ( refPair.getServiceObject(key) == null && methodExists( logger ) )
        {
            if ( m_paramTypes.contains(ParamType.serviceType) ) {
                return refPair.getServiceObject(key, context, logger);
            }
        }
        return true;
    }

    protected Object[] getParameters( Method method, BindParameters bp )
    {
        ComponentContextImpl key = bp.getComponentContext();
        Object[] result = new Object[ m_paramTypes.size()];
        RefPair<?, ?> refPair = bp.getRefPair();
        int i = 0;
        for ( ParamType pt: m_paramTypes ) {
            switch (pt) {
                case serviceReference:
                    result[i++] = refPair.getRef();
                    break;
               
                case serviceObjects:
                    result[i++] = refPair.getServiceObjects();
                    break;
               
                case map:
                    result[i++] = new ReadOnlyDictionary<String, Object>( refPair.getRef() );
                    break;
               
                case serviceType:
                    result[i++] = refPair.getServiceObject(key);
                    break;
               
                default: throw new IllegalStateException("unexpected ParamType: " + pt);
               
            }
        }
        return result;
    }


    protected String getMethodNamePrefix()
    {
        return "bind";
    }

}
TOP

Related Classes of org.apache.felix.scr.impl.helper.BindMethod

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.