/projects/xalan-2.7.1/src/org/apache/xml/serializer/utils/SystemIDResolver.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus · Java · 302 lines · 154 code · 27 blank · 121 comment · 43 complexity · 6cd2b7869e02456ef3d9dbfbcfd3a9c0 MD5 · raw file

  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 "License");
  7. * you may not use this file except in compliance with the License.
  8. * 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, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. /*
  19. * $Id: SystemIDResolver.java 468654 2006-10-28 07:09:23Z minchau $
  20. */
  21. package org.apache.xml.serializer.utils;
  22. import java.io.File;
  23. import javax.xml.transform.TransformerException;
  24. import org.apache.xml.serializer.utils.URI.MalformedURIException;
  25. /**
  26. * This class is used to resolve relative URIs and SystemID
  27. * strings into absolute URIs.
  28. *
  29. * <p>This is a generic utility for resolving URIs, other than the
  30. * fact that it's declared to throw TransformerException. Please
  31. * see code comments for details on how resolution is performed.</p>
  32. *
  33. * This class is a copy of the one in org.apache.xml.utils.
  34. * It exists to cut the serializers dependancy on that package.
  35. *
  36. * This class is not a public API, it is only public because it is
  37. * used in org.apache.xml.serializer.
  38. *
  39. * @xsl.usage internal
  40. */
  41. public final class SystemIDResolver
  42. {
  43. /**
  44. * Get an absolute URI from a given relative URI (local path).
  45. *
  46. * <p>The relative URI is a local filesystem path. The path can be
  47. * absolute or relative. If it is a relative path, it is resolved relative
  48. * to the system property "user.dir" if it is available; if not (i.e. in an
  49. * Applet perhaps which throws SecurityException) then we just return the
  50. * relative path. The space and backslash characters are also replaced to
  51. * generate a good absolute URI.</p>
  52. *
  53. * @param localPath The relative URI to resolve
  54. *
  55. * @return Resolved absolute URI
  56. */
  57. public static String getAbsoluteURIFromRelative(String localPath)
  58. {
  59. if (localPath == null || localPath.length() == 0)
  60. return "";
  61. // If the local path is a relative path, then it is resolved against
  62. // the "user.dir" system property.
  63. String absolutePath = localPath;
  64. if (!isAbsolutePath(localPath))
  65. {
  66. try
  67. {
  68. absolutePath = getAbsolutePathFromRelativePath(localPath);
  69. }
  70. // user.dir not accessible from applet
  71. catch (SecurityException se)
  72. {
  73. return "file:" + localPath;
  74. }
  75. }
  76. String urlString;
  77. if (null != absolutePath)
  78. {
  79. if (absolutePath.startsWith(File.separator))
  80. urlString = "file://" + absolutePath;
  81. else
  82. urlString = "file:///" + absolutePath;
  83. }
  84. else
  85. urlString = "file:" + localPath;
  86. return replaceChars(urlString);
  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 getAbsolutePathFromRelativePath(String relativePath)
  95. {
  96. return new File(relativePath).getAbsolutePath();
  97. }
  98. /**
  99. * Return true if the systemId denotes an absolute URI .
  100. *
  101. * @param systemId The systemId string
  102. * @return true if the systemId is an an absolute URI
  103. */
  104. public static boolean isAbsoluteURI(String systemId)
  105. {
  106. /** http://www.ietf.org/rfc/rfc2396.txt
  107. * Authors should be aware that a path segment which contains a colon
  108. * character cannot be used as the first segment of a relative URI path
  109. * (e.g., "this:that"), because it would be mistaken for a scheme name.
  110. **/
  111. /**
  112. * %REVIEW% Can we assume here that systemId is a valid URI?
  113. * It looks like we cannot ( See discussion of this common problem in
  114. * Bugzilla Bug 22777 ).
  115. **/
  116. //"fix" for Bugzilla Bug 22777
  117. if(isWindowsAbsolutePath(systemId)){
  118. return false;
  119. }
  120. final int fragmentIndex = systemId.indexOf('#');
  121. final int queryIndex = systemId.indexOf('?');
  122. final int slashIndex = systemId.indexOf('/');
  123. final int colonIndex = systemId.indexOf(':');
  124. //finding substring before '#', '?', and '/'
  125. int index = systemId.length() -1;
  126. if(fragmentIndex > 0)
  127. index = fragmentIndex;
  128. if((queryIndex > 0) && (queryIndex <index))
  129. index = queryIndex;
  130. if((slashIndex > 0) && (slashIndex <index))
  131. index = slashIndex;
  132. // return true if there is ':' before '#', '?', and '/'
  133. return ((colonIndex >0) && (colonIndex<index));
  134. }
  135. /**
  136. * Return true if the local path is an absolute path.
  137. *
  138. * @param systemId The path string
  139. * @return true if the path is absolute
  140. */
  141. public static boolean isAbsolutePath(String systemId)
  142. {
  143. if(systemId == null)
  144. return false;
  145. final File file = new File(systemId);
  146. return file.isAbsolute();
  147. }
  148. /**
  149. * Return true if the local path is a Windows absolute path.
  150. *
  151. * @param systemId The path string
  152. * @return true if the path is a Windows absolute path
  153. */
  154. private static boolean isWindowsAbsolutePath(String systemId)
  155. {
  156. if(!isAbsolutePath(systemId))
  157. return false;
  158. // On Windows, an absolute path starts with "[drive_letter]:\".
  159. if (systemId.length() > 2
  160. && systemId.charAt(1) == ':'
  161. && Character.isLetter(systemId.charAt(0))
  162. && (systemId.charAt(2) == '\\' || systemId.charAt(2) == '/'))
  163. return true;
  164. else
  165. return false;
  166. }
  167. /**
  168. * Replace spaces with "%20" and backslashes with forward slashes in
  169. * the input string to generate a well-formed URI string.
  170. *
  171. * @param str The input string
  172. * @return The string after conversion
  173. */
  174. private static String replaceChars(String str)
  175. {
  176. StringBuffer buf = new StringBuffer(str);
  177. int length = buf.length();
  178. for (int i = 0; i < length; i++)
  179. {
  180. char currentChar = buf.charAt(i);
  181. // Replace space with "%20"
  182. if (currentChar == ' ')
  183. {
  184. buf.setCharAt(i, '%');
  185. buf.insert(i+1, "20");
  186. length = length + 2;
  187. i = i + 2;
  188. }
  189. // Replace backslash with forward slash
  190. else if (currentChar == '\\')
  191. {
  192. buf.setCharAt(i, '/');
  193. }
  194. }
  195. return buf.toString();
  196. }
  197. /**
  198. * Take a SystemID string and try to turn it into a good absolute URI.
  199. *
  200. * @param systemId A URI string, which may be absolute or relative.
  201. *
  202. * @return The resolved absolute URI
  203. */
  204. public static String getAbsoluteURI(String systemId)
  205. {
  206. String absoluteURI = systemId;
  207. if (isAbsoluteURI(systemId))
  208. {
  209. // Only process the systemId if it starts with "file:".
  210. if (systemId.startsWith("file:"))
  211. {
  212. String str = systemId.substring(5);
  213. // Resolve the absolute path if the systemId starts with "file:///"
  214. // or "file:/". Don't do anything if it only starts with "file://".
  215. if (str != null && str.startsWith("/"))
  216. {
  217. if (str.startsWith("///") || !str.startsWith("//"))
  218. {
  219. // A Windows path containing a drive letter can be relative.
  220. // A Unix path starting with "file:/" is always absolute.
  221. int secondColonIndex = systemId.indexOf(':', 5);
  222. if (secondColonIndex > 0)
  223. {
  224. String localPath = systemId.substring(secondColonIndex-1);
  225. try {
  226. if (!isAbsolutePath(localPath))
  227. absoluteURI = systemId.substring(0, secondColonIndex-1) +
  228. getAbsolutePathFromRelativePath(localPath);
  229. }
  230. catch (SecurityException se) {
  231. return systemId;
  232. }
  233. }
  234. }
  235. }
  236. else
  237. {
  238. return getAbsoluteURIFromRelative(systemId.substring(5));
  239. }
  240. return replaceChars(absoluteURI);
  241. }
  242. else
  243. return systemId;
  244. }
  245. else
  246. return getAbsoluteURIFromRelative(systemId);
  247. }
  248. /**
  249. * Take a SystemID string and try to turn it into a good absolute URI.
  250. *
  251. * @param urlString SystemID string
  252. * @param base The URI string used as the base for resolving the systemID
  253. *
  254. * @return The resolved absolute URI
  255. * @throws TransformerException thrown if the string can't be turned into a URI.
  256. */
  257. public static String getAbsoluteURI(String urlString, String base)
  258. throws TransformerException
  259. {
  260. if (base == null)
  261. return getAbsoluteURI(urlString);
  262. String absoluteBase = getAbsoluteURI(base);
  263. URI uri = null;
  264. try
  265. {
  266. URI baseURI = new URI(absoluteBase);
  267. uri = new URI(baseURI, urlString);
  268. }
  269. catch (MalformedURIException mue)
  270. {
  271. throw new TransformerException(mue);
  272. }
  273. return replaceChars(uri.toString());
  274. }
  275. }