1 /*
2 * Copyright (c) 2005-2011, Fraunhofer-Gesellschaft
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * (1) Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the disclaimer at the end.
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * (2) Neither the name of Fraunhofer nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * DISCLAIMER
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
35 package org.ogf.graap.wsag.client.api;
36
37 import java.io.InputStream;
38 import java.util.Properties;
39
40 import javax.security.auth.login.LoginContext;
41
42 import org.w3.x2005.x08.addressing.EndpointReferenceType;
43
44 /*
45 * AgreementFactoryLocator
46 */
47
48 /**
49 * The Locator returns a new wsag4j client instances. The lookup mechanism for a client implementation class
50 * is as follows:
51 * <ol>
52 * <li>load the class specified in the system property <code>client interface class name</code>, for example
53 * {@linkplain org.ogf.graap.wsag.client.api.AgreementFactoryRegistryClient}</li>
54 * <li>load the class specified in the {@value #APP_CONFIG_FILENAME} file</li>
55 * <li>load the class specified in the {@value #IMPLEMENTATION_CONFIG_FILENAME} file</li>
56 * </ol>
57 *
58 * The key used in the configuration (system property) corresponds to the name of the client interface.
59 *
60 *
61 * @param <T>
62 * the type of the client
63 *
64 * @author Oliver Waeldrich
65 *
66 */
67 public class ClientLocator<T>
68 {
69 /**
70 * client implementation configuration
71 */
72 private static final String IMPLEMENTATION_CONFIG_FILENAME = "/META-INF"
73 + ClientFactory.DEFAULT_CONFIGURATION_FILE;
74
75 /**
76 * application configuration
77 */
78 private static final String APP_CONFIG_FILENAME = ClientFactory.DEFAULT_CONFIGURATION_FILE;
79
80 /**
81 * The name of the client interface class.
82 */
83 private final String configurationKey;
84
85 private final String implementationClassFromConfig;
86
87 /**
88 * Instantiates a new client locator.
89 *
90 * @param clazz
91 * the client class
92 */
93 protected ClientLocator( Class<T> clazz )
94 {
95 configurationKey = clazz.getName();
96 implementationClassFromConfig = readClassFromConfig();
97 }
98
99 private synchronized ClientFactory<T> newClientFactoryInstance()
100 {
101 return newClientFactoryInstance( null );
102 }
103
104 private synchronized ClientFactory<T> newClientFactoryInstance( String alternativeConfiguration )
105 {
106 //
107 // read from system properties
108 //
109 String clazzName =
110 System.getProperties().getProperty( configurationKey, implementationClassFromConfig );
111
112 if ( alternativeConfiguration != null )
113 {
114 clazzName = readClassFromConfigFile( alternativeConfiguration, clazzName );
115 }
116
117 if ( ( clazzName == null ) || "".equals( clazzName ) )
118 {
119 throw new RuntimeException( "failed to lookup client factory implementation for interface"
120 + configurationKey );
121 }
122
123 //
124 // instantiate locator class
125 //
126 try
127 {
128 @SuppressWarnings( "unchecked" )
129 Class<ClientFactory<T>> clazz =
130 (Class<ClientFactory<T>>) Class.forName( clazzName, true,
131 ClientLocator.class.getClassLoader() );
132
133 ClientFactory<T> instance = clazz.newInstance();
134 return instance;
135 }
136 catch ( Exception e )
137 {
138 throw new RuntimeException( "failed to instantiate client factory implementation for interface "
139 + configurationKey );
140 }
141 catch ( Error e )
142 {
143 System.err.println( "failed to instantiate client factory implementation for interface "
144 + configurationKey );
145 System.err.println( e.getMessage() );
146 throw e;
147 }
148 }
149
150 private String readClassFromConfig()
151 {
152 //
153 // read from client implementation configuration, no default value
154 //
155 String clientImplConfig = readClassFromConfigFile( IMPLEMENTATION_CONFIG_FILENAME, null );
156
157 //
158 // read from application configuration, default value from client impl configuration
159 //
160 String appConfig = readClassFromConfigFile( APP_CONFIG_FILENAME, clientImplConfig );
161 return appConfig;
162 }
163
164 /**
165 * Returns the locator class name form the wsag4j-client.config file at he specified path. If the property
166 * does not exist the default value is returned.
167 *
168 * @return the locator class name
169 */
170 private String readClassFromConfigFile( String fileName, String defaultValue )
171 {
172 Properties properties = new Properties();
173 try
174 {
175 InputStream inputStream = ClientLocator.class.getResourceAsStream( fileName );
176 properties.load( inputStream );
177 }
178 catch ( Exception e )
179 {
180 // failed to lookup config file
181 }
182
183 String fromConfig = properties.getProperty( configurationKey, defaultValue );
184
185 return fromConfig;
186 }
187
188 /**
189 * Returns a new client instance.
190 *
191 * @param epr
192 * the client epr
193 *
194 * @return the new client
195 *
196 * @throws Exception
197 * client instantiation error
198 */
199 public T newInstance( EndpointReferenceType epr ) throws Exception
200 {
201 return newClientFactoryInstance().newInstance( epr );
202 }
203
204 /**
205 * Returns a new client instance.
206 *
207 * @param epr
208 * the client epr
209 *
210 * @param context
211 * client login context
212 *
213 * @return the new client
214 *
215 * @throws Exception
216 * client instantiation error
217 */
218 public T newInstance( EndpointReferenceType epr, LoginContext context ) throws Exception
219 {
220 return newClientFactoryInstance().newInstance( epr, context );
221 }
222
223 /**
224 * Returns a new client instance providing an alternative client configuration file.
225 *
226 * @param epr
227 * the client epr
228 *
229 * @param altConfig
230 * alternative client factory implementation
231 *
232 * @return the new client
233 *
234 * @throws Exception
235 * client instantiation error
236 */
237 protected T newInstance( EndpointReferenceType epr, String altConfig ) throws Exception
238 {
239 return newClientFactoryInstance( altConfig ).newInstance( epr );
240 }
241
242 /**
243 * Returns a new client instance providing an alternative client configuration file.
244 *
245 * @param epr
246 * the client epr
247 *
248 * @param context
249 * client login context
250 *
251 * @param altConfig
252 * alternative client factory implementation
253 *
254 * @return the new client
255 *
256 * @throws Exception
257 * client instantiation error
258 */
259 protected T newInstance( EndpointReferenceType epr, LoginContext context, String altConfig )
260 throws Exception
261 {
262 return newClientFactoryInstance( altConfig ).newInstance( epr, context );
263 }
264 }