KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > fortress > impl > lookup > FortressServiceManager


1 /*
2  * Copyright 2003-2004 The Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.avalon.fortress.impl.lookup;
19
20 import org.apache.avalon.fortress.Container;
21 import org.apache.avalon.fortress.impl.AbstractContainer;
22 import org.apache.avalon.fortress.impl.handler.ComponentHandler;
23 import org.apache.avalon.framework.component.ComponentSelector;
24 import org.apache.avalon.framework.service.ServiceException;
25 import org.apache.avalon.framework.service.ServiceManager;
26 import org.apache.avalon.framework.service.ServiceSelector;
27 import org.apache.avalon.framework.service.WrapperServiceSelector;
28
29 import java.util.Collections JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Map JavaDoc;
32
33 /**
34  * This is the Default ServiceManager for the Container. It provides
35  * a very simple abstraction, and makes it easy for the Container to manage
36  * the references.
37  *
38  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
39  * @version CVS $Revision: 1.20 $ $Date: 2004/02/28 15:16:25 $
40  */

41 public class FortressServiceManager
42     implements ServiceManager
43 {
44     private final Container m_container;
45     private final Map JavaDoc m_used;
46     private final ServiceManager m_parent;
47
48     /**
49      * This constructor is for a ContainerComponentManager with a parent
50      * ComponentLocator
51      * @param container the impl
52      * @param parent the parent service manager
53      * @throws NullPointerException if the supplied impl is null
54      */

55     public FortressServiceManager( final Container container,
56                                    final ServiceManager parent ) throws NullPointerException JavaDoc
57     {
58         if ( null == container )
59         {
60             throw new NullPointerException JavaDoc( "impl" );
61         }
62
63         m_parent = parent;
64         m_container = container;
65         m_used = Collections.synchronizedMap(new HashMap JavaDoc());
66     }
67
68     public Object JavaDoc lookup( final String JavaDoc role )
69         throws ServiceException
70     {
71         final Lookup lookup = parseRole( role );
72
73         if ( !m_container.has( lookup.m_role, lookup.m_hint ) )
74         {
75             return m_parent.lookup( role );
76         }
77
78         final Object JavaDoc result = m_container.get( lookup.m_role, lookup.m_hint );
79         if ( result instanceof ServiceSelector )
80         {
81             return result;
82         }
83
84         if ( result instanceof ComponentSelector )
85         {
86             return new WrapperServiceSelector( lookup.m_role, (ComponentSelector) result );
87         }
88
89         if ( !( result instanceof ComponentHandler ) )
90         {
91             final String JavaDoc message = "Invalid entry in component manager";
92             throw new ServiceException( role, message );
93         }
94
95         try
96         {
97             final ComponentHandler handler = (ComponentHandler) result;
98             final Object JavaDoc component = handler.get();
99
100             m_used.put( new ComponentKey( component ), handler );
101             return component;
102         }
103         catch ( final ServiceException ce )
104         {
105             throw ce; // rethrow
106
}
107         catch ( final Exception JavaDoc e )
108         {
109             final String JavaDoc message =
110                 "Could not return a reference to the Component";
111             throw new ServiceException( role, message, e );
112         }
113     }
114
115     public boolean hasService( final String JavaDoc role )
116     {
117         final Lookup lookup = parseRole( role );
118
119         if ( m_container.has( lookup.m_role, lookup.m_hint ) )
120         {
121             return true;
122         }
123         else
124         {
125             return null != m_parent ? m_parent.hasService( role ) : false;
126         }
127     }
128
129     public void release( final Object JavaDoc component )
130     {
131         final ComponentHandler handler = (ComponentHandler) m_used.remove( new ComponentKey( component ) );
132         if ( null == handler )
133         {
134             if ( null == m_parent )
135             {
136                 /* This is a purplexing problem. SOmetimes the m_used hash
137                  * returns null for the component--usually a ThreadSafe
138                  * component. When there is no handler and no parent, that
139                  * is an error condition--but if the component is usually
140                  * ThreadSafe, the impact is essentially nill.
141                  */

142                 //Pete: This occurs when objects are released more often than
143
//when they are aquired
144
//Pete: It also happens when a release of a ComponentSelector occurs
145
}
146             else
147             {
148                 m_parent.release( component );
149             }
150         }
151         else
152         {
153             handler.put( component );
154         }
155     }
156
157     private Lookup parseRole( final String JavaDoc role )
158     {
159         final Lookup lookup = new Lookup();
160         lookup.m_role = role;
161         lookup.m_hint = AbstractContainer.DEFAULT_ENTRY;
162
163         if ( role.endsWith( "Selector" ) )
164         {
165             lookup.m_role = role.substring( 0, role.length() - "Selector".length() );
166             lookup.m_hint = AbstractContainer.SELECTOR_ENTRY;
167         }
168
169         final int index = role.lastIndexOf( "/" );
170
171         // needs to be further than the first character
172
if ( index > 0 )
173         {
174             lookup.m_role = role.substring( 0, index );
175             lookup.m_hint = role.substring( index + 1 );
176         }
177
178         return lookup;
179     }
180
181     private final static class Lookup
182     {
183         String JavaDoc m_role;
184         String JavaDoc m_hint;
185     }
186 }
187
Popular Tags