| /******************************************************************************* |
| * Copyright (c) 2000, 2014 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Nina Rinskaya |
| * Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=172820. |
| *******************************************************************************/ |
| package org.eclipse.jdt.core.tests.util; |
| |
| import java.io.*; |
| import java.net.ServerSocket; |
| import java.util.*; |
| import java.util.zip.*; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.jdt.core.compiler.CategorizedProblem; |
| import org.eclipse.jdt.core.compiler.IProblem; |
| import org.eclipse.jdt.core.tests.compiler.regression.Requestor; |
| import org.eclipse.jdt.internal.compiler.CompilationResult; |
| import org.eclipse.jdt.internal.compiler.Compiler; |
| import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; |
| import org.eclipse.jdt.internal.compiler.IProblemFactory; |
| import org.eclipse.jdt.internal.compiler.batch.CompilationUnit; |
| import org.eclipse.jdt.internal.compiler.batch.FileSystem; |
| import org.eclipse.jdt.internal.compiler.env.INameEnvironment; |
| import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; |
| import org.eclipse.jdt.internal.compiler.problem.DefaultProblem; |
| import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; |
| import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; |
| @SuppressWarnings({ "unchecked", "rawtypes" }) |
| public class Util { |
| // Trace for delete operation |
| /* |
| * Maximum time wasted repeating delete operations while running JDT/Core tests. |
| */ |
| private static int DELETE_MAX_TIME = 0; |
| /** |
| * Trace deletion operations while running JDT/Core tests. |
| */ |
| public static boolean DELETE_DEBUG = false; |
| /** |
| * Maximum of time in ms to wait in deletion operation while running JDT/Core tests. |
| * Default is 10 seconds. This number cannot exceed 1 minute (ie. 60000). |
| * <br> |
| * To avoid too many loops while waiting, the ten first ones are done waiting |
| * 10ms before repeating, the ten loops after are done waiting 100ms and |
| * the other loops are done waiting 1s... |
| */ |
| public static int DELETE_MAX_WAIT = 10000; |
| |
| private static final boolean DEBUG = false; |
| /** |
| * Initially, output directory was located in System.getProperty("java.io.tmpdir")+"\comptest". |
| * To allow user to run several compiler tests at the same time, main output directory |
| * is now located in a sub-directory of "comptest" which name is "run."+<code>System.currentMilliseconds</code>. |
| * |
| * @see #DELAY_BEFORE_CLEAN_PREVIOUS |
| */ |
| private final static String OUTPUT_DIRECTORY; |
| /** |
| * Let user specify the delay in hours before output directories are removed from file system |
| * while starting a new test run. Default value is 2 hours. |
| * <p> |
| * Note that this value may be a float and so have time less than one hour. |
| * If value is 0 or negative, then all previous run directories will be removed... |
| * |
| * @see #OUTPUT_DIRECTORY |
| */ |
| private final static String DELAY_BEFORE_CLEAN_PREVIOUS = System.getProperty("delay"); |
| /* |
| * Static initializer to clean directories created while running previous test suites. |
| */ |
| static { |
| // Get delay for cleaning sub-directories |
| long millisecondsPerHour = 1000L * 3600L; |
| long delay = millisecondsPerHour * 2; // default is to keep previous run directories for 2 hours |
| try { |
| if (DELAY_BEFORE_CLEAN_PREVIOUS != null) { |
| float hours = Float.parseFloat(DELAY_BEFORE_CLEAN_PREVIOUS); |
| delay = (int) (millisecondsPerHour * hours); |
| } |
| } |
| catch (NumberFormatException nfe) { |
| // use default |
| } |
| |
| // Get output directory root from system properties |
| String container = System.getProperty("jdt.test.output_directory"); |
| if (container == null){ |
| container = System.getProperty("java.io.tmpdir"); |
| } |
| if (container == null) { |
| container = "."; // use current directory |
| } |
| |
| // Get file for root directory |
| if (Character.isLowerCase(container.charAt(0)) && container.charAt(1) == ':') { |
| container = Character.toUpperCase(container.charAt(0)) + container.substring(1); |
| } |
| File dir = new File(new File(container), "comptest"); |
| |
| // If root directory already exists, clean it |
| if (dir.exists()) { |
| long now = System.currentTimeMillis(); |
| if ((now - dir.lastModified()) > delay) { |
| // remove all directory content |
| flushDirectoryContent(dir); |
| } else { |
| // remove only old sub-dirs |
| File[] testDirs = dir.listFiles(); |
| for (int i=0,l=testDirs.length; i<l; i++) { |
| if (testDirs[i].isDirectory()) { |
| if ((now - testDirs[i].lastModified()) > delay) { |
| delete(testDirs[i]); |
| } |
| } |
| } |
| } |
| } |
| |
| // Computed test run directory name based on current time |
| File dateDir = new File(dir, "run."+System.currentTimeMillis()); |
| String pathDir = null; |
| try { |
| pathDir = dateDir.getCanonicalPath(); |
| } catch (IOException e) { |
| pathDir = dateDir.getAbsolutePath(); |
| } |
| OUTPUT_DIRECTORY = pathDir; |
| } |
| |
| public static void appendProblem(StringBuffer problems, IProblem problem, char[] source, int problemCount) { |
| problems.append(problemCount + (problem.isError() ? ". ERROR" : problem.isWarning() ? ". WARNING" : ". INFO")); |
| problems.append(" in " + new String(problem.getOriginatingFileName())); |
| if (source != null) { |
| problems.append(((DefaultProblem)problem).errorReportSource(source)); |
| } |
| problems.append("\n"); |
| problems.append(problem.getMessage()); |
| problems.append("\n"); |
| } |
| |
| public static CompilationUnit[] compilationUnits(String[] testFiles) { |
| int length = testFiles.length / 2; |
| CompilationUnit[] result = new CompilationUnit[length]; |
| int index = 0; |
| for (int i = 0; i < length; i++) { |
| result[i] = new CompilationUnit(testFiles[index + 1].toCharArray(), testFiles[index], null); |
| index += 2; |
| } |
| return result; |
| } |
| public static void compile(String[] pathsAndContents, Map options, String outputPath) { |
| compile(pathsAndContents, options, null, outputPath); |
| } |
| public static void compile(String[] pathsAndContents, Map options, String[] classpath, String outputPath) { |
| IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault()); |
| Requestor requestor = |
| new Requestor( |
| false, |
| null /*no custom requestor*/, |
| false, /* show category */ |
| false /* show warning token*/); |
| requestor.outputPath = outputPath.endsWith(File.separator) ? outputPath : outputPath + File.separator; |
| |
| String[] classLibs = getJavaClassLibs(); |
| if (classpath != null) { |
| int length = classpath.length; |
| int classLibsLength = classLibs.length; |
| System.arraycopy(classpath, 0, classpath = new String[length + classLibsLength], 0, length); |
| System.arraycopy(classLibs, 0, classpath, length, classLibsLength); |
| } else { |
| classpath = classLibs; |
| } |
| |
| INameEnvironment nameEnvironment = new FileSystem(classpath, new String[] {}, null); |
| IErrorHandlingPolicy errorHandlingPolicy = |
| new IErrorHandlingPolicy() { |
| public boolean proceedOnErrors() { |
| return true; |
| } |
| public boolean stopOnFirstError() { |
| return false; |
| } |
| public boolean ignoreAllErrors() { |
| return false; |
| } |
| }; |
| CompilerOptions compilerOptions = new CompilerOptions(options); |
| compilerOptions.performMethodsFullRecovery = false; |
| compilerOptions.performStatementsRecovery = false; |
| Compiler batchCompiler = |
| new Compiler( |
| nameEnvironment, |
| errorHandlingPolicy, |
| compilerOptions, |
| requestor, |
| problemFactory); |
| batchCompiler.options.produceReferenceInfo = true; |
| batchCompiler.compile(compilationUnits(pathsAndContents)); // compile all files together |
| // cleanup |
| nameEnvironment.cleanup(); |
| if (requestor.hasErrors) |
| System.err.print(requestor.problemLog); // problem log empty if no problems |
| } |
| public static String[] concatWithClassLibs(String[] classpaths, boolean inFront) { |
| String[] classLibs = getJavaClassLibs(); |
| if (classpaths == null) return classLibs; |
| final int classLibsLength = classLibs.length; |
| final int classpathsLength = classpaths.length; |
| String[] defaultClassPaths = new String[classLibsLength + classpathsLength]; |
| if (inFront) { |
| System.arraycopy(classLibs, 0, defaultClassPaths, classpathsLength, classLibsLength); |
| System.arraycopy(classpaths, 0, defaultClassPaths, 0, classpathsLength); |
| } else { |
| System.arraycopy(classLibs, 0, defaultClassPaths, 0, classLibsLength); |
| System.arraycopy(classpaths, 0, defaultClassPaths, classLibsLength, classpathsLength); |
| } |
| for (int i = 0; i < classpathsLength; i++) { |
| File file = new File(classpaths[i]); |
| if (!file.exists()) { |
| file.mkdirs(); |
| } |
| } |
| return defaultClassPaths; |
| } |
| public static String[] concatWithClassLibs(String classpath, boolean inFront) { |
| String[] classLibs = getJavaClassLibs(); |
| final int length = classLibs.length; |
| File dir = new File(classpath); |
| if (!dir.exists()) |
| dir.mkdirs(); |
| String[] defaultClassPaths = new String[length + 1]; |
| if (inFront) { |
| System.arraycopy(classLibs, 0, defaultClassPaths, 1, length); |
| defaultClassPaths[0] = classpath; |
| } else { |
| System.arraycopy(classLibs, 0, defaultClassPaths, 0, length); |
| defaultClassPaths[length] = classpath; |
| } |
| return defaultClassPaths; |
| } |
| public static String convertToIndependantLineDelimiter(String source) { |
| if (source == null) return ""; |
| if (source.indexOf('\n') == -1 && source.indexOf('\r') == -1) return source; |
| StringBuffer buffer = new StringBuffer(); |
| for (int i = 0, length = source.length(); i < length; i++) { |
| char car = source.charAt(i); |
| if (car == '\r') { |
| buffer.append('\n'); |
| if (i < length-1 && source.charAt(i+1) == '\n') { |
| i++; // skip \n after \r |
| } |
| } else { |
| buffer.append(car); |
| } |
| } |
| return buffer.toString(); |
| } |
| /** |
| * Copy the given source (a file or a directory that must exists) to the given destination (a directory that must exists). |
| */ |
| public static void copy(String sourcePath, String destPath) { |
| sourcePath = toNativePath(sourcePath); |
| destPath = toNativePath(destPath); |
| File source = new File(sourcePath); |
| if (!source.exists()) return; |
| File dest = new File(destPath); |
| if (!dest.exists()) return; |
| if (source.isDirectory()) { |
| String[] files = source.list(); |
| if (files != null) { |
| for (int i = 0; i < files.length; i++) { |
| String file = files[i]; |
| File sourceFile = new File(source, file); |
| if (sourceFile.isDirectory()) { |
| File destSubDir = new File(dest, file); |
| destSubDir.mkdir(); |
| copy(sourceFile.getPath(), destSubDir.getPath()); |
| } else { |
| copy(sourceFile.getPath(), dest.getPath()); |
| } |
| } |
| } |
| } else { |
| FileInputStream in = null; |
| FileOutputStream out = null; |
| try { |
| in = new FileInputStream(source); |
| File destFile = new File(dest, source.getName()); |
| if (destFile.exists()) { |
| if (!Util.delete(destFile)) { |
| throw new IOException(destFile + " is in use"); |
| } |
| } |
| out = new FileOutputStream(destFile); |
| int bufferLength = 1024; |
| byte[] buffer = new byte[bufferLength]; |
| int read = 0; |
| while (read != -1) { |
| read = in.read(buffer, 0, bufferLength); |
| if (read != -1) { |
| out.write(buffer, 0, read); |
| } |
| } |
| } catch (IOException e) { |
| throw new Error(e.toString()); |
| } finally { |
| if (in != null) { |
| try { |
| in.close(); |
| } catch (IOException e) { |
| } |
| } |
| if (out != null) { |
| try { |
| out.close(); |
| } catch (IOException e) { |
| } |
| } |
| } |
| } |
| } |
| public static void createFile(String path, String contents) throws IOException { |
| FileOutputStream output = new FileOutputStream(path); |
| try { |
| output.write(contents.getBytes()); |
| } finally { |
| output.close(); |
| } |
| } |
| public static void createClassFolder(String[] pathsAndContents, String folderPath, String compliance) throws IOException { |
| File classesDir = new File(folderPath); |
| flushDirectoryContent(classesDir); |
| compile(pathsAndContents, getCompileOptions(compliance), folderPath); |
| } |
| public static void createEmptyJar(String jarPath, String compliance) throws IOException { |
| org.eclipse.jdt.core.tests.util.Util.createJar( |
| null, |
| new String[] { |
| "META-INF/MANIFEST.MF", |
| "Manifest-Version: 1.0\n", |
| }, |
| jarPath, |
| null, |
| compliance); |
| } |
| public static void createJar(String[] pathsAndContents, Map options, String jarPath) throws IOException { |
| createJar(pathsAndContents, null, options, null, jarPath); |
| } |
| public static void createJar(String[] pathsAndContents, String[] extraPathsAndContents, Map options, String[] classpath, String jarPath) throws IOException { |
| String classesPath = getOutputDirectory() + File.separator + "classes"; |
| File classesDir = new File(classesPath); |
| flushDirectoryContent(classesDir); |
| if (pathsAndContents != null) { |
| compile(pathsAndContents, options, classpath, classesPath); |
| } |
| if (extraPathsAndContents != null) { |
| for (int i = 0, l = extraPathsAndContents == null ? 0 : extraPathsAndContents.length; i < l; /* inc in loop */) { |
| File outputFile = new File(classesPath, extraPathsAndContents[i++]); |
| outputFile.getParentFile().mkdirs(); |
| Util.writeToFile(extraPathsAndContents[i++], outputFile.getAbsolutePath()); |
| } |
| } |
| zip(classesDir, jarPath); |
| } |
| public static void createJar(String[] javaPathsAndContents, String jarPath, String compliance) throws IOException { |
| createJar(javaPathsAndContents, null, jarPath, compliance); |
| } |
| public static void createJar(String[] javaPathsAndContents, String[] extraPathsAndContents, String jarPath, String compliance) throws IOException { |
| createJar(javaPathsAndContents, extraPathsAndContents, jarPath, null/*no classpath*/, compliance); |
| } |
| public static void createJar(String[] javaPathsAndContents, String[] extraPathsAndContents, String jarPath, String[] classpath, String compliance) throws IOException { |
| createJar(javaPathsAndContents, extraPathsAndContents, getCompileOptions(compliance), classpath, jarPath); |
| } |
| public static void createJar(String[] javaPathsAndContents, String[] extraPathsAndContents, String jarPath, String[] classpath, String compliance, Map options) throws IOException { |
| Map compileOptions = getCompileOptions(compliance); |
| if (options != null) { |
| compileOptions.putAll(options); |
| } |
| createJar(javaPathsAndContents, extraPathsAndContents, compileOptions, classpath, jarPath); |
| } |
| public static void createSourceZip(String[] pathsAndContents, String zipPath) throws IOException { |
| String sourcesPath = getOutputDirectory() + File.separator + "sources"; |
| createSourceDir(pathsAndContents, sourcesPath); |
| zip(new File(sourcesPath), zipPath); |
| } |
| |
| public static void createSourceDir(String[] pathsAndContents, String sourcesPath) throws IOException { |
| flushDirectoryContent(new File(sourcesPath)); |
| for (int i = 0, length = pathsAndContents.length; i < length; i+=2) { |
| String sourcePath = sourcesPath + File.separator + pathsAndContents[i]; |
| File sourceFile = new File(sourcePath); |
| sourceFile.getParentFile().mkdirs(); |
| createFile(sourcePath, pathsAndContents[i+1]); |
| } |
| } |
| /** |
| * Delete a file or directory and insure that the file is no longer present |
| * on file system. In case of directory, delete all the hierarchy underneath. |
| * |
| * @param file The file or directory to delete |
| * @return true iff the file was really delete, false otherwise |
| */ |
| public static boolean delete(File file) { |
| // flush all directory content |
| if (file.isDirectory()) { |
| flushDirectoryContent(file); |
| } |
| // remove file |
| file.delete(); |
| if (isFileDeleted(file)) { |
| return true; |
| } |
| return waitUntilFileDeleted(file); |
| } |
| /** |
| * Delete a file or directory and insure that the file is no longer present |
| * on file system. In case of directory, delete all the hierarchy underneath. |
| * |
| * @param resource The resource to delete |
| * @return true iff the file was really delete, false otherwise |
| */ |
| public static IStatus delete(IResource resource) { |
| IStatus status = null; |
| try { |
| resource.delete(true, null); |
| if (isResourceDeleted(resource)) { |
| return Status.OK_STATUS; |
| } |
| } catch (CoreException e) { |
| status = e.getStatus(); |
| } |
| boolean deleted = waitUntilResourceDeleted(resource); |
| if (deleted) { |
| return Status.OK_STATUS; |
| } |
| if (status != null) { |
| return status; |
| } |
| return new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, "Cannot delete resource "+resource); |
| } |
| /** |
| * Delete a file or directory and insure that the file is no longer present |
| * on file system. In case of directory, delete all the hierarchy underneath. |
| * |
| * @param path The path of the file or directory to delete |
| * @return true iff the file was really delete, false otherwise |
| */ |
| public static boolean delete(String path) { |
| return delete(new File(path)); |
| } |
| /** |
| * Generate a display string from the given String. |
| * @param inputString the given input string |
| * |
| * Example of use: [org.eclipse.jdt.core.tests.util.Util.displayString("abc\ndef\tghi")] |
| */ |
| public static String displayString(String inputString){ |
| return displayString(inputString, 0); |
| } |
| /** |
| * Generate a display string from the given String. |
| * It converts: |
| * <ul> |
| * <li>\t to \t</li> |
| * <li>\r to \\r</li> |
| * <li>\n to \n</li> |
| * <li>\b to \\b</li> |
| * <li>\f to \\f</li> |
| * <li>\" to \\\"</li> |
| * <li>\' to \\'</li> |
| * <li>\\ to \\\\</li> |
| * <li>All other characters are unchanged.</li> |
| * </ul> |
| * This method doesn't convert \r\n to \n. |
| * <p> |
| * Example of use: |
| * <o> |
| * <li> |
| * <pre> |
| * input string = "abc\ndef\tghi", |
| * indent = 3 |
| * result = "\"\t\t\tabc\\n" + |
| * "\t\t\tdef\tghi\"" |
| * </pre> |
| * </li> |
| * <li> |
| * <pre> |
| * input string = "abc\ndef\tghi\n", |
| * indent = 3 |
| * result = "\"\t\t\tabc\\n" + |
| * "\t\t\tdef\tghi\\n\"" |
| * </pre> |
| * </li> |
| * <li> |
| * <pre> |
| * input string = "abc\r\ndef\tghi\r\n", |
| * indent = 3 |
| * result = "\"\t\t\tabc\\r\\n" + |
| * "\t\t\tdef\tghi\\r\\n\"" |
| * </pre> |
| * </li> |
| * </ol> |
| * </p> |
| * |
| * @param inputString the given input string |
| * @param indent number of tabs are added at the begining of each line. |
| * |
| * @return the displayed string |
| */ |
| public static String displayString(String inputString, int indent) { |
| return displayString(inputString, indent, false); |
| } |
| public static String displayString(String inputString, int indent, boolean shift) { |
| if (inputString == null) |
| return "null"; |
| int length = inputString.length(); |
| StringBuffer buffer = new StringBuffer(length); |
| java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(inputString, "\n\r", true); |
| for (int i = 0; i < indent; i++) buffer.append("\t"); |
| if (shift) indent++; |
| buffer.append("\""); |
| while (tokenizer.hasMoreTokens()){ |
| |
| String token = tokenizer.nextToken(); |
| if (token.equals("\r")) { |
| buffer.append("\\r"); |
| if (tokenizer.hasMoreTokens()) { |
| token = tokenizer.nextToken(); |
| if (token.equals("\n")) { |
| buffer.append("\\n"); |
| if (tokenizer.hasMoreTokens()) { |
| buffer.append("\" + \n"); |
| for (int i = 0; i < indent; i++) buffer.append("\t"); |
| buffer.append("\""); |
| } |
| continue; |
| } |
| buffer.append("\" + \n"); |
| for (int i = 0; i < indent; i++) buffer.append("\t"); |
| buffer.append("\""); |
| } else { |
| continue; |
| } |
| } else if (token.equals("\n")) { |
| buffer.append("\\n"); |
| if (tokenizer.hasMoreTokens()) { |
| buffer.append("\" + \n"); |
| for (int i = 0; i < indent; i++) buffer.append("\t"); |
| buffer.append("\""); |
| } |
| continue; |
| } |
| |
| StringBuffer tokenBuffer = new StringBuffer(); |
| for (int i = 0; i < token.length(); i++){ |
| char c = token.charAt(i); |
| switch (c) { |
| case '\r' : |
| tokenBuffer.append("\\r"); |
| break; |
| case '\n' : |
| tokenBuffer.append("\\n"); |
| break; |
| case '\b' : |
| tokenBuffer.append("\\b"); |
| break; |
| case '\t' : |
| tokenBuffer.append("\t"); |
| break; |
| case '\f' : |
| tokenBuffer.append("\\f"); |
| break; |
| case '\"' : |
| tokenBuffer.append("\\\""); |
| break; |
| case '\'' : |
| tokenBuffer.append("\\'"); |
| break; |
| case '\\' : |
| tokenBuffer.append("\\\\"); |
| break; |
| default : |
| tokenBuffer.append(c); |
| } |
| } |
| buffer.append(tokenBuffer.toString()); |
| } |
| buffer.append("\""); |
| return buffer.toString(); |
| } |
| /** |
| * Reads the content of the given source file. |
| * Returns null if enable to read given source file. |
| * |
| * Example of use: [org.eclipse.jdt.core.tests.util.Util.fileContent("c:/temp/X.java")] |
| */ |
| public static String fileContent(String sourceFilePath) { |
| File sourceFile = new File(sourceFilePath); |
| if (!sourceFile.exists()) { |
| if (DEBUG) System.out.println("File " + sourceFilePath + " does not exists."); |
| return null; |
| } |
| if (!sourceFile.isFile()) { |
| if (DEBUG) System.out.println(sourceFilePath + " is not a file."); |
| return null; |
| } |
| StringBuffer sourceContentBuffer = new StringBuffer(); |
| FileInputStream input = null; |
| try { |
| input = new FileInputStream(sourceFile); |
| } catch (FileNotFoundException e) { |
| return null; |
| } |
| try { |
| int read; |
| do { |
| read = input.read(); |
| if (read != -1) { |
| sourceContentBuffer.append((char)read); |
| } |
| } while (read != -1); |
| input.close(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| return null; |
| } finally { |
| try { |
| input.close(); |
| } catch (IOException e2) { |
| } |
| } |
| return sourceContentBuffer.toString(); |
| } |
| |
| /** |
| * Reads the content of the given source file and converts it to a display string. |
| * |
| * Example of use: [org.eclipse.jdt.core.tests.util.Util.fileContentToDisplayString("c:/temp/X.java", 0)] |
| */ |
| public static String fileContentToDisplayString(String sourceFilePath, int indent, boolean independantLineDelimiter) { |
| String sourceString = fileContent(sourceFilePath); |
| if (independantLineDelimiter) { |
| sourceString = convertToIndependantLineDelimiter(sourceString); |
| } |
| return displayString(sourceString, indent); |
| } |
| /** |
| * Reads the content of the given source file, converts it to a display string. |
| * If the destination file path is not null, writes the result to this file. |
| * Otherwise writes it to the console. |
| * |
| * Example of use: [org.eclipse.jdt.core.tests.util.Util.fileContentToDisplayString("c:/temp/X.java", 0, null)] |
| */ |
| public static void fileContentToDisplayString(String sourceFilePath, int indent, String destinationFilePath, boolean independantLineDelimiter) { |
| String displayString = fileContentToDisplayString(sourceFilePath, indent, independantLineDelimiter); |
| if (destinationFilePath == null) { |
| System.out.println(displayString); |
| return; |
| } |
| writeToFile(displayString, destinationFilePath); |
| } |
| /** |
| * Flush content of a given directory (leaving it empty), |
| * no-op if not a directory. |
| */ |
| public static void flushDirectoryContent(File dir) { |
| File[] files = dir.listFiles(); |
| if (files == null) return; |
| for (int i = 0, max = files.length; i < max; i++) { |
| delete(files[i]); |
| } |
| } |
| private static Map getCompileOptions(String compliance) { |
| Map options = new HashMap(); |
| options.put(CompilerOptions.OPTION_Compliance, compliance); |
| options.put(CompilerOptions.OPTION_Source, compliance); |
| options.put(CompilerOptions.OPTION_TargetPlatform, compliance); |
| // Ignore options with new defaults (since bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=76530) |
| options.put(CompilerOptions.OPTION_ReportUnusedLocal, CompilerOptions.IGNORE); |
| options.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, CompilerOptions.IGNORE); |
| options.put(CompilerOptions.OPTION_ReportFieldHiding, CompilerOptions.IGNORE); |
| options.put(CompilerOptions.OPTION_ReportLocalVariableHiding, CompilerOptions.IGNORE); |
| options.put(CompilerOptions.OPTION_ReportTypeParameterHiding, CompilerOptions.IGNORE); |
| options.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); |
| options.put(CompilerOptions.OPTION_ReportRawTypeReference, CompilerOptions.IGNORE); |
| return options; |
| } |
| /** |
| * Returns the next available port number on the local host. |
| */ |
| public static int getFreePort() { |
| ServerSocket socket = null; |
| try { |
| socket = new ServerSocket(0); |
| return socket.getLocalPort(); |
| } catch (IOException e) { |
| // ignore |
| } finally { |
| if (socket != null) { |
| try { |
| socket.close(); |
| } catch (IOException e) { |
| // ignore |
| } |
| } |
| } |
| return -1; |
| } |
| /** |
| * Search the user hard-drive for a Java class library. |
| * Returns null if none could be found. |
| */ |
| public static String[] getJavaClassLibs() { |
| // check bootclasspath properties for Sun, JRockit and Harmony VMs |
| String bootclasspathProperty = System.getProperty("sun.boot.class.path"); //$NON-NLS-1$ |
| if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) { |
| // IBM J9 VMs |
| bootclasspathProperty = System.getProperty("vm.boot.class.path"); //$NON-NLS-1$ |
| if ((bootclasspathProperty == null) || (bootclasspathProperty.length() == 0)) { |
| // Harmony using IBM VME |
| bootclasspathProperty = System.getProperty("org.apache.harmony.boot.class.path"); //$NON-NLS-1$ |
| } |
| } |
| String[] jars = null; |
| if ((bootclasspathProperty != null) && (bootclasspathProperty.length() != 0)) { |
| StringTokenizer tokenizer = new StringTokenizer(bootclasspathProperty, File.pathSeparator); |
| final int size = tokenizer.countTokens(); |
| jars = new String[size]; |
| int i = 0; |
| while (tokenizer.hasMoreTokens()) { |
| final String fileName = toNativePath(tokenizer.nextToken()); |
| if (new File(fileName).exists()) { |
| jars[i] = fileName; |
| i++; |
| } |
| } |
| if (size != i) { |
| // resize |
| System.arraycopy(jars, 0, (jars = new String[i]), 0, i); |
| } |
| } else { |
| String jreDir = getJREDirectory(); |
| final String osName = System.getProperty("os.name"); |
| if (jreDir == null) { |
| return new String[] {}; |
| } |
| if (osName.startsWith("Mac")) { |
| return new String[] { |
| toNativePath(jreDir + "/../Classes/classes.jar") |
| }; |
| } |
| final String vmName = System.getProperty("java.vm.name"); |
| if ("J9".equals(vmName)) { |
| return new String[] { |
| toNativePath(jreDir + "/lib/jclMax/classes.zip") |
| }; |
| } |
| String[] jarsNames = null; |
| ArrayList paths = new ArrayList(); |
| if ("DRLVM".equals(vmName)) { |
| FilenameFilter jarFilter = new FilenameFilter() { |
| public boolean accept(File dir, String name) { |
| return name.endsWith(".jar") & !name.endsWith("-src.jar"); |
| } |
| }; |
| jarsNames = new File(jreDir + "/lib/boot/").list(jarFilter); |
| addJarEntries(jreDir + "/lib/boot/", jarsNames, paths); |
| } else { |
| jarsNames = new String[] { |
| "/lib/vm.jar", |
| "/lib/rt.jar", |
| "/lib/core.jar", |
| "/lib/security.jar", |
| "/lib/xml.jar", |
| "/lib/graphics.jar" |
| }; |
| addJarEntries(jreDir, jarsNames, paths); |
| } |
| jars = new String[paths.size()]; |
| paths.toArray(jars); |
| } |
| return jars; |
| } |
| private static void addJarEntries(String jreDir, String[] jarNames, ArrayList paths) { |
| for (int i = 0, max = jarNames.length; i < max; i++) { |
| final String currentName = jreDir + jarNames[i]; |
| File f = new File(currentName); |
| if (f.exists()) { |
| paths.add(toNativePath(currentName)); |
| } |
| } |
| } |
| public static String getJavaClassLibsAsString() { |
| String[] classLibs = getJavaClassLibs(); |
| StringBuffer buffer = new StringBuffer(); |
| for (int i = 0, max = classLibs.length; i < max; i++) { |
| buffer |
| .append(classLibs[i]) |
| .append(File.pathSeparatorChar); |
| } |
| return buffer.toString(); |
| } |
| /** |
| * Returns the JRE directory this tests are running on. |
| * Returns null if none could be found. |
| * |
| * Example of use: [org.eclipse.jdt.core.tests.util.Util.getJREDirectory()] |
| */ |
| public static String getJREDirectory() { |
| return System.getProperty("java.home"); |
| } |
| /** |
| * Search the user hard-drive for a possible output directory. |
| * Returns null if none could be found. |
| * |
| * Example of use: [org.eclipse.jdt.core.tests.util.Util.getOutputDirectory()] |
| */ |
| public static String getOutputDirectory() { |
| return OUTPUT_DIRECTORY; |
| } |
| /** |
| * Returns the parent's child file matching the given file or null if not found. |
| * |
| * @param file The searched file in parent |
| * @return The parent's child matching the given file or null if not found. |
| */ |
| private static File getParentChildFile(File file) { |
| File parent = file.getParentFile(); |
| if (parent == null || !parent.exists()) return null; |
| File[] files = parent.listFiles(); |
| int length = files==null ? 0 : files.length; |
| if (length > 0) { |
| for (int i=0; i<length; i++) { |
| if (files[i] == file) { |
| return files[i]; |
| } else if (files[i].equals(file)) { |
| return files[i]; |
| } else if (files[i].getPath().equals(file.getPath())) { |
| return files[i]; |
| } |
| } |
| } |
| return null; |
| } |
| /** |
| * Returns parent's child resource matching the given resource or null if not found. |
| * |
| * @param resource The searched file in parent |
| * @return The parent's child matching the given file or null if not found. |
| */ |
| private static IResource getParentChildResource(IResource resource) { |
| IContainer parent = resource.getParent(); |
| if (parent == null || !parent.exists()) return null; |
| try { |
| IResource[] members = parent.members(); |
| int length = members ==null ? 0 : members.length; |
| if (length > 0) { |
| for (int i=0; i<length; i++) { |
| if (members[i] == resource) { |
| return members[i]; |
| } else if (members[i].equals(resource)) { |
| return members[i]; |
| } else if (members[i].getFullPath().equals(resource.getFullPath())) { |
| return members[i]; |
| } |
| } |
| } |
| } |
| catch (CoreException ce) { |
| // skip |
| } |
| return null; |
| } |
| /** |
| * Returns the test name from stack elements info. |
| * |
| * @return The name of the test currently running |
| */ |
| private static String getTestName() { |
| StackTraceElement[] elements = new Exception().getStackTrace(); |
| int idx = 0, length=elements.length; |
| while (idx<length && !elements[idx++].getClassName().startsWith("org.eclipse.jdt")) { |
| // loop until JDT/Core class appears in the stack |
| } |
| if (idx<length) { |
| StackTraceElement testElement = null; |
| while (idx<length && elements[idx].getClassName().startsWith("org.eclipse.jdt")) { |
| testElement = elements[idx++]; |
| } |
| if (testElement != null) { |
| return testElement.getClassName() + " - " + testElement.getMethodName(); |
| } |
| } |
| return "?"; |
| } |
| public static String indentString(String inputString, int indent) { |
| if (inputString == null) |
| return ""; |
| int length = inputString.length(); |
| StringBuffer buffer = new StringBuffer(length); |
| java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(inputString, "\n\r", true); |
| StringBuffer indentStr = new StringBuffer(indent); |
| for (int i = 0; i < indent; i++) indentStr.append("\t"); |
| buffer.append(indentStr); |
| while (tokenizer.hasMoreTokens()){ |
| String token = tokenizer.nextToken(); |
| buffer.append(token); |
| if (token.equals("\r") || token.equals("\n")) { |
| buffer.append(indentStr); |
| } |
| } |
| return buffer.toString(); |
| } |
| /** |
| * Returns whether a file is really deleted or not. |
| * Does not only rely on {@link File#exists()} method but also |
| * look if it's not in its parent children {@link #getParentChildFile(File)}. |
| * |
| * @param file The file to test if deleted |
| * @return true if the file does not exist and was not found in its parent children. |
| */ |
| public static boolean isFileDeleted(File file) { |
| return !file.exists() && getParentChildFile(file) == null; |
| } |
| public static boolean isMacOS() { |
| return System.getProperty("os.name").indexOf("Mac") != -1; |
| } |
| /** |
| * Returns whether a resource is really deleted or not. |
| * Does not only rely on {@link IResource#isAccessible()} method but also |
| * look if it's not in its parent children {@link #getParentChildResource(IResource)}. |
| * |
| * @param resource The resource to test if deleted |
| * @return true if the resource is not accessible and was not found in its parent children. |
| */ |
| public static boolean isResourceDeleted(IResource resource) { |
| return !resource.isAccessible() && getParentChildResource(resource) == null; |
| } |
| /** |
| * Print given file information with specified indentation. |
| * These information are:<ul> |
| * <li>read {@link File#canRead()}</li> |
| * <li>write {@link File#canWrite()}</li> |
| * <li>exists {@link File#exists()}</li> |
| * <li>is file {@link File#isFile()}</li> |
| * <li>is directory {@link File#isDirectory()}</li> |
| * <li>is hidden {@link File#isHidden()}</li> |
| * </ul> |
| * May recurse several level in parents hierarchy. |
| * May also display children, but then will not recusre in parent |
| * hierarchy to avoid infinite loop... |
| * |
| * @param file The file to display information |
| * @param indent Number of tab to print before the information |
| * @param recurse Display also information on <code>recurse</code>th parents in hierarchy. |
| * If negative then display children information instead. |
| */ |
| private static void printFileInfo(File file, int indent, int recurse) { |
| String tab = ""; |
| for (int i=0; i<indent; i++) tab+="\t"; |
| System.out.print(tab+"- "+file.getName()+" file info: "); |
| String sep = ""; |
| if (file.canRead()) { |
| System.out.print("read"); |
| sep = ", "; |
| } |
| if (file.canWrite()) { |
| System.out.print(sep+"write"); |
| sep = ", "; |
| } |
| if (file.exists()) { |
| System.out.print(sep+"exist"); |
| sep = ", "; |
| } |
| if (file.isDirectory()) { |
| System.out.print(sep+"dir"); |
| sep = ", "; |
| } |
| if (file.isFile()) { |
| System.out.print(sep+"file"); |
| sep = ", "; |
| } |
| if (file.isHidden()) { |
| System.out.print(sep+"hidden"); |
| sep = ", "; |
| } |
| System.out.println(); |
| File[] files = file.listFiles(); |
| int length = files==null ? 0 : files.length; |
| if (length > 0) { |
| boolean children = recurse < 0; |
| System.out.print(tab+" + children: "); |
| if (children) System.out.println(); |
| for (int i=0; i<length; i++) { |
| if (children) { // display children |
| printFileInfo(files[i], indent+2, -1); |
| } else { |
| if (i>0) System.out.print(", "); |
| System.out.print(files[i].getName()); |
| if (files[i].isDirectory()) System.out.print("[dir]"); |
| else if (files[i].isFile()) System.out.print("[file]"); |
| else System.out.print("[?]"); |
| } |
| } |
| if (!children) System.out.println(); |
| } |
| if (recurse > 0) { |
| File parent = file.getParentFile(); |
| if (parent != null) printFileInfo(parent, indent+1, recurse-1); |
| } |
| } |
| /** |
| * Print stack trace with only JDT/Core elements. |
| * |
| * @param exception Exception of the stack trace. May be null, then a fake exception is used. |
| * @param indent Number of tab to display before the stack elements to display. |
| */ |
| private static void printJdtCoreStackTrace(Exception exception, int indent) { |
| String tab = ""; |
| for (int i=0; i<indent; i++) tab+="\t"; |
| StackTraceElement[] elements = (exception==null?new Exception():exception).getStackTrace(); |
| int idx = 0, length=elements.length; |
| while (idx<length && !elements[idx++].getClassName().startsWith("org.eclipse.jdt")) { |
| // loop until JDT/Core class appears in the stack |
| } |
| if (idx<length) { |
| System.out.print(tab+"- stack trace"); |
| if (exception == null) |
| System.out.println(":"); |
| else |
| System.out.println(" for exception "+exception+":"); |
| while (idx<length && elements[idx].getClassName().startsWith("org.eclipse.jdt")) { |
| StackTraceElement testElement = elements[idx++]; |
| System.out.println(tab+" -> "+testElement); |
| } |
| } else { |
| exception.printStackTrace(System.out); |
| } |
| } |
| /** |
| * Makes the given path a path using native path separators as returned by File.getPath() |
| * and trimming any extra slash. |
| */ |
| public static String toNativePath(String path) { |
| String nativePath = path.replace('\\', File.separatorChar).replace('/', File.separatorChar); |
| return |
| nativePath.endsWith("/") || nativePath.endsWith("\\") ? |
| nativePath.substring(0, nativePath.length() - 1) : |
| nativePath; |
| } |
| public static String toString(String[] strings, boolean addExtraNewLine) { |
| if (strings == null) return "null"; |
| StringBuffer buffer = new StringBuffer(); |
| for (int i = 0, length = strings.length; i < length; i++){ |
| buffer.append(strings[i]); |
| if (addExtraNewLine || i < length - 1) |
| buffer.append("\n"); |
| } |
| return buffer.toString(); |
| } |
| /** |
| * Unzip the contents of the given zip in the given directory (create it if it doesn't exist) |
| */ |
| public static void unzip(String zipPath, String destDirPath) throws IOException { |
| |
| InputStream zipIn = new FileInputStream(zipPath); |
| byte[] buf = new byte[8192]; |
| File destDir = new File(destDirPath); |
| ZipInputStream zis = new ZipInputStream(zipIn); |
| FileOutputStream fos = null; |
| try { |
| ZipEntry zEntry; |
| while ((zEntry = zis.getNextEntry()) != null) { |
| // if it is empty directory, create it |
| if (zEntry.isDirectory()) { |
| new File(destDir, zEntry.getName()).mkdirs(); |
| continue; |
| } |
| // if it is a file, extract it |
| String filePath = zEntry.getName(); |
| int lastSeparator = filePath.lastIndexOf("/"); //$NON-NLS-1$ |
| String fileDir = ""; //$NON-NLS-1$ |
| if (lastSeparator >= 0) { |
| fileDir = filePath.substring(0, lastSeparator); |
| } |
| //create directory for a file |
| new File(destDir, fileDir).mkdirs(); |
| //write file |
| File outFile = new File(destDir, filePath); |
| fos = new FileOutputStream(outFile); |
| int n = 0; |
| while ((n = zis.read(buf)) >= 0) { |
| fos.write(buf, 0, n); |
| } |
| fos.close(); |
| } |
| } catch (IOException ioe) { |
| if (fos != null) { |
| try { |
| fos.close(); |
| } catch (IOException ioe2) { |
| } |
| } |
| } finally { |
| try { |
| zipIn.close(); |
| if (zis != null) |
| zis.close(); |
| } catch (IOException ioe) { |
| } |
| } |
| } |
| public static void waitAtLeast(int time) { |
| long start = System.currentTimeMillis(); |
| do { |
| try { |
| Thread.sleep(time); |
| } catch (InterruptedException e) { |
| } |
| } while ((System.currentTimeMillis() - start) < time); |
| } |
| |
| /** |
| * Wait until the file is _really_ deleted on file system. |
| * |
| * @param file Deleted file |
| * @return true if the file was finally deleted, false otherwise |
| */ |
| private static boolean waitUntilFileDeleted(File file) { |
| if (DELETE_DEBUG) { |
| System.out.println(); |
| System.out.println("WARNING in test: "+getTestName()); |
| System.out.println(" - problems occured while deleting "+file); |
| printJdtCoreStackTrace(null, 1); |
| printFileInfo(file.getParentFile(), 1, -1); // display parent with its children |
| System.out.print(" - wait for ("+DELETE_MAX_WAIT+"ms max): "); |
| } |
| int count = 0; |
| int delay = 10; // ms |
| int maxRetry = DELETE_MAX_WAIT / delay; |
| int time = 0; |
| while (count < maxRetry) { |
| try { |
| count++; |
| Thread.sleep(delay); |
| time += delay; |
| if (time > DELETE_MAX_TIME) DELETE_MAX_TIME = time; |
| if (DELETE_DEBUG) System.out.print('.'); |
| if (file.exists()) { |
| if (file.delete()) { |
| // SUCCESS |
| if (DELETE_DEBUG) { |
| System.out.println(); |
| System.out.println(" => file really removed after "+time+"ms (max="+DELETE_MAX_TIME+"ms)"); |
| System.out.println(); |
| } |
| return true; |
| } |
| } |
| if (isFileDeleted(file)) { |
| // SUCCESS |
| if (DELETE_DEBUG) { |
| System.out.println(); |
| System.out.println(" => file disappeared after "+time+"ms (max="+DELETE_MAX_TIME+"ms)"); |
| System.out.println(); |
| } |
| return true; |
| } |
| // Increment waiting delay exponentially |
| if (count >= 10 && delay <= 100) { |
| count = 1; |
| delay *= 10; |
| maxRetry = DELETE_MAX_WAIT / delay; |
| if ((DELETE_MAX_WAIT%delay) != 0) { |
| maxRetry++; |
| } |
| } |
| } |
| catch (InterruptedException ie) { |
| break; // end loop |
| } |
| } |
| if (!DELETE_DEBUG) { |
| System.out.println(); |
| System.out.println("WARNING in test: "+getTestName()); |
| System.out.println(" - problems occured while deleting "+file); |
| printJdtCoreStackTrace(null, 1); |
| printFileInfo(file.getParentFile(), 1, -1); // display parent with its children |
| } |
| System.out.println(); |
| System.out.println(" !!! ERROR: "+file+" was never deleted even after having waited "+DELETE_MAX_TIME+"ms!!!"); |
| System.out.println(); |
| return false; |
| } |
| /** |
| * Wait until a resource is _really_ deleted on file system. |
| * |
| * @param resource Deleted resource |
| * @return true if the file was finally deleted, false otherwise |
| */ |
| public static boolean waitUntilResourceDeleted(IResource resource) { |
| IPath location = resource.getLocation(); |
| if (location == null) { |
| System.out.println(); |
| System.out.println(" !!! ERROR: "+resource+" getLocation() returned null!!!"); |
| System.out.println(); |
| return false; |
| } |
| File file = location.toFile(); |
| if (DELETE_DEBUG) { |
| System.out.println(); |
| System.out.println("WARNING in test: "+getTestName()); |
| System.out.println(" - problems occured while deleting resource "+resource); |
| printJdtCoreStackTrace(null, 1); |
| printFileInfo(file.getParentFile(), 1, -1); // display parent with its children |
| System.out.print(" - wait for ("+DELETE_MAX_WAIT+"ms max): "); |
| } |
| int count = 0; |
| int delay = 10; // ms |
| int maxRetry = DELETE_MAX_WAIT / delay; |
| int time = 0; |
| while (count < maxRetry) { |
| try { |
| count++; |
| Thread.sleep(delay); |
| time += delay; |
| if (time > DELETE_MAX_TIME) DELETE_MAX_TIME = time; |
| if (DELETE_DEBUG) System.out.print('.'); |
| if (resource.isAccessible()) { |
| try { |
| resource.delete(true, null); |
| if (isResourceDeleted(resource) && isFileDeleted(file)) { |
| // SUCCESS |
| if (DELETE_DEBUG) { |
| System.out.println(); |
| System.out.println(" => resource really removed after "+time+"ms (max="+DELETE_MAX_TIME+"ms)"); |
| System.out.println(); |
| } |
| return true; |
| } |
| } |
| catch (CoreException e) { |
| // skip |
| } |
| } |
| if (isResourceDeleted(resource) && isFileDeleted(file)) { |
| // SUCCESS |
| if (DELETE_DEBUG) { |
| System.out.println(); |
| System.out.println(" => resource disappeared after "+time+"ms (max="+DELETE_MAX_TIME+"ms)"); |
| System.out.println(); |
| } |
| return true; |
| } |
| // Increment waiting delay exponentially |
| if (count >= 10 && delay <= 100) { |
| count = 1; |
| delay *= 10; |
| maxRetry = DELETE_MAX_WAIT / delay; |
| if ((DELETE_MAX_WAIT%delay) != 0) { |
| maxRetry++; |
| } |
| } |
| } |
| catch (InterruptedException ie) { |
| break; // end loop |
| } |
| } |
| if (!DELETE_DEBUG) { |
| System.out.println(); |
| System.out.println("WARNING in test: "+getTestName()); |
| System.out.println(" - problems occured while deleting resource "+resource); |
| printJdtCoreStackTrace(null, 1); |
| printFileInfo(file.getParentFile(), 1, -1); // display parent with its children |
| } |
| System.out.println(); |
| System.out.println(" !!! ERROR: "+resource+" was never deleted even after having waited "+DELETE_MAX_TIME+"ms!!!"); |
| System.out.println(); |
| return false; |
| } |
| public static void writeToFile(String contents, String destinationFilePath) { |
| File destFile = new File(destinationFilePath); |
| FileOutputStream output = null; |
| PrintWriter writer = null; |
| try { |
| output = new FileOutputStream(destFile); |
| writer = new PrintWriter(output); |
| writer.print(contents); |
| writer.flush(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| return; |
| } finally { |
| if (writer != null) { |
| writer.close(); |
| } |
| } |
| } |
| public static void zip(File rootDir, String zipPath) throws IOException { |
| ZipOutputStream zip = null; |
| try { |
| File zipFile = new File(zipPath); |
| if (zipFile.exists()) { |
| if (!delete(zipFile)) |
| throw new IOException("Could not delete " + zipPath); |
| // ensure the new zip file has a different timestamp than the previous one |
| int timeToWait = 1000; // some platform (like Linux) have a 1s granularity) |
| waitAtLeast(timeToWait); |
| } else { |
| zipFile.getParentFile().mkdirs(); |
| } |
| zip = new ZipOutputStream(new FileOutputStream(zipFile)); |
| zip(rootDir, zip, rootDir.getPath().length()+1); // 1 for last slash |
| } finally { |
| if (zip != null) { |
| zip.close(); |
| } |
| } |
| } |
| private static void zip(File dir, ZipOutputStream zip, int rootPathLength) throws IOException { |
| File[] files = dir.listFiles(); |
| if (files != null) { |
| for (int i = 0, length = files.length; i < length; i++) { |
| File file = files[i]; |
| if (file.isFile()) { |
| String path = file.getPath(); |
| path = path.substring(rootPathLength); |
| ZipEntry entry = new ZipEntry(path.replace('\\', '/')); |
| zip.putNextEntry(entry); |
| zip.write(org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(file)); |
| zip.closeEntry(); |
| } else { |
| zip(file, zip, rootPathLength); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Zips the given files into the given jar. All the files are kept at the root of the zip. |
| */ |
| public static void zipFiles(File[] files, String zipPath) throws IOException { |
| File zipFile = new File(zipPath); |
| if (zipFile.exists()) { |
| if (!delete(zipFile)) |
| throw new IOException("Could not delete " + zipPath); |
| // ensure the new zip file has a different timestamp than the previous one |
| int timeToWait = 1000; // some platform (like Linux) have a 1s granularity) |
| waitAtLeast(timeToWait); |
| } else { |
| zipFile.getParentFile().mkdirs(); |
| } |
| ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(zipFile)); |
| try { |
| for (int i = 0, length = files.length; i < length; i++) { |
| File file = files[i]; |
| ZipEntry entry = new ZipEntry(file.getName()); |
| zip.putNextEntry(entry); |
| zip.write(org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(file)); |
| zip.closeEntry(); |
| } |
| } finally { |
| zip.close(); |
| } |
| } |
| /** |
| * Returns the compilation errors / warnings for the given CompilationResult. |
| * |
| * @param compilationResult the compilation result |
| * @param showCategory |
| * @param showWarningToken |
| * @return String the problem log |
| */ |
| public static String getProblemLog(CompilationResult compilationResult, boolean showCategory, boolean showWarningToken) { |
| StringBuffer buffer = new StringBuffer(100); |
| if (compilationResult.hasProblems() || compilationResult.hasTasks()) { |
| CategorizedProblem[] problems = compilationResult.getAllProblems(); |
| int count = problems.length; |
| int problemCount = 0; |
| char[] unitSource = compilationResult.compilationUnit.getContents(); |
| for (int i = 0; i < count; i++) { |
| DefaultProblem problem = (DefaultProblem) problems[i]; |
| if (problem != null) { |
| if (problemCount == 0) |
| buffer.append("----------\n"); |
| problemCount++; |
| buffer.append(problemCount + (problem.isError() ? ". ERROR" : problem.isWarning() ? ". WARNING" : ". INFO")); |
| buffer.append(" in " + new String(problem.getOriginatingFileName()).replace('/', '\\')); |
| try { |
| buffer.append(problem.errorReportSource(unitSource)); |
| buffer.append("\n"); |
| if (showCategory) { |
| String category = problem.getInternalCategoryMessage(); |
| if (category != null) { |
| buffer.append("[@cat:").append(category).append("] "); |
| } |
| } |
| if (showWarningToken) { |
| int irritant = ProblemReporter.getIrritant(problem.getID()); |
| if (irritant != 0) { |
| String warningToken = CompilerOptions.warningTokenFromIrritant(irritant); |
| if (warningToken != null) { |
| buffer.append("[@sup:").append(warningToken).append("] "); |
| } |
| } |
| } |
| buffer.append(problem.getMessage()); |
| buffer.append("\n"); |
| } catch (Exception e) { |
| } |
| buffer.append("----------\n"); |
| } |
| } |
| } |
| return buffer.toString(); |
| } |
| public static long getMajorMinorVMVersion() { |
| String classFileVersion = System.getProperty("java.class.version"); //$NON-NLS-1$ |
| if (classFileVersion != null) { |
| String[] versionParts = classFileVersion.split("\\."); //$NON-NLS-1$ |
| if (versionParts.length >= 2) { |
| int majorVersion = -1; |
| try { |
| majorVersion = Integer.parseInt(versionParts[0]); |
| } catch (NumberFormatException e) { |
| // ignore |
| } |
| int minorVersion = -1; |
| try { |
| minorVersion = Integer.parseInt(versionParts[1]); |
| } catch (NumberFormatException e) { |
| // ignore |
| } |
| if (minorVersion != -1 && majorVersion != -1) { |
| return ((long) majorVersion << 16) + minorVersion; |
| } |
| } |
| } |
| return -1; |
| } |
| } |