Package org.apache.hivemind.service.impl

Source Code of org.apache.hivemind.service.impl.AutowiringImpl

// Copyright 2007 The Apache Software Foundation
//
// Licensed 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.hivemind.service.impl;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.ErrorHandler;
import org.apache.hivemind.internal.RegistryInfrastructure;
import org.apache.hivemind.service.Autowiring;
import org.apache.hivemind.service.AutowiringStrategy;
import org.apache.hivemind.util.PropertyUtils;

/**
* Implementation of {@link Autowiring}.
* Skips properties of primitive type and the standard java data types (String, Double etc.).
* Properties that are already assigned are skipped too.
* Delegates the autowiring to implementations of {@link AutowiringStrategy}.
* If errors occur they are passed to an {@link ErrorHandler}. Depending on its
* implementation the wiring either continues with the next property or an exception
* is thrown.
*
* @author Achim Huegen
*/
public class AutowiringImpl implements Autowiring
{
    private static final Log LOG = LogFactory.getLog(AutowiringImpl.class);

    private Map _strategies = new TreeMap();

    private RegistryInfrastructure _registry;
   
    private ErrorHandler _errorHandler;
   
    private static Set SKIPPED_PROPERTY_TYPES = new HashSet();
   
    static {
        SKIPPED_PROPERTY_TYPES.add(String.class);
        SKIPPED_PROPERTY_TYPES.add(Double.class);
        SKIPPED_PROPERTY_TYPES.add(Integer.class);
        SKIPPED_PROPERTY_TYPES.add(Float.class);
        SKIPPED_PROPERTY_TYPES.add(Byte.class);
        SKIPPED_PROPERTY_TYPES.add(Short.class);
        SKIPPED_PROPERTY_TYPES.add(Character.class);
    }
   
    /**
     * @param registry  reference to registry
     * @param strategyContributions  list with instances of {@link AutowiringStrategyContribution}
     * @param errorHandler  handler for dealing with recoverable errors.
     */
    public AutowiringImpl(RegistryInfrastructure registry, List strategyContributions, ErrorHandler errorHandler)
    {
        _registry = registry;
        _errorHandler = errorHandler;
        // Add the strategies in default order to map
        for (Iterator iter = strategyContributions.iterator(); iter.hasNext();)
        {
            AutowiringStrategyContribution c = (AutowiringStrategyContribution) iter.next();
            _strategies.put(c.getName(), c.getStrategy());
        }
    }

    /**
     * @see org.apache.hivemind.service.Autowiring#autowireProperties(java.lang.Object)
     */
    public Object autowireProperties(Object target)
    {
        Set writeablePropertiesSet = new HashSet(PropertyUtils.getWriteableProperties(target));
        String[] writableProperties = (String[]) writeablePropertiesSet.toArray(new String[writeablePropertiesSet.size()]);
        return autowireProperties(target, writableProperties);
    }
   
    /**
     * @see org.apache.hivemind.service.Autowiring#autowireProperties(java.lang.Object, java.lang.String[])
     */
    public Object autowireProperties(Object target, String[] propertyNames)
    {
        for (int i = 0; i < propertyNames.length; i++)
        {
            String propertyName = propertyNames[i];
            if (isPropertyWirable(target, propertyName)) {
                autowirePropertyAllStrategies(target, propertyName);
            }
        }
        return target;
    }

    /**
     * Wires a single property by calling all available strategies in the configured order
     * until a strategy signals that the property has been wired.
     *
     * @param target
     * @param propertyName
     */
    private void autowirePropertyAllStrategies(Object target, String propertyName)
    {
        try
        {
            for (Iterator iter = _strategies.values().iterator(); iter.hasNext();)
            {
                AutowiringStrategy strategy = (AutowiringStrategy) iter.next();
                boolean isWired = strategy.autowireProperty(_registry, target, propertyName);
                // Stop if strategy has wired the property
                if (isWired)
                    break;
            }
        }
        catch (Exception ex)
        {
            _errorHandler.error(
                    LOG,
                    ServiceMessages.autowirePropertyFailure(propertyName, target.getClass(), ex),
                    null,
                    ex);
        }
    }
   
    /**
     * @see org.apache.hivemind.service.Autowiring#autowireProperties(java.lang.String, java.lang.Object)
     */
    public Object autowireProperties(String strategy, Object target)
    {
        Set writeablePropertiesSet = new HashSet(PropertyUtils.getWriteableProperties(target));
        String[] writableProperties = (String[]) writeablePropertiesSet.toArray(new String[writeablePropertiesSet.size()]);
        return autowireProperties(strategy, target, writableProperties);
    }

    /**
     * @see org.apache.hivemind.service.Autowiring#autowireProperties(java.lang.String, java.lang.Object, java.lang.String[])
     */
    public Object autowireProperties(String strategyName, Object target, String[] propertyNames)
    {
        for (int i = 0; i < propertyNames.length; i++)
        {
            String propertyName = propertyNames[i];
            if (isPropertyWirable(target, propertyName)) {
                autowireProperty(strategyName, target, propertyName);
            }
        }
        return target;
    }
   
    /**
     * @return  true if the property is wirable. Primitive types and the types in
     *  SKIPPED_PROPERTY_TYPES are ignored. If the property is already assigned it is
     *  ignored too.
     */
    private boolean isPropertyWirable(Object target, String propertyName)
    {
        Class propertyType = PropertyUtils.getPropertyType(target, propertyName);
        if (propertyType.isPrimitive() || SKIPPED_PROPERTY_TYPES.contains(propertyType)) {
            return false;
        } else {
            // Don't wire if value is already assigned
            if (PropertyUtils.isReadable(target, propertyName))
                return PropertyUtils.read(target, propertyName) == null;
            else return true;
        }
    }

    /**
     * Wires a single property by using the strategy <code>strategyName</code>
     * @param strategyName
     * @param target
     * @param propertyName
     * @return true if wiring succeeded
     */
    private boolean autowireProperty(String strategyName, Object target, String propertyName)
    {
        try
        {
           AutowiringStrategy strategy = (AutowiringStrategy) _strategies.get(strategyName);
           if (strategy == null) {
               throw new ApplicationRuntimeException(ServiceMessages.unknownStrategy(strategyName));
           }
           return strategy.autowireProperty(_registry, target, propertyName);
        }
        catch (Exception ex)
        {
            _errorHandler.error(
                    LOG,
                    ServiceMessages.autowirePropertyFailure(propertyName, target.getClass(), ex),
                    null,
                    ex);
        }
        return false;
    }

}
TOP

Related Classes of org.apache.hivemind.service.impl.AutowiringImpl

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.