Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/tripi/asp/AspFileFactory.java


1   /**
2    * ArrowHead ASP Server 
3    * This is a source file for the ArrowHead ASP Server - an 100% Java
4    * VBScript interpreter and ASP server.
5    *
6    * For more information, see http://www.tripi.com/arrowhead
7    *
8    * Copyright (C) 2002  Terence Haddock
9    *
10   * This program is free software; you can redistribute it and/or modify
11   * it under the terms of the GNU General Public License as published by
12   * the Free Software Foundation; either version 2 of the License, or
13   * (at your option) any later version.
14   *
15   * This program is distributed in the hope that it will be useful,
16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   * GNU General Public License for more details.
19   *
20   * You should have received a copy of the GNU General Public License
21   * along with this program; if not, write to the Free Software
22   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23   *
24   */
25  package com.tripi.asp;
26  
27  import com.tripi.asp.parse.FileFactory;
28  import com.tripi.asp.*;
29  import jregex.*;
30  import org.apache.log4j.Category;
31  import java.io.FileInputStream;
32  import java.io.InputStream;
33  import java.io.IOException;
34  import java.io.File;
35  import java.util.HashMap;
36  import java.util.Iterator;
37  import java.util.Map;
38  import java.net.URL;
39  
40  /**
41   * This class is a factory to handle finding files on the local file
42   * system. It is used by the other test routines.
43   */
44  public class AspFileFactory implements FileFactory
45  {
46      /** Debugging class */
47      private static final Category DBG = Category.getInstance(AspFileFactory.class);
48  
49      /** Asp Content */
50      AspContext context;
51  
52      /** Map of files loaded using this file factory, used to determine if
53          any of the files have changed. */
54      Map loadedFiles = new HashMap();
55  
56      /**
57       * Constructor, initialized with an AspContext.
58       * @param context AspContext to initiaze to
59       */
60      public AspFileFactory(AspContext context)
61      {
62          this.context = context;
63      }
64  
65      /**
66       * Resolve a relative file's location based on the given file.
67       * @param baseFile base file to use.
68       * @param relFile relative file to use.
69       */
70      public String resolveFile(String baseFilename, String relFile,
71          boolean virtual) throws AspException
72      {
73          if (DBG.isDebugEnabled())
74              DBG.debug("Resolve file: " + relFile + " / Base: " + baseFilename +
75                   " / Virtual: " + virtual);
76          String absFilename;
77          if (isSeparatorChar(relFile.charAt(0)))
78          {
79              if (DBG.isDebugEnabled()) DBG.debug("Virtual file");
80              /* Absolute filename */
81              if (virtual)
82              {
83                  Server server = context.getAspServer();
84                  absFilename = server.MapPath(relFile);
85              } else {
86                  absFilename = relFile;
87              }
88          } else {
89              /* Relative filename */
90              File baseFile = new File(baseFilename);
91              String path;
92              String basePath = baseFile.getParent();
93              if (basePath == null) basePath = "";
94              absFilename = concatPath(basePath, relFile);
95          }
96          if (DBG.isDebugEnabled()) DBG.debug("Result: " + absFilename);
97          return absFilename;
98      }
99  
100     private final static boolean isSeparatorChar(char ch)
101     {
102         if (ch == File.separatorChar || ch == '/') return true;
103         return false;
104     }
105 
106     /**
107      * Internal utility function to concatenate two paths.
108      * @param absPath Absolute path to start with
109      * @param addPath Relative path to add
110      */
111     private static String concatPath(String absPath, String addPath)
112         throws AspException
113     {
114         if (DBG.isDebugEnabled()) {
115             DBG.debug("concatPath(" + absPath + "," + addPath + ")");
116         }
117         final Pattern pathSep = new Pattern("/|\\\\");
118         String absPathStrings[] = pathSep.tokenizer(absPath).split();
119         String addPathStrings[] = pathSep.tokenizer(addPath).split();
120         String newPathStrings[] = new String[absPathStrings.length +
121             addPathStrings.length];
122         int absPathPos = absPathStrings.length - 1;
123         int addPathPos = 0;
124         int newPathPos = 0;
125         for (int i = 0; i < absPathStrings.length; i++) {
126             newPathStrings[i] = absPathStrings[i];
127             newPathPos++;
128         }
129         if (DBG.isDebugEnabled()) DBG.debug("newPathPos: " + newPathPos);
130         for (int i = 0; i < addPathStrings.length; i++) {
131             if (addPathStrings[i].equalsIgnoreCase(".")) continue;
132             if (addPathStrings[i].equalsIgnoreCase(".."))
133             {
134                 if (newPathPos == 0) throw new AspException("Invalid path: " + absPath + File.pathSeparator + addPath);
135                 newPathPos--;
136                 continue;
137             }
138             newPathStrings[newPathPos++] = addPathStrings[i];
139         }
140         if (DBG.isDebugEnabled()) DBG.debug("newPathPos: " + newPathPos);
141         StringBuffer buf = new StringBuffer();
142         if (isSeparatorChar(absPath.charAt(0)))
143         {
144             buf.append(File.separatorChar);
145         }
146         for (int i = 0; i < newPathPos; i++)
147         {
148             if (i != 0) buf.append(File.separatorChar);
149             buf.append(newPathStrings[i]);
150         }
151         if (DBG.isDebugEnabled()) DBG.debug("Final path: " + buf.toString());
152         return buf.toString();
153     }
154 
155     /**
156      * Get the file resource.
157      * @param file file to obtain stream of
158      * @return input stream of the specified file
159      */
160     public InputStream getResource(String filename) throws AspException
161     {
162         try {
163             Server server = context.getAspServer();
164             FileInformation finfo = getFileInformation(filename);
165             return new FileInputStream(finfo.file);
166         } catch (IOException ex) {
167             throw new AspNestedException(ex);
168         }
169     }
170 
171     /**
172      * Clear the loaded files cache.
173      */
174     public void clearLoadedFilesCache()
175     {
176         loadedFiles = new HashMap();
177     }
178 
179     /**
180      * Check if any of the cached files have been modified on the disk.
181      * @return <b>true</b> if a file has been modified, <b>false</b> otherwise.
182      */
183     public boolean isModified()
184     {
185         synchronized(loadedFiles)
186         {
187             for (Iterator i = loadedFiles.values().iterator(); i.hasNext();)
188             {
189                 FileInformation finfo = (FileInformation)i.next();
190                 if (DBG.isDebugEnabled())
191                 {
192                     DBG.debug("finfo.file.LastModified() = " +
193                         finfo.file.lastModified());
194                     DBG.debug("finfo.lastModifiedTime = " +
195                         finfo.lastModifiedTime);
196                 }
197                 if (finfo.file.lastModified() > finfo.lastModifiedTime)
198                 {
199                     return true;
200                 }
201             }
202         }
203         return false;
204     }
205 
206     /**
207      * Get the cached file information for the file.
208      */
209     private FileInformation getFileInformation(String fileLocation)
210     {
211         synchronized(loadedFiles)
212         {
213             if (!loadedFiles.containsKey(fileLocation))
214             {
215                 FileInformation finfo = new FileInformation();
216                 finfo.file = new File(fileLocation);
217                 finfo.lastModifiedTime = finfo.file.lastModified();
218                 loadedFiles.put(fileLocation, finfo);
219             }
220             return (FileInformation)loadedFiles.get(fileLocation);
221         }
222     }
223 
224     /**
225      * Class to contain cached file information.
226      */
227     private static class FileInformation
228     {
229         /** File handle */
230         File file;
231 
232         /** Last modified time */
233         long lastModifiedTime;
234     }
235 }