001 /*
002 * Copyright 2006 Stephen J. McConnell.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.lang;
020
021 /**
022 * Simple service registry implementation that selects the first service
023 * that is type assignable from the list of service instance supplied to
024 * the registry constructor.
025 *
026 * @author <a href="http://www.dpml.net">Digital Product Management Library</a>
027 * @version 2.1.1
028 */
029 public class SimpleServiceRegistry implements ServiceRegistry
030 {
031 private final ServiceRegistry m_parent;
032 private final Object[] m_args;
033
034 /**
035 * Creation of a new service registry with no parent.
036 * @param args an ordered sequence of thread-safe services
037 */
038 public SimpleServiceRegistry( Object... args )
039 {
040 this( null, args );
041 }
042
043 /**
044 * Creation of a new service registry with no parent.
045 * @param parent an optional fallback registry
046 * @param args an ordered sequence of thread-safe services
047 */
048 public SimpleServiceRegistry( ServiceRegistry parent, Object... args )
049 {
050 if( null == args )
051 {
052 throw new NullPointerException( "args" );
053 }
054 m_parent = parent;
055 m_args = args;
056 }
057
058 /**
059 * Matches a service in the registry with the supplied type. If no
060 * match is found and a parent registry has been delclared, the lookup
061 * request is passed onto the parent registry, otherwise null is
062 * returned.
063 * @param type the service type
064 * @return an instance of the type or null if the type could not be resolved
065 */
066 public <T>T lookup( Class<T> type )
067 {
068 for( Object object : m_args )
069 {
070 if( null != object )
071 {
072 Class c = object.getClass();
073 if( type.isAssignableFrom( c ) )
074 {
075 return type.cast( object );
076 }
077 }
078 }
079 if( null != m_parent )
080 {
081 return m_parent.lookup( type );
082 }
083 return null;
084 }
085 }
086