Skip to main content
summaryrefslogtreecommitdiffstats
blob: 90fc3566ac92419a55fc38d3023352f798e30596 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/*******************************************************************************
 * Copyright (c) 2003, 2005 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
 *******************************************************************************/
package org.eclipse.jst.server.core;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jst.server.core.internal.JavaServerPlugin;
import org.eclipse.jst.server.core.internal.RuntimeClasspathContainer;
import org.eclipse.jst.server.core.internal.Trace;
import org.eclipse.wst.server.core.IRuntime;
import org.eclipse.wst.server.core.model.RuntimeTargetHandlerDelegate;
/**
 * 
 */
public abstract class ClasspathRuntimeTargetHandler extends RuntimeTargetHandlerDelegate {
	/* (non-Javadoc)
	 * @see org.eclipse.wst.server.core.model.IRuntimeTargetDelegate#setRuntimeTarget(org.eclipse.core.resources.IProject, org.eclipse.wst.server.core.IRuntime)
	 */
	public void setRuntimeTarget(IProject project, IRuntime runtime, IProgressMonitor monitor) throws CoreException {
		if (project == null || runtime == null)
			return;

		IJavaProject javaProject = null;
		try {
			javaProject = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
		} catch (Exception e) {
			// ignore
		}
		
		if (javaProject == null)
			return;
		
		try {
			List list = new ArrayList();
			IClasspathEntry[] cp = javaProject.getRawClasspath();
			int size = cp.length;
			for (int i = 0; i < size; i++) {
				if (cp[i].getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
					if (!cp[i].getPath().segment(0).equals(RuntimeClasspathContainer.SERVER_CONTAINER))
						list.add(cp[i]);
				} else
					list.add(cp[i]);
			}
			
			List add = new ArrayList();
			IClasspathEntry[] entries = getDelegateClasspathEntries(runtime, monitor);
			if (entries != null) {
				size = entries.length;
				for (int i = 0; i < size; i++)
					add.add(entries[i]);
			}
			
			String[] ids = getClasspathEntryIds();
			if (ids != null) {
				size = ids.length;
				for (int i = 0; i < size; i++) {
					String id2 = getRuntimeTargetHandler().getId();
					IPath path = new Path(RuntimeClasspathContainer.SERVER_CONTAINER).append(id2).append(runtime.getId());
					if (ids[i] != null)
						path.append(ids[i]);
					add.add(JavaCore.newContainerEntry(path));
					String id = "";
					if (path.segmentCount() > 3)
						id = path.segment(3);
					RuntimeClasspathContainer rcc = new RuntimeClasspathContainer(path, this, runtime, id);
					JavaCore.setClasspathContainer(path, new IJavaProject[] { javaProject}, new IClasspathContainer[] { rcc }, monitor);
				}
			}
			
			// clean up duplicates
			cleanupDuplicateClasspath(javaProject, list, add);
			
			Iterator iterator = add.iterator();
			while (iterator.hasNext()) {
				list.add(iterator.next());
			}
			
			cp = new IClasspathEntry[list.size()];
			list.toArray(cp);
			javaProject.setRawClasspath(cp, monitor);
		} catch (Exception e) {
			Trace.trace(Trace.WARNING, "Error setting runtime target", e);
			throw new CoreException(new Status(IStatus.ERROR, JavaServerPlugin.PLUGIN_ID, 0, e.getLocalizedMessage(), e));
		}
	}
	
	protected void cleanupDuplicateClasspath(IJavaProject project, List current, List add) {
		// check if we even have to bother
		boolean sourceOnly = true;
		Iterator iterator = current.iterator();
		while (iterator.hasNext()) {
			IClasspathEntry entry = (IClasspathEntry) iterator.next();
			if (entry.getEntryKind() != IClasspathEntry.CPE_SOURCE)
				sourceOnly = false;
		}
		if (sourceOnly)
			return;
		
		// remove any of our own containers
		List remove = new ArrayList();
		iterator = current.iterator();
		while (iterator.hasNext()) {
			IClasspathEntry entry = (IClasspathEntry) iterator.next();
			
			if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
				try {
					if (RuntimeClasspathContainer.SERVER_CONTAINER.equals(entry.getPath().segment(0))
						|| JavaRuntime.JRE_CONTAINER.equals(entry.getPath().segment(0)))
						remove.add(entry);
				} catch (Exception e) {
					Trace.trace(Trace.FINEST, "Error resolving classpath container", e);
				}
			}
		}

