View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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.Set;
33  
34  import org.apache.myfaces.shared.util.ClassUtils;
35  import org.apache.myfaces.spi.ServiceProviderFinder;
36  
37  /**
38   * 
39   * @author Leonardo Uribe
40   * @since 2.0.3
41   *
42   */
43  public class DefaultServiceProviderFinder extends ServiceProviderFinder
44  {
45      private static final String META_INF_SERVICES = "META-INF/services/";
46  
47      protected Set<URL> getURLs(String spiClass)
48      {
49          // Use LinkedHashSet to preserve iteration order
50          Enumeration<URL> profiles = null;
51          try
52          {
53              profiles = ClassUtils.getContextClassLoader().getResources(
54                      META_INF_SERVICES + spiClass);
55          }
56          catch (IOException e)
57          {
58              return null;
59          }
60          if (null != profiles && profiles.hasMoreElements())
61          {
62              Set<URL> urls = new LinkedHashSet<URL>();
63              while (profiles.hasMoreElements())
64              {
65                  URL url = profiles.nextElement();
66                  urls.add(url);
67              }
68              return urls;
69          }
70          return Collections.emptySet();
71      }
72  
73      public List<String> getServiceProviderList(String spiClass)
74      {
75          Set<URL> urls = getURLs(spiClass);
76  
77          if (!urls.isEmpty())
78          {
79              List<String> results = new LinkedList<String>();
80              for (URL url : urls)
81              {
82                  InputStream is = null;
83      
84                  try
85                  {
86                      try
87                      {
88                          is = openStreamWithoutCache(url);
89                          if (is != null)
90                          {
91                              // This code is needed by EBCDIC and other
92                              // strange systems.  It's a fix for bugs
93                              // reported in xerces
94                              BufferedReader rd;
95                              try
96                              {
97                                  rd = new BufferedReader(new InputStreamReader(is,
98                                          "UTF-8"));
99                              }
100                             catch (java.io.UnsupportedEncodingException e)
101                             {
102                                 rd = new BufferedReader(new InputStreamReader(is));
103                             }
104     
105                             try
106                             {
107                                 String serviceImplName;
108                                 while ((serviceImplName = rd.readLine()) != null)
109                                 {
110                                     int idx = serviceImplName.indexOf('#');
111                                     if (idx >= 0)
112                                     {
113                                         serviceImplName = serviceImplName
114                                                 .substring(0, idx);
115                                     }
116                                     serviceImplName = serviceImplName.trim();
117     
118                                     if (serviceImplName.length() != 0)
119                                     {
120                                         results.add(serviceImplName);
121                                     }
122                                 }
123                             }
124                             finally
125                             {
126                                 if (rd != null)
127                                 {
128                                     rd.close();
129                                 }
130                             }
131                         }
132                     }
133                     finally
134                     {
135                         if (is != null)
136                         {
137                             is.close();
138                         }
139                     }
140                 }
141                 catch (IOException e)
142                 {
143                     // ignore
144                 }
145             }
146             return results;
147         }
148         return Collections.emptyList();
149     }
150 
151     private InputStream openStreamWithoutCache(URL url) throws IOException
152     {
153         URLConnection connection = url.openConnection();
154         connection.setUseCaches(false);
155         return connection.getInputStream();
156     }
157 }