1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.spi.impl;
20
21 import java.io.BufferedReader;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.net.URL;
26 import java.net.URLConnection;
27 import java.util.Collections;
28 import java.util.Enumeration;
29 import java.util.LinkedHashSet;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.ServiceLoader;
34 import java.util.Set;
35 import javax.faces.context.ExternalContext;
36
37 import org.apache.myfaces.shared.util.ClassUtils;
38 import org.apache.myfaces.spi.ServiceProviderFinder;
39
40
41
42
43
44
45
46 public class DefaultServiceProviderFinder extends ServiceProviderFinder
47 {
48 private static final String META_INF_SERVICES = "META-INF/services/";
49
50 private Map<String, List<String>> knownServicesMap = null;
51
52 protected Set<URL> getURLs(String spiClass)
53 {
54
55 Enumeration<URL> profiles = null;
56 try
57 {
58 profiles = ClassUtils.getContextClassLoader().getResources(
59 META_INF_SERVICES + spiClass);
60 }
61 catch (IOException e)
62 {
63 return null;
64 }
65 if (null != profiles && profiles.hasMoreElements())
66 {
67 Set<URL> urls = new LinkedHashSet<URL>();
68 while (profiles.hasMoreElements())
69 {
70 URL url = profiles.nextElement();
71 urls.add(url);
72 }
73 return urls;
74 }
75 return Collections.emptySet();
76 }
77
78 @Override
79 public List<String> getServiceProviderList(String spiClass)
80 {
81 if (knownServicesMap != null)
82 {
83 List<String> result = knownServicesMap.get(spiClass);
84 if (result != null)
85 {
86 return result;
87 }
88 }
89
90 Set<URL> urls = getURLs(spiClass);
91
92 if (!urls.isEmpty())
93 {
94 List<String> results = new LinkedList<String>();
95 for (URL url : urls)
96 {
97 InputStream is = null;
98
99 try
100 {
101 try
102 {
103 is = openStreamWithoutCache(url);
104 if (is != null)
105 {
106
107
108
109 BufferedReader rd;
110 try
111 {
112 rd = new BufferedReader(new InputStreamReader(is,
113 "UTF-8"));
114 }
115 catch (java.io.UnsupportedEncodingException e)
116 {
117 rd = new BufferedReader(new InputStreamReader(is));
118 }
119
120 try
121 {
122 String serviceImplName;
123 while ((serviceImplName = rd.readLine()) != null)
124 {
125 int idx = serviceImplName.indexOf('#');
126 if (idx >= 0)
127 {
128 serviceImplName = serviceImplName
129 .substring(0, idx);
130 }
131 serviceImplName = serviceImplName.trim();
132
133 if (serviceImplName.length() != 0)
134 {
135 results.add(serviceImplName);
136 }
137 }
138 }
139 finally
140 {
141 if (rd != null)
142 {
143 rd.close();
144 }
145 }
146 }
147 }
148 finally
149 {
150 if (is != null)
151 {
152 is.close();
153 }
154 }
155 }
156 catch (IOException e)
157 {
158
159 }
160 }
161 return results;
162 }
163 return Collections.emptyList();
164 }
165
166 private InputStream openStreamWithoutCache(URL url) throws IOException
167 {
168 URLConnection connection = url.openConnection();
169 connection.setUseCaches(false);
170 return connection.getInputStream();
171 }
172
173 @Override
174 public <S> ServiceLoader<S> load(Class<S> spiClass)
175 {
176 return ServiceLoader.load(spiClass);
177 }
178
179 @Override
180 public void initKnownServiceProviderMapInfo(ExternalContext ectx, Map<String, List<String>> map)
181 {
182 knownServicesMap = map;
183 }
184 }