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 import java.util.ServiceLoader; 022 023 import net.dpml.lang.ServiceRegistry; 024 025 /** 026 * Simple service registry implementation that selects the first service 027 * that is type assignable from the list of service instance supplied to 028 * the registry constructor. 029 * 030 * @author <a href="http://www.dpml.net">Digital Product Management Laboratory</a> 031 * @version 2.0.1 032 */ 033 public class SimpleServiceRegistry implements ServiceRegistry 034 { 035 private final ServiceRegistry m_parent; 036 private final Object[] m_args; 037 038 /** 039 * Creation of a new service registry with no parent. 040 * @param args an ordered sequence of thread-safe services 041 */ 042 public SimpleServiceRegistry( Object... args ) 043 { 044 this( null, args ); 045 } 046 047 /** 048 * Creation of a new service registry with no parent. 049 * @param parent an optional fallback registry 050 * @param args an ordered sequence of thread-safe services 051 */ 052 public SimpleServiceRegistry( ServiceRegistry parent, Object... args ) 053 { 054 if( null == args ) 055 { 056 throw new NullPointerException( "args" ); 057 } 058 m_parent = parent; 059 m_args = args; 060 } 061 062 /** 063 * Matches a service in the registry with the supplied type. If no 064 * match is found and a parent registry has been delclared, the lookup 065 * request is passed onto the parent registry, otherwise null is 066 * returned. 067 */ 068 public <T>T lookup( Class<T> type ) 069 { 070 for( Object object : m_args ) 071 { 072 if( null != object ) 073 { 074 Class c = object.getClass(); 075 if( type.isAssignableFrom( c ) ) 076 { 077 return type.cast( object ); 078 } 079 } 080 } 081 if( null != m_parent ) 082 { 083 return m_parent.lookup( type ); 084 } 085 return null; 086 } 087 } 088