View Javadoc

1   /*
2    * Copyright 2005,2009 Ivan SZKIBA
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.ini4j.spi;
17  
18  import java.io.BufferedReader;
19  import java.io.InputStream;
20  import java.io.InputStreamReader;
21  
22  /**
23   * JDK JAR Services API alap� service keres� oszt�ly.
24   *
25   * @author Szkiba Iv�n
26   * @version $Name:  $
27   */
28  final class ServiceFinder
29  {
30      private static final String SERVICES_PATH = "META-INF/services/";
31  
32      private ServiceFinder()
33      {
34      }
35  
36      /**
37       * Service objektum keres�s �s p�ld�nyos�t�s
38       *
39       * a JDK JAR specifik�ci�ban defini�lt <B>Services API</B>-nak
40       * megfelel�en service oszt�ly keres�s, majd pedig p�ld�ny k�pz�s a context
41       * ClassLoader seg�ts�g�vel.</p><p>
42       * Az implement�l� oszt�ly n�v keres�se a <CODE>serviceId</CODE> nev�
43       * system property vizsg�lat�val kezd�dik. Amennyiben nincs ilyen
44       * property, �gy a keres�s a
45       * <CODE>/META-INF/services/<I>serviceId</I></CODE> nev� file tartalm�val
46       * folytat�dik. Amennyiben nincs ilyen nev� file, �gy a param�terk�nt �tadott
47       * <CODE>defaultService</CODE> lesz az oszt�ly neve.</p><p>
48       * A fenti keres�st k�vet�en t�rt�nik a p�ld�ny k�pz�s. A visszat�r�si
49       * �rt�k mindig egy val�di objektum, l�v�n minden hiba exception-t gener�l.
50       * @param <T> type
51       * @param clazz keresett oszt�ly/service neve
52       * @throws IllegalArgumentException keres�si vagy p�ld�nyos�t�si hiba eset�n
53       * @return a keresett oszt�ly implement�l� objektum
54       */
55      static <T> T findService(Class<T> clazz)
56      {
57          try
58          {
59  
60              // ez a cast nem lenne szükséges, de úgy a ClassCastException csak a hívónál jön...
61              return clazz.cast(findServiceClass(clazz).newInstance());
62          }
63          catch (Exception x)
64          {
65              throw (IllegalArgumentException) new IllegalArgumentException("Provider " + clazz.getName() + " could not be instantiated: " + x)
66                .initCause(x);
67          }
68      }
69  
70      @SuppressWarnings(Warnings.UNCHECKED)
71      static <T> Class<? extends T> findServiceClass(Class<T> clazz) throws IllegalArgumentException
72      {
73          ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
74          String serviceClassName = findServiceClassName(clazz.getName());
75          Class<T> ret = clazz;
76  
77          if (serviceClassName != null)
78          {
79              try
80              {
81                  ret = (Class<T>) ((classLoader == null) ? Class.forName(serviceClassName) : classLoader.loadClass(serviceClassName));
82              }
83              catch (ClassNotFoundException x)
84              {
85                  throw (IllegalArgumentException) new IllegalArgumentException("Provider " + serviceClassName + " not found").initCause(x);
86              }
87          }
88  
89          return ret;
90      }
91  
92      static String findServiceClassName(String serviceId) throws IllegalArgumentException
93      {
94          String serviceClassName = null;
95  
96          // Use the system property first
97          try
98          {
99              String systemProp = System.getProperty(serviceId);
100 
101             if (systemProp != null)
102             {
103                 serviceClassName = systemProp;
104             }
105         }
106         catch (SecurityException x)
107         {
108             assert true;
109         }
110 
111         if (serviceClassName == null)
112         {
113             serviceClassName = loadLine(SERVICES_PATH + serviceId);
114         }
115 
116         return serviceClassName;
117     }
118 
119     private static String loadLine(String servicePath)
120     {
121         String ret = null;
122 
123         // try to find services in CLASSPATH
124         try
125         {
126             InputStream is = null;
127             ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
128 
129             if (classLoader == null)
130             {
131                 is = ClassLoader.getSystemResourceAsStream(servicePath);
132             }
133             else
134             {
135                 is = classLoader.getResourceAsStream(servicePath);
136             }
137 
138             if (is != null)
139             {
140                 BufferedReader rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
141                 String line = rd.readLine();
142 
143                 rd.close();
144                 if (line != null)
145                 {
146                     line = line.trim();
147                     if (line.length() != 0)
148                     {
149                         ret = line.split("\\s|#")[0];
150                     }
151                 }
152             }
153         }
154         catch (Exception x)
155         {
156             assert true;
157         }
158 
159         return ret;
160     }
161 }