org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/util/Util.java
Parent Directory
|
Revision Log
Revision 1.48 -
(download)
(annotate)
Wed Mar 29 17:22:13 2006 UTC (3 years, 7 months ago) by mvalenta
Branch: MAIN
CVS Tags: I20060510, M20061205, I200607032320, I200605031640, I20070409, R3_2, I20070402, I200604040100, I200610021645, I200603291800, I20070115, I200608211720, I20060917, I20060911, I200606191715, I200606261730, M200608151725, I20060714, I20070316, I20070219, I200604111815, I20070108, I200702051300, M200608161750, I200604130005, I20060330, M20061128, I20070220, I200604120001, M20060628, I200608081705, M20060711, M20061114, I20060605-1430, R3_2_1, R3_2_2, I20061120, I20061127, I20070303, I20060828_1701, I200606011710, I200604261810, I200607101745
Branch point for: R3_2_maintenance
Changes since 1.47: +2 -2 lines
Wed Mar 29 17:22:13 2006 UTC (3 years, 7 months ago) by mvalenta
Branch: MAIN
CVS Tags: I20060510, M20061205, I200607032320, I200605031640, I20070409, R3_2, I20070402, I200604040100, I200610021645, I200603291800, I20070115, I200608211720, I20060917, I20060911, I200606191715, I200606261730, M200608151725, I20060714, I20070316, I20070219, I200604111815, I20070108, I200702051300, M200608161750, I200604130005, I20060330, M20061128, I20070220, I200604120001, M20060628, I200608081705, M20060711, M20061114, I20060605-1430, R3_2_1, R3_2_2, I20061120, I20061127, I20070303, I20060828_1701, I200606011710, I200604261810, I200607101745
Branch point for: R3_2_maintenance
Changes since 1.47: +2 -2 lines
Updated copyrights
/******************************************************************************* * Copyright (c) 2000, 2006 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.team.internal.ccvs.core.util; import java.io.IOException; import java.io.InterruptedIOException; import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.osgi.util.NLS; import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.Session; import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; /** * Unsorted static helper-methods */ public class Util { /** * Return the last segment of the given path * @param path * @return String */ public static String getLastSegment(String path) { int index = path.lastIndexOf(Session.SERVER_SEPARATOR); if (index == -1) { return path; } if (index == path.length() - 1) { return getLastSegment(path.substring(0, index)); } return path.substring(index + 1); } /** * Return the the given path with the last segment removed * @param path * @return String */ public static String removeLastSegment(String path) { int index = path.lastIndexOf(Session.SERVER_SEPARATOR); if (index == -1) return ""; //$NON-NLS-1$ else return path.substring(0, index); } /** * Return the path without a trailing / * @param path * @return String */ public static String asPath(String path) { if (path.endsWith(Session.SERVER_SEPARATOR)) { return path.substring(0, path.length() - Session.SERVER_SEPARATOR.length()); } return path; } /* * * * Get the extention of the path of resource * relative to the path of root * * @throws CVSException if root is not a root-folder of resource */ public static String getRelativePath(String rootName, String resourceName) throws CVSException { if (!resourceName.startsWith(rootName) || rootName.length() > resourceName.length()) { throw new CVSException(CVSMessages.Util_Internal_error__resource_does_not_start_with_root_3); } // Otherwise we would get an ArrayOutOfBoundException // in case of two equal Resources if (rootName.length() == resourceName.length()) { return ""; //$NON-NLS-1$ } // Remove leading slash if there is one String result = resourceName.substring(rootName.length()); if (result.startsWith("/")) { //$NON-NLS-1$ result = result.substring(1); } return result; } /** * Append the prefix and suffix to form a valid CVS path. */ public static String appendPath(String prefix, String suffix) { if (prefix.length() == 0 || prefix.equals(Session.CURRENT_LOCAL_FOLDER)) { return suffix; } else if (prefix.endsWith(Session.SERVER_SEPARATOR)) { if (suffix.startsWith(Session.SERVER_SEPARATOR)) return prefix + suffix.substring(1); else return prefix + suffix; } else if (suffix.startsWith(Session.SERVER_SEPARATOR)) return prefix + suffix; else return prefix + Session.SERVER_SEPARATOR + suffix; } public static void logError(String message, Throwable throwable) { CVSProviderPlugin.log(IStatus.ERROR, message, throwable); } /** * If the number of segments in the relative path of <code>resource</code> to <code>root</code> is * greater than <code>split</code> then the returned path is truncated to <code>split</code> number * of segments and '...' is shown as the first segment of the path. */ public static String toTruncatedPath(ICVSResource resource, ICVSFolder root, int split) { try { String stringPath = resource.getRelativePath(root); if (stringPath.equals(Session.CURRENT_LOCAL_FOLDER)) { return resource.getName(); } String truncatedPath = toTruncatedPath(stringPath, split); return truncatedPath; } catch(CVSException e) { return resource.getName(); } } public static String toTruncatedPath(String stringPath, int split) { // Search backwards until split separators are found int count = 0; int index = stringPath.length(); while (count++ < split && index != -1) { index = stringPath.lastIndexOf(Session.SERVER_SEPARATOR, index - 1); } if (index == -1) { return stringPath; } else { return NLS.bind(CVSMessages.Util_truncatedPath, new String[] { stringPath.substring(index) }); } } /** * Helper method that will time out when making a socket connection. * This is required because there is no way to provide a timeout value * when creating a socket and in some instances, they don't seem to * timeout at all. */ public static Socket createSocket(final String host, final int port, IProgressMonitor monitor) throws UnknownHostException, IOException { // Start a thread to open a socket final Socket[] socket = new Socket[] { null }; final Exception[] exception = new Exception[] {null }; final Thread thread = new Thread(new Runnable() { public void run() { try { Socket newSocket = new Socket(host, port); synchronized (socket) { if (Thread.interrupted()) { // we we're either cancelled or timed out so just close the socket newSocket.close(); } else { socket[0] = newSocket; } } } catch (UnknownHostException e) { exception[0] = e; } catch (IOException e) { exception[0] = e; } } }); thread.start(); // Wait the appropriate number of seconds int timeout = CVSProviderPlugin.getPlugin().getTimeout(); if (timeout == 0) timeout = CVSProviderPlugin.DEFAULT_TIMEOUT; for (int i = 0; i < timeout; i++) { try { // wait for the thread to complete or 1 second, which ever comes first thread.join(1000); } catch (InterruptedException e) { // I think this means the thread was interupted but not necessarily timed out // so we don't need to do anything } synchronized (socket) { // if the user cancelled, clean up before preempting the operation if (monitor.isCanceled()) { if (thread.isAlive()) { thread.interrupt(); } if (socket[0] != null) { socket[0].close(); } // this method will throw the proper exception Policy.checkCanceled(monitor); } } } // If the thread is still running (i.e. we timed out) signal that it is too late synchronized (socket) { if (thread.isAlive()) { thread.interrupt(); } } if (exception[0] != null) { if (exception[0] instanceof UnknownHostException) throw (UnknownHostException)exception[0]; else throw (IOException)exception[0]; } if (socket[0] == null) { throw new InterruptedIOException(NLS.bind(CVSMessages.Util_timeout, new String[] { host })); } return socket[0]; } /** * Helper method that will time out when running an external command. * This is required because there is no way to provide a timeout value * when executing an external command and in some instances, they don't seem to * timeout at all. */ public static Process createProcess(final String[] command, IProgressMonitor monitor) throws IOException { // Start a thread to execute the command and get a handle to the process final Process[] process = new Process[] { null }; final Exception[] exception = new Exception[] {null }; final Thread thread = new Thread(new Runnable() { public void run() { try { Process newProcess = Runtime.getRuntime().exec(command); synchronized (process) { if (Thread.interrupted()) { // we we're either cancelled or timed out so just destroy the process newProcess.destroy(); } else { process[0] = newProcess; } } } catch (IOException e) { exception[0] = e; } } }); thread.start(); // Wait the appropriate number of seconds int timeout = CVSProviderPlugin.getPlugin().getTimeout(); if (timeout == 0) timeout = CVSProviderPlugin.DEFAULT_TIMEOUT; for (int i = 0; i < timeout; i++) { try { // wait for the thread to complete or 1 second, which ever comes first thread.join(1000); } catch (InterruptedException e) { // I think this means the thread was interupted but not necessarily timed out // so we don't need to do anything } synchronized (process) { // if the user cancelled, clean up before preempting the operation if (monitor.isCanceled()) { if (thread.isAlive()) { thread.interrupt(); } if (process[0] != null) { process[0].destroy(); } // this method will throw the proper exception Policy.checkCanceled(monitor); } } } // If the thread is still running (i.e. we timed out) signal that it is too late synchronized (process) { if (thread.isAlive()) { thread.interrupt(); } } if (exception[0] != null) { throw (IOException)exception[0]; } if (process[0] == null) { throw new InterruptedIOException(NLS.bind(CVSMessages.Util_processTimeout, new String[] { command[0] })); } return process[0]; } public static String[] parseIntoSubstrings(String string, String delimiter) { List result = new ArrayList(); int start = 0; int index = string.indexOf(delimiter); String next; while (index != -1) { next = string.substring(start, index); result.add(next); start = index + 1; index = string.indexOf(delimiter, start); } if (start >= string.length()) { next = "";//$NON-NLS-1$ } else { next = string.substring(start); } result.add(next); return (String[]) result.toArray(new String[result.size()]); } /** * Return the substring at the given index (starting at 0) where each * element is delimited by the provided delimiter. * * @param bytes * @param delimiter * @param index * @param includeRest * @return String */ public static String getSubstring(byte[] bytes, byte delimiter, int index, boolean includeRest) { byte[] bytesForSlot = getBytesForSlot(bytes, delimiter, index, includeRest); if (bytesForSlot == null) { return null; } return new String(bytesForSlot); } /** * Return the offset the the Nth delimeter from the given start index. * @param bytes * @param delimiter * @param start * @param n * @return int */ public static int getOffsetOfDelimeter(byte[] bytes, byte delimiter, int start, int n) { int count = 0; for (int i = start; i < bytes.length; i++) { if (bytes[i] == delimiter) count++; if (count == n) return i; } // the Nth delimeter was not found return -1; } /** * Method getBytesForSlot. * @param syncBytes * @param SEPARATOR_BYTE * @param i * @param b * @return byte[] */ public static byte[] getBytesForSlot(byte[] bytes, byte delimiter, int index, boolean includeRest) { // Find the starting index int start; if (index == 0) { // make start -1 so that end determination will start at offset 0. start = -1; } else { start = getOffsetOfDelimeter(bytes, delimiter, 0, index); if (start == -1) return null; } // Find the ending index int end = getOffsetOfDelimeter(bytes, delimiter, start + 1, 1); // Calculate the length int length; if (end == -1 || includeRest) { length = bytes.length - start - 1; } else { length = end - start - 1; } byte[] result = new byte[length]; System.arraycopy(bytes, start + 1, result, 0, length); return result; } /** * Method equals. * @param syncBytes * @param oldBytes * @return boolean */ public static boolean equals(byte[] syncBytes, byte[] oldBytes) { if (syncBytes == null || oldBytes == null) return syncBytes == oldBytes; if (syncBytes.length != oldBytes.length) return false; for (int i = 0; i < oldBytes.length; i++) { if (oldBytes[i] != syncBytes[i]) return false; } return true; } /** * Workaround a CVS bug where a CVS Folder with no immediately contained files has an incorrect * Tag type stored in the TAG file. In this case, the tag type is always BRANCH (Tv1) * * The fix is for folders with no files, use the tag type for the containing project. Since projects almost * always have files the TAG file is usually correct. * * For the case where the folder tag name does not match the project tag name we can not do much so we just * return the folder tag which will currently always be a branch. * * @param resource The IResource being tested. Can not be null. * @param tag The CVSTag as reported by CVS for the IResource. May be null. * @return CVSTag The corrected tag for the resource. May be null. */ public static CVSTag getAccurateFolderTag(IResource resource, CVSTag tag) { // Determine if the folder contains files as immediate children. if (resource.getType() != IResource.FOLDER) { return tag; } IResource[] members = null; try { members = ((IFolder) resource).members(); } catch (CoreException e1) { return tag; } for (int i = 0; i < members.length; i++) { if (members[i].getType() == IResource.FILE) { return tag; } } // Folder contains no files so this may not really be a branch. // Make the type the same as the project tag type if both are the same tag name. IProject project = resource.getProject(); if (project == null) { return tag; } ICVSFolder projectFolder = CVSWorkspaceRoot.getCVSFolderFor(project); FolderSyncInfo projectSyncInfo; try { projectSyncInfo = projectFolder.getFolderSyncInfo(); } catch (CVSException e) { return tag; } if (projectSyncInfo == null) { return tag; } CVSTag projectTag = projectSyncInfo.getTag(); if (projectTag != null && projectTag.getName().equals(tag.getName())) { return projectTag; } else { return tag; } } /** * Workaround for CVS "bug" where CVS ENTRIES file does not contain correct * Branch vs. Version info. Entries files always record a Tv1 so all entries would * appear as branches. * * By comparing the revision number to the tag name * you can determine if the tag is a branch or version. * * @param cvsResource the resource to test. Must nut be null. * @return the correct cVSTag. May be null. */ public static CVSTag getAccurateFileTag(ICVSResource cvsResource) throws CVSException { CVSTag tag = null; ResourceSyncInfo info = cvsResource.getSyncInfo(); if(info != null) { tag = info.getTag(); } FolderSyncInfo parentInfo = cvsResource.getParent().getFolderSyncInfo(); CVSTag parentTag = null; if(parentInfo != null) { parentTag = parentInfo.getTag(); } if(tag != null) { if(tag.getName().equals(info.getRevision())) { tag = new CVSTag(tag.getName(), CVSTag.VERSION); } else if(parentTag != null){ tag = new CVSTag(tag.getName(), parentTag.getType()); } } return tag; } /** * Return the fullest path that we can obtain for the given resource * @param resource * @return */ public static String getFullestPath(ICVSResource resource) { IResource local = resource.getIResource(); if (local != null) { return local.getFullPath().toString(); } try { String remotePath = resource.getRepositoryRelativePath(); if (remotePath != null) { return remotePath; } } catch (CVSException e) { // Ignore and try the next method; } return resource.getName(); } public static String getVariablePattern(String pattern, String variableName) { return "(" + variableName + ":" + pattern + ":" + variableName + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } /** * @param localRevision * @return */ public static int[] convertToDigits(String localRevision) { try { String digitStrings[] = localRevision.split("\\."); //$NON-NLS-1$ int[] digits = new int[digitStrings.length]; for (int i = 0; i < digitStrings.length; i++) { String digitString = digitStrings[i]; digits[i] = Integer.parseInt(digitString); } return digits; } catch (NumberFormatException e) { CVSProviderPlugin.log(CVSException.wrapException(e)); return new int[0]; } } public static String toTruncatedPath(ICVSStorage file, ICVSFolder localRoot, int i) { if (file instanceof ICVSResource) { return toTruncatedPath((ICVSResource)file, localRoot, i); } return file.getName(); } /** * If the status/log returns that the file is in the Attic, then remove the * Attic segment. This is because files added to a branch that are not in * the main trunk (HEAD) are added to the Attic but cvs does magic on * update to put them in the correct location. * (e.g. /project/Attic/file.txt -> /project/file.txt) */ public static String removeAtticSegment(String path) { int lastSeparator = path.lastIndexOf(Session.SERVER_SEPARATOR); if (lastSeparator == -1) return path; int secondLastSeparator = path.lastIndexOf(Session.SERVER_SEPARATOR, lastSeparator - 1); if (secondLastSeparator == -1) return path; String secondLastSegment = path.substring(secondLastSeparator + 1, lastSeparator); if (secondLastSegment.equals("Attic")) { //$NON-NLS-1$ return path.substring(0, secondLastSeparator) + path.substring(lastSeparator); } return path; } /** * Flatten the text in the multiline comment */ public static String flattenText(String string) { StringBuffer buffer = new StringBuffer(string.length() + 20); boolean skipAdjacentLineSeparator = true; for (int i = 0; i < string.length(); i++) { char c = string.charAt(i); if (c == '\r' || c == '\n') { if (!skipAdjacentLineSeparator) buffer.append(Session.SERVER_SEPARATOR); skipAdjacentLineSeparator = true; } else { buffer.append(c); skipAdjacentLineSeparator = false; } } return buffer.toString(); } }
| help@eclipse.org | ViewVC Help |
| Powered by ViewVC 1.0.3 |
