--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javacommons/fileutils/javasrc/com/nokia/mj/impl/fileutils/FileURL.java Mon May 03 12:27:20 2010 +0300
@@ -0,0 +1,386 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.mj.impl.fileutils;
+
+/**
+ * FileURL manages URL/Path handling. It is responsible to manage paths which
+ * have path separators specific to the platform. It will also manage
+ * differences between URL and Absolute path and make it transparent to use
+ * from.
+ */
+final class FileURL
+{
+ private static String FILE_PREFIX = "file://";
+
+ private static String FILE_VALID_START_1 = "file:///";
+
+ private static String FILE_VALID_START_2 = "file://localhost/";
+
+ public static final String S60_FILE_SEPARATOR = "\\";
+
+ public static final String LINUX_FILE_SEPARATOR = "/";
+
+ private boolean iIsS60Path;
+
+ // Contains the unescaped path.
+ private String iUnescapedPath;
+
+ // Contains the absolute path to the current target.
+ private String iTargetPath;
+
+ // Contains the name of the target.
+ private String iTargetName;
+
+ private String iSeparatorUsed;
+
+ /**
+ * Constructor for FileURL.
+ *
+ * @param aName
+ * Can contain either an Absolute path name or a File URL.
+ * <p>
+ * Path separator in Absolute path can be either "/" or platform
+ * specific path separator. This is specified in file.separator
+ * system property.
+ * <p>
+ * In case of file URL being passed as parameter, it must follow
+ * the format of a fully-qualified, absolute path file name as
+ * described by the file URL format in IETF RFCs 1738 & 2396.
+ */
+ public FileURL(String aName)
+ {
+ iIsS60Path = false;
+ String initialPath = aName;
+ String path = "";
+
+ if (aName.trim().length() <= 0)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ if (aName.startsWith(FILE_PREFIX))
+ {
+ validateUrlStart(aName);
+
+ // aName is a url of the form file://<host>/<path>
+ // We need just the absolute path. So we extract it.
+ path = initialPath.substring(initialPath.indexOf('/', FILE_PREFIX
+ .length()) + 1);
+
+ // A file URL should have only "/" as file separator.
+ if (initialPath.indexOf(S60_FILE_SEPARATOR) != -1)
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+ else
+ {
+ path = aName;
+ }
+
+ int endIndex = 0;
+ String tempName = path;
+ while (tempName.indexOf("//")!=-1)
+ {
+ endIndex = path.indexOf("//");
+ tempName = path.substring(0, endIndex);
+ if (endIndex < path.length())
+ {
+ tempName += path.substring(endIndex+1);
+ }
+ };
+ path = tempName;
+
+ // Check the sanity of path specified
+ checkPathValidity(path);
+ iUnescapedPath = path;
+
+ iIsS60Path = (iUnescapedPath.indexOf("\\") != -1);
+ int index = 0;
+
+ if (iIsS60Path)
+ {
+ iSeparatorUsed = "\\";
+ index = iUnescapedPath.lastIndexOf('\\',
+ iUnescapedPath.length() - 2);
+ }
+ else
+ {
+ iSeparatorUsed = "/";
+ index = iUnescapedPath
+ .lastIndexOf('/', iUnescapedPath.length() - 2);
+ }
+
+ iTargetName = iUnescapedPath.substring(index + 1);
+ iTargetPath = iUnescapedPath.substring(0, index + 1);
+ }
+
+ /**
+ * checks to see if URL begins with valid urls starts.<br/> It can either
+ * be file:/// or file://localhost/.
+ *
+ * @param url
+ * contains url passed to the constructor
+ */
+ private void validateUrlStart(String url)
+ {
+ if (url.startsWith(FILE_VALID_START_1)
+ || url.startsWith(FILE_VALID_START_2))
+ {
+ return;
+ }
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Getter method to retrieve path to the parent directory of the current
+ * target.
+ *
+ * @return string containing absloute path to the target's parent.
+ */
+ public String getPath()
+ {
+ return iTargetPath;
+ }
+
+ /**
+ * Getter method to retrieve name of the target.
+ *
+ * @return string containing the name of the target currently pointed to.
+ * This is derived from the url.
+ */
+ public String getName()
+ {
+ return iTargetName;
+ }
+
+ /**
+ * Getter method to retrieve the full path of the target. It will contain
+ * path to the target and the target too as a complete url.
+ *
+ * @return the full path of the target
+ */
+ public String getFullPath()
+ {
+ return iTargetPath + iTargetName;
+ }
+
+ protected String getSeparatorUsed()
+ {
+ return iSeparatorUsed;
+ }
+
+ /**
+ * Getter method to retrieve the file URL that can be passed as a parameter
+ * to FileConnection url. It will conform to File URL format in IETF RFCs
+ * 1738 & 2396.
+ *
+ * @return fully qualified File URL
+ */
+ public String getUrl()
+ {
+ // Get URL must return escaped url.
+ String aUrl = FILE_VALID_START_1 + iTargetPath + iTargetName;
+ String value = "";
+
+ for (int i = 0; i < aUrl.length(); i++)
+ {
+ char ch = aUrl.charAt(i);
+
+ // Also replace "\\" with "/"
+ if (ch == '\\')
+ {
+ value += "/";
+ continue;
+ }
+
+ boolean isLetter = (ch >= 'a' && ch <= 'z')
+ || (ch >= 'A' && ch <= 'Z');
+ boolean isDigit = (ch >= '0' && ch <= '9');
+ if (isLetter || isDigit)
+ {
+ value += ch;
+ }
+ else
+ {
+ value += stringToHex("" + ch);
+ }
+
+ }
+
+ return value;
+ }
+
+ /**
+ * Checks to see if the path passed is valid. Simple sanity checks for the
+ * path to point to a valid target.
+ *
+ * @param name
+ * contains an absolute path to a target.
+ */
+ private static final void checkPathValidity(String name)
+ {
+ // Only in S60 file system, we have the concept of drives.
+ // So, ":" should only appear in File systems that have
+ // file.separator as '\\'
+
+ String separator = System.getProperty("file.separator");
+
+ // If platform is S60 like.
+ if (separator.equals(S60_FILE_SEPARATOR))
+ {
+ makeS60SpecificChecks(name);
+ }
+ else
+ {
+ makeLinuxSpecificChecks(name);
+ }
+
+ if ((name.indexOf('*') != -1) || (name.indexOf('?') != -1)
+ || (name.indexOf('<') != -1) || (name.indexOf('>') != -1)
+ || (name.indexOf("//") != -1) || name.endsWith("/."))
+ {
+ throw new IllegalArgumentException(name);
+ }
+ }
+
+ /**
+ * Makes checks that are specific to S60 like File System. This should be
+ * called only in case file.separator is "\\"
+ *
+ * @param name
+ * contians the path that needs to be checked for sanity.
+ */
+ private static final void makeS60SpecificChecks(String name)
+ {
+ // First index of colon
+ int firstIndexOfColon = name.indexOf(':');
+ int indexOfColon = name.indexOf(':', firstIndexOfColon + 1);
+
+ if (indexOfColon != -1)
+ {
+ throw new IllegalArgumentException(name);
+ }
+
+ // In S60 like file system, it is possible to have "/" as the file
+ // separator as file url accepts it. But then, once there is "\\" as
+ // file separator, the entire url should follow the same convention.
+
+ if (name.indexOf(S60_FILE_SEPARATOR) != -1)
+ {
+ if (name.indexOf(LINUX_FILE_SEPARATOR) != -1)
+ {
+ // We must be having only one kind of separator
+ throw new IllegalArgumentException(name);
+ }
+
+ if (firstIndexOfColon > name.indexOf(S60_FILE_SEPARATOR))
+ {
+ throw new IllegalArgumentException(name);
+ }
+ }
+ else
+ {
+ if ((firstIndexOfColon > name.indexOf(LINUX_FILE_SEPARATOR)))
+ {
+ throw new IllegalArgumentException(name);
+ }
+ }
+ }
+
+ /**
+ * Makes checks that are specific to Linux like File System. This should be
+ * called only in case file.separator is "/"
+ *
+ * @param name
+ * contians the path that needs to be checked for sanity.
+ */
+ private static final void makeLinuxSpecificChecks(String name)
+ {
+ if (name.indexOf(':') != -1)
+ {
+ throw new IllegalArgumentException(name);
+ }
+
+ if (name.indexOf(S60_FILE_SEPARATOR) != -1)
+ {
+ throw new IllegalArgumentException(name);
+ }
+ }
+
+ /**
+ * encodes a unicode string to a string of 4-digit hex numbers <br />
+ * Note: this method is slower than stringToHex(String,StringBuffer)
+ *
+ * @param java
+ * normal java string
+ * @return string of 4-digit hex numbers
+ */
+ public static final String stringToHex(String str)
+ {
+ if (str == null)
+ return "";
+ int length = str.length();
+ StringBuffer result = new StringBuffer(length * 4);
+ stringToHex(str, result);
+ return result.toString();
+ }
+
+ /**
+ * encodes a unicode string to a string of 4-digit hex numbers.
+ *
+ * @param str
+ * normal java string
+ * @param out
+ * string of 4-digit hex numbers
+ */
+ public static final void stringToHex(String str, StringBuffer out)
+ {
+ // To improve performance, implement a table-lookup instead of if/then cases.
+
+ if (str == null)
+ return;
+ int length = str.length();
+ for (int pos = 0; pos < length; pos++)
+ {
+ char cur_char = str.charAt(pos);
+ int this_char = (int) cur_char;
+ if (this_char < 127 && cur_char != ' ')
+ {
+ out.append((char) this_char);
+ continue;
+ }
+ for (int digit = 0; digit < 4; digit++)
+ {
+ int this_digit = this_char & 0xf000;
+ this_char = this_char << 4;
+ this_digit = (this_digit >> 12);
+
+ // We get 4 digits, so on 2nd we insert a % sign and then value
+ if (digit == 2)
+ out.append('%');
+ if (digit < 2)
+ continue;
+ if (this_digit >= 10)
+ out.append((char)(this_digit + 87));
+ else
+ out.append((char)(this_digit + 48));
+ }
+ }
+ }
+}