		// expand the "add" list
		List addExpanded = new ArrayList();
		iterator = add.iterator();
		while (iterator.hasNext()) {
			IClasspathEntry entry = (IClasspathEntry) iterator.next();
			if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
				try {
					IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), project);
					IClasspathEntry[] entries = container.getClasspathEntries();
					int size = entries.length;
					for (int i = 0; i < size; i++) {
						if (entries[i] != null)
							addExpanded.add(entries[i]);
					}
				} catch (Exception e) {
					Trace.trace(Trace.FINEST, "Error resolving classpath container 2", e);
				}
			} else if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
				entry = JavaCore.getResolvedClasspathEntry(entry);
				if (entry != null)
					addExpanded.add(entry);
			} else
				addExpanded.add(entry);
		}
		
		// check for duplicates by also expanding the current list
		iterator = current.iterator();
		while (iterator.hasNext()) {
			IClasspathEntry entry = (IClasspathEntry) iterator.next();
			
			List currentExpanded = new ArrayList();
			if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
				try {
					IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), project);
					IClasspathEntry[] entries = container.getClasspathEntries();
					int size = entries.length;
					for (int i = 0; i < size; i++) {
						if (entries[i] != null)
							currentExpanded.add(entries[i]);
					}
				} catch (Exception e) {
					Trace.trace(Trace.FINEST, "Error resolving classpath container 3", e);
				}
			} else if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
				entry = JavaCore.getResolvedClasspathEntry(entry);
				if (entry != null)
					currentExpanded.add(entry);
			} else
				currentExpanded.add(entry);
			
			// loop over all of the expanded entries of this current entry
			boolean dup = false;
			Iterator iterator2 = currentExpanded.iterator();
			while (!dup && iterator2.hasNext()) {
				IClasspathEntry entry2 = (IClasspathEntry) iterator2.next();
				Iterator iterator3 = addExpanded.iterator();
				while (iterator3.hasNext()) {
					IClasspathEntry entry3 = (IClasspathEntry) iterator3.next();
					if (entry3.getPath().equals(entry2.getPath()))
						dup = true;
				}
			}
			if (dup && !remove.contains(entry))
				remove.add(entry);
		}
		
		// remove duplicates
		iterator = remove.iterator();
		while (iterator.hasNext()) {
			current.remove(iterator.next());
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.server.core.model.IRuntimeTargetDelegate#removeRuntimeTarget(org.eclipse.core.resources.IProject, org.eclipse.wst.server.core.IRuntime)
	 */
	public void removeRuntimeTarget(IProject project, IRuntime runtime, IProgressMonitor monitor) {
		Trace.trace(Trace.FINEST, "Removing runtime target");
		if (project == null || runtime == null)
			return;

		IJavaProject javaProject = null;
		try {
			javaProject = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
		} catch (Exception e) {
			// ignore
		}

		if (javaProject == null)
			return;
		
		try {
			IClasspathEntry[] delegates = getDelegateClasspathEntries(runtime, monitor);
			int delegateSize = 0;
			if (delegates != null)
				delegateSize = delegates.length;

			List list = new ArrayList();
			IClasspathEntry[] cp = javaProject.getRawClasspath();
			int size = cp.length;
			for (int i = 0; i < size; i++) {
				boolean remove = false;
				
				if (cp[i].getPath().segment(0).equals(RuntimeClasspathContainer.SERVER_CONTAINER))
					remove = true;
				
				for (int j = 0; j < delegateSize; j++) {
					if (cp[i].equals(delegates[j]))
						remove = true;
				}
				if (!remove)
					list.add(cp[i]);
			}
			
			cp = new IClasspathEntry[list.size()];
			list.toArray(cp);
			javaProject.setRawClasspath(cp, monitor);
		} catch (Exception e) {
			Trace.trace(Trace.WARNING, "Error removing runtime target", e);
		}
	}
	
	protected static void addJarFiles(File dir, List list, boolean includeSubdirectories) {
		int depth = 0;
		if (includeSubdirectories)
			depth = 2;
		addJarFiles(dir, list, depth);
	}
	
	private static void addJarFiles(File dir, List list, int depth) {
		File[] files = dir.listFiles();
		if (files != null) {
			int size = files.length;
			for (int i = 0; i < size; i++) {
				if (files[i].isDirectory() && depth > 0) {
					addJarFiles(files[i], list, depth - 1);
				} else if (files[i].getAbsolutePath().endsWith(".jar") || files[i].getAbsolutePath().endsWith(".zip")) {
					IPath path = new Path(files[i].getAbsolutePath());
					list.add(JavaCore.newLibraryEntry(path, null, null));
				}
			}
		}
	}
	
	protected static void addLibraryEntries(List list, File dir, boolean includeSubdirectories) {
		addJarFiles(dir, list, includeSubdirectories);
	}
	
	protected static void addLibraryEntry(List list, File dir) {
		IPath path = new Path(dir.getAbsolutePath());
		list.add(JavaCore.newLibraryEntry(path, null, null));
	}
	
	protected static void addLibraryEntry(List list, IPath path) {
		list.add(JavaCore.newLibraryEntry(path, null, null));
	}
	
	protected static void addLibraryEntry(List list, IPath path, IPath source, IPath root) {
		list.add(JavaCore.newLibraryEntry(path, source, root));
	}

	protected static IClasspathEntry[] resolveList(List list) {
		IClasspathEntry[] entries = new IClasspathEntry[list.size()]; 
		list.toArray(entries);
		return entries;
	}

	/**
	 * Returns the classpath entries that correspond to the given runtime.
	 * 
	 * @param runtime
	 * @param monitor
	 * @return an array of classpath entries
	 */
	public IClasspathEntry[] getDelegateClasspathEntries(IRuntime runtime, IProgressMonitor monitor) {
		return null;
	}

	/**
	 * Returns the classpath entry ids for this runtime target handler. These
	 * ids will be added to the classpath container id to create a new fully
	 * qualified classpath container id.
	 * <p>
	 * By default, there is a single classpath entry for the runtime, with no
	 * extra id (<code>new String[1]</code>). To create multiple ids, just
	 * return a string array containing the ids. For instance, to have two
	 * classpath containers with ids "id1" and "id2", use
	 * <code>new String[] { "id1", "id2" }</code>
	 * </p>
	 * 
	 * @param runtime
	 * @return
	 */
	public String[] getClasspathEntryIds() {
		return new String[1];
	}

	/**
	 * Returns the classpath container label for the given runtime and the given
	 * classpath container id (returned from getClasspathEntryIds()). This method
	 * must not return null.
	 * 
	 * @param runtime the runtime to resolve the container label for
	 * @param id the classpath entry id
	 * @return a classpath container label
	 */
	public abstract String getClasspathContainerLabel(IRuntime runtime, String id);

	/**
	 * Resolves (creates the classpath entries for) the classpath container with
	 * the given runtime and the given classpath container id (returned from
	 * getClasspathEntryIds()). If the classpath container cannot be resolved
	 * (for instance, if the runtime does not exist), return null.
	 * 
	 * @param runtime the runtime to resolve the container for
	 * @param id the classpath entry id
	 * @return an array of classpath entries for the container, or null if the
	 *   container could not be resolved
	 */
	public abstract IClasspathEntry[] resolveClasspathContainer(IRuntime runtime, String id);
}

Back to the top