View Javadoc

1   package org.apache.velocity.runtime.resource.loader;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.    
20   */
21  
22  import java.io.InputStream;
23  import java.io.IOException;
24  import java.net.URL;
25  import java.net.URLConnection;
26  import java.util.HashMap;
27  import org.apache.commons.collections.ExtendedProperties;
28  import org.apache.commons.lang.StringUtils;
29  import org.apache.velocity.exception.ResourceNotFoundException;
30  import org.apache.velocity.runtime.resource.Resource;
31  
32  /**
33   * This is a simple URL-based loader.
34   *
35   * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
36   * @author <a href="mailto:nbubna@apache.org">Nathan Bubna</a>
37   * @version $Id: URLResourceLoader.java 191743 2005-06-21 23:22:20Z dlr $
38   */
39  public class URLResourceLoader extends ResourceLoader
40  {
41      private String[] roots = null;
42      protected HashMap templateRoots = null;
43  
44      /**
45       * @see org.apache.velocity.runtime.resource.loader.ResourceLoader#init(org.apache.commons.collections.ExtendedProperties)
46       */
47      public void init(ExtendedProperties configuration)
48      {
49          log.trace("URLResourceLoader : initialization starting.");
50  
51          roots = configuration.getStringArray("root");
52  
53          if (log.isInfoEnabled())
54          {
55              for (int i=0; i < roots.length; i++)
56              {
57                  log.info("URLResourceLoader : adding root '" + roots[i] + "'");
58              }
59          }
60  
61          // init the template paths map
62          templateRoots = new HashMap();
63  
64          log.trace("URLResourceLoader : initialization complete.");
65      }
66  
67      /**
68       * Get an InputStream so that the Runtime can build a
69       * template with it.
70       *
71       * @param name name of template to fetch bytestream of
72       * @return InputStream containing the template
73       * @throws ResourceNotFoundException if template not found
74       *         in the file template path.
75       */
76      public synchronized InputStream getResourceStream(String name)
77          throws ResourceNotFoundException
78      {
79          if (StringUtils.isEmpty(name))
80          {
81              throw new ResourceNotFoundException("URLResourceLoader : No template name provided");
82          }
83  
84          InputStream inputStream = null;
85          Exception exception = null;
86          for(int i=0; i < roots.length; i++)
87          {
88              try
89              {
90                  URL u = new URL(roots[i] + name);
91                  inputStream = u.openStream();
92  
93                  if (inputStream != null)
94                  {
95                      if (log.isDebugEnabled()) log.debug("URLResourceLoader: Found '"+name+"' at '"+roots[i]+"'");
96  
97                      // save this root for later re-use
98                      templateRoots.put(name, roots[i]);
99                      break;
100                 }
101             }
102             catch(IOException ioe)
103             {
104                 if (log.isDebugEnabled()) log.debug("URLResourceLoader: Exception when looking for '"+name+"' at '"+roots[i]+"'", ioe);
105 
106                 // only save the first one for later throwing
107                 if (exception == null)
108                 {
109                     exception = ioe;
110                 }
111             }
112         }
113 
114         // if we never found the template
115         if (inputStream == null)
116         {
117             String msg;
118             if (exception == null)
119             {
120                 msg = "URLResourceLoader : Resource '" + name + "' not found.";
121             }
122             else
123             {
124                 msg = exception.getMessage();
125             }
126             // convert to a general Velocity ResourceNotFoundException
127             throw new ResourceNotFoundException(msg);
128         }
129 
130         return inputStream;
131     }
132 
133     /**
134      * Checks to see if a resource has been deleted, moved or modified.
135      *
136      * @param resource Resource  The resource to check for modification
137      * @return boolean  True if the resource has been modified, moved, or unreachable
138      */
139     public boolean isSourceModified(Resource resource)
140     {
141         long fileLastModified = getLastModified(resource);
142         // if the file is unreachable or otherwise changed
143         if (fileLastModified == 0 ||
144             fileLastModified != resource.getLastModified())
145         {
146             return true;
147         }
148         return false;
149     }
150 
151     /**
152      * Checks to see when a resource was last modified
153      *
154      * @param resource Resource the resource to check
155      * @return long The time when the resource was last modified or 0 if the file can't be reached
156      */
157     public long getLastModified(Resource resource)
158     {
159         // get the previously used root
160         String name = resource.getName();
161         String root = (String)templateRoots.get(name);
162 
163         try
164         {
165             // get a connection to the URL
166             URL u = new URL(root + name);
167             URLConnection conn = u.openConnection();
168             return conn.getLastModified();
169         }
170         catch (IOException ioe)
171         {
172             // the file is not reachable at its previous address
173             log.warn("URLResourceLoader: '" + name +
174                      "' is no longer reachable at '" + root + "'", ioe);
175             return 0;
176         }
177     }
178 
179 }