1 //----------------------------------------------------------------------
2 //
3 // PerfectJPattern: "Design patterns are good but components are better!"
4 // ServiceLocator.java Copyright (c) 2009 Giovanni Azua Garcia
5 // bravegag@hotmail.com
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 3
10 // of the License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, see <http://www.gnu.org/licenses/>.
19 //
20 //----------------------------------------------------------------------
21 package org.perfectjpattern.jee.business.servicelocator;
22
23 import java.util.*;
24
25 import javax.naming.*;
26
27 import org.perfectjpattern.core.api.creational.singleton.*;
28 import org.perfectjpattern.jee.api.business.servicelocator.*;
29
30 /**
31 * Generic componentized implementation of {@link IServiceLocator}. Provides
32 * concrete {@link IServiceLocator} implementations with reusable JNDI service
33 * lookup and Services caching.
34 * <br/><br/>
35 * Note that all initial properties are loaded from the <code>jndi.properties
36 * </code> file
37 *
38 * @author <a href="mailto:bravegag@hotmail.com">Giovanni Azua</a>
39 * @version $Revision: 1.0 $Date: Feb 7, 2009 2:35:20 PM $
40 */
41 public final
42 class ServiceLocator
43 implements IServiceLocator, ISingleton
44 {
45 //------------------------------------------------------------------------
46 // public
47 //------------------------------------------------------------------------
48 /**
49 * Returns Singleton instance of {@link IServiceLocator}
50 *
51 * @return Singleton instance of {@link IServiceLocator}
52 */
53 public static IServiceLocator
54 getInstance()
55 {
56 return INSTANCE;
57 }
58
59 //------------------------------------------------------------------------
60 /**
61 * {@inheritDoc}
62 */
63 @SuppressWarnings("unchecked")
64 public <S> S
65 locate(String aName)
66 throws IllegalArgumentException
67 {
68 S myService = null;
69
70 if (theServiceCache.containsKey(aName))
71 {
72 myService = (S) theServiceCache.get(aName);
73 }
74 else
75 {
76 try
77 {
78 myService = (S) theContext.lookup(aName);
79
80 assert myService != null : "'myService' must not be null";
81
82 // save in cache
83 theServiceCache.put(aName, myService);
84 }
85 catch (NamingException anException)
86 {
87 // propagate the exception
88 throw new ServiceLocatorException(anException);
89 }
90 }
91
92 return myService;
93 }
94
95 //------------------------------------------------------------------------
96 /**
97 * {@inheritDoc}
98 */
99 public void
100 shutdown()
101 throws ServiceLocatorException
102 {
103 try
104 {
105 theContext.close();
106 }
107 catch (NamingException anException)
108 {
109 // propagate the exception
110 throw new ServiceLocatorException(anException);
111 }
112 }
113
114 //------------------------------------------------------------------------
115 // private
116 //------------------------------------------------------------------------
117 private
118 ServiceLocator()
119 {
120 try
121 {
122 theContext = new InitialContext();
123 }
124 catch (NamingException anException)
125 {
126 // propagate the exception
127 throw new ServiceLocatorException(anException);
128 }
129 }
130
131 //------------------------------------------------------------------------
132 // members
133 //------------------------------------------------------------------------
134 private static final IServiceLocator INSTANCE = new ServiceLocator();
135 private final Context theContext;
136 private final Map<String, Object> theServiceCache =
137 new HashMap<String, Object>();
138 }