1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php 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 package com.android.ide.eclipse.adt; 18 19 import org.eclipse.core.resources.IFile; 20 import org.eclipse.core.resources.IResource; 21 import org.eclipse.core.resources.IWorkspaceRoot; 22 import org.eclipse.core.resources.ResourcesPlugin; 23 import org.eclipse.core.runtime.IPath; 24 import org.eclipse.ui.IEditorInput; 25 import org.eclipse.ui.IEditorPart; 26 import org.eclipse.ui.IFileEditorInput; 27 import org.eclipse.ui.IWorkbenchPage; 28 import org.eclipse.ui.IWorkbenchWindow; 29 import org.eclipse.ui.PlatformUI; 30 import org.eclipse.ui.texteditor.ITextEditor; 31 32 33 /** Utility methods for ADT */ 34 public class AdtUtils { 35 /** 36 * Returns true if the given string ends with the given suffix, using a 37 * case-insensitive comparison. 38 * 39 * @param string the full string to be checked 40 * @param suffix the suffix to be checked for 41 * @return true if the string case-insensitively ends with the given suffix 42 */ endsWithIgnoreCase(String string, String suffix)43 public static boolean endsWithIgnoreCase(String string, String suffix) { 44 return string.regionMatches(true /* ignoreCase */, string.length() - suffix.length(), 45 suffix, 0, suffix.length()); 46 } 47 48 /** 49 * Returns true if the given sequence ends with the given suffix (case 50 * sensitive). 51 * 52 * @param sequence the character sequence to be checked 53 * @param suffix the suffix to look for 54 * @return true if the given sequence ends with the given suffix 55 */ endsWith(CharSequence sequence, CharSequence suffix)56 public static boolean endsWith(CharSequence sequence, CharSequence suffix) { 57 return endsWith(sequence, sequence.length(), suffix); 58 } 59 60 /** 61 * Returns true if the given sequence ends at the given offset with the given suffix (case 62 * sensitive) 63 * 64 * @param sequence the character sequence to be checked 65 * @param endOffset the offset at which the sequence is considered to end 66 * @param suffix the suffix to look for 67 * @return true if the given sequence ends with the given suffix 68 */ endsWith(CharSequence sequence, int endOffset, CharSequence suffix)69 public static boolean endsWith(CharSequence sequence, int endOffset, CharSequence suffix) { 70 if (endOffset < suffix.length()) { 71 return false; 72 } 73 74 for (int i = endOffset - 1, j = suffix.length() - 1; j >= 0; i--, j--) { 75 if (sequence.charAt(i) != suffix.charAt(j)) { 76 return false; 77 } 78 } 79 80 return true; 81 } 82 83 /** 84 * Strips the whitespace from the given string 85 * 86 * @param string the string to be cleaned up 87 * @return the string, without whitespace 88 */ stripWhitespace(String string)89 public static String stripWhitespace(String string) { 90 StringBuilder sb = new StringBuilder(string.length()); 91 for (int i = 0, n = string.length(); i < n; i++) { 92 char c = string.charAt(i); 93 if (!Character.isWhitespace(c)) { 94 sb.append(c); 95 } 96 } 97 98 return sb.toString(); 99 } 100 101 /** 102 * Creates a Java class name out of the given string, if possible. For 103 * example, "My Project" becomes "MyProject", "hello" becomes "Hello", 104 * "Java's" becomes "Java", and so on. 105 * 106 * @param string the string to be massaged into a Java class 107 * @return the string as a Java class, or null if a class name could not be 108 * extracted 109 */ extractClassName(String string)110 public static String extractClassName(String string) { 111 StringBuilder sb = new StringBuilder(string.length()); 112 int n = string.length(); 113 114 int i = 0; 115 for (; i < n; i++) { 116 char c = Character.toUpperCase(string.charAt(i)); 117 if (Character.isJavaIdentifierStart(c)) { 118 sb.append(c); 119 i++; 120 break; 121 } 122 } 123 if (sb.length() > 0) { 124 for (; i < n; i++) { 125 char c = string.charAt(i); 126 if (Character.isJavaIdentifierPart(c)) { 127 sb.append(c); 128 } 129 } 130 131 return sb.toString(); 132 } 133 134 return null; 135 } 136 137 /** 138 * Strips off the last file extension from the given filename, e.g. 139 * "foo.backup.diff" will be turned into "foo.backup". 140 * <p> 141 * Note that dot files (e.g. ".profile") will be left alone. 142 * 143 * @param filename the filename to be stripped 144 * @return the filename without the last file extension. 145 */ stripLastExtension(String filename)146 public static String stripLastExtension(String filename) { 147 int dotIndex = filename.lastIndexOf('.'); 148 if (dotIndex > 0) { // > 0 instead of != -1: Treat dot files (e.g. .profile) differently 149 return filename.substring(0, dotIndex); 150 } else { 151 return filename; 152 } 153 } 154 155 /** 156 * Strips off all extensions from the given filename, e.g. "foo.9.png" will 157 * be turned into "foo". 158 * <p> 159 * Note that dot files (e.g. ".profile") will be left alone. 160 * 161 * @param filename the filename to be stripped 162 * @return the filename without any file extensions 163 */ stripAllExtensions(String filename)164 public static String stripAllExtensions(String filename) { 165 int dotIndex = filename.indexOf('.'); 166 if (dotIndex > 0) { // > 0 instead of != -1: Treat dot files (e.g. .profile) differently 167 return filename.substring(0, dotIndex); 168 } else { 169 return filename; 170 } 171 } 172 173 /** 174 * Capitalizes the string, i.e. transforms the initial [a-z] into [A-Z]. 175 * Returns the string unmodified if the first character is not [a-z]. 176 * 177 * @param str The string to capitalize. 178 * @return The capitalized string 179 */ capitalize(String str)180 public static String capitalize(String str) { 181 if (str == null || str.length() < 1 || Character.isUpperCase(str.charAt(0))) { 182 return str; 183 } 184 185 StringBuilder sb = new StringBuilder(); 186 sb.append(Character.toUpperCase(str.charAt(0))); 187 sb.append(str.substring(1)); 188 return sb.toString(); 189 } 190 191 /** 192 * Computes the edit distance (number of insertions, deletions or substitutions 193 * to edit one string into the other) between two strings. In particular, 194 * this will compute the Levenshtein distance. 195 * <p> 196 * See http://en.wikipedia.org/wiki/Levenshtein_distance for details. 197 * 198 * @param s the first string to compare 199 * @param t the second string to compare 200 * @return the edit distance between the two strings 201 */ editDistance(String s, String t)202 public static int editDistance(String s, String t) { 203 int m = s.length(); 204 int n = t.length(); 205 int[][] d = new int[m + 1][n + 1]; 206 for (int i = 0; i <= m; i++) { 207 d[i][0] = i; 208 } 209 for (int j = 0; j <= n; j++) { 210 d[0][j] = j; 211 } 212 for (int j = 1; j <= n; j++) { 213 for (int i = 1; i <= m; i++) { 214 if (s.charAt(i - 1) == t.charAt(j - 1)) { 215 d[i][j] = d[i - 1][j - 1]; 216 } else { 217 int deletion = d[i - 1][j] + 1; 218 int insertion = d[i][j - 1] + 1; 219 int substitution = d[i - 1][j - 1] + 1; 220 d[i][j] = Math.min(deletion, Math.min(insertion, substitution)); 221 } 222 } 223 } 224 225 return d[m][n]; 226 } 227 228 /** 229 * Returns the current editor (the currently visible and active editor), or null if 230 * not found 231 * 232 * @return the current editor, or null 233 */ getActiveEditor()234 public static IEditorPart getActiveEditor() { 235 IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 236 if (window != null) { 237 IWorkbenchPage page = window.getActivePage(); 238 if (page != null) { 239 return page.getActiveEditor(); 240 } 241 } 242 243 return null; 244 } 245 246 /** 247 * Returns the current text editor (the currently visible and active editor), or null 248 * if not found. 249 * 250 * @return the current text editor, or null 251 */ getActiveTextEditor()252 public static ITextEditor getActiveTextEditor() { 253 IEditorPart editor = getActiveEditor(); 254 if (editor != null) { 255 if (editor instanceof ITextEditor) { 256 return (ITextEditor) editor; 257 } else { 258 return (ITextEditor) editor.getAdapter(ITextEditor.class); 259 } 260 } 261 262 return null; 263 } 264 265 /** 266 * Returns the file for the current editor, if any. 267 * 268 * @return the file for the current editor, or null if none 269 */ getActiveFile()270 public static IFile getActiveFile() { 271 IEditorPart editor = getActiveEditor(); 272 if (editor != null) { 273 IEditorInput input = editor.getEditorInput(); 274 if (input instanceof IFileEditorInput) { 275 IFileEditorInput fileInput = (IFileEditorInput) input; 276 return fileInput.getFile(); 277 } 278 } 279 280 return null; 281 } 282 283 /** 284 * Returns an absolute path to the given resource 285 * 286 * @param resource the resource to look up a path for 287 * @return an absolute file system path to the resource 288 */ getAbsolutePath(IResource resource)289 public static IPath getAbsolutePath(IResource resource) { 290 IWorkspaceRoot workspace = ResourcesPlugin.getWorkspace().getRoot(); 291 IPath workspacePath = workspace.getLocation(); 292 return workspacePath.append(resource.getFullPath()); 293 } 294 } 295