1 /*******************************************************************************
2  * Copyright (c) 2000, 2015 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.core.tests.model;
15 
16 import java.io.File;
17 import java.io.FileFilter;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.List;
24 import java.util.StringTokenizer;
25 
26 import org.eclipse.core.resources.IResource;
27 import org.eclipse.core.resources.IWorkspace;
28 import org.eclipse.core.resources.IWorkspaceRoot;
29 import org.eclipse.core.resources.ResourcesPlugin;
30 import org.eclipse.core.runtime.FileLocator;
31 import org.eclipse.core.runtime.IPath;
32 import org.eclipse.core.runtime.Path;
33 import org.eclipse.core.runtime.Platform;
34 import org.eclipse.jdt.core.*;
35 import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
36 
37 @SuppressWarnings({"rawtypes", "unchecked"})
38 public class ModelTestsUtil {
39 
collectAllFiles(File root, ArrayList collector, FileFilter fileFilter)40 static private void collectAllFiles(File root, ArrayList collector, FileFilter fileFilter) {
41 	File[] files = root.listFiles(fileFilter);
42 	for (int i = 0; i < files.length; i++) {
43 		final File currentFile = files[i];
44 		if (currentFile.isDirectory()) {
45 			collectAllFiles(currentFile, collector, fileFilter);
46 		} else {
47 			collector.add(currentFile);
48 		}
49 	}
50 }
51 
convertToIndependantLineDelimiter(File file)52 static public boolean convertToIndependantLineDelimiter(File file) {
53 	return file.getName().endsWith(".java");
54 }
55 
56 /**
57  * Copy file from src (path to the original file) to dest (path to the destination file).
58  */
copy(File src, File dest)59 static public void copy(File src, File dest) throws IOException {
60 	// read source bytes
61 	byte[] srcBytes = read(src);
62 
63 	if (convertToIndependantLineDelimiter(src)) {
64 		String contents = new String(srcBytes);
65 		contents = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(contents);
66 		srcBytes = contents.getBytes();
67 	}
68 
69 	// write bytes to dest
70 	FileOutputStream out = new FileOutputStream(dest);
71 	try {
72 		out.write(srcBytes);
73 	} finally {
74 		out.close();
75 	}
76 }
77 
78 /**
79  * Copy the given source directory (and all its contents) to the given target directory.
80  */
copyDirectory(File source, File target)81 static public void copyDirectory(File source, File target) throws IOException {
82 	if (!target.exists()) {
83 		target.mkdirs();
84 	}
85 	File[] files = source.listFiles();
86 	if (files == null) return;
87 	for (int i = 0; i < files.length; i++) {
88 		File sourceChild = files[i];
89 		String name =  sourceChild.getName();
90 		if (name.equals("CVS") || name.equals(".svn")) continue;
91 		File targetChild = new File(target, name);
92 		if (sourceChild.isDirectory()) {
93 			copyDirectory(sourceChild, targetChild);
94 		} else {
95 			copy(sourceChild, targetChild);
96 		}
97 	}
98 }
99 
getAllFiles(File root, FileFilter fileFilter)100 public static File[] getAllFiles(File root, FileFilter fileFilter) {
101 	ArrayList files = new ArrayList();
102 	if (root.isDirectory()) {
103 		collectAllFiles(root, files, fileFilter);
104 		File[] result = new File[files.size()];
105 		files.toArray(result);
106 		return result;
107 	} else {
108 		return null;
109 	}
110 }
111 
112 /**
113  * Returns the specified compilation unit in the given project, root, and
114  * package fragment or <code>null</code> if it does not exist.
115  */
getClassFile(IJavaProject project, String rootPath, String packageName, String className)116 static public IClassFile getClassFile(IJavaProject project, String rootPath, String packageName, String className) throws JavaModelException {
117 	IPackageFragment pkg= getPackageFragment(project, rootPath, packageName);
118 	if (pkg == null) {
119 		return null;
120 	}
121 	return pkg.getClassFile(className);
122 }
123 
124 /**
125  * Returns compilation unit with given name in given project and package.
126  * @param javaProject
127  * @param packageName
128  * @param unitName
129  * @return org.eclipse.jdt.core.ICompilationUnit
130  */
getCompilationUnit(IJavaProject javaProject, String packageName, String unitName)131 static public ICompilationUnit getCompilationUnit(IJavaProject javaProject, String packageName, String unitName) throws JavaModelException {
132 	if (javaProject == null) return null;
133 	IType type = javaProject.findType(packageName, unitName);
134 	if (type != null) {
135 		return type.getCompilationUnit();
136 	}
137 	return null;
138 }
139 
140 /**
141  * Returns all compilation units of a given project.
142  * @param javaProject Project to collect units
143  * @return List of org.eclipse.jdt.core.ICompilationUnit
144  */
getCompilationUnits(IJavaProject javaProject)145 static public List getCompilationUnits(IJavaProject javaProject) throws JavaModelException {
146 	IPackageFragmentRoot[] fragmentRoots = javaProject.getPackageFragmentRoots();
147 	int length = fragmentRoots.length;
148 	List allUnits = new ArrayList();
149 	for (int i=0; i<length; i++) {
150 		if (fragmentRoots[i] instanceof JarPackageFragmentRoot) continue;
151 		IJavaElement[] packages= fragmentRoots[i].getChildren();
152 		for (int k= 0; k < packages.length; k++) {
153 			IPackageFragment pack = (IPackageFragment) packages[k];
154 			ICompilationUnit[] units = pack.getCompilationUnits();
155 			allUnits.addAll(Arrays.asList(units));
156 		}
157 	}
158 	return allUnits;
159 }
160 
161 /**
162  * Returns all compilation units of a given project.
163  * @param root The package fragment root to collect units
164  * @return List of org.eclipse.jdt.core.ICompilationUnit
165  */
getCompilationUnits(IPackageFragmentRoot root)166 static public List getCompilationUnits(IPackageFragmentRoot root) throws JavaModelException {
167 	List allUnits = new ArrayList();
168 	if (!(root instanceof JarPackageFragmentRoot)) {
169 		IJavaElement[] packages= root.getChildren();
170 		for (int k= 0; k < packages.length; k++) {
171 			IPackageFragment pack = (IPackageFragment) packages[k];
172 			ICompilationUnit[] units = pack.getCompilationUnits();
173 			allUnits.addAll(Arrays.asList(units));
174 		}
175 	}
176 	return allUnits;
177 }
178 
getExternalJarFile(IJavaProject project, String jarSimpleName)179 static public IPackageFragmentRoot getExternalJarFile(IJavaProject project, String jarSimpleName) throws JavaModelException {
180 	IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
181 	if (roots == null || roots.length == 0) {
182 		return null;
183 	}
184 	for (int i = 0; i < roots.length; i++) {
185 		IPackageFragmentRoot root = roots[i];
186 		if (root.isExternal() && root.getElementName().equals(jarSimpleName)) {
187 			return root;
188 		}
189 	}
190 	return null;
191 }
192 
193 /**
194  * Returns the IPath to the external java class library (e.g. jclMin.jar)
195  */
getExternalJCLPath()196 static public IPath getExternalJCLPath() {
197 	return new Path(getExternalJCLPathString(""));
198 }
199 /**
200  * Returns the IPath to the external java class library (e.g. jclMin.jar)
201  */
getExternalJCLPath(String compliance)202 static public IPath getExternalJCLPath(String compliance) {
203 	return new Path(getExternalJCLPathString(compliance));
204 }
205 /**
206  * Returns the java.io path to the external java class library (e.g. jclMin.jar)
207  */
getExternalJCLPathString()208 static public String getExternalJCLPathString() {
209 	return getExternalJCLPathString("");
210 }
211 /**
212  * Returns the java.io path to the external java class library (e.g. jclMin.jar)
213  */
getExternalJCLPathString(String compliance)214 static public String getExternalJCLPathString(String compliance) {
215 	return getExternalPath() + "jclMin" + compliance + ".jar";
216 }
217 /**
218  * Returns the IPath to the root source of the external java class library (e.g. "src")
219  */
getExternalJCLRootSourcePath()220 static public IPath getExternalJCLRootSourcePath() {
221 	return new Path("src");
222 }
223 /**
224  * Returns the IPath to the source of the external java class library (e.g. jclMinsrc.zip)
225  */
getExternalJCLSourcePath()226 static public IPath getExternalJCLSourcePath() {
227 	return new Path(getExternalJCLSourcePathString(""));
228 }
229 /**
230  * Returns the IPath to the source of the external java class library (e.g. jclMinsrc.zip)
231  */
getExternalJCLSourcePath(String compliance)232 static public IPath getExternalJCLSourcePath(String compliance) {
233 	return new Path(getExternalJCLSourcePathString(compliance));
234 }
235 /**
236  * Returns the java.io path to the source of the external java class library (e.g. jclMinsrc.zip)
237  */
getExternalJCLSourcePathString()238 static public String getExternalJCLSourcePathString() {
239 	return getExternalJCLSourcePathString("");
240 }
241 /**
242  * Returns the java.io path to the source of the external java class library (e.g. jclMinsrc.zip)
243  */
getExternalJCLSourcePathString(String compliance)244 static public String getExternalJCLSourcePathString(String compliance) {
245 	return getExternalPath() + "jclMin" + compliance + "src.zip";
246 }
247 /*
248  * Returns the OS path to the external directory that contains external jar files.
249  * This path ends with a File.separatorChar.
250  */
getExternalPath()251 static public String getExternalPath() {
252 	try {
253 		String path = getWorkspaceRoot().getLocation().toFile().getParentFile().getCanonicalPath();
254 		if (path.charAt(path.length()-1) != File.separatorChar)
255 			path += File.separatorChar;
256 		return path;
257 	} catch (IOException e) {
258 		e.printStackTrace();
259 	}
260 	return  null;
261 }
262 
263 /**
264  * Returns the specified package fragment in the given project and root, or
265  * <code>null</code> if it does not exist.
266  * The rootPath must be specified as a project relative path. The empty
267  * path refers to the default package fragment.
268  */
getPackageFragment(IJavaProject project, String rootPath, String packageName)269 static public IPackageFragment getPackageFragment(IJavaProject project, String rootPath, String packageName) throws JavaModelException {
270 	IPackageFragmentRoot root= getPackageFragmentRoot(project, rootPath);
271 	if (root == null) {
272 		return null;
273 	}
274 	return root.getPackageFragment(packageName);
275 }
276 
277 /**
278  * Returns the specified package fragment root in the given project, or
279  * <code>null</code> if it does not exist.
280  * If relative, the rootPath must be specified as a project relative path.
281  * The empty path refers to the package fragment root that is the project
282  * folder itself.
283  * If absolute, the rootPath refers to either an external jar, or a resource
284  * internal to the workspace
285  */
getPackageFragmentRoot( IJavaProject project, String rootPath)286 static public IPackageFragmentRoot getPackageFragmentRoot(
287 	IJavaProject project,
288 	String rootPath)
289 	throws JavaModelException {
290 
291 	if (project == null) {
292 		return null;
293 	}
294 	IPath path = new Path(rootPath);
295 	if (path.isAbsolute()) {
296 		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
297 		IResource resource = workspaceRoot.findMember(path);
298 		IPackageFragmentRoot root;
299 		if (resource == null) {
300 			// external jar
301 			root = project.getPackageFragmentRoot(rootPath);
302 		} else {
303 			// resource in the workspace
304 			root = project.getPackageFragmentRoot(resource);
305 		}
306 		return root;
307 	} else {
308 		IPackageFragmentRoot[] roots = project.getPackageFragmentRoots();
309 		if (roots == null || roots.length == 0) {
310 			return null;
311 		}
312 		for (int i = 0; i < roots.length; i++) {
313 			IPackageFragmentRoot root = roots[i];
314 			if (!root.isExternal()
315 				&& root.getUnderlyingResource().getProjectRelativePath().equals(path)) {
316 				return root;
317 			}
318 		}
319 	}
320 	return getExternalJarFile(project, rootPath);
321 }
getPluginDirectoryPath()322 static public String getPluginDirectoryPath() {
323 	return getPluginDirectoryPath("model");
324 }
325 /**
326  * Returns the OS path to the directory that contains this plugin.
327  *
328  * @param type May be one of the following value
329  */
getPluginDirectoryPath(String type)330 static public String getPluginDirectoryPath(String type) {
331 	try {
332 		StringBuffer bundleName = new StringBuffer("org.eclipse.jdt.core.tests");
333 		if (type != null) {
334 			bundleName.append('.');
335 			bundleName.append(type);
336 		}
337 		URL platformURL = Platform.getBundle(bundleName.toString()).getEntry("/");
338 		return new File(FileLocator.toFileURL(platformURL).getFile()).getAbsolutePath();
339 	} catch (IOException e) {
340 		e.printStackTrace();
341 	}
342 	return null;
343 }
344 
getSourceWorkspacePath(String workspace)345 static public String getSourceWorkspacePath(String workspace) {
346 	return getPluginDirectoryPath() +  java.io.File.separator + workspace;
347 }
348 
349 /**
350  * Returns the IWorkspace this test suite is running on.
351  */
getWorkspace()352 static public IWorkspace getWorkspace() {
353 	return ResourcesPlugin.getWorkspace();
354 }
355 
getWorkspaceRoot()356 static public IWorkspaceRoot getWorkspaceRoot() {
357 	return getWorkspace().getRoot();
358 }
359 
read(java.io.File file)360 static public byte[] read(java.io.File file) throws java.io.IOException {
361 	int fileLength;
362 	byte[] fileBytes = new byte[fileLength = (int) file.length()];
363 	java.io.FileInputStream stream = new java.io.FileInputStream(file);
364 	int bytesRead = 0;
365 	int lastReadSize = 0;
366 	try {
367 		while ((lastReadSize != -1) && (bytesRead != fileLength)) {
368 			lastReadSize = stream.read(fileBytes, bytesRead, fileLength - bytesRead);
369 			bytesRead += lastReadSize;
370 		}
371 		return fileBytes;
372 	} finally {
373 		stream.close();
374 	}
375 }
376 
377 /**
378  * Remove all white spaces from a string.
379  *
380  * @param input The input string
381  * @return A new string without any whitespaces
382  */
removeWhiteSpace(String input)383 public static String removeWhiteSpace(String input) {
384 	StringTokenizer tokenizer = new StringTokenizer(input);
385 	StringBuffer buffer = new StringBuffer();
386 	while (tokenizer.hasMoreTokens()) {
387 		buffer.append(tokenizer.nextToken());
388 	}
389     return buffer.toString();
390 }
391 
392 /**
393  * Check locally for the required JCL files, <jclName>.jar and <jclName>src.zip.
394  * If not available, copy from the project resources.
395  */
setupExternalJCL(String jclName)396 static public void setupExternalJCL(String jclName) throws IOException {
397 	String externalPath = getExternalPath();
398 	String separator = java.io.File.separator;
399 	String resourceJCLDir = getPluginDirectoryPath() + separator + "JCL";
400 	java.io.File jclDir = new java.io.File(externalPath);
401 	java.io.File jclMin =
402 		new java.io.File(externalPath + jclName + ".jar");
403 	java.io.File jclMinsrc = new java.io.File(externalPath + jclName + "src.zip");
404 	if (!jclDir.exists()) {
405 		if (!jclDir.mkdir()) {
406 			//mkdir failed
407 			throw new IOException("Could not create the directory " + jclDir);
408 		}
409 		//copy the two files to the JCL directory
410 		java.io.File resourceJCLMin =
411 			new java.io.File(resourceJCLDir + separator + jclName + ".jar");
412 		copy(resourceJCLMin, jclMin);
413 		java.io.File resourceJCLMinsrc =
414 			new java.io.File(resourceJCLDir + separator + jclName + "src.zip");
415 		copy(resourceJCLMinsrc, jclMinsrc);
416 	} else {
417 		//check that the two files, jclMin.jar and jclMinsrc.zip are present
418 		//copy either file that is missing or less recent than the one in workspace
419 		java.io.File resourceJCLMin =
420 			new java.io.File(resourceJCLDir + separator + jclName + ".jar");
421 		if ((jclMin.lastModified() < resourceJCLMin.lastModified())
422                 || (jclMin.length() != resourceJCLMin.length())) {
423 			copy(resourceJCLMin, jclMin);
424 		}
425 		java.io.File resourceJCLMinsrc =
426 			new java.io.File(resourceJCLDir + separator + jclName + "src.zip");
427 		if ((jclMinsrc.lastModified() < resourceJCLMinsrc.lastModified())
428                 || (jclMinsrc.length() != resourceJCLMinsrc.length())) {
429 			copy(resourceJCLMinsrc, jclMinsrc);
430 		}
431 	}
432 }
433 
setUpJCLClasspathVariables(String compliance)434 static public void setUpJCLClasspathVariables(String compliance) throws JavaModelException, IOException {
435 	if ("1.8".equals(compliance)) {
436 		if (JavaCore.getClasspathVariable("JCL18_LIB") == null) {
437 			setupExternalJCL("jclMin1.8");
438 			JavaCore.setClasspathVariables(
439 				new String[] {"JCL18_LIB", "JCL18_SRC", "JCL_SRCROOT"},
440 				new IPath[] {getExternalJCLPath(compliance), getExternalJCLSourcePath(compliance), getExternalJCLRootSourcePath()},
441 				null);
442 		}
443 	} else if ("1.7".equals(compliance)) {
444 		if (JavaCore.getClasspathVariable("JCL17_LIB") == null) {
445 			setupExternalJCL("jclMin1.7");
446 			JavaCore.setClasspathVariables(
447 				new String[] {"JCL17_LIB", "JCL17_SRC", "JCL_SRCROOT"},
448 				new IPath[] {getExternalJCLPath(compliance), getExternalJCLSourcePath(compliance), getExternalJCLRootSourcePath()},
449 				null);
450 		}
451 	} else if ("1.5".equals(compliance)) {
452 		if (JavaCore.getClasspathVariable("JCL15_LIB") == null) {
453 			setupExternalJCL("jclMin1.5");
454 			JavaCore.setClasspathVariables(
455 				new String[] {"JCL15_LIB", "JCL15_SRC", "JCL_SRCROOT"},
456 				new IPath[] {getExternalJCLPath(compliance), getExternalJCLSourcePath(compliance), getExternalJCLRootSourcePath()},
457 				null);
458 		}
459 	} else {
460 		if (JavaCore.getClasspathVariable("JCL_LIB") == null) {
461 			setupExternalJCL("jclMin");
462 			JavaCore.setClasspathVariables(
463 				new String[] {"JCL_LIB", "JCL_SRC", "JCL_SRCROOT"},
464 				new IPath[] {getExternalJCLPath(), getExternalJCLSourcePath(), getExternalJCLRootSourcePath()},
465 				null);
466 		}
467 	}
468 }
469 
470 /**
471  * Remove all white spaces at the deginning of each lines from a string.
472  *
473  * @param input The input string
474  * @return A new string without any whitespaces
475  */
trimLinesLeadingWhitespaces(String input)476 public static String trimLinesLeadingWhitespaces(String input) {
477 	StringTokenizer tokenizer = new StringTokenizer(input, "\r\n\f");
478 	StringBuffer buffer = new StringBuffer();
479 	while (tokenizer.hasMoreTokens()) {
480 		String line = tokenizer.nextToken();
481 		int length = line.length();
482 		int size = 0;
483 		int idx = -1;
484 		if (length > 0) {
485 			loop: while ((idx+1) < length) {
486 				char ch = line.charAt(++idx);
487 				switch (ch) {
488 					case '\t':
489 						size += 4;
490 						break;
491 					case '*':
492 					case ' ':
493 						break;
494 					default:
495 						break loop;
496 				}
497 			}
498 		}
499 		if (length > 0 && idx > 0 && idx < length) {
500 			int splitLineIndex = line.indexOf("||", idx);
501 			if (splitLineIndex > 0) {
502 				int commentStart = line.indexOf("/*", splitLineIndex);
503 				if (commentStart >= 80-((size*3)/4)) {
504 					StringBuffer newLine = new StringBuffer(line.substring(idx-1, splitLineIndex).trim());
505 					newLine.append('\n');
506 					newLine.append(line.substring(splitLineIndex).trim());
507 					newLine.append('\n');
508 					buffer.append(newLine);
509 					continue;
510 				}
511 			}
512 			buffer.append(line.substring(idx).trim());
513 		} else {
514 			buffer.append(line);
515 		}
516 		buffer.append('\n');
517 	}
518     return buffer.toString();
519 }
520 
521 }
522