KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xml > utils > SystemIDResolver


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: SystemIDResolver.java,v 1.24 2004/02/17 04:21:14 minchau Exp $
18  */

19 package org.apache.xml.utils;
20
21 import java.io.File JavaDoc;
22
23 import javax.xml.transform.TransformerException JavaDoc;
24
25 import org.apache.xml.utils.URI.MalformedURIException;
26
27 /**
28  * This class is used to resolve relative URIs and SystemID
29  * strings into absolute URIs.
30  *
31  * <p>This is a generic utility for resolving URIs, other than the
32  * fact that it's declared to throw TransformerException. Please
33  * see code comments for details on how resolution is performed.</p>
34  * @xsl.usage internal
35  */

36 public class SystemIDResolver
37 {
38
39   /**
40    * Get an absolute URI from a given relative URI (local path).
41    *
42    * <p>The relative URI is a local filesystem path. The path can be
43    * absolute or relative. If it is a relative path, it is resolved relative
44    * to the system property "user.dir" if it is available; if not (i.e. in an
45    * Applet perhaps which throws SecurityException) then we just return the
46    * relative path. The space and backslash characters are also replaced to
47    * generate a good absolute URI.</p>
48    *
49    * @param localPath The relative URI to resolve
50    *
51    * @return Resolved absolute URI
52    */

53   public static String JavaDoc getAbsoluteURIFromRelative(String JavaDoc localPath)
54   {
55     if (localPath == null || localPath.length() == 0)
56       return "";
57       
58     // If the local path is a relative path, then it is resolved against
59
// the "user.dir" system property.
60
String JavaDoc absolutePath = localPath;
61     if (!isAbsolutePath(localPath))
62     {
63       try
64       {
65         absolutePath = getAbsolutePathFromRelativePath(localPath);
66       }
67       // user.dir not accessible from applet
68
catch (SecurityException JavaDoc se)
69       {
70         return "file:" + localPath;
71       }
72     }
73
74     String JavaDoc urlString;
75     if (null != absolutePath)
76     {
77       if (absolutePath.startsWith(File.separator))
78         urlString = "file://" + absolutePath;
79       else
80         urlString = "file:///" + absolutePath;
81     }
82     else
83       urlString = "file:" + localPath;
84     
85     return replaceChars(urlString);
86   }
87   
88   /**
89    * Return an absolute path from a relative path.
90    *
91    * @param relativePath A relative path
92    * @return The absolute path
93    */

94   private static String JavaDoc getAbsolutePathFromRelativePath(String JavaDoc relativePath)
95   {
96     return new File JavaDoc(relativePath).getAbsolutePath();
97   }
98   
99   /**
100    * Return true if the systemId denotes an absolute URI .
101    *
102    * @param systemId The systemId string
103    * @return true if the systemId is an an absolute URI
104    */

105   public static boolean isAbsoluteURI(String JavaDoc systemId)
106   {
107      /** http://www.ietf.org/rfc/rfc2396.txt
108       * Authors should be aware that a path segment which contains a colon
109       * character cannot be used as the first segment of a relative URI path
110       * (e.g., "this:that"), because it would be mistaken for a scheme name.
111      **/

112      /**
113       * %REVIEW% Can we assume here that systemId is a valid URI?
114       * It looks like we cannot ( See discussion of this common problem in
115       * Bugzilla Bug 22777 ).
116      **/

117      //"fix" for Bugzilla Bug 22777
118
if(isWindowsAbsolutePath(systemId)){
119         return false;
120      }
121     
122     final int fragmentIndex = systemId.indexOf('#');
123     final int queryIndex = systemId.indexOf('?');
124     final int slashIndex = systemId.indexOf('/');
125     final int colonIndex = systemId.indexOf(':');
126     
127     //finding substring before '#', '?', and '/'
128
int index = systemId.length() -1;
129     if(fragmentIndex > 0)
130         index = fragmentIndex;
131     if((queryIndex > 0) && (queryIndex <index))
132         index = queryIndex;
133     if((slashIndex > 0) && (slashIndex <index))
134         index = slashIndex;
135     // return true if there is ':' before '#', '?', and '/'
136
return ((colonIndex >0) && (colonIndex<index));
137     
138   }
139   
140   /**
141    * Return true if the local path is an absolute path.
142    *
143    * @param systemId The path string
144    * @return true if the path is absolute
145    */

146   public static boolean isAbsolutePath(String JavaDoc systemId)
147   {
148     if(systemId == null)
149         return false;
150     final File JavaDoc file = new File JavaDoc(systemId);
151     return file.isAbsolute();
152     
153   }
154   
155    /**
156    * Return true if the local path is a Windows absolute path.
157    *
158    * @param systemId The path string
159    * @return true if the path is a Windows absolute path
160    */

161     private static boolean isWindowsAbsolutePath(String JavaDoc systemId)
162   {
163     if(!isAbsolutePath(systemId))
164       return false;
165     // On Windows, an absolute path starts with "[drive_letter]:\".
166
if (systemId.length() > 2
167         && systemId.charAt(1) == ':'
168         && Character.isLetter(systemId.charAt(0))
169         && (systemId.charAt(2) == '\\' || systemId.charAt(2) == '/'))
170       return true;
171     else
172       return false;
173   }
174   
175   /**
176    * Replace spaces with "%20" and backslashes with forward slashes in
177    * the input string to generate a well-formed URI string.
178    *
179    * @param str The input string
180    * @return The string after conversion
181    */

182   private static String JavaDoc replaceChars(String JavaDoc str)
183   {
184     StringBuffer JavaDoc buf = new StringBuffer JavaDoc(str);
185     int length = buf.length();
186     for (int i = 0; i < length; i++)
187     {
188       char currentChar = buf.charAt(i);
189       // Replace space with "%20"
190
if (currentChar == ' ')
191       {
192         buf.setCharAt(i, '%');
193         buf.insert(i+1, "20");
194         length = length + 2;
195         i = i + 2;
196       }
197       // Replace backslash with forward slash
198
else if (currentChar == '\\')
199       {
200         buf.setCharAt(i, '/');
201       }
202     }
203     
204     return buf.toString();
205   }
206   
207   /**
208    * Take a SystemID string and try to turn it into a good absolute URI.
209    *
210    * @param systemId A URI string, which may be absolute or relative.
211    *
212    * @return The resolved absolute URI
213    */

214   public static String JavaDoc getAbsoluteURI(String JavaDoc systemId)
215   {
216     String JavaDoc absoluteURI = systemId;
217     if (isAbsoluteURI(systemId))
218     {
219       // Only process the systemId if it starts with "file:".
220
if (systemId.startsWith("file:"))
221       {
222         String JavaDoc str = systemId.substring(5);
223         
224         // Resolve the absolute path if the systemId starts with "file:///"
225
// or "file:/". Don't do anything if it only starts with "file://".
226
if (str != null && str.startsWith("/"))
227         {
228           if (str.startsWith("///") || !str.startsWith("//"))
229           {
230             // A Windows path containing a drive letter can be relative.
231
// A Unix path starting with "file:/" is always absolute.
232
int secondColonIndex = systemId.indexOf(':', 5);
233             if (secondColonIndex > 0)
234             {
235               String JavaDoc localPath = systemId.substring(secondColonIndex-1);
236               try {
237                 if (!isAbsolutePath(localPath))
238                   absoluteURI = systemId.substring(0, secondColonIndex-1) +
239                                 getAbsolutePathFromRelativePath(localPath);
240               }
241               catch (SecurityException JavaDoc se) {
242                 return systemId;
243               }
244             }
245           }
246         }
247         else
248         {
249           return getAbsoluteURIFromRelative(systemId.substring(5));
250         }
251                 
252         return replaceChars(absoluteURI);
253       }
254       else
255         return systemId;
256     }
257     else
258       return getAbsoluteURIFromRelative(systemId);
259     
260   }
261
262
263   /**
264    * Take a SystemID string and try to turn it into a good absolute URI.
265    *
266    * @param urlString SystemID string
267    * @param base The URI string used as the base for resolving the systemID
268    *
269    * @return The resolved absolute URI
270    * @throws TransformerException thrown if the string can't be turned into a URI.
271    */

272   public static String JavaDoc getAbsoluteURI(String JavaDoc urlString, String JavaDoc base)
273           throws TransformerException JavaDoc
274   {
275     if (base == null)
276       return getAbsoluteURI(urlString);
277     
278     String JavaDoc absoluteBase = getAbsoluteURI(base);
279     URI uri = null;
280     try
281     {
282       URI baseURI = new URI(absoluteBase);
283       uri = new URI(baseURI, urlString);
284     }
285     catch (MalformedURIException mue)
286     {
287       throw new TransformerException JavaDoc(mue);
288     }
289     
290     return replaceChars(uri.toString());
291   }
292   
293 }
294
Popular Tags