Package org.apache.hivemind.service.impl

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

// Copyright 2004, 2005 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.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.hivemind.ErrorLog;
import org.apache.hivemind.HiveMind;
import org.apache.hivemind.Location;
import org.apache.hivemind.impl.BaseLocatable;
import org.apache.hivemind.service.EventLinker;

/**
* Implementation of {@link org.apache.hivemind.service.EventLinker}. Will output warnings whenever
* a consumer can't be registered for at least one event set (which can happen when the consumer
* does not implement the necessary interfaces).
*
* @author Howard Lewis Ship
*/
public class EventLinkerImpl extends BaseLocatable implements EventLinker
{
    private ErrorLog _errorLog;

    /**
     * Map of {@link java.beans.EventSetDescriptor}[], keyed on producer class.
     */
    private Map _producerEventSets;

    public EventLinkerImpl(ErrorLog errorLog)
    {
        _errorLog = errorLog;
    }

    public void addEventListener(Object producer, String eventSetName, Object consumer,
            Location location)
    {
        EventSetDescriptor[] sets = getEventSets(producer);
        boolean nameMatch = HiveMind.isNonBlank(eventSetName);
        Class consumerClass = consumer.getClass();

        int count = 0;
        for (int i = 0; i < sets.length; i++)
        {
            EventSetDescriptor set = sets[i];
            String name = set.getName();

            if (nameMatch)
            {
                if (!eventSetName.equals(name))
                    continue;

                if (isAssignable(set, consumerClass))
                    addEventListener(producer, set, consumer, location);
                else
                {
                    _errorLog.error(
                            ServiceMessages.notCompatibleWithEvent(consumer, set, producer),
                            location,
                            null);
                }

                return;
            }

            // Not matching on name, add anything that fits!

            if (isAssignable(set, consumerClass))
            {
                addEventListener(producer, set, consumer, location);
                count++;
            }
        }

        if (count == 0)
        {
            if (nameMatch)
                _errorLog.error(
                        ServiceMessages.noSuchEventSet(producer, eventSetName),
                        location,
                        null);
            else
                _errorLog.error(ServiceMessages.noEventMatches(consumer, producer), location, null);
        }
    }

    private boolean isAssignable(EventSetDescriptor set, Class consumerClass)
    {
        return set.getListenerType().isAssignableFrom(consumerClass);
    }

    private void addEventListener(Object producer, EventSetDescriptor set, Object consumer,
            Location location)
    {
        Method m = set.getAddListenerMethod();

        try
        {
            m.invoke(producer, new Object[]
            { consumer });
        }
        catch (Exception ex)
        {
            _errorLog.error(ServiceMessages.unableToAddListener(
                    producer,
                    set,
                    consumer,
                    location,
                    ex), location, ex);

        }
    }

    private EventSetDescriptor[] getEventSets(Object producer)
    {
        return getEventSets(producer.getClass());
    }

    private synchronized EventSetDescriptor[] getEventSets(Class producerClass)
    {
        EventSetDescriptor[] result = null;

        if (_producerEventSets == null)
            _producerEventSets = new HashMap();
        else
            result = (EventSetDescriptor[]) _producerEventSets.get(producerClass);

        if (result == null)
        {
            result = findEventSets(producerClass);

            _producerEventSets.put(producerClass, result);
        }

        return result;
    }

    private EventSetDescriptor[] findEventSets(Class producerClass)
    {
        synchronized (HiveMind.INTROSPECTOR_MUTEX)
        {
            try
            {
                BeanInfo beanInfo = Introspector.getBeanInfo(producerClass);

                // Will return an empty array (not null) when the class contains
                // no event sets.

                return beanInfo.getEventSetDescriptors();
            }
            catch (IntrospectionException ex)
            {
                _errorLog.error(
                        ServiceMessages.unableToIntrospectClass(producerClass, ex),
                        null,
                        ex);

                return new EventSetDescriptor[0];
            }
        }
    }

}
TOP

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

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.