View Javadoc

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 }