Java tutorial
//package com.java2s; /* * This file is part of OpenVPN-Settings. * * Copyright 2009-2012 Friedrich Schuffelhut * * OpenVPN-Settings is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenVPN-Settings is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenVPN-Settings. If not, see <http://www.gnu.org/licenses/>. * * Report bugs or new features at: http://code.google.com/p/android-openvpn-settings/ * Contact the author at: android.openvpn@schaeuffelhut.de */ public class Main { /** * The Unix separator character. */ private static final char UNIX_SEPARATOR = '/'; /** * The Windows separator character. */ private static final char WINDOWS_SEPARATOR = '\\'; /** * Gets the prefix from a full filename, such as <code>C:/</code> * or <code>~/</code>. * <p> * This method will handle a file in either Unix or Windows format. * The prefix includes the first slash in the full filename where applicable. * <pre> * Windows: * a\b\c.txt --> "" --> relative * \a\b\c.txt --> "\" --> current drive absolute * C:a\b\c.txt --> "C:" --> drive relative * C:\a\b\c.txt --> "C:\" --> absolute * \\server\a\b\c.txt --> "\\server\" --> UNC * * Unix: * a/b/c.txt --> "" --> relative * /a/b/c.txt --> "/" --> absolute * ~/a/b/c.txt --> "~/" --> current user * ~ --> "~/" --> current user (slash added) * ~user/a/b/c.txt --> "~user/" --> named user * ~user --> "~user/" --> named user (slash added) * </pre> * <p> * The output will be the same irrespective of the machine that the code is running on. * ie. both Unix and Windows prefixes are matched regardless. * * @param filename the filename to query, null returns null * @return the prefix of the file, null if invalid */ public static String getPrefix(String filename) { if (filename == null) { return null; } int len = getPrefixLength(filename); if (len < 0) { return null; } if (len > filename.length()) { return filename + UNIX_SEPARATOR; // we know this only happens for unix } return filename.substring(0, len); } /** * Returns the length of the filename prefix, such as <code>C:/</code> or <code>~/</code>. * <p> * This method will handle a file in either Unix or Windows format. * <p> * The prefix length includes the first slash in the full filename * if applicable. Thus, it is possible that the length returned is greater * than the length of the input string. * <pre> * Windows: * a\b\c.txt --> "" --> relative * \a\b\c.txt --> "\" --> current drive absolute * C:a\b\c.txt --> "C:" --> drive relative * C:\a\b\c.txt --> "C:\" --> absolute * \\server\a\b\c.txt --> "\\server\" --> UNC * * Unix: * a/b/c.txt --> "" --> relative * /a/b/c.txt --> "/" --> absolute * ~/a/b/c.txt --> "~/" --> current user * ~ --> "~/" --> current user (slash added) * ~user/a/b/c.txt --> "~user/" --> named user * ~user --> "~user/" --> named user (slash added) * </pre> * <p> * The output will be the same irrespective of the machine that the code is running on. * ie. both Unix and Windows prefixes are matched regardless. * * @param filename the filename to find the prefix in, null returns -1 * @return the length of the prefix, -1 if invalid or null */ public static int getPrefixLength(String filename) { if (filename == null) { return -1; } int len = filename.length(); if (len == 0) { return 0; } char ch0 = filename.charAt(0); if (ch0 == ':') { return -1; } if (len == 1) { if (ch0 == '~') { return 2; // return a length greater than the input } return (isSeparator(ch0) ? 1 : 0); } else { if (ch0 == '~') { int posUnix = filename.indexOf(UNIX_SEPARATOR, 1); int posWin = filename.indexOf(WINDOWS_SEPARATOR, 1); if (posUnix == -1 && posWin == -1) { return len + 1; // return a length greater than the input } posUnix = (posUnix == -1 ? posWin : posUnix); posWin = (posWin == -1 ? posUnix : posWin); return Math.min(posUnix, posWin) + 1; } char ch1 = filename.charAt(1); if (ch1 == ':') { ch0 = Character.toUpperCase(ch0); if (ch0 >= 'A' && ch0 <= 'Z') { if (len == 2 || isSeparator(filename.charAt(2)) == false) { return 2; } return 3; } return -1; } else if (isSeparator(ch0) && isSeparator(ch1)) { int posUnix = filename.indexOf(UNIX_SEPARATOR, 2); int posWin = filename.indexOf(WINDOWS_SEPARATOR, 2); if ((posUnix == -1 && posWin == -1) || posUnix == 2 || posWin == 2) { return -1; } posUnix = (posUnix == -1 ? posWin : posUnix); posWin = (posWin == -1 ? posUnix : posWin); return Math.min(posUnix, posWin) + 1; } else { return (isSeparator(ch0) ? 1 : 0); } } } /** * Checks if the character is a separator. * * @param ch the character to check * @return true if it is a separator character */ private static boolean isSeparator(char ch) { return (ch == UNIX_SEPARATOR) || (ch == WINDOWS_SEPARATOR); } }