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.resource;
20  
21  import java.io.IOException;
22  import java.net.URL;
23  import java.util.HashSet;
24  import java.util.Set;
25  import javax.faces.application.ResourceHandler;
26  import javax.faces.context.ExternalContext;
27  import org.apache.myfaces.shared.util.ClassUtils;
28  import org.apache.myfaces.shared.util.WebConfigParamUtils;
29  import org.apache.myfaces.spi.ResourceLibraryContractsProvider;
30  import org.apache.myfaces.view.facelets.util.Classpath;
31  
32  /**
33   *
34   * @author Leonardo Uribe
35   */
36  public class DefaultResourceLibraryContractsProvider extends ResourceLibraryContractsProvider
37  {
38      private static final String META_INF_CONTRACTS_PREFIX = "META-INF/contracts/";
39      private static final String META_INF_CONTRACTS_SUFFIX = "javax.faces.contract.xml";
40      private static final String META_INF_CONTRACTS_FILE = "/javax.faces.contract.xml";
41      private static final String CONTRACTS = "contracts";
42  
43      @Override
44      public Set<String> getExternalContextResourceLibraryContracts(ExternalContext context)
45          throws IOException
46      {
47          String directory = WebConfigParamUtils.getStringInitParameter(context, 
48              ResourceHandler.WEBAPP_CONTRACTS_DIRECTORY_PARAM_NAME, CONTRACTS);
49          
50          if (directory.startsWith("/"))
51          {
52              throw new IllegalStateException("javax.faces.WEBAPP_CONTRACTS_DIRECTORY cannot start with '/");
53          }
54          if (directory.endsWith("/"))
55          {
56              directory = directory.substring(0, directory.length()-1);
57          }
58          
59          directory = "/"+directory+"/";
60          Set<String> contracts = new HashSet<String>();
61          Set<String> paths = context.getResourcePaths(directory);
62          if (paths != null)
63          {
64              for (String path : paths)
65              {
66                  if (path.endsWith("/"))
67                  {
68                      //Add all subdirectories no questions asked.
69                      contracts.add(path.substring(directory.length(), path.length()-1));
70                  }
71              }
72          }
73          return contracts;
74      }
75  
76      @Override
77      public Set<String> getClassloaderResourceLibraryContracts(ExternalContext context)
78          throws IOException
79      {
80          Set<String> contracts = new HashSet<String>();
81          URL[] urls = Classpath.search(getClassLoader(), 
82              META_INF_CONTRACTS_PREFIX, META_INF_CONTRACTS_SUFFIX);
83          for (int i = 0; i < urls.length; i++)
84          {
85              String urlString = urls[i].toExternalForm();
86              int suffixPos = urlString.lastIndexOf(META_INF_CONTRACTS_FILE);
87              int slashPos = urlString.lastIndexOf('/', suffixPos-1);
88              if (suffixPos > 0 && slashPos > 0)
89              {
90                  contracts.add(urlString.substring(slashPos+1, suffixPos));
91              }
92          }
93          return contracts;
94      }
95  
96      private ClassLoader getClassLoader()
97      {
98          ClassLoader loader = ClassUtils.getContextClassLoader();
99          if (loader == null)
100         {
101             loader = this.getClass().getClassLoader();
102         }
103         return loader;
104     }
105 }