| 1 | /******************************************************************************* | 
| 2 |  * Copyright (c) 2007, 2009 IBM Corporation and others. | 
| 3 |  * All rights reserved. This program and the accompanying materials | 
| 4 |  * are made available under the terms of the Eclipse Public License v1.0 | 
| 5 |  * which accompanies this distribution, and is available at | 
| 6 |  * http://www.eclipse.org/legal/epl-v10.html | 
| 7 |  *  | 
| 8 |  * Contributors: | 
| 9 |  *     IBM Corporation - initial API and implementation | 
| 10 |  *******************************************************************************/ | 
| 11 | package org.eclipse.pde.api.tools.internal.util; | 
| 12 |   | 
| 13 | import java.io.BufferedInputStream; | 
| 14 | import java.io.BufferedOutputStream; | 
| 15 | import java.io.BufferedWriter; | 
| 16 | import java.io.ByteArrayInputStream; | 
| 17 | import java.io.ByteArrayOutputStream; | 
| 18 | import java.io.File; | 
| 19 | import java.io.FileFilter; | 
| 20 | import java.io.FileInputStream; | 
| 21 | import java.io.FileNotFoundException; | 
| 22 | import java.io.FileOutputStream; | 
| 23 | import java.io.FileWriter; | 
| 24 | import java.io.FilenameFilter; | 
| 25 | import java.io.IOException; | 
| 26 | import java.io.InputStream; | 
| 27 | import java.io.LineNumberReader; | 
| 28 | import java.io.PrintWriter; | 
| 29 | import java.io.StringReader; | 
| 30 | import java.io.UnsupportedEncodingException; | 
| 31 | import java.lang.reflect.Field; | 
| 32 | import java.nio.ByteBuffer; | 
| 33 | import java.nio.charset.Charset; | 
| 34 | import java.nio.charset.CharsetDecoder; | 
| 35 | import java.nio.charset.CodingErrorAction; | 
| 36 | import java.nio.charset.IllegalCharsetNameException; | 
| 37 | import java.nio.charset.UnsupportedCharsetException; | 
| 38 | import java.util.ArrayList; | 
| 39 | import java.util.Arrays; | 
| 40 | import java.util.Comparator; | 
| 41 | import java.util.Enumeration; | 
| 42 | import java.util.HashSet; | 
| 43 | import java.util.Iterator; | 
| 44 | import java.util.List; | 
| 45 | import java.util.Properties; | 
| 46 | import java.util.Set; | 
| 47 | import java.util.StringTokenizer; | 
| 48 | import java.util.jar.JarFile; | 
| 49 | import java.util.regex.Pattern; | 
| 50 | import java.util.regex.PatternSyntaxException; | 
| 51 | import java.util.zip.ZipEntry; | 
| 52 | import java.util.zip.ZipException; | 
| 53 | import java.util.zip.ZipFile; | 
| 54 | import java.util.zip.ZipInputStream; | 
| 55 |   | 
| 56 | import javax.xml.parsers.DocumentBuilder; | 
| 57 | import javax.xml.parsers.DocumentBuilderFactory; | 
| 58 | import javax.xml.parsers.FactoryConfigurationError; | 
| 59 | import javax.xml.parsers.ParserConfigurationException; | 
| 60 | import javax.xml.transform.OutputKeys; | 
| 61 | import javax.xml.transform.Transformer; | 
| 62 | import javax.xml.transform.TransformerException; | 
| 63 | import javax.xml.transform.TransformerFactory; | 
| 64 | import javax.xml.transform.dom.DOMSource; | 
| 65 | import javax.xml.transform.stream.StreamResult; | 
| 66 |   | 
| 67 | import org.eclipse.core.filebuffers.FileBuffers; | 
| 68 | import org.eclipse.core.filebuffers.ITextFileBufferManager; | 
| 69 | import org.eclipse.core.filebuffers.LocationKind; | 
| 70 | import org.eclipse.core.resources.IFile; | 
| 71 | import org.eclipse.core.resources.IMarker; | 
| 72 | import org.eclipse.core.resources.IProject; | 
| 73 | import org.eclipse.core.resources.IResource; | 
| 74 | import org.eclipse.core.resources.IncrementalProjectBuilder; | 
| 75 | import org.eclipse.core.resources.ResourcesPlugin; | 
| 76 | import org.eclipse.core.runtime.Assert; | 
| 77 | import org.eclipse.core.runtime.CoreException; | 
| 78 | import org.eclipse.core.runtime.IPath; | 
| 79 | import org.eclipse.core.runtime.IProgressMonitor; | 
| 80 | import org.eclipse.core.runtime.IStatus; | 
| 81 | import org.eclipse.core.runtime.NullProgressMonitor; | 
| 82 | import org.eclipse.core.runtime.OperationCanceledException; | 
| 83 | import org.eclipse.core.runtime.Path; | 
| 84 | import org.eclipse.core.runtime.Status; | 
| 85 | import org.eclipse.core.runtime.SubMonitor; | 
| 86 | import org.eclipse.core.runtime.jobs.Job; | 
| 87 | import org.eclipse.jdt.core.Flags; | 
| 88 | import org.eclipse.jdt.core.ICompilationUnit; | 
| 89 | import org.eclipse.jdt.core.IField; | 
| 90 | import org.eclipse.jdt.core.IJavaProject; | 
| 91 | import org.eclipse.jdt.core.IMember; | 
| 92 | import org.eclipse.jdt.core.IMethod; | 
| 93 | import org.eclipse.jdt.core.IType; | 
| 94 | import org.eclipse.jdt.core.JavaCore; | 
| 95 | import org.eclipse.jdt.core.JavaModelException; | 
| 96 | import org.eclipse.jdt.core.Signature; | 
| 97 | import org.eclipse.jdt.internal.compiler.codegen.ConstantPool; | 
| 98 | import org.eclipse.jdt.launching.IVMInstall; | 
| 99 | import org.eclipse.jdt.launching.JavaRuntime; | 
| 100 | import org.eclipse.jdt.launching.LibraryLocation; | 
| 101 | import org.eclipse.jdt.launching.environments.ExecutionEnvironmentDescription; | 
| 102 | import org.eclipse.jface.text.IDocument; | 
| 103 | import org.eclipse.osgi.util.NLS; | 
| 104 | import org.eclipse.pde.api.tools.internal.ApiFilterStore; | 
| 105 | import org.eclipse.pde.api.tools.internal.IApiCoreConstants; | 
| 106 | import org.eclipse.pde.api.tools.internal.builder.BuildState; | 
| 107 | import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin; | 
| 108 | import org.eclipse.pde.api.tools.internal.provisional.Factory; | 
| 109 | import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants; | 
| 110 | import org.eclipse.pde.api.tools.internal.provisional.IRequiredComponentDescription; | 
| 111 | import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers; | 
| 112 | import org.eclipse.pde.api.tools.internal.provisional.comparator.DeltaVisitor; | 
| 113 | import org.eclipse.pde.api.tools.internal.provisional.comparator.IDelta; | 
| 114 | import org.eclipse.pde.api.tools.internal.provisional.descriptors.IReferenceTypeDescriptor; | 
| 115 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiBaseline; | 
| 116 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent; | 
| 117 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement; | 
| 118 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiType; | 
| 119 | import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeRoot; | 
| 120 | import org.eclipse.pde.api.tools.internal.search.SkippedComponent; | 
| 121 | import org.objectweb.asm.Opcodes; | 
| 122 | import org.osgi.framework.Version; | 
| 123 | import org.w3c.dom.Document; | 
| 124 | import org.w3c.dom.Element; | 
| 125 | import org.xml.sax.SAXException; | 
| 126 | import org.xml.sax.helpers.DefaultHandler; | 
| 127 |   | 
| 128 | /** | 
| 129 |  * A Utility class to use for API tools | 
| 130 |  *  | 
| 131 |  * @since 1.0.0 | 
| 132 |  */ | 
| 133 | public final class Util { | 
| 134 |   | 
| 135 |         /** | 
| 136 |          * Class that runs a build in the workspace or the given project | 
| 137 |          */ | 
| 138 |         private static final class BuildJob extends Job { | 
| 139 |                 private final IProject[] fProjects; | 
| 140 |                 private int fBuildType; | 
| 141 |   | 
| 142 |                 /** | 
| 143 |                  * Constructor | 
| 144 |                  * @param name | 
| 145 |                  * @param project | 
| 146 |                  */ | 
| 147 |                 BuildJob(String name, IProject[] projects) { | 
| 148 |                         this(name, projects, IncrementalProjectBuilder.FULL_BUILD); | 
| 149 |                 } | 
| 150 |                 BuildJob(String name, IProject[] projects, int buildType) { | 
| 151 |                         super(name); | 
| 152 |                         fProjects = projects; | 
| 153 |                         this.fBuildType = buildType; | 
| 154 |                 } | 
| 155 |                 public boolean belongsTo(Object family) { | 
| 156 |                         return ResourcesPlugin.FAMILY_MANUAL_BUILD == family; | 
| 157 |                 } | 
| 158 |                  | 
| 159 |                 /** | 
| 160 |                  * Returns if this build job is covered by another build job | 
| 161 |                  * @param other | 
| 162 |                  * @return true if covered by another build job, false otherwise | 
| 163 |                  */ | 
| 164 |                 public boolean isCoveredBy(BuildJob other) { | 
| 165 |                         if (other.fProjects == null) { | 
| 166 |                                 return true; | 
| 167 |                         } | 
| 168 |                         if (this.fProjects != null) { | 
| 169 |                                 for (int i = 0, max = this.fProjects.length; i < max; i++) { | 
| 170 |                                         if (!other.contains(this.fProjects[i])) { | 
| 171 |                                                 return false; | 
| 172 |                                         } | 
| 173 |                                 } | 
| 174 |                                 return true; | 
| 175 |                         } | 
| 176 |                         return false; | 
| 177 |                 } | 
| 178 |                  | 
| 179 |                 public boolean contains(IProject project) { | 
| 180 |                         if (project == null) return false; | 
| 181 |                         for (int i = 0, max = this.fProjects.length; i < max; i++) { | 
| 182 |                                 if (project.equals(this.fProjects[i])) { | 
| 183 |                                         return true; | 
| 184 |                                 } | 
| 185 |                         } | 
| 186 |                         return false; | 
| 187 |                 } | 
| 188 |                 /* (non-Javadoc) | 
| 189 |                  * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) | 
| 190 |                  */ | 
| 191 |                 protected IStatus run(IProgressMonitor monitor) { | 
| 192 |                         synchronized (getClass()) { | 
| 193 |                                 if (monitor.isCanceled()) { | 
| 194 |                                         return Status.CANCEL_STATUS; | 
| 195 |                                 } | 
| 196 |                                 //cancelBuild(ResourcesPlugin.FAMILY_AUTO_BUILD); | 
| 197 |                                 cancelBuild(ResourcesPlugin.FAMILY_MANUAL_BUILD); | 
| 198 |                         } | 
| 199 |                         try { | 
| 200 |                                 if (fProjects != null) { | 
| 201 |                                         SubMonitor localmonitor = SubMonitor.convert(monitor, UtilMessages.Util_0, fProjects.length); | 
| 202 |                                         for (int i = 0, max = fProjects.length; i < max; i++) { | 
| 203 |                                                 // clear last build state for project to force a full build using our builder | 
| 204 |                                                 // This makes it possible to have only an incremental build from the java builder | 
| 205 |                                                 IProject currentProject = fProjects[i]; | 
| 206 |                                                 if (this.fBuildType == IncrementalProjectBuilder.FULL_BUILD) { | 
| 207 |                                                         BuildState.setLastBuiltState(currentProject, null); | 
| 208 |                                                 } | 
| 209 |                                                 localmonitor.subTask(NLS.bind(UtilMessages.Util_5, currentProject.getName()));  | 
| 210 |                                                 if (ResourcesPlugin.getWorkspace().isAutoBuilding()) { | 
| 211 |                                                         currentProject.touch(null); | 
| 212 |                                                 } else { | 
| 213 |                                                         currentProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, localmonitor.newChild(1)); | 
| 214 |                                                 } | 
| 215 |                                         } | 
| 216 |                                 } | 
| 217 |                         } catch (CoreException e) { | 
| 218 |                                 return e.getStatus(); | 
| 219 |                         } catch (OperationCanceledException e) { | 
| 220 |                                 return Status.CANCEL_STATUS; | 
| 221 |                         } | 
| 222 |                         finally { | 
| 223 |                                 monitor.done(); | 
| 224 |                         } | 
| 225 |                         return Status.OK_STATUS; | 
| 226 |                 } | 
| 227 |                  | 
| 228 |                 private void cancelBuild(Object jobfamily) { | 
| 229 |                         Job[] buildJobs = Job.getJobManager().find(jobfamily); | 
| 230 |                         for (int i= 0; i < buildJobs.length; i++) { | 
| 231 |                                 Job curr = buildJobs[i]; | 
| 232 |                                 if (curr != this && curr instanceof BuildJob) { | 
| 233 |                                         BuildJob job = (BuildJob) curr; | 
| 234 |                                         if (job.isCoveredBy(this)) { | 
| 235 |                                                 curr.cancel(); // cancel all other build jobs of our kind | 
| 236 |                                         } | 
| 237 |                                 } | 
| 238 |                         } | 
| 239 |                 } | 
| 240 |         } | 
| 241 |          | 
| 242 |         public static boolean DEBUG; | 
| 243 |   | 
| 244 |         public static final String EMPTY_STRING = "";//$NON-NLS-1$ | 
| 245 |         public static final String DEFAULT_PACKAGE_NAME = EMPTY_STRING; | 
| 246 |         public static final String MANIFEST_NAME = "MANIFEST.MF"; //$NON-NLS-1$ | 
| 247 |          | 
| 248 |         public static final String DOT_CLASS_SUFFIX = ".class"; //$NON-NLS-1$ | 
| 249 |         public static final String DOT_JAVA_SUFFIX = ".java"; //$NON-NLS-1$ | 
| 250 |   | 
| 251 |         /** | 
| 252 |          * Constant representing the default size to read from an input stream | 
| 253 |          */ | 
| 254 |         private static final int DEFAULT_READING_SIZE = 8192; | 
| 255 |          | 
| 256 |         private static final String JAVA_LANG_OBJECT = "java.lang.Object"; //$NON-NLS-1$ | 
| 257 |         private static final String JAVA_LANG_RUNTIMEEXCEPTION = "java.lang.RuntimeException"; //$NON-NLS-1$ | 
| 258 |         public static final String LINE_DELIMITER = System.getProperty("line.separator"); //$NON-NLS-1$ | 
| 259 |          | 
| 260 |         public static final String UNKNOWN_ELEMENT_KIND = "UNKNOWN_ELEMENT_KIND"; //$NON-NLS-1$ | 
| 261 |   | 
| 262 |         public static final String UNKNOWN_FLAGS = "UNKNOWN_FLAGS"; //$NON-NLS-1$ | 
| 263 |         public static final String UNKNOWN_KIND = "UNKNOWN_KIND"; //$NON-NLS-1$ | 
| 264 |         public static final String UNKNOWN_VISIBILITY = "UNKNOWN_VISIBILITY"; //$NON-NLS-1$ | 
| 265 |         public static final String ISO_8859_1 = "ISO-8859-1"; //$NON-NLS-1$ | 
| 266 |         public static final String REGULAR_EXPRESSION_START = "R:"; //$NON-NLS-1$ | 
| 267 |   | 
| 268 |         // Trace for delete operation | 
| 269 |         /* | 
| 270 |          * Maximum time wasted repeating delete operations while running JDT/Core tests. | 
| 271 |          */ | 
| 272 |         private static int DELETE_MAX_TIME = 0; | 
| 273 |         /** | 
| 274 |          * Trace deletion operations while running JDT/Core tests. | 
| 275 |          */ | 
| 276 |         private static boolean DELETE_DEBUG = false; | 
| 277 |         /** | 
| 278 |          * Maximum of time in ms to wait in deletion operation while running JDT/Core tests. | 
| 279 |          * Default is 10 seconds. This number cannot exceed 1 minute (i.e. 60000). | 
| 280 |          * <br> | 
| 281 |          * To avoid too many loops while waiting, the ten first ones are done waiting | 
| 282 |          * 10ms before repeating, the ten loops after are done waiting 100ms and | 
| 283 |          * the other loops are done waiting 1s... | 
| 284 |          */ | 
| 285 |         private static int DELETE_MAX_WAIT = 10000; | 
| 286 |   | 
| 287 |         public static final IPath MANIFEST_PROJECT_RELATIVE_PATH = new Path(JarFile.MANIFEST_NAME); | 
| 288 |   | 
| 289 |         public static final String ORG_ECLIPSE_SWT = "org.eclipse.swt"; //$NON-NLS-1$ | 
| 290 |   | 
| 291 |         static { | 
| 292 |                 String property = System.getProperty("DEBUG"); //$NON-NLS-1$ | 
| 293 |                 DEBUG = property != null && property.equalsIgnoreCase("TRUE"); //$NON-NLS-1$ | 
| 294 |         } | 
| 295 |   | 
| 296 |         /** | 
| 297 |          * Throws an exception with the given message and underlying exception. | 
| 298 |          *  | 
| 299 |          * @param message error message | 
| 300 |          * @param exception underlying exception, or <code>null</code> | 
| 301 |          * @throws CoreException | 
| 302 |          */ | 
| 303 |         private static void abort(String message, Throwable exception) throws CoreException { | 
| 304 |                 IStatus status = new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID, message, exception); | 
| 305 |                 throw new CoreException(status); | 
| 306 |         } | 
| 307 |   | 
| 308 |         /** | 
| 309 |          * Appends a property to the given string buffer with the given key and value | 
| 310 |          * in the format "key=value\n". | 
| 311 |          *  | 
| 312 |          * @param buffer buffer to append to | 
| 313 |          * @param key key | 
| 314 |          * @param value value | 
| 315 |          */ | 
| 316 |         private static void appendProperty(StringBuffer buffer, String key, String value) { | 
| 317 |                 buffer.append(key); | 
| 318 |                 buffer.append('='); | 
| 319 |                 buffer.append(value); | 
| 320 |                 buffer.append('\n'); | 
| 321 |         } | 
| 322 |   | 
| 323 |         /** | 
| 324 |          * Collects all of the deltas from the given parent delta | 
| 325 |          * @param delta | 
| 326 |          * @return | 
| 327 |          */ | 
| 328 |         public static List collectAllDeltas(IDelta delta) { | 
| 329 |                 final List list = new ArrayList(); | 
| 330 |                 delta.accept(new DeltaVisitor() { | 
| 331 |                         public void endVisit(IDelta localDelta) { | 
| 332 |                                 if (localDelta.getChildren().length == 0) { | 
| 333 |                                         list.add(localDelta); | 
| 334 |                                 } | 
| 335 |                                 super.endVisit(localDelta); | 
| 336 |                         } | 
| 337 |                 }); | 
| 338 |                 return list; | 
| 339 |         } | 
| 340 |          | 
| 341 |         /** | 
| 342 |          * Collects files into the collector array list | 
| 343 |          *  | 
| 344 |          * @param root | 
| 345 |          *            the root to collect the files from | 
| 346 |          * @param collector | 
| 347 |          *            the collector to place matches into | 
| 348 |          * @param fileFilter | 
| 349 |          *            the filter for files or <code>null</code> to accept all | 
| 350 |          *            files | 
| 351 |          */ | 
| 352 |         private static void collectAllFiles(File root, ArrayList collector, FileFilter fileFilter) { | 
| 353 |                 File[] files = root.listFiles(fileFilter); | 
| 354 |                 for (int i = 0; i < files.length; i++) { | 
| 355 |                         final File currentFile = files[i]; | 
| 356 |                         if (currentFile.isDirectory()) { | 
| 357 |                                 collectAllFiles(currentFile, collector, fileFilter); | 
| 358 |                         } else { | 
| 359 |                                 collector.add(currentFile); | 
| 360 |                         } | 
| 361 |                 } | 
| 362 |         } | 
| 363 |   | 
| 364 |         /** | 
| 365 |          * Returns all of the API projects in the workspace | 
| 366 |          * @return all of the API projects in the workspace or <code>null</code> if there are none. | 
| 367 |          */ | 
| 368 |         public static IProject[] getApiProjects() { | 
| 369 |                 IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); | 
| 370 |                 ArrayList temp = new ArrayList(); | 
| 371 |                 IProject project = null; | 
| 372 |                 for (int i = 0, max = allProjects.length; i < max; i++) { | 
| 373 |                         project = allProjects[i]; | 
| 374 |                         if (project.isAccessible()) { | 
| 375 |                                 try { | 
| 376 |                                         if (project.hasNature(org.eclipse.pde.api.tools.internal.provisional.ApiPlugin.NATURE_ID)) { | 
| 377 |                                                 temp.add(project); | 
| 378 |                                         } | 
| 379 |                                 }  | 
| 380 |                                 catch (CoreException e) {} | 
| 381 |                         } | 
| 382 |                 } | 
| 383 |                 IProject[] projects = null; | 
| 384 |                 if (temp.size() != 0) { | 
| 385 |                         projects = new IProject[temp.size()]; | 
| 386 |                         temp.toArray(projects); | 
| 387 |                 } | 
| 388 |                 return projects; | 
| 389 |         } | 
| 390 |          | 
| 391 |         /** | 
| 392 |          * Copies the given file to the new file | 
| 393 |          * @param file | 
| 394 |          * @param newFile | 
| 395 |          * @return if the copy succeeded | 
| 396 |          */ | 
| 397 |         public static boolean copy(File file, File newFile) { | 
| 398 |                 byte[] bytes = null; | 
| 399 |                 BufferedInputStream inputStream = null; | 
| 400 |                 try { | 
| 401 |                         inputStream = new BufferedInputStream(new FileInputStream(file)); | 
| 402 |                         bytes = Util.getInputStreamAsByteArray(inputStream, -1); | 
| 403 |                 } catch (FileNotFoundException e) { | 
| 404 |                         ApiPlugin.log(e); | 
| 405 |                 } catch (IOException e) { | 
| 406 |                         ApiPlugin.log(e); | 
| 407 |                 } finally { | 
| 408 |                         if (inputStream != null) { | 
| 409 |                                 try { | 
| 410 |                                         inputStream.close(); | 
| 411 |                                 } catch (IOException e) { | 
| 412 |                                         ApiPlugin.log(e); | 
| 413 |                                 } | 
| 414 |                         } | 
| 415 |                 } | 
| 416 |                 if (bytes != null) { | 
| 417 |                         BufferedOutputStream outputStream = null; | 
| 418 |                         try { | 
| 419 |                                 outputStream = new BufferedOutputStream(new FileOutputStream(newFile)); | 
| 420 |                                 outputStream.write(bytes); | 
| 421 |                                 outputStream.flush(); | 
| 422 |                         } catch (FileNotFoundException e) { | 
| 423 |                                 ApiPlugin.log(e); | 
| 424 |                         } catch (IOException e) { | 
| 425 |                                 ApiPlugin.log(e); | 
| 426 |                         } finally { | 
| 427 |                                 if (outputStream != null) { | 
| 428 |                                         try { | 
| 429 |                                                 outputStream.close(); | 
| 430 |                                         } catch(IOException e) { | 
| 431 |                                                 // ignore | 
| 432 |                                         } | 
| 433 |                                 } | 
| 434 |                         } | 
| 435 |                         return true; | 
| 436 |                 } | 
| 437 |                 return false; | 
| 438 |         } | 
| 439 |          | 
| 440 |         /** | 
| 441 |          * Creates an EE file for the given JRE and specified EE id | 
| 442 |          * @param jre | 
| 443 |          * @param eeid | 
| 444 |          * @return | 
| 445 |          * @throws IOException | 
| 446 |          */ | 
| 447 |         public static File createEEFile(IVMInstall jre, String eeid) throws IOException { | 
| 448 |                 String string = Util.generateEEContents(jre, eeid); | 
| 449 |                 File eeFile = File.createTempFile("eed", ".ee"); //$NON-NLS-1$ //$NON-NLS-2$ | 
| 450 |                 eeFile.deleteOnExit(); | 
| 451 |                 FileOutputStream outputStream = null; | 
| 452 |                 try { | 
| 453 |                         outputStream = new FileOutputStream(eeFile); | 
| 454 |                         outputStream.write(string.getBytes(IApiCoreConstants.UTF_8)); | 
| 455 |                 } finally { | 
| 456 |                         if (outputStream != null) { | 
| 457 |                                 outputStream.close(); | 
| 458 |                         } | 
| 459 |                 } | 
| 460 |                 return eeFile; | 
| 461 |         }         | 
| 462 |   | 
| 463 |         /** | 
| 464 |          * Returns whether the objects are equal, accounting for either one being <code>null</code>. | 
| 465 |          *  | 
| 466 |          * @param o1 | 
| 467 |          * @param o2 | 
| 468 |          * @return whether the objects are equal, or both are <code>null</code> | 
| 469 |          */ | 
| 470 |         public static boolean equalsOrNull(Object o1, Object o2) { | 
| 471 |                 if (o1 == null) { | 
| 472 |                         return o2 == null; | 
| 473 |                 } | 
| 474 |                 return o1.equals(o2); | 
| 475 |         } | 
| 476 |   | 
| 477 |         /** | 
| 478 |          * Returns an execution environment description for the given VM. | 
| 479 |          *   | 
| 480 |          * @param vm JRE to create an definition for | 
| 481 |          * @return an execution environment description for the given VM | 
| 482 |          * @throws IOException if unable to generate description | 
| 483 |          */ | 
| 484 |         public static String generateEEContents(IVMInstall vm, String eeId) throws IOException { | 
| 485 |                 StringBuffer buffer = new StringBuffer(); | 
| 486 |                 appendProperty(buffer, ExecutionEnvironmentDescription.JAVA_HOME, vm.getInstallLocation().getCanonicalPath()); | 
| 487 |                 StringBuffer paths = new StringBuffer(); | 
| 488 |                 LibraryLocation[] libraryLocations = JavaRuntime.getLibraryLocations(vm); | 
| 489 |                 for (int i = 0; i < libraryLocations.length; i++) { | 
| 490 |                         LibraryLocation lib = libraryLocations[i]; | 
| 491 |                         paths.append(lib.getSystemLibraryPath().toOSString()); | 
| 492 |                         if (i < (libraryLocations.length - 1)) { | 
| 493 |                                 paths.append(File.pathSeparatorChar); | 
| 494 |                         } | 
| 495 |                 } | 
| 496 |                 appendProperty(buffer, ExecutionEnvironmentDescription.BOOT_CLASS_PATH, paths.toString()); | 
| 497 |                 appendProperty(buffer, ExecutionEnvironmentDescription.CLASS_LIB_LEVEL, eeId); | 
| 498 |                 return  buffer.toString(); | 
| 499 |         } | 
| 500 |          | 
| 501 |         /** | 
| 502 |          * Returns an array of all of the files from the given root that are | 
| 503 |          * accepted by the given file filter. If the file filter is null all files | 
| 504 |          * within the given root are returned. | 
| 505 |          *  | 
| 506 |          * @param root | 
| 507 |          * @param fileFilter | 
| 508 |          * @return the list of files from within the given root | 
| 509 |          */ | 
| 510 |         public static File[] getAllFiles(File root, FileFilter fileFilter) { | 
| 511 |                 ArrayList files = new ArrayList(); | 
| 512 |                 if (root.isDirectory()) { | 
| 513 |                         collectAllFiles(root, files, fileFilter); | 
| 514 |                         File[] result = new File[files.size()]; | 
| 515 |                         files.toArray(result); | 
| 516 |                         return result; | 
| 517 |                 } | 
| 518 |                 return null; | 
| 519 |         } | 
| 520 |   | 
| 521 |         /** | 
| 522 |          * Returns a build job that will perform a full build on the given projects. | 
| 523 |          *  | 
| 524 |          * If <code>projects</code> are null, then an AssertionFailedException is thrown | 
| 525 |          * @param projects the projects to build | 
| 526 |          * @return the build job | 
| 527 |          * @throws AssertionFailedException if the given projects are null | 
| 528 |          */ | 
| 529 |         public static Job getBuildJob(final IProject[] projects) { | 
| 530 |                 Assert.isNotNull(projects); | 
| 531 |                 Job buildJob = new BuildJob(UtilMessages.Util_4, projects); | 
| 532 |                 buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule()); | 
| 533 |                 buildJob.setUser(true); | 
| 534 |                 return buildJob; | 
| 535 |         } | 
| 536 |          | 
| 537 |         /** | 
| 538 |          * Returns a build job that will return the build that corresponds to the given | 
| 539 |          * build kind on the given projects. | 
| 540 |          *  | 
| 541 |          * If <code>projects</code> are null, then an AssertionFailedException is thrown | 
| 542 |          * @param projects the projects to build | 
| 543 |          * @param buildKind the given build kind | 
| 544 |          * @return the build job | 
| 545 |          * @throws AssertionFailedException if the given projects are null | 
| 546 |          */ | 
| 547 |         public static Job getBuildJob(final IProject[] projects, int buildKind) { | 
| 548 |                 Assert.isNotNull(projects); | 
| 549 |                 Job buildJob = new BuildJob(UtilMessages.Util_4, projects, buildKind); | 
| 550 |                 buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule()); | 
| 551 |                 buildJob.setUser(true); | 
| 552 |                 return buildJob; | 
| 553 |         } | 
| 554 |   | 
| 555 |         /** | 
| 556 |          * Returns a result of searching the given components for  class file with the | 
| 557 |          * given type name. | 
| 558 |          *   | 
| 559 |          * @param components API components to search or <code>null</code> if none | 
| 560 |          * @param typeName type to search for | 
| 561 |          * @return class file or <code>null</code> if none found | 
| 562 |          */ | 
| 563 |         public static IApiTypeRoot getClassFile(IApiComponent[] components, String typeName) { | 
| 564 |                 if (components == null) { | 
| 565 |                         return null; | 
| 566 |                 } | 
| 567 |                 for (int i = 0, max = components.length; i < max; i++) { | 
| 568 |                         IApiComponent apiComponent = components[i]; | 
| 569 |                         if (apiComponent != null) { | 
| 570 |                                 try { | 
| 571 |                                         IApiTypeRoot classFile = apiComponent.findTypeRoot(typeName); | 
| 572 |                                         if (classFile != null) return classFile; | 
| 573 |                                 } catch (CoreException e) { | 
| 574 |                                         // ignore | 
| 575 |                                 } | 
| 576 |                         } | 
| 577 |                 } | 
| 578 |                 return null; | 
| 579 |         } | 
| 580 |          | 
| 581 |         /** | 
| 582 |          * Return a string that represents the element type of the given delta. | 
| 583 |          * Returns {@link #UNKNOWN_ELEMENT_KIND} if the element type cannot be determined. | 
| 584 |          *  | 
| 585 |          * @param delta the given delta | 
| 586 |          * @return a string that represents the element type of the given delta. | 
| 587 |          */ | 
| 588 |         public static String getDeltaElementType(IDelta delta) { | 
| 589 |                 return getDeltaElementType(delta.getElementType()); | 
| 590 |         } | 
| 591 |   | 
| 592 |         /** | 
| 593 |          * Returns a text representation of a marker severity level | 
| 594 |          * @param severity | 
| 595 |          * @return text of a marker severity level | 
| 596 |          */ | 
| 597 |         public static String getSeverity(int severity) { | 
| 598 |                 switch(severity) { | 
| 599 |                         case IMarker.SEVERITY_ERROR: { | 
| 600 |                                 return "ERROR"; //$NON-NLS-1$ | 
| 601 |                         } | 
| 602 |                         case IMarker.SEVERITY_INFO: { | 
| 603 |                                 return "INFO"; //$NON-NLS-1$ | 
| 604 |                         } | 
| 605 |                         case IMarker.SEVERITY_WARNING: { | 
| 606 |                                 return "WARNING"; //$NON-NLS-1$ | 
| 607 |                         } | 
| 608 |                         default: { | 
| 609 |                                 return "UNKNOWN_SEVERITY"; //$NON-NLS-1$ | 
| 610 |                         } | 
| 611 |                 } | 
| 612 |         } | 
| 613 |         /** | 
| 614 |          * Return an int value that represents the given element type | 
| 615 |          * Returns -1 if the element type cannot be determined. | 
| 616 |          *  | 
| 617 |          * @param elementType the given element type | 
| 618 |          * @return an int that represents the given element type constant. | 
| 619 |          */ | 
| 620 |         public static int getDeltaElementTypeValue(String elementType) { | 
| 621 |                 Class IDeltaClass = IDelta.class; | 
| 622 |                 try { | 
| 623 |                         Field field = IDeltaClass.getField(elementType); | 
| 624 |                         return field.getInt(null); | 
| 625 |                 } catch (SecurityException e) { | 
| 626 |                         // ignore | 
| 627 |                 } catch (IllegalArgumentException e) { | 
| 628 |                         // ignore | 
| 629 |                 } catch (NoSuchFieldException e) { | 
| 630 |                         // ignore | 
| 631 |                 } catch (IllegalAccessException e) { | 
| 632 |                         // ignore | 
| 633 |                 } | 
| 634 |                 return -1; | 
| 635 |         } | 
| 636 |         /** | 
| 637 |          * Return a string that represents the given element type | 
| 638 |          * Returns {@link #UNKNOWN_ELEMENT_KIND} if the element type cannot be determined. | 
| 639 |          *  | 
| 640 |          * @param elementType the given element type | 
| 641 |          * @return a string that represents the given element type. | 
| 642 |          */ | 
| 643 |         public static String getDeltaElementType(int elementType) { | 
| 644 |                 switch(elementType) { | 
| 645 |                         case IDelta.ANNOTATION_ELEMENT_TYPE : | 
| 646 |                                 return "ANNOTATION_ELEMENT_TYPE"; //$NON-NLS-1$ | 
| 647 |                         case IDelta.INTERFACE_ELEMENT_TYPE : | 
| 648 |                                 return "INTERFACE_ELEMENT_TYPE"; //$NON-NLS-1$ | 
| 649 |                         case IDelta.ENUM_ELEMENT_TYPE : | 
| 650 |                                 return "ENUM_ELEMENT_TYPE"; //$NON-NLS-1$ | 
| 651 |                         case IDelta.API_COMPONENT_ELEMENT_TYPE : | 
| 652 |                                 return "API_COMPONENT_ELEMENT_TYPE"; //$NON-NLS-1$ | 
| 653 |                         case IDelta.API_PROFILE_ELEMENT_TYPE : | 
| 654 |                                 return "API_PROFILE_ELEMENT_TYPE"; //$NON-NLS-1$ | 
| 655 |                         case IDelta.CONSTRUCTOR_ELEMENT_TYPE : | 
| 656 |                                 return "CONSTRUCTOR_ELEMENT_TYPE"; //$NON-NLS-1$ | 
| 657 |                         case IDelta.METHOD_ELEMENT_TYPE : | 
| 658 |                                 return "METHOD_ELEMENT_TYPE"; //$NON-NLS-1$ | 
| 659 |                         case IDelta.FIELD_ELEMENT_TYPE : | 
| 660 |                                 return "FIELD_ELEMENT_TYPE"; //$NON-NLS-1$ | 
| 661 |                         case IDelta.CLASS_ELEMENT_TYPE : | 
| 662 |                                 return "CLASS_ELEMENT_TYPE"; //$NON-NLS-1$ | 
| 663 |                         case IDelta.TYPE_PARAMETER_ELEMENT_TYPE : | 
| 664 |                                 return "TYPE_PARAMETER_ELEMENT_TYPE"; //$NON-NLS-1$ | 
| 665 |                 } | 
| 666 |                 return UNKNOWN_ELEMENT_KIND; | 
| 667 |         } | 
| 668 |          | 
| 669 |         /** | 
| 670 |          * Return a string that represents the given flags | 
| 671 |          * Returns {@link #UNKNOWN_FLAGS} if the flags cannot be determined. | 
| 672 |          *  | 
| 673 |          * @param flags the given delta's flags | 
| 674 |          * @return a string that represents the given flags. | 
| 675 |          */ | 
| 676 |         public static String getDeltaFlagsName(int flags) { | 
| 677 |                 switch(flags) { | 
| 678 |                         case IDelta.ABSTRACT_TO_NON_ABSTRACT : return "ABSTRACT_TO_NON_ABSTRACT"; //$NON-NLS-1$ | 
| 679 |                         case IDelta.ANNOTATION_DEFAULT_VALUE : return "ANNOTATION_DEFAULT_VALUE"; //$NON-NLS-1$ | 
| 680 |                         case IDelta.API_COMPONENT : return "API_COMPONENT"; //$NON-NLS-1$ | 
| 681 |                         case IDelta.ARRAY_TO_VARARGS : return "ARRAY_TO_VARARGS"; //$NON-NLS-1$ | 
| 682 |                         case IDelta.CHECKED_EXCEPTION : return "CHECKED_EXCEPTION"; //$NON-NLS-1$ | 
| 683 |                         case IDelta.CLASS_BOUND : return "CLASS_BOUND"; //$NON-NLS-1$ | 
| 684 |                         case IDelta.CLINIT : return "CLINIT"; //$NON-NLS-1$ | 
| 685 |                         case IDelta.CONSTRUCTOR : return "CONSTRUCTOR"; //$NON-NLS-1$ | 
| 686 |                         case IDelta.CONTRACTED_SUPERINTERFACES_SET : return "CONTRACTED_SUPERINTERFACES_SET"; //$NON-NLS-1$ | 
| 687 |                         case IDelta.DECREASE_ACCESS : return "DECREASE_ACCESS"; //$NON-NLS-1$ | 
| 688 |                         case IDelta.ENUM_CONSTANT : return "ENUM_CONSTANT"; //$NON-NLS-1$ | 
| 689 |                         case IDelta.EXECUTION_ENVIRONMENT : return "EXECUTION_ENVIRONMENT"; //$NON-NLS-1$ | 
| 690 |                         case IDelta.EXPANDED_SUPERINTERFACES_SET : return "EXPANDED_SUPERINTERFACES_SET"; //$NON-NLS-1$ | 
| 691 |                         case IDelta.FIELD : return "FIELD"; //$NON-NLS-1$ | 
| 692 |                         case IDelta.FIELD_MOVED_UP : return "FIELD_MOVED_UP"; //$NON-NLS-1$ | 
| 693 |                         case IDelta.FINAL_TO_NON_FINAL : return "FINAL_TO_NON_FINAL"; //$NON-NLS-1$ | 
| 694 |                         case IDelta.FINAL_TO_NON_FINAL_NON_STATIC : return "FINAL_TO_NON_FINAL_NON_STATIC"; //$NON-NLS-1$ | 
| 695 |                         case IDelta.FINAL_TO_NON_FINAL_STATIC_CONSTANT : return "FINAL_TO_NON_FINAL_STATIC_CONSTANT"; //$NON-NLS-1$ | 
| 696 |                         case IDelta.FINAL_TO_NON_FINAL_STATIC_NON_CONSTANT : return "FINAL_TO_NON_FINAL_STATIC_NON_CONSTANT"; //$NON-NLS-1$ | 
| 697 |                         case IDelta.INCREASE_ACCESS : return "INCREASE_ACCESS"; //$NON-NLS-1$ | 
| 698 |                         case IDelta.INTERFACE_BOUND : return "INTERFACE_BOUND"; //$NON-NLS-1$ | 
| 699 |                         case IDelta.METHOD : return "METHOD"; //$NON-NLS-1$ | 
| 700 |                         case IDelta.METHOD_MOVED_UP : return "METHOD_MOVED_UP"; //$NON-NLS-1$ | 
| 701 |                         case IDelta.METHOD_WITH_DEFAULT_VALUE : return "METHOD_WITH_DEFAULT_VALUE"; //$NON-NLS-1$ | 
| 702 |                         case IDelta.METHOD_WITHOUT_DEFAULT_VALUE : return "METHOD_WITHOUT_DEFAULT_VALUE"; //$NON-NLS-1$ | 
| 703 |                         case IDelta.NATIVE_TO_NON_NATIVE : return "NATIVE_TO_NON_NATIVE"; //$NON-NLS-1$ | 
| 704 |                         case IDelta.NON_ABSTRACT_TO_ABSTRACT : return "NON_ABSTRACT_TO_ABSTRACT"; //$NON-NLS-1$ | 
| 705 |                         case IDelta.NON_FINAL_TO_FINAL : return "NON_FINAL_TO_FINAL"; //$NON-NLS-1$ | 
| 706 |                         case IDelta.NON_NATIVE_TO_NATIVE : return "NON_NATIVE_TO_NATIVE"; //$NON-NLS-1$ | 
| 707 |                         case IDelta.NON_STATIC_TO_STATIC : return "NON_STATIC_TO_STATIC"; //$NON-NLS-1$ | 
| 708 |                         case IDelta.NON_SYNCHRONIZED_TO_SYNCHRONIZED : return "NON_SYNCHRONIZED_TO_SYNCHRONIZED"; //$NON-NLS-1$ | 
| 709 |                         case IDelta.NON_TRANSIENT_TO_TRANSIENT : return "NON_TRANSIENT_TO_TRANSIENT"; //$NON-NLS-1$ | 
| 710 |                         case IDelta.OVERRIDEN_METHOD : return "OVERRIDEN_METHOD"; //$NON-NLS-1$ | 
| 711 |                         case IDelta.STATIC_TO_NON_STATIC : return "STATIC_TO_NON_STATIC"; //$NON-NLS-1$ | 
| 712 |                         case IDelta.SUPERCLASS : return "SUPERCLASS"; //$NON-NLS-1$ | 
| 713 |                         case IDelta.SYNCHRONIZED_TO_NON_SYNCHRONIZED : return "SYNCHRONIZED_TO_NON_SYNCHRONIZED"; //$NON-NLS-1$ | 
| 714 |                         case IDelta.TYPE_CONVERSION : return "TYPE_CONVERSION"; //$NON-NLS-1$ | 
| 715 |                         case IDelta.TRANSIENT_TO_NON_TRANSIENT : return "TRANSIENT_TO_NON_TRANSIENT"; //$NON-NLS-1$ | 
| 716 |                         case IDelta.TYPE : return "TYPE"; //$NON-NLS-1$ | 
| 717 |                         case IDelta.TYPE_ARGUMENTS : return "TYPE_ARGUMENTS"; //$NON-NLS-1$ | 
| 718 |                         case IDelta.TYPE_MEMBER : return "TYPE_MEMBER"; //$NON-NLS-1$ | 
| 719 |                         case IDelta.TYPE_PARAMETER : return "TYPE_PARAMETER"; //$NON-NLS-1$ | 
| 720 |                         case IDelta.TYPE_PARAMETER_NAME : return "TYPE_PARAMETER_NAME"; //$NON-NLS-1$ | 
| 721 |                         case IDelta.TYPE_PARAMETERS : return "TYPE_PARAMETERS"; //$NON-NLS-1$ | 
| 722 |                         case IDelta.TYPE_VISIBILITY : return "TYPE_VISIBILITY"; //$NON-NLS-1$ | 
| 723 |                         case IDelta.UNCHECKED_EXCEPTION : return "UNCHECKED_EXCEPTION"; //$NON-NLS-1$ | 
| 724 |                         case IDelta.VALUE : return "VALUE"; //$NON-NLS-1$ | 
| 725 |                         case IDelta.VARARGS_TO_ARRAY : return "VARARGS_TO_ARRAY"; //$NON-NLS-1$ | 
| 726 |                         case IDelta.RESTRICTIONS : return "RESTRICTIONS"; //$NON-NLS-1$ | 
| 727 |                         case IDelta.API_TYPE : return "API_TYPE"; //$NON-NLS-1$ | 
| 728 |                         case IDelta.NON_VOLATILE_TO_VOLATILE : return "NON_VOLATILE_TO_VOLATILE"; //$NON-NLS-1$ | 
| 729 |                         case IDelta.VOLATILE_TO_NON_VOLATILE : return "VOLATILE_TO_NON_VOLATILE"; //$NON-NLS-1$ | 
| 730 |                         case IDelta.MINOR_VERSION : return "MINOR_VERSION"; //$NON-NLS-1$ | 
| 731 |                         case IDelta.MAJOR_VERSION : return "MAJOR_VERSION"; //$NON-NLS-1$ | 
| 732 |                         case IDelta.API_FIELD : return "API_FIELD"; //$NON-NLS-1$ | 
| 733 |                         case IDelta.API_METHOD : return "API_METHOD"; //$NON-NLS-1$ | 
| 734 |                         case IDelta.API_CONSTRUCTOR : return "API_CONSTRUCTOR"; //$NON-NLS-1$ | 
| 735 |                         case IDelta.API_ENUM_CONSTANT : return "API_ENUM_CONSTANT"; //$NON-NLS-1$ | 
| 736 |                         case IDelta.API_METHOD_WITH_DEFAULT_VALUE : return "API_METHOD_WITH_DEFAULT_VALUE"; //$NON-NLS-1$ | 
| 737 |                         case IDelta.API_METHOD_WITHOUT_DEFAULT_VALUE : return "API_METHOD_WITHOUT_DEFAULT_VALUE"; //$NON-NLS-1$ | 
| 738 |                         case IDelta.TYPE_ARGUMENT : return "TYPE_ARGUMENT"; //$NON-NLS-1$ | 
| 739 |                         case IDelta.SUPER_INTERFACE_WITH_METHODS : return "SUPER_INTERFACE_WITH_METHODS"; //$NON-NLS-1$ | 
| 740 |                         case IDelta.REEXPORTED_API_TYPE : return "REEXPORTED_API_TYPE"; //$NON-NLS-1$ | 
| 741 |                         case IDelta.REEXPORTED_TYPE : return "REEXPORTED_TYPE"; //$NON-NLS-1$ | 
| 742 |                         case IDelta.METHOD_MOVED_DOWN : return "METHOD_MOVED_DOWN"; //$NON-NLS-1$ | 
| 743 |                         case IDelta.DEPRECATION : return "DEPRECATION"; //$NON-NLS-1$ | 
| 744 |                 } | 
| 745 |                 return UNKNOWN_FLAGS; | 
| 746 |         } | 
| 747 |   | 
| 748 |         /** | 
| 749 |          * Return a string that represents the kind of the given delta. | 
| 750 |          * Returns {@link #UNKNOWN_KIND} if the kind cannot be determined. | 
| 751 |          *  | 
| 752 |          * @param delta the given delta | 
| 753 |          * @return a string that represents the kind of the given delta. | 
| 754 |          */ | 
| 755 |         public static String getDeltaKindName(IDelta delta) { | 
| 756 |                 return getDeltaKindName(delta.getKind()); | 
| 757 |         } | 
| 758 |   | 
| 759 |         /** | 
| 760 |          * Return a string that represents the given kind. | 
| 761 |          * Returns {@link #UNKNOWN_KIND} if the kind cannot be determined. | 
| 762 |          *  | 
| 763 |          * @param delta the given kind | 
| 764 |          * @return a string that represents the given kind. | 
| 765 |          */ | 
| 766 |         public static String getDeltaKindName(int kind) { | 
| 767 |                 switch(kind) { | 
| 768 |                         case IDelta.ADDED : | 
| 769 |                                 return "ADDED"; //$NON-NLS-1$ | 
| 770 |                         case IDelta.CHANGED : | 
| 771 |                                 return "CHANGED"; //$NON-NLS-1$ | 
| 772 |                         case IDelta.REMOVED : | 
| 773 |                                 return "REMOVED"; //$NON-NLS-1$ | 
| 774 |                 } | 
| 775 |                 return UNKNOWN_KIND; | 
| 776 |         } | 
| 777 |   | 
| 778 |         /** | 
| 779 |          * Returns the preference key for the given element type, the given kind and the given flags. | 
| 780 |          *  | 
| 781 |          * @param elementType the given element type (retrieved using {@link IDelta#getElementType()} | 
| 782 |          * @param kind the given kind (retrieved using {@link IDelta#getKind()} | 
| 783 |          * @param flags the given flags (retrieved using {@link IDelta#getFlags()} | 
| 784 |          * @return the preference key for the given element type, the given kind and the given flags. | 
| 785 |          */ | 
| 786 |         public static String getDeltaPrefererenceKey(int elementType, int kind, int flags) { | 
| 787 |                 StringBuffer buffer = new StringBuffer(Util.getDeltaElementType(elementType)); | 
| 788 |                 buffer.append('_').append(Util.getDeltaKindName(kind)); | 
| 789 |                 if (flags != -1) { | 
| 790 |                         buffer.append('_'); | 
| 791 |                         switch(flags) { | 
| 792 |                                 case IDelta.API_FIELD : | 
| 793 |                                         buffer.append(Util.getDeltaFlagsName(IDelta.FIELD)); | 
| 794 |                                         break; | 
| 795 |                                 case IDelta.API_ENUM_CONSTANT : | 
| 796 |                                         buffer.append(Util.getDeltaFlagsName(IDelta.ENUM_CONSTANT)); | 
| 797 |                                         break; | 
| 798 |                                 case IDelta.API_CONSTRUCTOR : | 
| 799 |                                         buffer.append(Util.getDeltaFlagsName(IDelta.CONSTRUCTOR)); | 
| 800 |                                         break; | 
| 801 |                                 case IDelta.API_METHOD : | 
| 802 |                                         buffer.append(Util.getDeltaFlagsName(IDelta.METHOD)); | 
| 803 |                                         break; | 
| 804 |                                 case IDelta.API_METHOD_WITH_DEFAULT_VALUE : | 
| 805 |                                         if (kind == IDelta.REMOVED) { | 
| 806 |                                                 buffer.append(Util.getDeltaFlagsName(IDelta.METHOD)); | 
| 807 |                                         } else { | 
| 808 |                                                 buffer.append(Util.getDeltaFlagsName(IDelta.METHOD_WITH_DEFAULT_VALUE)); | 
| 809 |                                         } | 
| 810 |                                         break; | 
| 811 |                                 case IDelta.API_METHOD_WITHOUT_DEFAULT_VALUE : | 
| 812 |                                         if (kind == IDelta.REMOVED) { | 
| 813 |                                                 buffer.append(Util.getDeltaFlagsName(IDelta.METHOD)); | 
| 814 |                                         } else { | 
| 815 |                                                 buffer.append(Util.getDeltaFlagsName(IDelta.METHOD_WITHOUT_DEFAULT_VALUE)); | 
| 816 |                                         } | 
| 817 |                                         break; | 
| 818 |                                 case IDelta.METHOD_WITH_DEFAULT_VALUE : | 
| 819 |                                         if (kind == IDelta.REMOVED) { | 
| 820 |                                                 buffer.append(Util.getDeltaFlagsName(IDelta.METHOD)); | 
| 821 |                                         } else { | 
| 822 |                                                 buffer.append(Util.getDeltaFlagsName(IDelta.METHOD_WITH_DEFAULT_VALUE)); | 
| 823 |                                         } | 
| 824 |                                         break; | 
| 825 |                                 case IDelta.METHOD_WITHOUT_DEFAULT_VALUE : | 
| 826 |                                         if (kind == IDelta.REMOVED) { | 
| 827 |                                                 buffer.append(Util.getDeltaFlagsName(IDelta.METHOD)); | 
| 828 |                                         } else { | 
| 829 |                                                 buffer.append(Util.getDeltaFlagsName(IDelta.METHOD_WITHOUT_DEFAULT_VALUE)); | 
| 830 |                                         } | 
| 831 |                                         break; | 
| 832 |                                 default: | 
| 833 |                                         buffer.append(Util.getDeltaFlagsName(flags)); | 
| 834 |                         } | 
| 835 |                 } | 
| 836 |                 return String.valueOf(buffer); | 
| 837 |         } | 
| 838 |   | 
| 839 |         /** | 
| 840 |          * Returns the details of the api delta as a string | 
| 841 |          * @param delta | 
| 842 |          * @return the details of the delta as a string | 
| 843 |          */ | 
| 844 |         public static String getDetail(IDelta delta) { | 
| 845 |                 StringBuffer buffer = new StringBuffer(); | 
| 846 |                 switch(delta.getElementType()) { | 
| 847 |                         case IDelta.CLASS_ELEMENT_TYPE : | 
| 848 |                                 buffer.append("class"); //$NON-NLS-1$ | 
| 849 |                                 break; | 
| 850 |                         case IDelta.ANNOTATION_ELEMENT_TYPE : | 
| 851 |                                 buffer.append("annotation"); //$NON-NLS-1$ | 
| 852 |                                 break; | 
| 853 |                         case IDelta.INTERFACE_ELEMENT_TYPE : | 
| 854 |                                 buffer.append("interface"); //$NON-NLS-1$ | 
| 855 |                                 break; | 
| 856 |                         case IDelta.API_COMPONENT_ELEMENT_TYPE : | 
| 857 |                                 buffer.append("api component"); //$NON-NLS-1$ | 
| 858 |                                 break; | 
| 859 |                         case IDelta.API_PROFILE_ELEMENT_TYPE : | 
| 860 |                                 buffer.append("api profile"); //$NON-NLS-1$ | 
| 861 |                                 break; | 
| 862 |                         case IDelta.METHOD_ELEMENT_TYPE: | 
| 863 |                                 buffer.append("method"); //$NON-NLS-1$ | 
| 864 |                                 break; | 
| 865 |                         case IDelta.CONSTRUCTOR_ELEMENT_TYPE : | 
| 866 |                                 buffer.append("constructor"); //$NON-NLS-1$ | 
| 867 |                                 break; | 
| 868 |                         case IDelta.ENUM_ELEMENT_TYPE : | 
| 869 |                                 buffer.append("enum"); //$NON-NLS-1$ | 
| 870 |                                 break; | 
| 871 |                         case IDelta.FIELD_ELEMENT_TYPE : | 
| 872 |                                 buffer.append("field"); //$NON-NLS-1$ | 
| 873 |                                 break; | 
| 874 |                 } | 
| 875 |                 buffer.append(' '); | 
| 876 |                 switch(delta.getKind()) { | 
| 877 |                         case IDelta.ADDED : | 
| 878 |                                 buffer.append("added"); //$NON-NLS-1$ | 
| 879 |                                 break; | 
| 880 |                         case IDelta.REMOVED : | 
| 881 |                                 buffer.append("removed"); //$NON-NLS-1$ | 
| 882 |                                 break; | 
| 883 |                         case IDelta.CHANGED : | 
| 884 |                                 buffer.append("changed"); //$NON-NLS-1$ | 
| 885 |                                 break; | 
| 886 |                         default: | 
| 887 |                                 buffer.append("unknown kind"); //$NON-NLS-1$ | 
| 888 |                         break; | 
| 889 |                 } | 
| 890 |                 buffer.append(' ').append(getDeltaFlagsName(delta.getFlags())).append(' ').append(delta.getTypeName()).append("#").append(delta.getKey()); //$NON-NLS-1$ | 
| 891 |                 return String.valueOf(buffer); | 
| 892 |         } | 
| 893 |   | 
| 894 |         /** | 
| 895 |          * Returns the {@link IDocument} for the specified {@link ICompilationUnit} | 
| 896 |          * @param cu | 
| 897 |          * @return the {@link IDocument} for the specified {@link ICompilationUnit} | 
| 898 |          * @throws CoreException | 
| 899 |          */ | 
| 900 |         public static IDocument getDocument(ICompilationUnit cu) throws CoreException { | 
| 901 |                 if (cu.getOwner() == null) { | 
| 902 |                         IFile file= (IFile) cu.getResource(); | 
| 903 |                         if (file.exists()) { | 
| 904 |                                 ITextFileBufferManager bufferManager= FileBuffers.getTextFileBufferManager(); | 
| 905 |                                 IPath path= cu.getPath(); | 
| 906 |                                 bufferManager.connect(path, LocationKind.IFILE, new NullProgressMonitor()); | 
| 907 |                                 try { | 
| 908 |                                         return bufferManager.getTextFileBuffer(path, LocationKind.IFILE).getDocument(); | 
| 909 |                                 } finally { | 
| 910 |                                         bufferManager.disconnect(path, LocationKind.IFILE, null); | 
| 911 |                                 } | 
| 912 |                         } | 
| 913 |                 } | 
| 914 |                 return new org.eclipse.jface.text.Document(cu.getSource()); | 
| 915 |         } | 
| 916 |   | 
| 917 |         /** | 
| 918 |          * Returns the OSGi profile properties corresponding to the given execution | 
| 919 |          * environment id, or <code>null</code> if none. | 
| 920 |          *  | 
| 921 |          * @param eeId OSGi profile identifier | 
| 922 |          * | 
| 923 |          * @return the corresponding properties or <code>null</code> if none | 
| 924 |          */ | 
| 925 |         public static Properties getEEProfile(String eeId) { | 
| 926 |                 String profileName = eeId + ".profile"; //$NON-NLS-1$ | 
| 927 |                 InputStream stream = Util.class.getResourceAsStream("profiles/" + profileName); //$NON-NLS-1$ | 
| 928 |                 if (stream != null) { | 
| 929 |                         try { | 
| 930 |                                 Properties profile = new Properties(); | 
| 931 |                                 profile.load(stream); | 
| 932 |                                 return profile; | 
| 933 |                         } catch (IOException e) { | 
| 934 |                                 ApiPlugin.log(e); | 
| 935 |                         } finally { | 
| 936 |                                 try { | 
| 937 |                                         stream.close(); | 
| 938 |                                 } catch(IOException e) { | 
| 939 |                                         ApiPlugin.log(e); | 
| 940 |                                 } | 
| 941 |                         } | 
| 942 |                 } | 
| 943 |                 return null; | 
| 944 |         } | 
| 945 |          | 
| 946 |         /** | 
| 947 |          * Returns the number of fragments for the given version value, -1 if the format is unknown. | 
| 948 |          * The version is formed like: [optional plugin name] major.minor.micro.qualifier. | 
| 949 |          *  | 
| 950 |          * @param version the given version value | 
| 951 |          * @return the number of fragments for the given version value or -1 if the format is unknown | 
| 952 |          * @throws IllegalArgumentException if version is null | 
| 953 |          */ | 
| 954 |         public static final int getFragmentNumber(String version) { | 
| 955 |                 if (version == null) throw new IllegalArgumentException("The given version should not be null"); //$NON-NLS-1$ | 
| 956 |                 int index = version.indexOf(' '); | 
| 957 |                 char[] charArray = version.toCharArray(); | 
| 958 |                 int length = charArray.length; | 
| 959 |                 if (index + 1 >= length) { | 
| 960 |                         return -1; | 
| 961 |                 } | 
| 962 |                 int counter = 1; | 
| 963 |                 for (int i = index + 1; i < length; i++) { | 
| 964 |                         switch(charArray[i]) { | 
| 965 |                                 case '0' : | 
| 966 |                                 case '1' : | 
| 967 |                                 case '2' : | 
| 968 |                                 case '3' : | 
| 969 |                                 case '4' : | 
| 970 |                                 case '5' : | 
| 971 |                                 case '6' : | 
| 972 |                                 case '7' : | 
| 973 |                                 case '8' : | 
| 974 |                                 case '9' : | 
| 975 |                                         continue; | 
| 976 |                                 case '.' : | 
| 977 |                                         counter++; | 
| 978 |                                         break; | 
| 979 |                                 default : | 
| 980 |                                         return -1; | 
| 981 |                         } | 
| 982 |                 } | 
| 983 |                 return counter; | 
| 984 |         } | 
| 985 |   | 
| 986 |         public static IMember getIMember(IDelta delta, IJavaProject javaProject) { | 
| 987 |                 String typeName = delta.getTypeName(); | 
| 988 |                 if (typeName == null) return null; | 
| 989 |                 IType type = null; | 
| 990 |                 try { | 
| 991 |                         type = javaProject.findType(typeName.replace('$', '.')); | 
| 992 |                 } catch (JavaModelException e) { | 
| 993 |                         // ignore | 
| 994 |                 } | 
| 995 |                 if (type == null) return null; | 
| 996 |                 String key = delta.getKey(); | 
| 997 |                 switch(delta.getElementType()) { | 
| 998 |                         case IDelta.FIELD_ELEMENT_TYPE : { | 
| 999 |                                         IField field = type.getField(key); | 
| 1000 |                                         if (field.exists()) { | 
| 1001 |                                                 return field; | 
| 1002 |                                         } | 
| 1003 |                                 } | 
| 1004 |                                 break; | 
| 1005 |                         case IDelta.CLASS_ELEMENT_TYPE : | 
| 1006 |                         case IDelta.ANNOTATION_ELEMENT_TYPE : | 
| 1007 |                         case IDelta.INTERFACE_ELEMENT_TYPE : | 
| 1008 |                         case IDelta.ENUM_ELEMENT_TYPE : | 
| 1009 |                                 // we report the marker on the type | 
| 1010 |                                 switch(delta.getKind()) { | 
| 1011 |                                         case IDelta.ADDED : | 
| 1012 |                                                 switch(delta.getFlags()) { | 
| 1013 |                                                         case IDelta.FIELD : | 
| 1014 |                                                         case IDelta.ENUM_CONSTANT : | 
| 1015 |                                                                 IField field = type.getField(key); | 
| 1016 |                                                                 if (field.exists()) { | 
| 1017 |                                                                         return field; | 
| 1018 |                                                                 } | 
| 1019 |                                                                 break; | 
| 1020 |                                                         case IDelta.METHOD_WITH_DEFAULT_VALUE : | 
| 1021 |                                                         case IDelta.METHOD_WITHOUT_DEFAULT_VALUE : | 
| 1022 |                                                         case IDelta.METHOD : | 
| 1023 |                                                         case IDelta.CONSTRUCTOR : | 
| 1024 |                                                                 return getMethod(type, key); | 
| 1025 |                                                         case IDelta.TYPE_MEMBER : | 
| 1026 |                                                                 IType type2 = type.getType(key); | 
| 1027 |                                                                 if (type2.exists()) { | 
| 1028 |                                                                         return type2; | 
| 1029 |                                                                 } | 
| 1030 |                                                 } | 
| 1031 |                                                 break; | 
| 1032 |                                         case IDelta.REMOVED : | 
| 1033 |                                                 switch(delta.getFlags()) { | 
| 1034 |                                                         case IDelta.API_FIELD : | 
| 1035 |                                                         case IDelta.API_ENUM_CONSTANT : | 
| 1036 |                                                                 IField field = type.getField(key); | 
| 1037 |                                                                 if (field.exists()) { | 
| 1038 |                                                                         return field; | 
| 1039 |                                                                 } | 
| 1040 |                                                                 break; | 
| 1041 |                                                         case IDelta.API_METHOD_WITH_DEFAULT_VALUE : | 
| 1042 |                                                         case IDelta.API_METHOD_WITHOUT_DEFAULT_VALUE : | 
| 1043 |                                                         case IDelta.API_METHOD : | 
| 1044 |                                                         case IDelta.API_CONSTRUCTOR : | 
| 1045 |                                                                 return getMethod(type, key); | 
| 1046 |                                                 } | 
| 1047 |                                 } | 
| 1048 |                                 return type; | 
| 1049 |                         case IDelta.METHOD_ELEMENT_TYPE : | 
| 1050 |                         case IDelta.CONSTRUCTOR_ELEMENT_TYPE : { | 
| 1051 |                                         return getMethod(type, key); | 
| 1052 |                                 } | 
| 1053 |                         case IDelta.API_COMPONENT_ELEMENT_TYPE : | 
| 1054 |                                 return type; | 
| 1055 |                 } | 
| 1056 |                 return null; | 
| 1057 |         } | 
| 1058 |   | 
| 1059 |         /** | 
| 1060 |          * Updates a given progress monitor the given amount of work. | 
| 1061 |          * Throws an {@link OperationCanceledException} if the monitor has been canceled. | 
| 1062 |          *  | 
| 1063 |          * @param monitor | 
| 1064 |          * @param work | 
| 1065 |          * @throws OperationCanceledException | 
| 1066 |          */ | 
| 1067 |         public static void updateMonitor(IProgressMonitor monitor, int work) throws OperationCanceledException { | 
| 1068 |                 if(monitor == null) { | 
| 1069 |                         return; | 
| 1070 |                 } | 
| 1071 |                 if(monitor.isCanceled()) { | 
| 1072 |                         throw new OperationCanceledException(); | 
| 1073 |                 } | 
| 1074 |                 monitor.worked(work); | 
| 1075 |         } | 
| 1076 |          | 
| 1077 |         /** | 
| 1078 |          * Updates the given monitor 0 work ticks. This method is used to poll for cancellation | 
| 1079 |          * without advancing the work done. | 
| 1080 |          *  | 
| 1081 |          * @param monitor | 
| 1082 |          * @throws OperationCanceledException | 
| 1083 |          */ | 
| 1084 |         public static void updateMonitor(IProgressMonitor monitor) throws OperationCanceledException { | 
| 1085 |                 updateMonitor(monitor, 0); | 
| 1086 |         } | 
| 1087 |          | 
| 1088 |         private static IMember getMethod(IType type, String key) { | 
| 1089 |                 boolean isGeneric = false; | 
| 1090 |                 int indexOfTypeVariable = key.indexOf('<'); | 
| 1091 |                 int index = 0; | 
| 1092 |                 if (indexOfTypeVariable == -1) { | 
| 1093 |                         int indexOfParen = key.indexOf('('); | 
| 1094 |                         if (indexOfParen == -1) { | 
| 1095 |                                 return null; | 
| 1096 |                         } | 
| 1097 |                         index = indexOfParen; | 
| 1098 |                 } else { | 
| 1099 |                         int indexOfParen = key.indexOf('('); | 
| 1100 |                         if (indexOfParen == -1) { | 
| 1101 |                                 return null; | 
| 1102 |                         } | 
| 1103 |                         if (indexOfParen < indexOfTypeVariable) { | 
| 1104 |                                 index = indexOfParen; | 
| 1105 |                         } else { | 
| 1106 |                                 index = indexOfTypeVariable; | 
| 1107 |                                 isGeneric = true; | 
| 1108 |                         } | 
| 1109 |                 } | 
| 1110 |                 String selector = key.substring(0, index); | 
| 1111 |                 String descriptor = key.substring(index, key.length()); | 
| 1112 |                 IMethod method = null; | 
| 1113 |                 String signature = descriptor.replace('/', '.'); | 
| 1114 |                 String[] parameterTypes = null; | 
| 1115 |                 if (isGeneric) { | 
| 1116 |                         // remove all type variables first | 
| 1117 |                         signature = signature.substring(signature.indexOf('(')); | 
| 1118 |                         parameterTypes = Signature.getParameterTypes(signature); | 
| 1119 |                 } else { | 
| 1120 |                         parameterTypes = Signature.getParameterTypes(signature); | 
| 1121 |                 } | 
| 1122 |   | 
| 1123 |                 try { | 
| 1124 |                         method = type.getMethod(selector, parameterTypes); | 
| 1125 |                 } catch (IllegalArgumentException e) { | 
| 1126 |                         ApiPlugin.log(e); | 
| 1127 |                 } | 
| 1128 |                 if (method == null) { | 
| 1129 |                         return null; | 
| 1130 |                 } | 
| 1131 |                 if (method.exists()) { | 
| 1132 |                         return method; | 
| 1133 |                 } else { | 
| 1134 |                         // if the method is not null and it doesn't exist, it might be the default constructor | 
| 1135 |                         if (selector.equals(type.getElementName()) && parameterTypes.length == 0) { | 
| 1136 |                                 return null; | 
| 1137 |                         } | 
| 1138 |                         // try to check by selector | 
| 1139 |                         IMethod[] methods = null; | 
| 1140 |                         try { | 
| 1141 |                                 methods = type.getMethods(); | 
| 1142 |                         } catch (JavaModelException e) { | 
| 1143 |                                 ApiPlugin.log(e); | 
| 1144 |                                 // do not default to the enclosing type - see bug 224713 | 
| 1145 |                                 ApiPlugin.log( | 
| 1146 |                                                 new Status(IStatus.ERROR, | 
| 1147 |                                                                 ApiPlugin.PLUGIN_ID, | 
| 1148 |                                                                 NLS.bind(UtilMessages.Util_6, new String[] { selector, descriptor }))); | 
| 1149 |                                 return null; | 
| 1150 |                         } | 
| 1151 |                         List list = new ArrayList(); | 
| 1152 |                         for (int i = 0, max = methods.length; i < max; i++) { | 
| 1153 |                                 IMethod method2 = methods[i]; | 
| 1154 |                                 if (selector.equals(method2.getElementName())) { | 
| 1155 |                                         list.add(method2); | 
| 1156 |                                 } | 
| 1157 |                         } | 
| 1158 |                         switch(list.size()) { | 
| 1159 |                                 case 0 : | 
| 1160 |                                         // do not default to the enclosing type - see bug 224713 | 
| 1161 |                                         ApiPlugin.log( | 
| 1162 |                                                         new Status(IStatus.ERROR, | 
| 1163 |                                                                         ApiPlugin.PLUGIN_ID, | 
| 1164 |                                                                         NLS.bind(UtilMessages.Util_6, new String[] { selector, descriptor }))); | 
| 1165 |                                         return null; | 
| 1166 |                                 case 1 : | 
| 1167 |                                         return (IMember) list.get(0); | 
| 1168 |                                 default: | 
| 1169 |                                         // need to find a matching parameters | 
| 1170 |                                         for (Iterator iterator = list.iterator(); iterator.hasNext(); ) { | 
| 1171 |                                                 IMethod method2 = (IMethod) iterator.next(); | 
| 1172 |                                                 try { | 
| 1173 |                                                         if (Signatures.matchesSignatures(method2.getSignature(), signature)) { | 
| 1174 |                                                                 return method2; | 
| 1175 |                                                         } | 
| 1176 |                                                 } catch (JavaModelException e) { | 
| 1177 |                                                         // ignore | 
| 1178 |                                                 } | 
| 1179 |                                         } | 
| 1180 |                         } | 
| 1181 |                 } | 
| 1182 |                 // do not default to the enclosing type - see bug 224713 | 
| 1183 |                 ApiPlugin.log( | 
| 1184 |                                 new Status(IStatus.ERROR, | 
| 1185 |                                                 ApiPlugin.PLUGIN_ID, | 
| 1186 |                                                 NLS.bind(UtilMessages.Util_6, new String[] { selector, descriptor }))); | 
| 1187 |                 return null; | 
| 1188 |         } | 
| 1189 |   | 
| 1190 |         /** | 
| 1191 |          * Returns the given input stream as a byte array | 
| 1192 |          * @param stream the stream to get as a byte array | 
| 1193 |          * @param length the length to read from the stream or -1 for unknown | 
| 1194 |          * @return the given input stream as a byte array | 
| 1195 |          * @throws IOException | 
| 1196 |          */ | 
| 1197 |         public static byte[] getInputStreamAsByteArray(InputStream stream, int length) throws IOException { | 
| 1198 |                 byte[] contents; | 
| 1199 |                 if (length == -1) { | 
| 1200 |                         contents = new byte[0]; | 
| 1201 |                         int contentsLength = 0; | 
| 1202 |                         int amountRead = -1; | 
| 1203 |                         do { | 
| 1204 |                                 // read at least 8K | 
| 1205 |                                 int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE); | 
| 1206 |                                 // resize contents if needed | 
| 1207 |                                 if (contentsLength + amountRequested > contents.length) { | 
| 1208 |                                         System.arraycopy(contents, | 
| 1209 |                                                         0, | 
| 1210 |                                                         contents = new byte[contentsLength + amountRequested], | 
| 1211 |                                                         0, | 
| 1212 |                                                         contentsLength); | 
| 1213 |                                 } | 
| 1214 |                                 // read as many bytes as possible | 
| 1215 |                                 amountRead = stream.read(contents, contentsLength, amountRequested); | 
| 1216 |                                 if (amountRead > 0) { | 
| 1217 |                                         // remember length of contents | 
| 1218 |                                         contentsLength += amountRead; | 
| 1219 |                                 } | 
| 1220 |                         } while (amountRead != -1); | 
| 1221 |                         // resize contents if necessary | 
| 1222 |                         if (contentsLength < contents.length) { | 
| 1223 |                                 System.arraycopy(contents, 0, contents = new byte[contentsLength], 0, contentsLength); | 
| 1224 |                         } | 
| 1225 |                 } else { | 
| 1226 |                         contents = new byte[length]; | 
| 1227 |                         int len = 0; | 
| 1228 |                         int readSize = 0; | 
| 1229 |                         while ((readSize != -1) && (len != length)) { | 
| 1230 |                                 // See PR 1FMS89U | 
| 1231 |                                 // We record first the read size. In this case length is the actual | 
| 1232 |                                 // read size. | 
| 1233 |                                 len += readSize; | 
| 1234 |                                 readSize = stream.read(contents, len, length - len); | 
| 1235 |                         } | 
| 1236 |                 } | 
| 1237 |                 return contents; | 
| 1238 |         } | 
| 1239 |          | 
| 1240 |         /** | 
| 1241 |          * Returns the given input stream's contents as a character array. | 
| 1242 |          * If a length is specified (i.e. if length != -1), this represents the number of bytes in the stream. | 
| 1243 |          * Note the specified stream is not closed in this method | 
| 1244 |          * @param stream the stream to get convert to the char array  | 
| 1245 |          * @param length the length of the input stream, or -1 if unknown | 
| 1246 |          * @param encoding the encoding to use when reading the stream | 
| 1247 |          * @return the given input stream's contents as a character array. | 
| 1248 |          * @throws IOException if a problem occurred reading the stream. | 
| 1249 |          */ | 
| 1250 |         public static char[] getInputStreamAsCharArray(InputStream stream, int length, String encoding) throws IOException { | 
| 1251 |                 Charset charset = null; | 
| 1252 |                 try { | 
| 1253 |                         charset = Charset.forName(encoding); | 
| 1254 |                 } catch (IllegalCharsetNameException e) { | 
| 1255 |                         System.err.println("Illegal charset name : " + encoding); //$NON-NLS-1$ | 
| 1256 |                         return null; | 
| 1257 |                 } catch(UnsupportedCharsetException e) { | 
| 1258 |                         System.err.println("Unsupported charset : " + encoding); //$NON-NLS-1$ | 
| 1259 |                         return null; | 
| 1260 |                 } | 
| 1261 |                 CharsetDecoder charsetDecoder = charset.newDecoder(); | 
| 1262 |                 charsetDecoder.onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE); | 
| 1263 |                 byte[] contents = getInputStreamAsByteArray(stream, length); | 
| 1264 |                 ByteBuffer byteBuffer = ByteBuffer.allocate(contents.length); | 
| 1265 |                 byteBuffer.put(contents); | 
| 1266 |                 byteBuffer.flip(); | 
| 1267 |                 return charsetDecoder.decode(byteBuffer).array(); | 
| 1268 |         } | 
| 1269 |          | 
| 1270 |         /** | 
| 1271 |          * Tries to find the 'MANIFEST.MF' file with in the given project in the  | 
| 1272 |          * 'META-INF folder'. | 
| 1273 |          *  | 
| 1274 |          * @param currentProject | 
| 1275 |          * @return a handle to the manifest file or <code>null</code> if not found | 
| 1276 |          */ | 
| 1277 |         public static IResource getManifestFile(IProject currentProject) { | 
| 1278 |                 return currentProject.findMember("META-INF/MANIFEST.MF"); //$NON-NLS-1$ | 
| 1279 |         } | 
| 1280 |          | 
| 1281 |         /** | 
| 1282 |          * Returns if the given {@link IMarker} is representing an {@link org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem} | 
| 1283 |          * or not | 
| 1284 |          * @param marker the marker to check | 
| 1285 |          * @return true if the marker is for an {@link org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem} false otherwise | 
| 1286 |          * @throws CoreException | 
| 1287 |          */ | 
| 1288 |         public static boolean isApiProblemMarker(IMarker marker) { | 
| 1289 |                 return marker.getAttribute(IApiMarkerConstants.API_MARKER_ATTR_ID, -1) > 0; | 
| 1290 |         } | 
| 1291 |          | 
| 1292 |         /** | 
| 1293 |          * Returns a reference type for the given fully qualified type name. | 
| 1294 |          *  | 
| 1295 |          * @param fullyQualifiedName type name | 
| 1296 |          * @return reference type | 
| 1297 |          */ | 
| 1298 |         public static IReferenceTypeDescriptor getType(String fullyQualifiedName) { | 
| 1299 |                 int index = fullyQualifiedName.lastIndexOf('.'); | 
| 1300 |                 String pkg = index == -1 ? DEFAULT_PACKAGE_NAME : fullyQualifiedName.substring(0, index); | 
| 1301 |                 String type = index == -1 ? fullyQualifiedName : fullyQualifiedName.substring(index + 1); | 
| 1302 |                 return Factory.packageDescriptor(pkg).getType(type); | 
| 1303 |         } | 
| 1304 |         /** | 
| 1305 |          * Returns if the given project is API enabled | 
| 1306 |          * @param project | 
| 1307 |          * @return true if the project is API enabled, false otherwise | 
| 1308 |          */ | 
| 1309 |         public static boolean isApiProject(IProject project) { | 
| 1310 |                 try { | 
| 1311 |                         return project.hasNature(ApiPlugin.NATURE_ID); | 
| 1312 |                 } catch (CoreException e) { | 
| 1313 |                         return false; | 
| 1314 |                 } | 
| 1315 |         } | 
| 1316 |          | 
| 1317 |         /** | 
| 1318 |          * Returns if the given project is API enabled | 
| 1319 |          * @param project | 
| 1320 |          * @return true if the project is API enabled, false otherwise | 
| 1321 |          */ | 
| 1322 |         public static boolean isApiProject(IJavaProject project) { | 
| 1323 |                 return isApiProject(project.getProject()); | 
| 1324 |         } | 
| 1325 |          | 
| 1326 |         /** | 
| 1327 |          * Returns if the given {@link IApiComponent} is a valid {@link IApiComponent} | 
| 1328 |          * @param apiComponent | 
| 1329 |          * @return true if the given {@link IApiComponent} is valid, false otherwise | 
| 1330 |          */ | 
| 1331 |         public static boolean isApiToolsComponent(IApiComponent apiComponent) { | 
| 1332 |                 File file = new File(apiComponent.getLocation()); | 
| 1333 |                 if (file.exists()) { | 
| 1334 |                         if (file.isDirectory()) { | 
| 1335 |                                 // directory binary bundle | 
| 1336 |                                 File apiDescription = new File(file, IApiCoreConstants.API_DESCRIPTION_XML_NAME); | 
| 1337 |                                 return apiDescription.exists(); | 
| 1338 |                         } | 
| 1339 |                         ZipFile zipFile = null; | 
| 1340 |                         try { | 
| 1341 |                                 zipFile = new ZipFile(file); | 
| 1342 |                                 return zipFile.getEntry(IApiCoreConstants.API_DESCRIPTION_XML_NAME) != null; | 
| 1343 |                         } catch (ZipException e) { | 
| 1344 |                                 // ignore | 
| 1345 |                         } catch (IOException e) { | 
| 1346 |                                 // ignore | 
| 1347 |                         } finally { | 
| 1348 |                                 try { | 
| 1349 |                                         if (zipFile != null) zipFile.close(); | 
| 1350 |                                 } catch (IOException e) { | 
| 1351 |                                         // ignore | 
| 1352 |                                 } | 
| 1353 |                         } | 
| 1354 |                 } | 
| 1355 |                 return false; | 
| 1356 |         } | 
| 1357 |          | 
| 1358 |         /** | 
| 1359 |          * Returns if the specified file name is an archive name. A name is | 
| 1360 |          * considered to be an archive name if it ends with either '.zip' or '.jar' | 
| 1361 |          *  | 
| 1362 |          * @param fileName | 
| 1363 |          * @return true if the file name is an archive name false otherwise | 
| 1364 |          */ | 
| 1365 |         public static boolean isArchive(String fileName) { | 
| 1366 |                 String normalizedFileName = fileName.toLowerCase(); | 
| 1367 |                 return normalizedFileName.endsWith(".zip") || normalizedFileName.endsWith(".jar"); //$NON-NLS-1$ //$NON-NLS-2$ | 
| 1368 |         } | 
| 1369 |          | 
| 1370 |         /** | 
| 1371 |          * Returns if the flags are for a class | 
| 1372 |          * @param accessFlags | 
| 1373 |          * @return | 
| 1374 |          */ | 
| 1375 |         public static boolean isClass(int accessFlags) { | 
| 1376 |                 return (accessFlags & (Opcodes.ACC_ENUM | Opcodes.ACC_ANNOTATION | Opcodes.ACC_INTERFACE)) == 0; | 
| 1377 |         } | 
| 1378 |          | 
| 1379 |         /** | 
| 1380 |          * Returns if the specified file name is for a class file. A name is | 
| 1381 |          * considered to be a class file if it ends in '.class' | 
| 1382 |          *  | 
| 1383 |          * @param fileName | 
| 1384 |          * @return true if the name is for a class file false otherwise | 
| 1385 |          */ | 
| 1386 |         public static boolean isClassFile(String fileName) { | 
| 1387 |                 return fileName.toLowerCase().endsWith(DOT_CLASS_SUFFIX);  | 
| 1388 |         } | 
| 1389 |   | 
| 1390 |         public static boolean isDefault(int accessFlags) { | 
| 1391 |                 // none of the private, protected or public bit is set | 
| 1392 |                 return (accessFlags & (Opcodes.ACC_PRIVATE | 
| 1393 |                 |        Opcodes.ACC_PROTECTED | 
| 1394 |                 |        Opcodes.ACC_PUBLIC)) == 0; | 
| 1395 |         } | 
| 1396 |   | 
| 1397 |         public static final boolean isDifferentVersion(String versionToBeChecked, String referenceVersion) { | 
| 1398 |                 SinceTagVersion sinceTagVersion1 = null; | 
| 1399 |                 SinceTagVersion sinceTagVersion2 = null; | 
| 1400 |                 try { | 
| 1401 |                         sinceTagVersion1 = new SinceTagVersion(versionToBeChecked); | 
| 1402 |                         sinceTagVersion2 = new SinceTagVersion(referenceVersion); | 
| 1403 |                 } catch (IllegalArgumentException e) { | 
| 1404 |                         // We cannot compare the two versions as their format is unknown | 
| 1405 |                         // TODO (olivier) should we report these as malformed tags? | 
| 1406 |                         return false; | 
| 1407 |                 } | 
| 1408 |                 Version version1 = sinceTagVersion1.getVersion(); | 
| 1409 |                 Version version2 = sinceTagVersion2.getVersion(); | 
| 1410 |                 if (version1.getMajor() != version2.getMajor()) { | 
| 1411 |                         return true; | 
| 1412 |                 } | 
| 1413 |                 if (version1.getMinor() != version2.getMinor()) { | 
| 1414 |                         return true; | 
| 1415 |                 } | 
| 1416 |                 if (version1.getMicro() != version2.getMicro()) { | 
| 1417 |                         return true; | 
| 1418 |                 } | 
| 1419 |                 return false; | 
| 1420 |         } | 
| 1421 |   | 
| 1422 |         /** | 
| 1423 |          * Returns if the specified file name is for a java source file. A name is | 
| 1424 |          * considered to be a java source file if it ends in '.java' | 
| 1425 |          *  | 
| 1426 |          * @param fileName | 
| 1427 |          * @return true if the name is for a java source file, false otherwise | 
| 1428 |          */ | 
| 1429 |         public static boolean isJavaFileName(String fileName) { | 
| 1430 |                 return fileName.toLowerCase().endsWith(DOT_JAVA_SUFFIX); | 
| 1431 |         } | 
| 1432 |   | 
| 1433 |         /** | 
| 1434 |          * Returns if the given name is {@link java.lang.Object} | 
| 1435 |          * @param name | 
| 1436 |          * @return true if the name is java.lang.Object, false otherwise | 
| 1437 |          */ | 
| 1438 |         public static boolean isJavaLangObject(String name) { | 
| 1439 |                 return name != null && name.equals(JAVA_LANG_OBJECT); | 
| 1440 |         } | 
| 1441 |          | 
| 1442 |         /** | 
| 1443 |          * Return if the name is {@link java.lang.RuntimeException} | 
| 1444 |          * @param name | 
| 1445 |          * @return true if the name is java.lang.RuntimeException, false otherwise | 
| 1446 |          */ | 
| 1447 |         public static boolean isJavaLangRuntimeException(String name) { | 
| 1448 |                 return name != null && name.equals(JAVA_LANG_RUNTIMEEXCEPTION); | 
| 1449 |         } | 
| 1450 |         public static boolean isVisible(int modifiers) { | 
| 1451 |                 return Flags.isProtected(modifiers) || Flags.isPublic(modifiers); | 
| 1452 |         } | 
| 1453 |         public static boolean isBinaryProject(IProject project) { | 
| 1454 |                 return org.eclipse.pde.internal.core.WorkspaceModelManager.isBinaryProject(project); | 
| 1455 |         } | 
| 1456 |         /** | 
| 1457 |          * Returns a new XML document. | 
| 1458 |          *  | 
| 1459 |          * @return document | 
| 1460 |          * @throws CoreException if unable to create a new document | 
| 1461 |          */ | 
| 1462 |         public static Document newDocument() throws CoreException { | 
| 1463 |                 DocumentBuilderFactory dfactory= DocumentBuilderFactory.newInstance(); | 
| 1464 |                 DocumentBuilder docBuilder = null; | 
| 1465 |                 try { | 
| 1466 |                         docBuilder = dfactory.newDocumentBuilder(); | 
| 1467 |                 } catch (ParserConfigurationException e) { | 
| 1468 |                         abort("Unable to create new XML document.", e); //$NON-NLS-1$ | 
| 1469 |                 } | 
| 1470 |                 Document doc= docBuilder.newDocument(); | 
| 1471 |                 return doc; | 
| 1472 |         } | 
| 1473 |          | 
| 1474 |         /** | 
| 1475 |          * Parses the given string representing an XML document, returning its | 
| 1476 |          * root element. | 
| 1477 |          *  | 
| 1478 |          * @param document XML document as a string | 
| 1479 |          * @return the document's root element | 
| 1480 |          * @throws CoreException if unable to parse the document | 
| 1481 |          */ | 
| 1482 |         public static Element parseDocument(String document) throws CoreException { | 
| 1483 |                 Element root = null; | 
| 1484 |                 InputStream stream = null; | 
| 1485 |                 try{ | 
| 1486 |                         DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); | 
| 1487 |                         parser.setErrorHandler(new DefaultHandler()); | 
| 1488 |                         stream = new ByteArrayInputStream(document.getBytes()); | 
| 1489 |                         root = parser.parse(stream).getDocumentElement(); | 
| 1490 |                 } catch (ParserConfigurationException e) { | 
| 1491 |                         abort("Unable to parse XML document.", e);  //$NON-NLS-1$ | 
| 1492 |                 } catch (FactoryConfigurationError e) { | 
| 1493 |                         abort("Unable to parse XML document.", e);  //$NON-NLS-1$ | 
| 1494 |                 } catch (SAXException e) { | 
| 1495 |                         abort("Unable to parse XML document.", e);  //$NON-NLS-1$ | 
| 1496 |                 } catch (IOException e) { | 
| 1497 |                         abort("Unable to parse XML document.", e);  //$NON-NLS-1$ | 
| 1498 |                 } finally {  | 
| 1499 |                         try{ | 
| 1500 |                                 if (stream != null) { | 
| 1501 |                                         stream.close(); | 
| 1502 |                                 } | 
| 1503 |                         } catch(IOException e) { | 
| 1504 |                                 abort("Unable to parse XML document.", e);  //$NON-NLS-1$ | 
| 1505 |                         } | 
| 1506 |                 } | 
| 1507 |                 return root; | 
| 1508 |         } | 
| 1509 |          | 
| 1510 |         /** | 
| 1511 |          * Save the given contents into the given file. The file parent folder must exist. | 
| 1512 |          *  | 
| 1513 |          * @param file the given file target | 
| 1514 |          * @param contents the given contents | 
| 1515 |          * @throws IOException if an IOException occurs while saving the file | 
| 1516 |          */ | 
| 1517 |         public static void saveFile(File file, String contents) throws IOException { | 
| 1518 |                 BufferedWriter writer = null; | 
| 1519 |                 try { | 
| 1520 |                         writer = new BufferedWriter(new FileWriter(file)); | 
| 1521 |                         writer.write(contents); | 
| 1522 |                         writer.flush(); | 
| 1523 |                 } finally { | 
| 1524 |                         if (writer != null) { | 
| 1525 |                                 try { | 
| 1526 |                                         writer.close(); | 
| 1527 |                                 } catch(IOException e) { | 
| 1528 |                                         // ignore | 
| 1529 |                                 } | 
| 1530 |                         } | 
| 1531 |                 } | 
| 1532 |         } | 
| 1533 |   | 
| 1534 |         /** | 
| 1535 |          * Returns the contents of the given file as a string, or <code>null</code> | 
| 1536 |          * @param file the file to get the contents for | 
| 1537 |          * @return the contents of the file as a {@link String} or <code>null</code> | 
| 1538 |          */ | 
| 1539 |         public static String getFileContentAsString(File file) { | 
| 1540 |                 String contents = null; | 
| 1541 |                 FileInputStream stream = null; | 
| 1542 |                 try { | 
| 1543 |                         stream = new FileInputStream(file); | 
| 1544 |                         char[] array = getInputStreamAsCharArray(stream, -1, IApiCoreConstants.UTF_8); | 
| 1545 |                         contents = new String(array); | 
| 1546 |                 } | 
| 1547 |                 catch(IOException ioe) { | 
| 1548 |                         ApiPlugin.log(ioe); | 
| 1549 |                 } finally { | 
| 1550 |                         if (stream != null) { | 
| 1551 |                                 try { | 
| 1552 |                                         stream.close(); | 
| 1553 |                                 } catch (IOException e) { | 
| 1554 |                                         // ignore | 
| 1555 |                                 } | 
| 1556 |                         } | 
| 1557 |                 } | 
| 1558 |                 return contents; | 
| 1559 |         } | 
| 1560 |          | 
| 1561 |         /** | 
| 1562 |          * Returns the given string as an {@link InputStream}. It is up to the caller to close | 
| 1563 |          * the new stream. | 
| 1564 |          * @param string the string to convert | 
| 1565 |          * @return the {@link InputStream} for the given string | 
| 1566 |          */ | 
| 1567 |         public static InputStream getInputStreamFromString(String string) { | 
| 1568 |                 try { | 
| 1569 |                         return new ByteArrayInputStream(string.getBytes(IApiCoreConstants.UTF_8)); | 
| 1570 |                 } | 
| 1571 |                 catch(UnsupportedEncodingException uee) { | 
| 1572 |                         ApiPlugin.log(uee); | 
| 1573 |                 } | 
| 1574 |                 return null; | 
| 1575 |         } | 
| 1576 |          | 
| 1577 |         /** | 
| 1578 |          * Serializes the given XML document into a UTF-8 string. | 
| 1579 |          *  | 
| 1580 |          * @param document XML document to serialize | 
| 1581 |          * @return a string representing the given document | 
| 1582 |          * @throws CoreException if unable to serialize the document | 
| 1583 |          */ | 
| 1584 |         public static String serializeDocument(Document document) throws CoreException { | 
| 1585 |                 try { | 
| 1586 |                         ByteArrayOutputStream s = new ByteArrayOutputStream(); | 
| 1587 |                         TransformerFactory factory = TransformerFactory.newInstance(); | 
| 1588 |                         Transformer transformer = factory.newTransformer(); | 
| 1589 |                         transformer.setOutputProperty(OutputKeys.METHOD, "xml");  //$NON-NLS-1$ | 
| 1590 |                         transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ | 
| 1591 |                         transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount","4"); //$NON-NLS-1$ //$NON-NLS-2$ | 
| 1592 |                         DOMSource source = new DOMSource(document); | 
| 1593 |                         StreamResult outputTarget = new StreamResult(s); | 
| 1594 |                         transformer.transform(source, outputTarget); | 
| 1595 |                         return s.toString(IApiCoreConstants.UTF_8);         | 
| 1596 |                 } catch (TransformerException e) { | 
| 1597 |                         abort("Unable to serialize XML document.", e);   //$NON-NLS-1$ | 
| 1598 |                 } catch (IOException e) { | 
| 1599 |                         abort("Unable to serialize XML document.",e);  //$NON-NLS-1$ | 
| 1600 |                 } | 
| 1601 |                 return null; | 
| 1602 |         } | 
| 1603 |         /** | 
| 1604 |          * Unzip the contents of the given zip in the given directory (create it if it doesn't exist) | 
| 1605 |          */ | 
| 1606 |         public static void unzip(String zipPath, String destDirPath) throws IOException { | 
| 1607 |                 InputStream zipIn = new FileInputStream(zipPath); | 
| 1608 |                 byte[] buf = new byte[8192]; | 
| 1609 |                 File destDir = new File(destDirPath); | 
| 1610 |                 ZipInputStream zis = new ZipInputStream(new BufferedInputStream(zipIn)); | 
| 1611 |                 BufferedOutputStream outputStream = null; | 
| 1612 |                 try { | 
| 1613 |                         ZipEntry zEntry; | 
| 1614 |                         while ((zEntry = zis.getNextEntry()) != null) { | 
| 1615 |                                 // if it is empty directory, create it | 
| 1616 |                                 if (zEntry.isDirectory()) { | 
| 1617 |                                         new File(destDir, zEntry.getName()).mkdirs(); | 
| 1618 |                                         continue; | 
| 1619 |                                 } | 
| 1620 |                                 // if it is a file, extract it | 
| 1621 |                                 String filePath = zEntry.getName(); | 
| 1622 |                                 int lastSeparator = filePath.lastIndexOf("/"); //$NON-NLS-1$ | 
| 1623 |                                 String fileDir = ""; //$NON-NLS-1$ | 
| 1624 |                                 if (lastSeparator >= 0) { | 
| 1625 |                                         fileDir = filePath.substring(0, lastSeparator); | 
| 1626 |                                 } | 
| 1627 |                                 //create directory for a file | 
| 1628 |                                 new File(destDir, fileDir).mkdirs(); | 
| 1629 |                                 //write file | 
| 1630 |                                 File outFile = new File(destDir, filePath); | 
| 1631 |                                 outputStream = new BufferedOutputStream(new FileOutputStream(outFile)); | 
| 1632 |                                 int n = 0; | 
| 1633 |                                 while ((n = zis.read(buf)) >= 0) { | 
| 1634 |                                         outputStream.write(buf, 0, n); | 
| 1635 |                                 } | 
| 1636 |                                 outputStream.close(); | 
| 1637 |                         } | 
| 1638 |                 } catch (IOException ioe) { | 
| 1639 |                         if (outputStream != null) { | 
| 1640 |                                 try { | 
| 1641 |                                         outputStream.close(); | 
| 1642 |                                 } catch (IOException ioe2) { | 
| 1643 |                                 } | 
| 1644 |                         } | 
| 1645 |                 } finally { | 
| 1646 |                         try { | 
| 1647 |                                 zipIn.close(); | 
| 1648 |                                 zis.close(); | 
| 1649 |                         } catch (IOException ioe) { | 
| 1650 |                         } | 
| 1651 |                 } | 
| 1652 |         } | 
| 1653 |         /** | 
| 1654 |          * Unzip the contents of the given zip in the given directory (create it if it doesn't exist) | 
| 1655 |          */ | 
| 1656 |         public static void guntar(String zipPath, String destDirPath) throws TarException, IOException { | 
| 1657 |                 TarFile tarFile = new TarFile(zipPath); | 
| 1658 |                 Enumeration entries = tarFile.entries(); | 
| 1659 |                 byte[] buf = new byte[8192]; | 
| 1660 |                 for (;entries.hasMoreElements(); ) { | 
| 1661 |                         TarEntry zEntry; | 
| 1662 |                         while ((zEntry = (TarEntry) entries.nextElement()) != null) { | 
| 1663 |                                 // if it is empty directory, create it | 
| 1664 |                                 if (zEntry.getFileType() == TarEntry.DIRECTORY) { | 
| 1665 |                                         new File(destDirPath, zEntry.getName()).mkdirs(); | 
| 1666 |                                         continue; | 
| 1667 |                                 } | 
| 1668 |                                 // if it is a file, extract it | 
| 1669 |                                 String filePath = zEntry.getName(); | 
| 1670 |                                 int lastSeparator = filePath.lastIndexOf("/"); //$NON-NLS-1$ | 
| 1671 |                                 String fileDir = ""; //$NON-NLS-1$ | 
| 1672 |                                 if (lastSeparator >= 0) { | 
| 1673 |                                         fileDir = filePath.substring(0, lastSeparator); | 
| 1674 |                                 } | 
| 1675 |                                 //create directory for a file | 
| 1676 |                                 new File(destDirPath, fileDir).mkdirs(); | 
| 1677 |                                 //write file | 
| 1678 |                                 File outFile = new File(destDirPath, filePath); | 
| 1679 |                                 BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outFile)); | 
| 1680 |                                 int n = 0; | 
| 1681 |                                 InputStream inputStream = tarFile.getInputStream(zEntry); | 
| 1682 |                                 BufferedInputStream stream = new BufferedInputStream(inputStream); | 
| 1683 |                                 while ((n = stream.read(buf)) >= 0) { | 
| 1684 |                                         outputStream.write(buf, 0, n); | 
| 1685 |                                 } | 
| 1686 |                                 outputStream.close(); | 
| 1687 |                                 stream.close(); | 
| 1688 |                         } | 
| 1689 |                 } | 
| 1690 |         } | 
| 1691 |         /** | 
| 1692 |          * Gets the .ee file supplied to run tests based on system | 
| 1693 |          * property. | 
| 1694 |          *  | 
| 1695 |          * @return | 
| 1696 |          */ | 
| 1697 |         public static File getEEDescriptionFile() { | 
| 1698 |                 // generate a fake 1.6 ee file | 
| 1699 |                 File fakeEEFile = null; | 
| 1700 |                 PrintWriter writer = null; | 
| 1701 |                 try { | 
| 1702 |                         fakeEEFile = File.createTempFile("eefile", ".ee"); //$NON-NLS-1$ //$NON-NLS-2$ | 
| 1703 |                         fakeEEFile.deleteOnExit(); | 
| 1704 |                         writer = new PrintWriter(new BufferedWriter(new FileWriter(fakeEEFile))); | 
| 1705 |                         writer.print("-Djava.home="); //$NON-NLS-1$ | 
| 1706 |                         writer.println(System.getProperty("java.home")); //$NON-NLS-1$ | 
| 1707 |                         writer.print("-Dee.bootclasspath="); //$NON-NLS-1$ | 
| 1708 |                         writer.println(getJavaClassLibsAsString()); | 
| 1709 |                         writer.println("-Dee.language.level=1.6"); //$NON-NLS-1$ | 
| 1710 |                         writer.println("-Dee.class.library.level=JavaSE-1.6"); //$NON-NLS-1$ | 
| 1711 |                         writer.flush(); | 
| 1712 |                 } catch (IOException e) { | 
| 1713 |                         // ignore | 
| 1714 |                 } finally { | 
| 1715 |                         if (writer != null) { | 
| 1716 |                                 writer.close(); | 
| 1717 |                         } | 
| 1718 |                 } | 
| 1719 |                 return fakeEEFile; | 
| 1720 |         } | 
| 1721 |   | 
| 1722 |         /** | 
| 1723 |          * @return a string representation of all of the libraries from the bootpath  | 
| 1724 |          * of the current default system VM. | 
| 1725 |          */ | 
| 1726 |         public static String getJavaClassLibsAsString() { | 
| 1727 |                 String[] libs = Util.getJavaClassLibs(); | 
| 1728 |                 StringBuffer buffer = new StringBuffer(); | 
| 1729 |                 for (int i = 0, max = libs.length; i < max; i++) { | 
| 1730 |                         if (i > 0) { | 
| 1731 |                                 buffer.append(File.pathSeparatorChar); | 
| 1732 |                         } | 
| 1733 |                         buffer.append(libs[i]); | 
| 1734 |                 } | 
| 1735 |                 return String.valueOf(buffer); | 
| 1736 |         } | 
| 1737 |          | 
| 1738 |         /** | 
| 1739 |          * @return an array of the library names from the bootpath of the current default system VM  | 
| 1740 |          */ | 
| 1741 |         public static String[] getJavaClassLibs() { | 
| 1742 |                 // check bootclasspath properties for Sun, JRockit and Harmony VMs | 
| 1743 |                 String bootclasspathProperty = System.getProperty("sun.boot.class.path"); //$NON-NLS-1$ | 
| 1744 |                 if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) { | 
| 1745 |                         // IBM J9 VMs | 
| 1746 |                         bootclasspathProperty = System.getProperty("vm.boot.class.path"); //$NON-NLS-1$ | 
| 1747 |                         if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) { | 
| 1748 |                                 // Harmony using IBM VME | 
| 1749 |                                 bootclasspathProperty = System.getProperty("org.apache.harmony.boot.class.path"); //$NON-NLS-1$ | 
| 1750 |                         } | 
| 1751 |                 } | 
| 1752 |                 String[] jars = null; | 
| 1753 |                 if ((bootclasspathProperty != null) && (bootclasspathProperty.length() != 0)) { | 
| 1754 |                         StringTokenizer tokenizer = new StringTokenizer(bootclasspathProperty, File.pathSeparator); | 
| 1755 |                         final int size = tokenizer.countTokens(); | 
| 1756 |                         jars = new String[size]; | 
| 1757 |                         int i = 0; | 
| 1758 |                         while (tokenizer.hasMoreTokens()) { | 
| 1759 |                                 final String fileName = toNativePath(tokenizer.nextToken()); | 
| 1760 |                                 if (new File(fileName).exists()) { | 
| 1761 |                                         jars[i] = fileName; | 
| 1762 |                                         i++; | 
| 1763 |                                 } | 
| 1764 |                         } | 
| 1765 |                         if (size != i) { | 
| 1766 |                                 // resize | 
| 1767 |                                 System.arraycopy(jars, 0, (jars = new String[i]), 0, i); | 
| 1768 |                         } | 
| 1769 |                 } else { | 
| 1770 |                         String jreDir = System.getProperty("java.home"); //$NON-NLS-1$ | 
| 1771 |                         final String osName = System.getProperty("os.name"); //$NON-NLS-1$ | 
| 1772 |                         if (jreDir == null) { | 
| 1773 |                                 return new String[] {}; | 
| 1774 |                         } | 
| 1775 |                         if (osName.startsWith("Mac")) { //$NON-NLS-1$ | 
| 1776 |                                 return new String[] { | 
| 1777 |                                                 toNativePath(jreDir + "/../Classes/classes.jar") //$NON-NLS-1$ | 
| 1778 |                                 }; | 
| 1779 |                         } | 
| 1780 |                         final String vmName = System.getProperty("java.vm.name"); //$NON-NLS-1$ | 
| 1781 |                         if ("J9".equals(vmName)) { //$NON-NLS-1$ | 
| 1782 |                                 return new String[] { | 
| 1783 |                                                 toNativePath(jreDir + "/lib/jclMax/classes.zip") //$NON-NLS-1$ | 
| 1784 |                                 }; | 
| 1785 |                         } | 
| 1786 |                         String[] jarsNames = null; | 
| 1787 |                         ArrayList paths = new ArrayList(); | 
| 1788 |                         if ("DRLVM".equals(vmName)) { //$NON-NLS-1$ | 
| 1789 |                                 FilenameFilter jarFilter = new FilenameFilter() { | 
| 1790 |                                         public boolean accept(File dir, String name) { | 
| 1791 |                                                 return name.endsWith(".jar") & !name.endsWith("-src.jar");  //$NON-NLS-1$//$NON-NLS-2$ | 
| 1792 |                                         } | 
| 1793 |                                 }; | 
| 1794 |                                 jarsNames = new File(jreDir + "/lib/boot/").list(jarFilter); //$NON-NLS-1$ | 
| 1795 |                                 addJarEntries(jreDir + "/lib/boot/", jarsNames, paths); //$NON-NLS-1$ | 
| 1796 |                         } else { | 
| 1797 |                                 jarsNames = new String[] { | 
| 1798 |                                                 "/lib/vm.jar", //$NON-NLS-1$ | 
| 1799 |                                                 "/lib/rt.jar", //$NON-NLS-1$ | 
| 1800 |                                                 "/lib/core.jar", //$NON-NLS-1$ | 
| 1801 |                                                 "/lib/security.jar", //$NON-NLS-1$ | 
| 1802 |                                                 "/lib/xml.jar", //$NON-NLS-1$ | 
| 1803 |                                                 "/lib/graphics.jar" //$NON-NLS-1$ | 
| 1804 |                                 }; | 
| 1805 |                                 addJarEntries(jreDir, jarsNames, paths); | 
| 1806 |                         } | 
| 1807 |                         jars = new String[paths.size()]; | 
| 1808 |                         paths.toArray(jars); | 
| 1809 |                 } | 
| 1810 |                 return jars; | 
| 1811 |         } | 
| 1812 |         /** | 
| 1813 |          * Makes the given path a path using native path separators as returned by File.getPath() | 
| 1814 |          * and trimming any extra slash. | 
| 1815 |          */ | 
| 1816 |         public static String toNativePath(String path) { | 
| 1817 |                 String nativePath = path.replace('\\', File.separatorChar).replace('/', File.separatorChar); | 
| 1818 |                 return | 
| 1819 |                 nativePath.endsWith("/") || nativePath.endsWith("\\") ? //$NON-NLS-1$ //$NON-NLS-2$ | 
| 1820 |                                 nativePath.substring(0, nativePath.length() - 1) : | 
| 1821 |                                         nativePath; | 
| 1822 |         } | 
| 1823 |   | 
| 1824 |         private static void addJarEntries(String jreDir, String[] jarNames, ArrayList paths) { | 
| 1825 |                 for (int i = 0, max = jarNames.length; i < max; i++) { | 
| 1826 |                         final String currentName = jreDir + jarNames[i]; | 
| 1827 |                         File f = new File(currentName); | 
| 1828 |                         if (f.exists()) { | 
| 1829 |                                 paths.add(toNativePath(currentName)); | 
| 1830 |                         } | 
| 1831 |                 } | 
| 1832 |         } | 
| 1833 |         /** | 
| 1834 |          * Delete a file or directory and insure that the file is no longer present | 
| 1835 |          * on file system. In case of directory, delete all the hierarchy underneath. | 
| 1836 |          * | 
| 1837 |          * @param file The file or directory to delete | 
| 1838 |          * @return true iff the file was really delete, false otherwise | 
| 1839 |          */ | 
| 1840 |         public static boolean delete(File file) { | 
| 1841 |                 if (!file.exists()) { | 
| 1842 |                         return true; | 
| 1843 |                 } | 
| 1844 |                 // flush all directory content | 
| 1845 |                 if (file.isDirectory()) { | 
| 1846 |                         flushDirectoryContent(file); | 
| 1847 |                 } | 
| 1848 |                 // remove file | 
| 1849 |                 file.delete(); | 
| 1850 |                 if (isFileDeleted(file)) { | 
| 1851 |                         return true; | 
| 1852 |                 } | 
| 1853 |                 return waitUntilFileDeleted(file); | 
| 1854 |         } | 
| 1855 |         public static void flushDirectoryContent(File dir) { | 
| 1856 |                 File[] files = dir.listFiles(); | 
| 1857 |                 if (files == null) return; | 
| 1858 |                 for (int i = 0, max = files.length; i < max; i++) { | 
| 1859 |                         delete(files[i]); | 
| 1860 |                 } | 
| 1861 |         } | 
| 1862 |         /** | 
| 1863 |          * Wait until the file is _really_ deleted on file system. | 
| 1864 |          * | 
| 1865 |          * @param file Deleted file | 
| 1866 |          * @return true if the file was finally deleted, false otherwise | 
| 1867 |          */ | 
| 1868 |         private static boolean waitUntilFileDeleted(File file) { | 
| 1869 |                 int count = 0; | 
| 1870 |                 int delay = 10; // ms | 
| 1871 |                 int maxRetry = DELETE_MAX_WAIT / delay; | 
| 1872 |                 int time = 0; | 
| 1873 |                 while (count < maxRetry) { | 
| 1874 |                         try { | 
| 1875 |                                 count++; | 
| 1876 |                                 Thread.sleep(delay); | 
| 1877 |                                 time += delay; | 
| 1878 |                                 if (time > DELETE_MAX_TIME) DELETE_MAX_TIME = time; | 
| 1879 |                                 if (DELETE_DEBUG) System.out.print('.'); | 
| 1880 |                                 if (file.exists()) { | 
| 1881 |                                         if (file.delete()) { | 
| 1882 |                                                 // SUCCESS | 
| 1883 |                                                 return true; | 
| 1884 |                                         } | 
| 1885 |                                 } | 
| 1886 |                                 if (isFileDeleted(file)) { | 
| 1887 |                                         // SUCCESS | 
| 1888 |                                         return true; | 
| 1889 |                                 } | 
| 1890 |                                 // Increment waiting delay exponentially | 
| 1891 |                                 if (count >= 10 && delay <= 100) { | 
| 1892 |                                         count = 1; | 
| 1893 |                                         delay *= 10; | 
| 1894 |                                         maxRetry = DELETE_MAX_WAIT / delay; | 
| 1895 |                                         if ((DELETE_MAX_WAIT%delay) != 0) { | 
| 1896 |                                                 maxRetry++; | 
| 1897 |                                         } | 
| 1898 |                                 } | 
| 1899 |                         } | 
| 1900 |                         catch (InterruptedException ie) { | 
| 1901 |                                 break; // end loop | 
| 1902 |                         } | 
| 1903 |                 } | 
| 1904 |                 System.err.println(); | 
| 1905 |                 System.err.println("        !!! ERROR: "+file+" was never deleted even after having waited "+DELETE_MAX_TIME+"ms!!!"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | 
| 1906 |                 System.err.println(); | 
| 1907 |                 return false; | 
| 1908 |         } | 
| 1909 |         /** | 
| 1910 |          * Returns whether a file is really deleted or not. | 
| 1911 |          * Does not only rely on {@link File#exists()} method but also | 
| 1912 |          * look if it's not in its parent children {@link #getParentChildFile(File)}. | 
| 1913 |          * | 
| 1914 |          * @param file The file to test if deleted | 
| 1915 |          * @return true if the file does not exist and was not found in its parent children. | 
| 1916 |          */ | 
| 1917 |         public static boolean isFileDeleted(File file) { | 
| 1918 |                 return !file.exists() && getParentChildFile(file) == null; | 
| 1919 |         } | 
| 1920 |         /** | 
| 1921 |          * Returns the parent's child file matching the given file or null if not found. | 
| 1922 |          * | 
| 1923 |          * @param file The searched file in parent | 
| 1924 |          * @return The parent's child matching the given file or null if not found. | 
| 1925 |          */ | 
| 1926 |         private static File getParentChildFile(File file) { | 
| 1927 |                 File parent = file.getParentFile(); | 
| 1928 |                 if (parent == null || !parent.exists()) return null; | 
| 1929 |                 File[] files = parent.listFiles(); | 
| 1930 |                 int length = files==null ? 0 : files.length; | 
| 1931 |                 if (length > 0) { | 
| 1932 |                         for (int i=0; i<length; i++) { | 
| 1933 |                                 if (files[i] == file) { | 
| 1934 |                                         return files[i]; | 
| 1935 |                                 } else if (files[i].equals(file)) { | 
| 1936 |                                         return files[i]; | 
| 1937 |                                 } else if (files[i].getPath().equals(file.getPath())) { | 
| 1938 |                                         return files[i]; | 
| 1939 |                                 } | 
| 1940 |                         } | 
| 1941 |                 } | 
| 1942 |                 return null; | 
| 1943 |         } | 
| 1944 |   | 
| 1945 |         /** | 
| 1946 |          * Turns the given array of strings into a {@link HashSet} | 
| 1947 |          * @param values | 
| 1948 |          * @return a new {@link HashSet} of the string array | 
| 1949 |          */ | 
| 1950 |         public static Set convertAsSet(String[] values) { | 
| 1951 |                 Set set = new HashSet(); | 
| 1952 |                 if (values != null && values.length != 0) { | 
| 1953 |                         for (int i = 0, max = values.length; i < max; i++) { | 
| 1954 |                                 set.add(values[i]); | 
| 1955 |                         } | 
| 1956 |                 } | 
| 1957 |                 return set; | 
| 1958 |         } | 
| 1959 |   | 
| 1960 |         /** | 
| 1961 |          * Returns an identifier for the given API component including its version identifier | 
| 1962 |          * (component id + '(' + major + . + minor + . + micro + ')' ) | 
| 1963 |          *   | 
| 1964 |          * @param component API component | 
| 1965 |          * @return API component + version identifier | 
| 1966 |          */ | 
| 1967 |         public static String getDeltaComponentVersionsId(IApiComponent component) { | 
| 1968 |                 StringBuffer buffer = new StringBuffer(component.getId()); | 
| 1969 |                 String version = component.getVersion(); | 
| 1970 |                 // remove the qualifier part | 
| 1971 |                 if (version != null) { | 
| 1972 |                         buffer.append('('); | 
| 1973 |                         try { | 
| 1974 |                                 Version version2 = new Version(version); | 
| 1975 |                                 buffer | 
| 1976 |                                         .append(version2.getMajor()) | 
| 1977 |                                         .append('.') | 
| 1978 |                                         .append(version2.getMinor()) | 
| 1979 |                                         .append('.') | 
| 1980 |                                         .append(version2.getMicro()); | 
| 1981 |                         } catch (IllegalArgumentException e) { | 
| 1982 |                                 // the version string doesn't follow the Eclipse pattern | 
| 1983 |                                 // we keep the version as is | 
| 1984 |                                 buffer.append(version); | 
| 1985 |                         } | 
| 1986 |                         buffer.append(')'); | 
| 1987 |                 } | 
| 1988 |                 return String.valueOf(buffer); | 
| 1989 |         } | 
| 1990 |         /** | 
| 1991 |          * Returns an identifier for the given API component including its version identifier | 
| 1992 |          * (component id + _ + major + _ + minor + _ + micro) | 
| 1993 |          *   | 
| 1994 |          * @param component API component | 
| 1995 |          * @return API component + version identifier | 
| 1996 |          */ | 
| 1997 |         public static String getComponentVersionsId(IApiComponent component) { | 
| 1998 |                 StringBuffer buffer = new StringBuffer(component.getId()); | 
| 1999 |                 String version = component.getVersion(); | 
| 2000 |                 // remove the qualifier part | 
| 2001 |                 if (version != null) { | 
| 2002 |                         buffer.append('_'); | 
| 2003 |                         try { | 
| 2004 |                                 Version version2 = new Version(version); | 
| 2005 |                                 buffer | 
| 2006 |                                         .append(version2.getMajor()) | 
| 2007 |                                         .append('.') | 
| 2008 |                                         .append(version2.getMinor()) | 
| 2009 |                                         .append('.') | 
| 2010 |                                         .append(version2.getMicro()); | 
| 2011 |                         } catch (IllegalArgumentException e) { | 
| 2012 |                                 // the version string doesn't follow the Eclipse pattern | 
| 2013 |                                 // we keep the version as is | 
| 2014 |                                 buffer.append(version); | 
| 2015 |                         } | 
| 2016 |                 } | 
| 2017 |                 return String.valueOf(buffer); | 
| 2018 |         } | 
| 2019 |         public static String getDescriptorName(IApiType descriptor) { | 
| 2020 |                 String typeName = descriptor.getName(); | 
| 2021 |                 int index = typeName.lastIndexOf('$'); | 
| 2022 |                 if (index != -1) { | 
| 2023 |                         return typeName.replace('$', '.'); | 
| 2024 |                 } | 
| 2025 |                 return typeName; | 
| 2026 |         } | 
| 2027 |   | 
| 2028 |         public static String getDeltaArgumentString(IDelta delta) { | 
| 2029 |                 String[] arguments = delta.getArguments(); | 
| 2030 |                 switch(delta.getFlags()) { | 
| 2031 |                         case IDelta.TYPE_MEMBER : | 
| 2032 |                         case IDelta.TYPE : | 
| 2033 |                                 return arguments[0]; | 
| 2034 |                         case IDelta.METHOD : | 
| 2035 |                         case IDelta.CONSTRUCTOR : | 
| 2036 |                         case IDelta.ENUM_CONSTANT : | 
| 2037 |                         case IDelta.METHOD_WITH_DEFAULT_VALUE : | 
| 2038 |                         case IDelta.METHOD_WITHOUT_DEFAULT_VALUE : | 
| 2039 |                         case IDelta.FIELD : | 
| 2040 |                                 return arguments[1]; | 
| 2041 |                         case IDelta.INCREASE_ACCESS : | 
| 2042 |                                 switch(delta.getElementType()) { | 
| 2043 |                                         case IDelta.FIELD_ELEMENT_TYPE : | 
| 2044 |                                         case IDelta.METHOD_ELEMENT_TYPE : | 
| 2045 |                                         case IDelta.CONSTRUCTOR_ELEMENT_TYPE : | 
| 2046 |                                                 return arguments[1]; | 
| 2047 |                                         default: | 
| 2048 |                                                 return arguments[0]; | 
| 2049 |                                 } | 
| 2050 |                 } | 
| 2051 |                 return EMPTY_STRING; | 
| 2052 |         } | 
| 2053 |          | 
| 2054 |         /** | 
| 2055 |          * Returns the string representation of the {@link IApiElement} type | 
| 2056 |          * @param type | 
| 2057 |          * @return the string of the {@link IApiElement} type | 
| 2058 |          */ | 
| 2059 |         public static String getApiElementType(int type) { | 
| 2060 |                 switch(type) { | 
| 2061 |                         case IApiElement.API_TYPE_CONTAINER : | 
| 2062 |                                 return "API_TYPE_CONTAINER"; //$NON-NLS-1$ | 
| 2063 |                         case IApiElement.API_TYPE_ROOT : | 
| 2064 |                                 return "API_TYPE_ROOT"; //$NON-NLS-1$ | 
| 2065 |                         case IApiElement.BASELINE : | 
| 2066 |                                 return "BASELINE"; //$NON-NLS-1$ | 
| 2067 |                         case IApiElement.COMPONENT : | 
| 2068 |                                 return "COMPONENT"; //$NON-NLS-1$ | 
| 2069 |                         case IApiElement.FIELD : | 
| 2070 |                                 return "FIELD"; //$NON-NLS-1$ | 
| 2071 |                         case IApiElement.METHOD : | 
| 2072 |                                 return "METHOD"; //$NON-NLS-1$ | 
| 2073 |                         case IApiElement.TYPE : | 
| 2074 |                                 return "TYPE"; //$NON-NLS-1$ | 
| 2075 |                         default: | 
| 2076 |                                 return "UNKNOWN"; //$NON-NLS-1$ | 
| 2077 |                 } | 
| 2078 |         } | 
| 2079 |   | 
| 2080 |         public static boolean isConstructor(String referenceMemberName) { | 
| 2081 |                 return Arrays.equals(ConstantPool.Init, referenceMemberName.toCharArray()); | 
| 2082 |         } | 
| 2083 |          | 
| 2084 |         public static boolean isManifest(IPath path) { | 
| 2085 |                 return MANIFEST_PROJECT_RELATIVE_PATH.equals(path); | 
| 2086 |         } | 
| 2087 |         public static void touchCorrespondingResource(IProject project, IResource resource, String typeName) { | 
| 2088 |                 if (typeName != null && typeName != ApiFilterStore.GLOBAL) { | 
| 2089 |                         if (Util.isManifest(resource.getProjectRelativePath())) { | 
| 2090 |                                 try { | 
| 2091 |                                         IJavaProject javaProject = JavaCore.create(project); | 
| 2092 |                                         IType findType = javaProject.findType(typeName); | 
| 2093 |                                         if (findType != null) { | 
| 2094 |                                                 ICompilationUnit compilationUnit = findType.getCompilationUnit(); | 
| 2095 |                                                 if (compilationUnit != null) { | 
| 2096 |                                                         IResource cuResource = compilationUnit.getResource(); | 
| 2097 |                                                         if (cuResource != null) { | 
| 2098 |                                                                 cuResource.touch(null); | 
| 2099 |                                                         } | 
| 2100 |                                                 } | 
| 2101 |                                         } | 
| 2102 |                                 } catch (JavaModelException e) { | 
| 2103 |                                         ApiPlugin.log(e); | 
| 2104 |                                 } catch (CoreException e) { | 
| 2105 |                                         ApiPlugin.log(e); | 
| 2106 |                                 } | 
| 2107 |                         } else { | 
| 2108 |                                 try { | 
| 2109 |                                         resource.touch(null); | 
| 2110 |                                 } catch (CoreException e) { | 
| 2111 |                                         ApiPlugin.log(e); | 
| 2112 |                                 } | 
| 2113 |                         } | 
| 2114 |                 } | 
| 2115 |         } | 
| 2116 |         public static String getTypeNameFromMarker(IMarker marker) { | 
| 2117 |                 return marker.getAttribute(IApiMarkerConstants.MARKER_ATTR_PROBLEM_TYPE_NAME, null); | 
| 2118 |         } | 
| 2119 |          | 
| 2120 |         public static IApiComponent[] getReexportedComponents(IApiComponent component) { | 
| 2121 |                 try { | 
| 2122 |                         IRequiredComponentDescription[] requiredComponents = component.getRequiredComponents(); | 
| 2123 |                         int length = requiredComponents.length; | 
| 2124 |                         if (length != 0) { | 
| 2125 |                                 List reexportedComponents = null; | 
| 2126 |                                 IApiBaseline baseline = component.getBaseline(); | 
| 2127 |                                 for (int i = 0; i < length; i++) { | 
| 2128 |                                         IRequiredComponentDescription description = requiredComponents[i]; | 
| 2129 |                                         if (description.isExported()) { | 
| 2130 |                                                 String id = description.getId(); | 
| 2131 |                                                 IApiComponent reexportedComponent = baseline.getApiComponent(id); | 
| 2132 |                                                 if (reexportedComponent != null) { | 
| 2133 |                                                         if (reexportedComponents == null) { | 
| 2134 |                                                                 reexportedComponents = new ArrayList(); | 
| 2135 |                                                         } | 
| 2136 |                                                         reexportedComponents.add(reexportedComponent); | 
| 2137 |                                                 } | 
| 2138 |                                         } | 
| 2139 |                                 } | 
| 2140 |                                 if (reexportedComponents == null || reexportedComponents.size() == 0) { | 
| 2141 |                                         return null; | 
| 2142 |                                 } | 
| 2143 |                                 return (IApiComponent[]) reexportedComponents.toArray(new IApiComponent[reexportedComponents.size()]); | 
| 2144 |                         } | 
| 2145 |                 } catch (CoreException e) { | 
| 2146 |                         ApiPlugin.log(e); | 
| 2147 |                 } | 
| 2148 |                 return null; | 
| 2149 |         } | 
| 2150 |   | 
| 2151 |         /** | 
| 2152 |          * Returns the {@link IResource} to create markers on when building. If the {@link IType} is <code>null</code> | 
| 2153 |          * or the type cannot be located (does not exist) than the MANIFEST.MF will be returned. | 
| 2154 |          * @param project the project to look in for the {@link IResource} | 
| 2155 |          * @param type the type we are looking for the resource for, or <code>null</code> | 
| 2156 |          * @return the {@link IResource} associated with the given {@link IType} or the MANIFEST.MF file | 
| 2157 |          */ | 
| 2158 |         public static IResource getResource(IProject project, IType type) { | 
| 2159 |                 IResource resource = null; | 
| 2160 |                 try { | 
| 2161 |                         if (type == null) { | 
| 2162 |                                 IResource manifestFile = Util.getManifestFile(project); | 
| 2163 |                                 if (manifestFile == null) { | 
| 2164 |                                         // Cannot retrieve the manifest.mf file | 
| 2165 |                                         return null; | 
| 2166 |                                 } | 
| 2167 |                                 resource = manifestFile; | 
| 2168 |                         } else { | 
| 2169 |                                 ICompilationUnit unit = type.getCompilationUnit(); | 
| 2170 |                                 if (unit != null) { | 
| 2171 |                                         resource = unit.getCorrespondingResource(); | 
| 2172 |                                         if (resource == null) { | 
| 2173 |                                                 return null; | 
| 2174 |                                         } | 
| 2175 |                                         if (project.findMember(resource.getProjectRelativePath()) == null) { | 
| 2176 |                                                 resource = null; | 
| 2177 |                                                 IResource manifestFile = Util.getManifestFile(project); | 
| 2178 |                                                 if (manifestFile == null) { | 
| 2179 |                                                         // Cannot retrieve the manifest.mf file | 
| 2180 |                                                         return null; | 
| 2181 |                                                 } | 
| 2182 |                                                 resource = manifestFile; | 
| 2183 |                                         } | 
| 2184 |                                 } else { | 
| 2185 |                                         IResource manifestFile = Util.getManifestFile(project); | 
| 2186 |                                         if (manifestFile == null) { | 
| 2187 |                                                 // Cannot retrieve the manifest.mf file | 
| 2188 |                                                 return null; | 
| 2189 |                                         } | 
| 2190 |                                         resource = manifestFile; | 
| 2191 |                                 } | 
| 2192 |                         } | 
| 2193 |                 } catch (JavaModelException e) { | 
| 2194 |                         ApiPlugin.log(e); | 
| 2195 |                 } | 
| 2196 |                 return resource; | 
| 2197 |         } | 
| 2198 |   | 
| 2199 |         /** | 
| 2200 |          * Default comparator that orders {@link IApiComponent} by their ID  | 
| 2201 |          */ | 
| 2202 |         public static final Comparator componentsorter = new Comparator(){ | 
| 2203 |                 public int compare(Object o1, Object o2) { | 
| 2204 |                         if(o1 instanceof IApiComponent && o2 instanceof IApiComponent) { | 
| 2205 |                                 return ((IApiComponent)o1).getId().compareTo(((IApiComponent)o2).getId()); | 
| 2206 |                         } | 
| 2207 |                         if(o1 instanceof SkippedComponent && o2 instanceof SkippedComponent) { | 
| 2208 |                                 return ((SkippedComponent)o1).getComponentId().compareTo(((SkippedComponent)o2).getComponentId()); | 
| 2209 |                         } | 
| 2210 |                         if(o1 instanceof String && o2 instanceof String) { | 
| 2211 |                                 return ((String)o1).compareTo((String)o2); | 
| 2212 |                         } | 
| 2213 |                         return -1; | 
| 2214 |                 } | 
| 2215 |         }; | 
| 2216 |   | 
| 2217 |         /** | 
| 2218 |          * Initializes the exclude set with regex support. The API baseline is used to determine which | 
| 2219 |          * bundles should be added to the list when processing regex expressions. | 
| 2220 |          *  | 
| 2221 |          * @param location | 
| 2222 |          * @param baseline | 
| 2223 |          * @return the list of bundles to be excluded | 
| 2224 |          */ | 
| 2225 |         public static Set initializeRegexExcludeList(String location, IApiBaseline baseline) { | 
| 2226 |                 HashSet list = new HashSet(); | 
| 2227 |                 if (location != null) { | 
| 2228 |                         File file = new File(location); | 
| 2229 |                         if (file.exists()) { | 
| 2230 |                                 InputStream stream = null; | 
| 2231 |                                 char[] contents = null; | 
| 2232 |                                 try { | 
| 2233 |                                         stream = new BufferedInputStream(new FileInputStream(file)); | 
| 2234 |                                         contents = getInputStreamAsCharArray(stream, -1, ISO_8859_1); | 
| 2235 |                                 }  | 
| 2236 |                                 catch (FileNotFoundException e) {}  | 
| 2237 |                                 catch (IOException e) {}  | 
| 2238 |                                 finally { | 
| 2239 |                                         if (stream != null) { | 
| 2240 |                                                 try { | 
| 2241 |                                                         stream.close(); | 
| 2242 |                                                 } catch (IOException e) {} | 
| 2243 |                                         } | 
| 2244 |                                 } | 
| 2245 |                                 if (contents != null) { | 
| 2246 |                                         LineNumberReader reader = new LineNumberReader(new StringReader(new String(contents))); | 
| 2247 |                                         String line = null; | 
| 2248 |                                         try { | 
| 2249 |                                                 while ((line = reader.readLine()) != null) { | 
| 2250 |                                                         if (line.startsWith("#") || line.length() == 0) { //$NON-NLS-1$ | 
| 2251 |                                                                 continue;  | 
| 2252 |                                                         } | 
| 2253 |                                                         if(line.startsWith(REGULAR_EXPRESSION_START)) { | 
| 2254 |                                                                 if(baseline != null) { | 
| 2255 |                                                                         Util.collectRegexIds(line, list, baseline.getApiComponents()); | 
| 2256 |                                                                 } | 
| 2257 |                                                         } | 
| 2258 |                                                         else { | 
| 2259 |                                                                 list.add(line); | 
| 2260 |                                                         } | 
| 2261 |                                                 } | 
| 2262 |                                         }  | 
| 2263 |                                         catch (IOException e) {}  | 
| 2264 |                                         catch (Exception e) {}  | 
| 2265 |                                         finally { | 
| 2266 |                                                 try { | 
| 2267 |                                                         reader.close(); | 
| 2268 |                                                 } catch (IOException e) {} | 
| 2269 |                                         } | 
| 2270 |                                 } | 
| 2271 |                         } | 
| 2272 |                 } | 
| 2273 |                 return list; | 
| 2274 |         } | 
| 2275 |   | 
| 2276 |         /** | 
| 2277 |          * Collects the set of component ids that match a given regex in the exclude file | 
| 2278 |          * @param line | 
| 2279 |          * @param list | 
| 2280 |          * @param components | 
| 2281 |          */ | 
| 2282 |         public static void collectRegexIds(String line, Set list, IApiComponent[] components) throws Exception { | 
| 2283 |                 if (line.startsWith(REGULAR_EXPRESSION_START)) { | 
| 2284 |                         String componentname = line; | 
| 2285 |                         // regular expression | 
| 2286 |                         componentname = componentname.substring(2); | 
| 2287 |                         Pattern pattern = null; | 
| 2288 |                         try { | 
| 2289 |                                 pattern = Pattern.compile(componentname); | 
| 2290 |                                 String componentid = null; | 
| 2291 |                                 for (int j = 0, max2 = components.length; j < max2; j++) { | 
| 2292 |                                         componentid = components[j].getId(); | 
| 2293 |                                         if (pattern.matcher(componentid).matches()) { | 
| 2294 |                                                 list.add(componentid); | 
| 2295 |                                         } | 
| 2296 |                                 } | 
| 2297 |                         } catch (PatternSyntaxException e) { | 
| 2298 |                                 throw new Exception(NLS.bind( | 
| 2299 |                                                 UtilMessages.comparison_invalidRegularExpression, | 
| 2300 |                                                 componentname)); | 
| 2301 |                         } | 
| 2302 |                 } | 
| 2303 |         } | 
| 2304 |   | 
| 2305 |         /** | 
| 2306 |          * Default comparator that orders {@link File}s by their name | 
| 2307 |          */ | 
| 2308 |         public static final Comparator filesorter = new Comparator(){ | 
| 2309 |                 public int compare(Object o1, Object o2) { | 
| 2310 |                         if(o1 instanceof File && o2 instanceof File) { | 
| 2311 |                                 return ((File)o1).getName().compareTo(((File)o2).getName()); | 
| 2312 |                         } | 
| 2313 |                         return 0; | 
| 2314 |                 } | 
| 2315 |         }; | 
| 2316 |   | 
| 2317 |         /** | 
| 2318 |          * Returns true if the given {@link IApiType} is API or not, where API is defined | 
| 2319 |          * as having API visibility in an API description and having either the public of protected  | 
| 2320 |          * Java flag set | 
| 2321 |          *  | 
| 2322 |          * @param visibility | 
| 2323 |          * @param typeDescriptor | 
| 2324 |          * @return true if the given type is API, false otherwise | 
| 2325 |          */ | 
| 2326 |         public static boolean isAPI(int visibility, IApiType typeDescriptor) { | 
| 2327 |                 int access = typeDescriptor.getModifiers(); | 
| 2328 |                 return VisibilityModifiers.isAPI(visibility) && (Flags.isPublic(access) || Flags.isProtected(access)); | 
| 2329 |         } | 
| 2330 | } |