001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.wizards.plugin;
011:
012: import java.util.ArrayList;
013: import java.util.HashSet;
014: import java.util.Hashtable;
015: import java.util.Map;
016:
017: import org.eclipse.core.resources.IFile;
018: import org.eclipse.core.resources.IProject;
019: import org.eclipse.core.resources.IResource;
020: import org.eclipse.core.runtime.CoreException;
021: import org.eclipse.core.runtime.IPath;
022: import org.eclipse.jdt.core.IAccessRule;
023: import org.eclipse.jdt.core.IClasspathAttribute;
024: import org.eclipse.jdt.core.IClasspathEntry;
025: import org.eclipse.jdt.core.IJavaModelStatus;
026: import org.eclipse.jdt.core.IJavaProject;
027: import org.eclipse.jdt.core.IPackageFragmentRoot;
028: import org.eclipse.jdt.core.JavaConventions;
029: import org.eclipse.jdt.core.JavaCore;
030: import org.eclipse.jdt.core.JavaModelException;
031: import org.eclipse.jdt.launching.JavaRuntime;
032: import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
033: import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
034: import org.eclipse.osgi.service.resolver.BundleDescription;
035: import org.eclipse.pde.core.build.IBuild;
036: import org.eclipse.pde.core.build.IBuildEntry;
037: import org.eclipse.pde.core.build.IBuildModel;
038: import org.eclipse.pde.core.plugin.IPluginLibrary;
039: import org.eclipse.pde.core.plugin.IPluginModelBase;
040: import org.eclipse.pde.internal.core.ClasspathUtilCore;
041: import org.eclipse.pde.internal.core.ExecutionEnvironmentAnalyzer;
042: import org.eclipse.pde.internal.core.JavadocLocationManager;
043: import org.eclipse.pde.internal.core.PDECore;
044: import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
045: import org.eclipse.pde.internal.core.util.CoreUtility;
046: import org.eclipse.team.core.RepositoryProvider;
047:
048: public class ClasspathComputer {
049:
050: private static Hashtable fSeverityTable = null;
051: private static final int SEVERITY_ERROR = 3;
052: private static final int SEVERITY_WARNING = 2;
053: private static final int SEVERITY_IGNORE = 1;
054:
055: public static void setClasspath(IProject project,
056: IPluginModelBase model) throws CoreException {
057: IClasspathEntry[] entries = getClasspath(project, model, false);
058: JavaCore.create(project).setRawClasspath(entries, null);
059: }
060:
061: public static IClasspathEntry[] getClasspath(IProject project,
062: IPluginModelBase model, boolean clear) throws CoreException {
063:
064: ArrayList result = new ArrayList();
065:
066: IBuild build = getBuild(project);
067:
068: // add own libraries/source
069: addSourceAndLibraries(project, model, build, clear, result);
070:
071: // add JRE and set compliance options
072: String ee = getExecutionEnvironment(model
073: .getBundleDescription());
074: result.add(createJREEntry(ee));
075: setComplianceOptions(JavaCore.create(project),
076: ExecutionEnvironmentAnalyzer.getCompliance(ee));
077:
078: // add pde container
079: result.add(createContainerEntry());
080:
081: IClasspathEntry[] entries = (IClasspathEntry[]) result
082: .toArray(new IClasspathEntry[result.size()]);
083: IJavaProject javaProject = JavaCore.create(project);
084: IJavaModelStatus validation = JavaConventions
085: .validateClasspath(javaProject, entries, javaProject
086: .getOutputLocation());
087: if (!validation.isOK()) {
088: PDECore.logErrorMessage(validation.getMessage());
089: throw new CoreException(validation);
090: }
091: return (IClasspathEntry[]) result
092: .toArray(new IClasspathEntry[result.size()]);
093: }
094:
095: public static void addSourceAndLibraries(IProject project,
096: IPluginModelBase model, IBuild build, boolean clear,
097: ArrayList result) throws CoreException {
098:
099: HashSet paths = new HashSet();
100:
101: // keep existing source folders
102: if (!clear) {
103: IClasspathEntry[] entries = JavaCore.create(project)
104: .getRawClasspath();
105: for (int i = 0; i < entries.length; i++) {
106: IClasspathEntry entry = entries[i];
107: if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
108: if (paths.add(entry.getPath()))
109: result.add(entry);
110: }
111: }
112: }
113:
114: IClasspathAttribute[] attrs = getClasspathAttributes(project,
115: model);
116: IPluginLibrary[] libraries = model.getPluginBase()
117: .getLibraries();
118: for (int i = 0; i < libraries.length; i++) {
119: IBuildEntry buildEntry = build == null ? null : build
120: .getEntry("source." + libraries[i].getName()); //$NON-NLS-1$
121: if (buildEntry != null) {
122: addSourceFolder(buildEntry, project, paths, result);
123: } else {
124: if (libraries[i].getName().equals(".")) //$NON-NLS-1$
125: addJARdPlugin(project, ClasspathUtilCore
126: .getFilename(model), attrs, result);
127: else
128: addLibraryEntry(project, libraries[i], attrs,
129: result);
130: }
131: }
132: if (libraries.length == 0) {
133: if (build != null) {
134: IBuildEntry buildEntry = build == null ? null : build
135: .getEntry("source.."); //$NON-NLS-1$
136: if (buildEntry != null) {
137: addSourceFolder(buildEntry, project, paths, result);
138: }
139: } else if (ClasspathUtilCore.hasBundleStructure(model)) {
140: addJARdPlugin(project, ClasspathUtilCore
141: .getFilename(model), attrs, result);
142: }
143: }
144: }
145:
146: private static IClasspathAttribute[] getClasspathAttributes(
147: IProject project, IPluginModelBase model) {
148: IClasspathAttribute[] attributes = new IClasspathAttribute[0];
149: if (!RepositoryProvider.isShared(project)) {
150: JavadocLocationManager manager = PDECore.getDefault()
151: .getJavadocLocationManager();
152: String javadoc = manager.getJavadocLocation(model);
153: if (javadoc != null) {
154: attributes = new IClasspathAttribute[] { JavaCore
155: .newClasspathAttribute(
156: IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME,
157: javadoc) };
158: }
159: }
160: return attributes;
161: }
162:
163: private static void addSourceFolder(IBuildEntry buildEntry,
164: IProject project, HashSet paths, ArrayList result)
165: throws CoreException {
166: String[] folders = buildEntry.getTokens();
167: for (int j = 0; j < folders.length; j++) {
168: String folder = folders[j];
169: IPath path = project.getFullPath().append(folder);
170: if (paths.add(path)) {
171: if (project.findMember(folder) == null) {
172: CoreUtility.createFolder(project.getFolder(folder));
173: } else {
174: IPackageFragmentRoot root = JavaCore
175: .create(project).getPackageFragmentRoot(
176: path.toString());
177: if (root.exists()
178: && root.getKind() == IPackageFragmentRoot.K_BINARY) {
179: result.add(root.getRawClasspathEntry());
180: continue;
181: }
182: }
183: result.add(JavaCore.newSourceEntry(path));
184: }
185: }
186: }
187:
188: protected static IBuild getBuild(IProject project)
189: throws CoreException {
190: IFile buildFile = project.getFile("build.properties"); //$NON-NLS-1$
191: IBuildModel buildModel = null;
192: if (buildFile.exists()) {
193: buildModel = new WorkspaceBuildModel(buildFile);
194: buildModel.load();
195: }
196: return (buildModel != null) ? buildModel.getBuild() : null;
197: }
198:
199: private static void addLibraryEntry(IProject project,
200: IPluginLibrary library, IClasspathAttribute[] attrs,
201: ArrayList result) throws JavaModelException {
202: String name = ClasspathUtilCore.expandLibraryName(library
203: .getName());
204: IResource jarFile = project.findMember(name);
205: if (jarFile == null)
206: return;
207:
208: IPackageFragmentRoot root = JavaCore.create(project)
209: .getPackageFragmentRoot(jarFile);
210: if (root.exists()
211: && root.getKind() == IPackageFragmentRoot.K_BINARY) {
212: IClasspathEntry oldEntry = root.getRawClasspathEntry();
213: if (oldEntry.getSourceAttachmentPath() != null
214: && !result.contains(oldEntry)) {
215: result.add(oldEntry);
216: return;
217: }
218: }
219:
220: IResource resource = project.findMember(getSourceZipName(name));
221: IPath srcAttachment = resource != null ? resource.getFullPath()
222: : null;
223: IClasspathEntry entry = JavaCore.newLibraryEntry(jarFile
224: .getFullPath(), srcAttachment, null,
225: new IAccessRule[0], attrs, library.isExported());
226: if (!result.contains(entry))
227: result.add(entry);
228: }
229:
230: private static void addJARdPlugin(IProject project,
231: String filename, IClasspathAttribute[] attrs,
232: ArrayList result) {
233: String name = ClasspathUtilCore.expandLibraryName(filename);
234: IResource jarFile = project.findMember(name);
235: if (jarFile != null) {
236: IResource resource = project
237: .findMember(getSourceZipName(name));
238: IPath srcAttachment = resource != null ? resource
239: .getFullPath() : jarFile.getFullPath();
240: IClasspathEntry entry = JavaCore.newLibraryEntry(jarFile
241: .getFullPath(), srcAttachment, null,
242: new IAccessRule[0], attrs, true);
243: if (!result.contains(entry))
244: result.add(entry);
245: }
246: }
247:
248: public static String getSourceZipName(String libraryName) {
249: int dot = libraryName.lastIndexOf('.');
250: return (dot != -1) ? libraryName.substring(0, dot) + "src.zip" : libraryName; //$NON-NLS-1$
251: }
252:
253: private static String getExecutionEnvironment(
254: BundleDescription bundleDescription) {
255: if (bundleDescription != null) {
256: String[] envs = bundleDescription
257: .getExecutionEnvironments();
258: if (envs.length > 0)
259: return envs[0];
260: }
261: return null;
262: }
263:
264: public static void setComplianceOptions(IJavaProject project,
265: String compliance) {
266: Map map = project.getOptions(false);
267: if (compliance == null) {
268: if (map.size() > 0) {
269: map.remove(JavaCore.COMPILER_COMPLIANCE);
270: map.remove(JavaCore.COMPILER_SOURCE);
271: map.remove(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM);
272: map.remove(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER);
273: map.remove(JavaCore.COMPILER_PB_ENUM_IDENTIFIER);
274: } else {
275: return;
276: }
277: } else if (JavaCore.VERSION_1_6.equals(compliance)) {
278: map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6);
279: map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);
280: map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
281: JavaCore.VERSION_1_6);
282: map.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER,
283: JavaCore.ERROR);
284: map.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER,
285: JavaCore.ERROR);
286: } else if (JavaCore.VERSION_1_5.equals(compliance)) {
287: map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
288: map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
289: map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
290: JavaCore.VERSION_1_5);
291: map.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER,
292: JavaCore.ERROR);
293: map.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER,
294: JavaCore.ERROR);
295: } else if (JavaCore.VERSION_1_4.equals(compliance)) {
296: map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
297: map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
298: map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
299: JavaCore.VERSION_1_2);
300: updateSeverityComplianceOption(map,
301: JavaCore.COMPILER_PB_ASSERT_IDENTIFIER,
302: JavaCore.WARNING);
303: updateSeverityComplianceOption(map,
304: JavaCore.COMPILER_PB_ENUM_IDENTIFIER,
305: JavaCore.WARNING);
306: } else if (JavaCore.VERSION_1_3.equals(compliance)) {
307: map.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_3);
308: map.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
309: map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM,
310: JavaCore.VERSION_1_1);
311: updateSeverityComplianceOption(map,
312: JavaCore.COMPILER_PB_ASSERT_IDENTIFIER,
313: JavaCore.IGNORE);
314: updateSeverityComplianceOption(map,
315: JavaCore.COMPILER_PB_ENUM_IDENTIFIER,
316: JavaCore.IGNORE);
317: }
318: project.setOptions(map);
319: }
320:
321: private static void updateSeverityComplianceOption(Map map,
322: String key, String value) {
323: Integer current_value = null;
324: Integer new_value = null;
325: String current_string_value = null;
326: int current_int_value = 0;
327: int new_int_value = 0;
328: // Initialize the severity table (only once)
329: if (fSeverityTable == null) {
330: fSeverityTable = new Hashtable(SEVERITY_ERROR);
331: fSeverityTable.put(JavaCore.IGNORE, new Integer(
332: SEVERITY_IGNORE));
333: fSeverityTable.put(JavaCore.WARNING, new Integer(
334: SEVERITY_WARNING));
335: fSeverityTable.put(JavaCore.ERROR, new Integer(
336: SEVERITY_ERROR));
337: }
338: // Get the current severity
339: current_string_value = (String) map.get(key);
340: if (current_string_value != null) {
341: current_value = (Integer) fSeverityTable
342: .get(current_string_value);
343: if (current_value != null) {
344: current_int_value = current_value.intValue();
345: }
346: }
347: // Get the new severity
348: new_value = (Integer) fSeverityTable.get(value);
349: if (new_value != null) {
350: new_int_value = new_value.intValue();
351: }
352: // If the current severity is not higher than the new severity, replace it
353: if (new_int_value > current_int_value) {
354: map.put(key, value);
355: }
356: }
357:
358: public static IClasspathEntry createJREEntry(String ee) {
359: IPath path = null;
360: if (ee != null) {
361: IExecutionEnvironmentsManager manager = JavaRuntime
362: .getExecutionEnvironmentsManager();
363: IExecutionEnvironment env = manager.getEnvironment(ee);
364: if (env != null)
365: path = JavaRuntime.newJREContainerPath(env);
366: }
367: if (path == null)
368: path = JavaRuntime.newDefaultJREContainerPath();
369: return JavaCore.newContainerEntry(path);
370: }
371:
372: public static IClasspathEntry createContainerEntry() {
373: return JavaCore
374: .newContainerEntry(PDECore.REQUIRED_PLUGINS_CONTAINER_PATH);
375: }
376:
377: }
|