Package org.apache.tapestry.ioc.internal

Source Code of org.apache.tapestry.ioc.internal.ServiceBinderImpl

// 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.tapestry.ioc.internal;

import org.apache.tapestry.ioc.*;
import org.apache.tapestry.ioc.annotations.EagerLoad;
import org.apache.tapestry.ioc.annotations.Marker;
import org.apache.tapestry.ioc.annotations.Scope;
import org.apache.tapestry.ioc.def.ServiceDef;
import org.apache.tapestry.ioc.internal.util.CollectionFactory;
import static org.apache.tapestry.ioc.internal.util.Defense.notBlank;
import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
import org.apache.tapestry.ioc.internal.util.InternalUtils;
import org.apache.tapestry.ioc.internal.util.OneShotLock;
import org.apache.tapestry.ioc.services.ClassFactory;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Set;

public class ServiceBinderImpl implements ServiceBinder, ServiceBindingOptions
{
    private final OneShotLock _lock = new OneShotLock();

    private final ServiceDefAccumulator _accumulator;

    private final ClassFactory _classFactory;

    private final Set<Class> _defaultMarkers;

    public ServiceBinderImpl(ServiceDefAccumulator accumulator, ClassFactory classFactory, Set<Class> defaultMarkers)
    {
        _accumulator = accumulator;
        _classFactory = classFactory;
        _defaultMarkers = defaultMarkers;
    }

    private String _serviceId;

    private Class _serviceInterface;

    private final Set<Class> _markers = CollectionFactory.newSet();

    private Class _serviceImplementation;

    private boolean _eagerLoad;

    private String _scope;

    public void finish()
    {
        _lock.lock();

        flush();
    }

    protected void flush()
    {
        if (_serviceInterface == null) return;

        final Constructor constructor = findConstructor();

        ObjectCreatorSource source = new ObjectCreatorSource()
        {
            public ObjectCreator constructCreator(ServiceBuilderResources resources)
            {
                return new ConstructorServiceCreator(resources, getDescription(), constructor);
            }

            public String getDescription()
            {
                return _classFactory.getConstructorLocation(constructor).toString();
            }
        };

        // Combine service-specific markers with those inherited form the module.
        Set<Class> markers = CollectionFactory.newSet(_defaultMarkers);
        markers.addAll(_markers);

        ServiceDef serviceDef = new ServiceDefImpl(_serviceInterface, _serviceId, markers, _scope, _eagerLoad, source);

        _accumulator.addServiceDef(serviceDef);

        _serviceId = null;
        _serviceInterface = null;
        _markers.clear();
        _serviceImplementation = null;
        _eagerLoad = false;
        _scope = null;
    }

    private Constructor findConstructor()
    {
        Constructor result = InternalUtils.findAutobuildConstructor(_serviceImplementation);

        if (result == null) throw new RuntimeException(IOCMessages
                .noConstructor(_serviceImplementation, _serviceId));

        return result;
    }

    public <T> ServiceBindingOptions bind(Class<T> implementationClass)
    {
        return bind(implementationClass, implementationClass);
    }

    public <T> ServiceBindingOptions bind(Class<T> serviceInterface, Class<? extends T> serviceImplementation)
    {
        notNull(serviceInterface, "serviceIterface");
        notNull(serviceImplementation, "serviceImplementation");

        _lock.check();

        flush();

        _serviceInterface = serviceInterface;
        _serviceImplementation = serviceImplementation;

        // Set defaults for the other properties.

        _eagerLoad = serviceImplementation.getAnnotation(EagerLoad.class) != null;
        _serviceId = serviceInterface.getSimpleName();

        Scope scope = serviceImplementation.getAnnotation(Scope.class);

        _scope = scope != null ? scope.value() : IOCConstants.DEFAULT_SCOPE;

        Marker marker = serviceImplementation.getAnnotation(Marker.class);

        if (marker != null)
        {
            InternalUtils.validateMarkerAnnotations(marker.value());
            _markers.addAll(Arrays.asList(marker.value()));
        }

        return this;
    }

    public ServiceBindingOptions eagerLoad()
    {
        _lock.check();

        _eagerLoad = true;

        return this;
    }

    public ServiceBindingOptions withId(String id)
    {
        notBlank(id, "id");

        _lock.check();

        _serviceId = id;

        return this;
    }

    public ServiceBindingOptions scope(String scope)
    {
        notBlank(scope, "scope");

        _lock.check();

        _scope = scope;

        return this;
    }

    public <T extends Annotation> ServiceBindingOptions withMarker(Class<T>... marker)
    {
        _lock.check();

        InternalUtils.validateMarkerAnnotations(marker);

        _markers.addAll(Arrays.asList(marker));

        return this;
    }

}
TOP

Related Classes of org.apache.tapestry.ioc.internal.ServiceBinderImpl

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.