1 /*******************************************************************************
2 * Copyright (c) 2000, 2017 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.*;
17 import java.util.StringTokenizer;
18
19 import org.eclipse.core.resources.*;
20 import org.eclipse.core.runtime.*;
21 import org.eclipse.jdt.core.*;
22 import org.eclipse.jdt.core.compiler.batch.BatchCompiler;
23 import org.eclipse.jdt.core.tests.util.Util;
24 import org.eclipse.jdt.internal.core.JavaElement;
25 import org.eclipse.jdt.internal.core.nd.indexer.Indexer;
26
27 public class ModifyingResourceTests extends AbstractJavaModelTests {
28
ModifyingResourceTests(String name)29 public ModifyingResourceTests(String name) {
30 super(name);
31 }
ModifyingResourceTests(String name, int tabs)32 public ModifyingResourceTests(String name, int tabs) {
33 super(name, tabs);
34 }
assertElementDescendants(String message, String expected, IJavaElement element)35 protected void assertElementDescendants(String message, String expected, IJavaElement element) throws CoreException {
36 String actual = expandAll(element);
37 if (!expected.equals(actual)){
38 System.out.print(displayString(actual, 3));
39 System.out.println(",");
40 }
41 assertEquals(
42 message,
43 expected,
44 actual);
45 }
assertStatus(String expected, IStatus status)46 protected void assertStatus(String expected, IStatus status) {
47 String actual = status.getMessage();
48 if (!expected.equals(actual)) {
49 System.out.print(Util.displayString(actual, 2));
50 System.out.println(",");
51 }
52 assertEquals(expected, actual);
53 }
assertStatus(String message, String expected, IStatus status)54 protected void assertStatus(String message, String expected, IStatus status) {
55 String actual = status.getMessage();
56 if (!expected.equals(actual)) {
57 System.out.print(Util.displayString(actual, 2));
58 System.out.println(",");
59 }
60 assertEquals(message, expected, actual);
61 }
62 /**
63 * E.g. <code>
64 * org.eclipse.jdt.tests.core.ModifyingResourceTests.generateClassFile(
65 * "A",
66 * "public class A {\n" +
67 * "}")
68 */
generateClassFile(String className, String javaSource)69 public static void generateClassFile(String className, String javaSource) throws IOException {
70 String cu = "d:/temp/" + className + ".java";
71 Util.createFile(cu, javaSource);
72 BatchCompiler.compile(cu + " -d d:/temp -classpath " + System.getProperty("java.home") + "/lib/rt.jar", new PrintWriter(System.out), new PrintWriter(System.err), null/*progress*/);
73 FileInputStream input = new FileInputStream("d:/temp/" + className + ".class");
74 try {
75 System.out.println("{");
76 byte[] buffer = new byte[80];
77 int read = 0;
78 while (read != -1) {
79 read = input.read(buffer);
80 if (read != -1) System.out.print("\t");
81 for (int i = 0; i < read; i++) {
82 System.out.print(buffer[i]);
83 System.out.print(", ");
84 }
85 if (read != -1) System.out.println();
86 }
87 System.out.print("}");
88 } finally {
89 input.close();
90 }
91 }
92
createExternalFolder(String relativePath)93 protected boolean createExternalFolder(String relativePath) {
94 return new File(getExternalPath(), relativePath).mkdirs();
95 }
96
createExternalFile(String relativePath, String contents)97 protected void createExternalFile(String relativePath, String contents) {
98 Util.writeToFile(contents, getExternalPath() + relativePath);
99 }
100
101 @Override
createFile(String path, InputStream content)102 protected IFile createFile(String path, InputStream content) throws CoreException {
103 IFile file = getFile(path);
104 file.create(content, true, null);
105 try {
106 content.close();
107 } catch (IOException e) {
108 e.printStackTrace();
109 }
110 Indexer.getInstance().waitForIndex(null);
111 return file;
112 }
113
114 @Override
createFile(String path, byte[] content)115 protected IFile createFile(String path, byte[] content) throws CoreException {
116 return createFile(path, new ByteArrayInputStream(content));
117 }
118
119 @Override
createFile(String path, String content)120 protected IFile createFile(String path, String content) throws CoreException {
121 return createFile(path, content.getBytes());
122 }
createFile(String path, String content, String charsetName)123 protected IFile createFile(String path, String content, String charsetName) throws CoreException, UnsupportedEncodingException {
124 return createFile(path, content.getBytes(charsetName));
125 }
createFolder(File parent, String name)126 protected File createFolder(File parent, String name) {
127 File file = new File(parent, name);
128 file.mkdirs();
129 return file;
130 }
131 @Override
createFolder(String path)132 protected IFolder createFolder(String path) throws CoreException {
133 return createFolder(new Path(path));
134 }
deleteExternalResource(String relativePath)135 protected void deleteExternalResource(String relativePath) {
136 deleteResource(new File(getExternalPath() + relativePath));
137 }
deleteFile(String filePath)138 protected void deleteFile(String filePath) throws CoreException {
139 deleteResource(getFile(filePath));
140 }
deleteFolder(String folderPath)141 protected void deleteFolder(String folderPath) throws CoreException {
142 deleteFolder(new Path(folderPath));
143 }
editFile(String path, String content)144 protected IFile editFile(String path, String content) throws CoreException {
145 IFile file = getFile(path);
146 InputStream input = new ByteArrayInputStream(content.getBytes());
147 file.setContents(input, IResource.FORCE, null);
148 return file;
149 }
150 /*
151 * Expands (i.e. open) the given element and returns a toString() representation
152 * of the tree.
153 */
expandAll(IJavaElement element)154 protected String expandAll(IJavaElement element) throws CoreException {
155 StringBuffer buffer = new StringBuffer();
156 this.expandAll(element, 0, buffer);
157 return buffer.toString();
158 }
expandAll(IJavaElement element, int tab, StringBuffer buffer)159 private void expandAll(IJavaElement element, int tab, StringBuffer buffer) throws CoreException {
160 IJavaElement[] children = null;
161 // force opening of element by getting its children
162 if (element instanceof IParent) {
163 IParent parent = (IParent)element;
164 children = parent.getChildren();
165 }
166 ((JavaElement)element).toStringInfo(tab, buffer);
167 if (children != null) {
168 for (int i = 0, length = children.length; i < length; i++) {
169 buffer.append("\n");
170 this.expandAll(children[i], tab+1, buffer);
171 }
172 }
173 }
renameProject(String project, String newName)174 protected void renameProject(String project, String newName) throws CoreException {
175 getProject(project).move(new Path(newName), true, null);
176 }
getClassFile(String path)177 protected IOrdinaryClassFile getClassFile(String path) {
178 return (IOrdinaryClassFile)JavaCore.create(getFile(path));
179 }
getFolder(String path)180 protected IFolder getFolder(String path) {
181 return getFolder(new Path(path));
182 }
getPackage(String path)183 protected IPackageFragment getPackage(String path) {
184 if (path.indexOf('/', 1) != -1) { // if path as more than one segment
185 IJavaElement element = JavaCore.create(this.getFolder(path));
186 if (element instanceof IPackageFragmentRoot) {
187 return ((IPackageFragmentRoot)element).getPackageFragment("");
188 }
189 return (IPackageFragment)element;
190 }
191 IProject project = getProject(path);
192 return JavaCore.create(project).getPackageFragmentRoot(project).getPackageFragment("");
193 }
getPackageFragmentRoot(String path)194 protected IPackageFragmentRoot getPackageFragmentRoot(String path) {
195 if (path.indexOf('/', 1) != -1) { // if path as more than one segment
196 if (path.endsWith(".jar")) {
197 return (IPackageFragmentRoot)JavaCore.create(getFile(path));
198 }
199 return (IPackageFragmentRoot)JavaCore.create(this.getFolder(path));
200 }
201 IProject project = getProject(path);
202 return JavaCore.create(project).getPackageFragmentRoot(project);
203 }
moveFile(String sourcePath, String destPath)204 protected void moveFile(String sourcePath, String destPath) throws CoreException {
205 getFile(sourcePath).move(getFile(destPath).getFullPath(), false, null);
206 }
moveFolder(String sourcePath, String destPath)207 protected void moveFolder(String sourcePath, String destPath) throws CoreException {
208 this.getFolder(sourcePath).move(this.getFolder(destPath).getFullPath(), false, null);
209 }
swapFiles(String firstPath, String secondPath)210 protected void swapFiles(String firstPath, String secondPath) throws CoreException {
211 final IFile first = getFile(firstPath);
212 final IFile second = getFile(secondPath);
213 IWorkspaceRunnable runnable = new IWorkspaceRunnable( ) {
214 public void run(IProgressMonitor monitor) throws CoreException {
215 IPath tempPath = first.getParent().getFullPath().append("swappingFile.temp");
216 first.move(tempPath, false, monitor);
217 second.move(first.getFullPath(), false, monitor);
218 getWorkspaceRoot().getFile(tempPath).move(second.getFullPath(), false, monitor);
219 }
220 };
221 getWorkspace().run(runnable, null);
222 }
createClassFile(String libPath, String classFileRelativePath, String contents)223 protected IClassFile createClassFile(String libPath, String classFileRelativePath, String contents) throws CoreException {
224 IOrdinaryClassFile classFile = getClassFile(libPath + "/" + classFileRelativePath);
225 // classFile.getResource().delete(false, null);
226 Util.delete(classFile.getResource());
227 IJavaProject javaProject = classFile.getJavaProject();
228 IProject project = javaProject.getProject();
229 String sourcePath = project.getLocation().toOSString() + File.separatorChar + classFile.getType().getElementName() + ".java";
230 String libOSPath = new Path(libPath).segmentCount() > 1 ? getFolder(libPath).getLocation().toOSString() : getProject(libPath).getLocation().toOSString();
231 Util.compile(new String[] {sourcePath, contents}, javaProject.getOptions(true), libOSPath);
232 project.refreshLocal(IResource.DEPTH_INFINITE, null);
233 return classFile;
234 }
235 /*
236 * Returns a new classpath from the given source folders and their respective exclusion/inclusion patterns.
237 * The folder path is an absolute workspace-relative path.
238 * The given array as the following form:
239 * [<folder>, "<pattern>[|<pattern]*"]*
240 * E.g. new String[] {
241 * "/P/src1", "p/A.java",
242 * "/P", "*.txt|com.tests/**"
243 * }
244 */
createClasspath(String[] foldersAndPatterns, boolean hasInclusionPatterns, boolean hasExclusionPatterns)245 protected IClasspathEntry[] createClasspath(String[] foldersAndPatterns, boolean hasInclusionPatterns, boolean hasExclusionPatterns) {
246 int length = foldersAndPatterns.length;
247 int increment = 1;
248 if (hasInclusionPatterns) increment++;
249 if (hasExclusionPatterns) increment++;
250 IClasspathEntry[] classpath = new IClasspathEntry[length/increment];
251 for (int i = 0; i < length; i+=increment) {
252 String src = foldersAndPatterns[i];
253 IPath[] accessibleFiles = new IPath[0];
254 if (hasInclusionPatterns) {
255 String patterns = foldersAndPatterns[i+1];
256 StringTokenizer tokenizer = new StringTokenizer(patterns, "|");
257 int patternsCount = tokenizer.countTokens();
258 accessibleFiles = new IPath[patternsCount];
259 for (int j = 0; j < patternsCount; j++) {
260 accessibleFiles[j] = new Path(tokenizer.nextToken());
261 }
262 }
263 IPath[] nonAccessibleFiles = new IPath[0];
264 if (hasExclusionPatterns) {
265 String patterns = foldersAndPatterns[i+increment-1];
266 StringTokenizer tokenizer = new StringTokenizer(patterns, "|");
267 int patternsCount = tokenizer.countTokens();
268 nonAccessibleFiles = new IPath[patternsCount];
269 for (int j = 0; j < patternsCount; j++) {
270 nonAccessibleFiles[j] = new Path(tokenizer.nextToken());
271 }
272 }
273 IPath folderPath = new Path(src);
274 classpath[i/increment] = JavaCore.newSourceEntry(folderPath, accessibleFiles, nonAccessibleFiles, null);
275 }
276 return classpath;
277 }
278 /*
279 * Returns a new classpath from the given folders and their respective accessible/non accessible files patterns.
280 * The folder path is an absolute workspace-relative path. If the given project name is non-null,
281 * the folder path is considered a project path if it has 1 segment that is different from the project name.
282 * The given array as the following form:
283 * [<folder>, "<+|-><pattern>[|<+|-><pattern]*"]*
284 * E.g. new String[] {
285 * "/P/src1", "+p/A.java",
286 * "/P", "-*.txt|+com.tests/**"
287 * }
288 */
createClasspath(String projectName, String[] foldersAndPatterns)289 protected IClasspathEntry[] createClasspath(String projectName, String[] foldersAndPatterns) {
290 int length = foldersAndPatterns.length;
291 IClasspathEntry[] classpath = new IClasspathEntry[length/2];
292 for (int i = 0; i < length; i+=2) {
293 String src = foldersAndPatterns[i];
294 String patterns = foldersAndPatterns[i+1];
295 classpath[i/2] = createSourceEntry(projectName, src, patterns);
296 }
297 return classpath;
298 }
createSourceEntry(String referingProjectName, String src, String patterns)299 public IClasspathEntry createSourceEntry(String referingProjectName, String src, String patterns) {
300 StringTokenizer tokenizer = new StringTokenizer(patterns, "|");
301 int ruleCount = tokenizer.countTokens();
302 IAccessRule[] accessRules = new IAccessRule[ruleCount];
303 int nonAccessibleRules = 0;
304 for (int j = 0; j < ruleCount; j++) {
305 String rule = tokenizer.nextToken();
306 int kind;
307 boolean ignoreIfBetter = false;
308 switch (rule.charAt(0)) {
309 case '+':
310 kind = IAccessRule.K_ACCESSIBLE;
311 break;
312 case '~':
313 kind = IAccessRule.K_DISCOURAGED;
314 break;
315 case '?':
316 kind = IAccessRule.K_NON_ACCESSIBLE;
317 ignoreIfBetter = true;
318 break;
319 case '-':
320 default: // TODO (maxime) consider forbidding unspecified rule start; this one tolerates
321 // shortcuts that only specify a path matching pattern
322 kind = IAccessRule.K_NON_ACCESSIBLE;
323 break;
324 }
325 nonAccessibleRules++;
326 accessRules[j] = JavaCore.newAccessRule(new Path(rule.substring(1)), ignoreIfBetter ? kind | IAccessRule.IGNORE_IF_BETTER : kind);
327 }
328
329 IPath folderPath = new Path(src);
330 if (referingProjectName != null && folderPath.segmentCount() == 1 && !referingProjectName.equals(folderPath.lastSegment())) {
331 return JavaCore.newProjectEntry(folderPath, accessRules, true/*combine access restrictions*/, new IClasspathAttribute[0], false);
332 } else {
333 IPath[] accessibleFiles = new IPath[ruleCount-nonAccessibleRules];
334 int accessibleIndex = 0;
335 IPath[] nonAccessibleFiles = new IPath[nonAccessibleRules];
336 int nonAccessibleIndex = 0;
337 for (int j = 0; j < ruleCount; j++) {
338 IAccessRule accessRule = accessRules[j];
339 if (accessRule.getKind() == IAccessRule.K_ACCESSIBLE)
340 accessibleFiles[accessibleIndex++] = accessRule.getPattern();
341 else
342 nonAccessibleFiles[nonAccessibleIndex++] = accessRule.getPattern();
343 }
344 return JavaCore.newSourceEntry(folderPath, accessibleFiles, nonAccessibleFiles, null);
345 }
346 }
deleteExternalFile(String filePath)347 protected void deleteExternalFile(String filePath) throws CoreException {
348 deleteResource(new File(filePath));
349 }
350 }
351