0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.pde.internal.ui.wizards.imports;
0011:
0012: import java.io.File;
0013: import java.io.IOException;
0014: import java.util.ArrayList;
0015: import java.util.Enumeration;
0016: import java.util.HashMap;
0017: import java.util.Hashtable;
0018: import java.util.List;
0019: import java.util.ListIterator;
0020: import java.util.Stack;
0021: import java.util.jar.JarFile;
0022: import java.util.zip.ZipEntry;
0023: import java.util.zip.ZipFile;
0024:
0025: import org.eclipse.core.resources.IContainer;
0026: import org.eclipse.core.resources.IFile;
0027: import org.eclipse.core.resources.IFolder;
0028: import org.eclipse.core.resources.IProject;
0029: import org.eclipse.core.resources.IProjectDescription;
0030: import org.eclipse.core.resources.IResource;
0031: import org.eclipse.core.resources.IncrementalProjectBuilder;
0032: import org.eclipse.core.resources.ResourcesPlugin;
0033: import org.eclipse.core.runtime.CoreException;
0034: import org.eclipse.core.runtime.IPath;
0035: import org.eclipse.core.runtime.IProgressMonitor;
0036: import org.eclipse.core.runtime.IStatus;
0037: import org.eclipse.core.runtime.MultiStatus;
0038: import org.eclipse.core.runtime.NullProgressMonitor;
0039: import org.eclipse.core.runtime.OperationCanceledException;
0040: import org.eclipse.core.runtime.Path;
0041: import org.eclipse.core.runtime.Platform;
0042: import org.eclipse.core.runtime.Status;
0043: import org.eclipse.core.runtime.SubProgressMonitor;
0044: import org.eclipse.core.runtime.jobs.Job;
0045: import org.eclipse.jdt.core.IClasspathEntry;
0046: import org.eclipse.jdt.core.JavaCore;
0047: import org.eclipse.jdt.core.JavaModelException;
0048: import org.eclipse.jdt.launching.JavaRuntime;
0049: import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
0050: import org.eclipse.osgi.service.environment.Constants;
0051: import org.eclipse.osgi.service.resolver.BundleDescription;
0052: import org.eclipse.osgi.service.resolver.HostSpecification;
0053: import org.eclipse.osgi.util.ManifestElement;
0054: import org.eclipse.osgi.util.NLS;
0055: import org.eclipse.pde.core.build.IBuild;
0056: import org.eclipse.pde.core.build.IBuildEntry;
0057: import org.eclipse.pde.core.plugin.IFragment;
0058: import org.eclipse.pde.core.plugin.IFragmentModel;
0059: import org.eclipse.pde.core.plugin.IPluginLibrary;
0060: import org.eclipse.pde.core.plugin.IPluginModelBase;
0061: import org.eclipse.pde.core.plugin.PluginRegistry;
0062: import org.eclipse.pde.internal.core.ClasspathUtilCore;
0063: import org.eclipse.pde.internal.core.PDECore;
0064: import org.eclipse.pde.internal.core.SourceLocationManager;
0065: import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
0066: import org.eclipse.pde.internal.core.bundle.WorkspaceBundleModel;
0067: import org.eclipse.pde.internal.core.ibundle.IBundle;
0068: import org.eclipse.pde.internal.core.natures.PDE;
0069: import org.eclipse.pde.internal.core.util.CoreUtility;
0070: import org.eclipse.pde.internal.ui.PDEPlugin;
0071: import org.eclipse.pde.internal.ui.PDEUIMessages;
0072: import org.eclipse.pde.internal.ui.wizards.plugin.ClasspathComputer;
0073: import org.eclipse.team.core.RepositoryProvider;
0074: import org.eclipse.team.core.TeamException;
0075: import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
0076: import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider;
0077: import org.osgi.framework.BundleException;
0078:
0079: public class PluginImportOperation extends JarImportOperation {
0080:
0081: public static final int IMPORT_BINARY = 1;
0082:
0083: public static final int IMPORT_BINARY_WITH_LINKS = 2;
0084:
0085: public static final int IMPORT_WITH_SOURCE = 3;
0086:
0087: private IPluginModelBase[] fModels;
0088:
0089: private int fImportType;
0090:
0091: private IImportQuery fReplaceQuery;
0092:
0093: private Hashtable fProjectClasspaths = new Hashtable();
0094:
0095: private boolean fForceAutobuild;
0096:
0097: private IImportQuery fExecutionQuery;
0098:
0099: public interface IImportQuery {
0100: public static final int CANCEL = 0;
0101:
0102: public static final int NO = 1;
0103:
0104: public static final int YES = 2;
0105:
0106: int doQuery(String message);
0107: }
0108:
0109: public PluginImportOperation(IPluginModelBase[] models,
0110: int importType, IImportQuery replaceQuery,
0111: IImportQuery executionQuery) {
0112: fModels = models;
0113: fImportType = importType;
0114: fReplaceQuery = replaceQuery;
0115: fExecutionQuery = executionQuery;
0116: }
0117:
0118: public PluginImportOperation(IPluginModelBase[] models,
0119: int importType, IImportQuery replaceQuery,
0120: IImportQuery executionQuery, boolean forceAutobuild) {
0121: this (models, importType, replaceQuery, executionQuery);
0122: fForceAutobuild = forceAutobuild;
0123: }
0124:
0125: public void run(IProgressMonitor monitor) throws CoreException,
0126: OperationCanceledException {
0127: if (monitor == null) {
0128: monitor = new NullProgressMonitor();
0129: }
0130: monitor.beginTask(
0131: PDEUIMessages.ImportWizard_operation_creating,
0132: fModels.length + 1);
0133: try {
0134: MultiStatus multiStatus = new MultiStatus(PDEPlugin
0135: .getPluginId(), IStatus.OK,
0136: PDEUIMessages.ImportWizard_operation_multiProblem,
0137: null);
0138:
0139: for (int i = 0; i < fModels.length; i++) {
0140: try {
0141: importPlugin(fModels[i], new SubProgressMonitor(
0142: monitor, 1));
0143: } catch (CoreException e) {
0144: multiStatus.merge(e.getStatus());
0145: }
0146: if (monitor.isCanceled()) {
0147: setClasspaths(new SubProgressMonitor(monitor, 1));
0148: throw new OperationCanceledException();
0149: }
0150: }
0151: setClasspaths(new SubProgressMonitor(monitor, 1));
0152: if (!ResourcesPlugin.getWorkspace().isAutoBuilding()
0153: && fForceAutobuild)
0154: runBuildJob();
0155: if (!multiStatus.isOK())
0156: throw new CoreException(multiStatus);
0157: } finally {
0158: monitor.done();
0159: }
0160: }
0161:
0162: private void runBuildJob() {
0163: Job buildJob = new Job(
0164: PDEUIMessages.CompilersConfigurationBlock_building) {
0165: public boolean belongsTo(Object family) {
0166: return ResourcesPlugin.FAMILY_AUTO_BUILD == family;
0167: }
0168:
0169: protected IStatus run(IProgressMonitor monitor) {
0170: try {
0171: PDEPlugin
0172: .getWorkspace()
0173: .build(
0174: IncrementalProjectBuilder.INCREMENTAL_BUILD,
0175: monitor);
0176: } catch (CoreException e) {
0177: }
0178: return Status.OK_STATUS;
0179: }
0180: };
0181: buildJob.setRule(ResourcesPlugin.getWorkspace()
0182: .getRuleFactory().buildRule());
0183: buildJob.schedule();
0184: }
0185:
0186: private void setClasspaths(IProgressMonitor monitor)
0187: throws JavaModelException {
0188: monitor.beginTask("", fProjectClasspaths.size()); //$NON-NLS-1$
0189: Enumeration keys = fProjectClasspaths.keys();
0190: while (keys.hasMoreElements()) {
0191: IProject project = (IProject) keys.nextElement();
0192: IClasspathEntry[] classpath = (IClasspathEntry[]) fProjectClasspaths
0193: .get(project);
0194: monitor.subTask(project.getName());
0195: JavaCore.create(project).setRawClasspath(classpath,
0196: new SubProgressMonitor(monitor, 1));
0197: }
0198: }
0199:
0200: private void importPlugin(IPluginModelBase model,
0201: IProgressMonitor monitor) throws CoreException {
0202: String id = model.getPluginBase().getId();
0203: monitor.beginTask(NLS.bind(
0204: PDEUIMessages.ImportWizard_operation_creating2, id), 6);
0205: try {
0206: BundleDescription desc = model.getBundleDescription();
0207: if (desc != null) {
0208: IExecutionEnvironmentsManager manager = JavaRuntime
0209: .getExecutionEnvironmentsManager();
0210: String[] envs = desc.getExecutionEnvironments();
0211: boolean found = false;
0212: for (int i = 0; i < envs.length; i++) {
0213: if (manager.getEnvironment(envs[i]) != null) {
0214: found = true;
0215: break;
0216: }
0217: }
0218: if (envs.length > 0 && !found) {
0219: String message = NLS
0220: .bind(
0221: PDEUIMessages.PluginImportOperation_executionEnvironment,
0222: id, envs[0]);
0223: if (!queryExecutionEnvironment(message))
0224: return;
0225: }
0226: }
0227:
0228: IProject project = findProject(id);
0229:
0230: if (project.exists()
0231: || new File(project.getParent().getLocation()
0232: .toFile(), project.getName()).exists()) {
0233: if (!queryReplace(project))
0234: return;
0235: if (RepositoryProvider.isShared(project))
0236: RepositoryProvider.unmap(project);
0237: if (!project.exists())
0238: project.create(new SubProgressMonitor(monitor, 1));
0239: project.delete(true, true, monitor);
0240: }
0241:
0242: project.create(monitor);
0243: if (!project.isOpen())
0244: project.open(monitor);
0245: monitor.worked(1);
0246:
0247: switch (fImportType) {
0248: case IMPORT_BINARY:
0249: importAsBinary(project, model, true,
0250: new SubProgressMonitor(monitor, 4));
0251: break;
0252: case IMPORT_BINARY_WITH_LINKS:
0253: if (id.startsWith("org.eclipse.swt") && !isJARd(model)) { //$NON-NLS-1$
0254: importAsBinary(project, model, true, monitor);
0255: } else {
0256: importAsBinaryWithLinks(project, model,
0257: new SubProgressMonitor(monitor, 4));
0258: }
0259: break;
0260: case IMPORT_WITH_SOURCE:
0261: if (isExempt(model)) {
0262: importAsBinary(project, model, true,
0263: new SubProgressMonitor(monitor, 4));
0264: } else {
0265: importAsSource(project, model,
0266: new SubProgressMonitor(monitor, 4));
0267: }
0268: }
0269:
0270: setProjectDescription(project, model);
0271:
0272: if (project.hasNature(JavaCore.NATURE_ID)
0273: && project.findMember(".classpath") == null) //$NON-NLS-1$
0274: fProjectClasspaths.put(project, ClasspathComputer
0275: .getClasspath(project, model, true));
0276: } catch (CoreException e) {
0277: } finally {
0278: monitor.done();
0279: }
0280: }
0281:
0282: private void importAsBinaryWithLinks(IProject project,
0283: IPluginModelBase model, IProgressMonitor monitor)
0284: throws CoreException {
0285: if (isJARd(model)) {
0286: extractJARdPlugin(project, model, monitor);
0287: } else {
0288: File installLocation = new File(model.getInstallLocation());
0289: File[] items = installLocation.listFiles();
0290: if (items != null) {
0291: monitor.beginTask(
0292: PDEUIMessages.PluginImportOperation_linking,
0293: items.length + 1);
0294: for (int i = 0; i < items.length; i++) {
0295: File sourceFile = items[i];
0296: String name = sourceFile.getName();
0297: if (sourceFile.isDirectory()) {
0298: project.getFolder(name).createLink(
0299: new Path(sourceFile.getPath()),
0300: IResource.NONE,
0301: new SubProgressMonitor(monitor, 1));
0302: } else {
0303: if (!name.equals(".project")) { //$NON-NLS-1$
0304: project.getFile(name).createLink(
0305: new Path(sourceFile.getPath()),
0306: IResource.NONE,
0307: new SubProgressMonitor(monitor, 1));
0308: } else {
0309: // if the binary project with links has a .project file, copy it instead of linking (allows us to edit it)
0310: ArrayList filesToImport = new ArrayList(1);
0311: filesToImport.add(sourceFile);
0312: importContent(
0313: installLocation,
0314: project.getFullPath(),
0315: FileSystemStructureProvider.INSTANCE,
0316: filesToImport,
0317: new SubProgressMonitor(monitor, 1));
0318: }
0319: }
0320: }
0321: }
0322: linkSourceArchives(project, model, new SubProgressMonitor(
0323: monitor, 1));
0324: }
0325: try {
0326: RepositoryProvider.map(project,
0327: PDECore.BINARY_REPOSITORY_PROVIDER);
0328: } catch (TeamException e) {
0329: }
0330: }
0331:
0332: private void importAsBinary(IProject project,
0333: IPluginModelBase model, boolean markAsBinary,
0334: IProgressMonitor monitor) throws CoreException {
0335: monitor.beginTask("", 3); //$NON-NLS-1$
0336: if (isJARd(model)) {
0337: extractJARdPlugin(project, model, new SubProgressMonitor(
0338: monitor, 2));
0339: } else {
0340: importContent(new File(model.getInstallLocation()), project
0341: .getFullPath(),
0342: FileSystemStructureProvider.INSTANCE, null,
0343: new SubProgressMonitor(monitor, 1));
0344: importSourceArchives(project, model,
0345: new SubProgressMonitor(monitor, 1));
0346:
0347: // make sure all libraries have been imported
0348: // if any are missing, check in fragments
0349: IFragment[] fragments = getFragmentsFor(model);
0350: IPluginLibrary[] libraries = model.getPluginBase()
0351: .getLibraries();
0352:
0353: for (int i = 0; i < libraries.length; i++) {
0354: String libraryName = libraries[i].getName();
0355: if (ClasspathUtilCore.containsVariables(libraryName)
0356: && !project.exists(new Path(ClasspathUtilCore
0357: .expandLibraryName(libraryName)))) {
0358: for (int j = 0; j < fragments.length; j++) {
0359: importJarFromFragment(project, fragments[j],
0360: libraryName);
0361: importSourceFromFragment(project, fragments[j],
0362: libraryName);
0363: }
0364: }
0365: }
0366: }
0367: if (markAsBinary) {
0368: project.setPersistentProperty(
0369: PDECore.EXTERNAL_PROJECT_PROPERTY,
0370: PDECore.BINARY_PROJECT_VALUE);
0371: importAdditionalResources(project, model,
0372: new SubProgressMonitor(monitor, 1));
0373: } else {
0374: monitor.done();
0375: }
0376: }
0377:
0378: private void importAsSource(IProject project,
0379: IPluginModelBase model, SubProgressMonitor monitor)
0380: throws CoreException {
0381: monitor.beginTask("", 4); //$NON-NLS-1$
0382: importAsBinary(project, model, false, new SubProgressMonitor(
0383: monitor, 2));
0384: List list = importAdditionalResources(project, model,
0385: new SubProgressMonitor(monitor, 1));
0386: WorkspaceBuildModel buildModel = new WorkspaceBuildModel(
0387: project.getFile("build.properties")); //$NON-NLS-1$
0388: if (!isJARd(model)
0389: || containsCode(new File(model.getInstallLocation()))) {
0390: String[] libraries = getLibraryNames(model, false);
0391: if (libraries.length == 0)
0392: libraries = new String[] { "." }; //$NON-NLS-1$
0393: for (int i = 0; i < libraries.length; i++) {
0394: if (ClasspathUtilCore.containsVariables(libraries[i]))
0395: continue;
0396: String name = ClasspathUtilCore
0397: .expandLibraryName(libraries[i]);
0398: IPath libraryPath = (name.equals(".") && isJARd(model)) //$NON-NLS-1$
0399: ? new Path(new File(model.getInstallLocation())
0400: .getName())
0401: : new Path(name);
0402: IResource jarFile = project.findMember(libraryPath);
0403: if (jarFile != null) {
0404: String srcName = ClasspathUtilCore
0405: .getSourceZipName(libraryPath.lastSegment());
0406: IResource srcZip = jarFile.getProject().findMember(
0407: srcName);
0408: // srcZip == null if plug-in has embedded source
0409: // if it jarred, all necessary files already in src folder
0410: if (srcZip == null
0411: && libraries[i].equals(".") && !isJARd(model)) //$NON-NLS-1$
0412: // if src does not exist (and returns null), then must not be plug-in with embedded source
0413: srcZip = jarFile.getProject().findMember("src"); //$NON-NLS-1$
0414: if (srcZip != null) {
0415: String jarName = libraries[i].equals(".") ? "" : libraryPath.removeFileExtension().lastSegment(); //$NON-NLS-1$ //$NON-NLS-2$
0416: String folder = addBuildEntry(
0417: buildModel,
0418: "source." + libraries[i], "src" + (jarName.length() == 0 ? "/" : "-" + jarName + "/")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
0419: IFolder dest = jarFile.getProject().getFolder(
0420: folder);
0421: if (!dest.exists()) {
0422: dest.create(true, true, null);
0423: }
0424: if (srcZip instanceof IFile) {
0425: extractZipFile(srcZip.getLocation()
0426: .toFile(), dest.getFullPath(),
0427: new SubProgressMonitor(monitor, 1));
0428: srcZip.delete(true, null);
0429: } else
0430: monitor.worked(1);
0431:
0432: if (jarFile instanceof IFile) {
0433: if (isJARd(model)) {
0434: extractJavaResources(jarFile
0435: .getLocation().toFile(), dest,
0436: new SubProgressMonitor(monitor,
0437: 1));
0438: } else {
0439: extractResources(jarFile.getLocation()
0440: .toFile(), dest,
0441: new SubProgressMonitor(monitor,
0442: 1));
0443: }
0444: jarFile.delete(true, null);
0445: } else {
0446: copyAndDeleteBinaryContents(
0447: (IContainer) jarFile, dest,
0448: new SubProgressMonitor(monitor, 1));
0449: }
0450: }
0451: } else if (name.equals(".") && project.getFolder("src").exists()) { //$NON-NLS-1$ //$NON-NLS-2$
0452: addBuildEntry(buildModel, "source..", "src/"); //$NON-NLS-1$ //$NON-NLS-2$
0453: }
0454: }
0455: }
0456: configureBinIncludes(buildModel, model, project);
0457: if (list.size() > 0)
0458: configureSrcIncludes(buildModel, list);
0459: buildModel.save();
0460: }
0461:
0462: private void copyAndDeleteBinaryContents(IContainer srcFolder,
0463: IFolder dest, IProgressMonitor monitor) {
0464: try {
0465: // get all the folders for which we want to search
0466: IResource[] children = dest.members();
0467: ArrayList validFolders = new ArrayList();
0468: for (int i = 0; i < children.length; i++)
0469: if (children[i] instanceof IFolder) {
0470: String folderName = children[i].getName();
0471: IResource folder = srcFolder.findMember(folderName);
0472: if (folder != null && folder instanceof IFolder)
0473: validFolders.add(folder);
0474: }
0475:
0476: monitor.beginTask(new String(), validFolders.size());
0477:
0478: ListIterator li = validFolders.listIterator();
0479: while (li.hasNext()) {
0480: IFolder folder = (IFolder) li.next();
0481: int pathSegments = folder.getProjectRelativePath()
0482: .segmentCount() - 1;
0483: Stack stack = new Stack();
0484: IResource[] resources = folder.members();
0485: for (int i = 0; i < resources.length; i++)
0486: stack.push(resources[i]);
0487:
0488: while (!stack.isEmpty()) {
0489: IResource res = (IResource) stack.pop();
0490: if (res instanceof IFile) {
0491: if (!res.getName().endsWith(".class")) { //$NON-NLS-1$
0492: String pathName = res
0493: .getProjectRelativePath()
0494: .removeFirstSegments(pathSegments)
0495: .toString();
0496: IFile destFile = dest.getFile(pathName);
0497: if (!destFile.getParent().exists()) {
0498: CoreUtility
0499: .createFolder((IFolder) destFile
0500: .getParent());
0501: }
0502: // file might exist if previous project was deleted without removing underlying resources
0503: if (destFile.exists())
0504: destFile.delete(true, null);
0505: res
0506: .move(destFile.getFullPath(), true,
0507: null);
0508: }
0509: } else {
0510: resources = ((IFolder) res).members();
0511: for (int i = 0; i < resources.length; i++)
0512: stack.push(resources[i]);
0513: }
0514: }
0515: folder.delete(true, null);
0516: monitor.worked(1);
0517: }
0518: } catch (CoreException e) {
0519: }
0520: }
0521:
0522: private List importAdditionalResources(IProject project,
0523: IPluginModelBase model, SubProgressMonitor monitor)
0524: throws CoreException {
0525: SourceLocationManager manager = PDECore.getDefault()
0526: .getSourceLocationManager();
0527: File location = manager.findSourcePlugin(model.getPluginBase());
0528: File[] children = location == null ? null : location
0529: .listFiles();
0530: ArrayList list = new ArrayList();
0531: if (children != null) {
0532: for (int i = 0; i < children.length; i++) {
0533: String name = children[i].getName();
0534: if (!project.exists(new Path(name))
0535: && !"src.zip".equals(name)) { //$NON-NLS-1$
0536: list.add(children[i]);
0537: }
0538: }
0539:
0540: importContent(location, project.getFullPath(),
0541: FileSystemStructureProvider.INSTANCE, list, monitor);
0542: }
0543: return list;
0544: }
0545:
0546: private void configureBinIncludes(WorkspaceBuildModel buildModel,
0547: IPluginModelBase model, IProject project)
0548: throws CoreException {
0549: IBuild build = buildModel.getBuild(true);
0550: IBuildEntry entry = build.getEntry("bin.includes"); //$NON-NLS-1$
0551: HashMap libraryDirs = getSourceDirectories(build);
0552: if (entry == null) {
0553: entry = buildModel.getFactory().createEntry("bin.includes"); //$NON-NLS-1$
0554: File location = new File(model.getInstallLocation());
0555: if (location.isDirectory()) {
0556: File[] files = location.listFiles();
0557: for (int i = 0; i < files.length; i++) {
0558: String token = files[i].getName();
0559: if ((project.findMember(token) == null)
0560: && (build.getEntry(IBuildEntry.JAR_PREFIX
0561: + token) == null))
0562: continue;
0563: if (files[i].isDirectory()) {
0564: token = token + "/"; //$NON-NLS-1$
0565: if (libraryDirs.containsKey(token))
0566: token = libraryDirs.get(token).toString();
0567: }
0568: entry.addToken(token);
0569: }
0570: } else {
0571: String[] tokens = getTopLevelResources(location);
0572: for (int i = 0; i < tokens.length; i++) {
0573: IResource res = project.findMember(tokens[i]);
0574: if ((res == null)
0575: && (build.getEntry(IBuildEntry.JAR_PREFIX
0576: + tokens[i]) == null))
0577: continue;
0578: if ((res instanceof IFolder)
0579: && (libraryDirs.containsKey(tokens[i])))
0580: continue;
0581: entry.addToken(tokens[i]);
0582: }
0583: }
0584: buildModel.getBuild().add(entry);
0585: }
0586: }
0587:
0588: private HashMap getSourceDirectories(IBuild build) {
0589: HashMap set = new HashMap();
0590: IBuildEntry[] entries = build.getBuildEntries();
0591: for (int i = 0; i < entries.length; i++) {
0592: String name = entries[i].getName();
0593: if (name.startsWith(IBuildEntry.JAR_PREFIX)) {
0594: name = name.substring(7);
0595: String[] tokens = entries[i].getTokens();
0596: for (int j = 0; j < tokens.length; j++) {
0597: set.put(tokens[j], name);
0598: }
0599: }
0600: }
0601: return set;
0602: }
0603:
0604: private void configureSrcIncludes(WorkspaceBuildModel buildModel,
0605: List list) throws CoreException {
0606: IBuildEntry entry = buildModel.getBuild(true).getEntry(
0607: "src.includes"); //$NON-NLS-1$
0608: if (entry == null) {
0609: entry = buildModel.getFactory().createEntry("src.includes"); //$NON-NLS-1$
0610: for (int i = 0; i < list.size(); i++) {
0611: File location = (File) list.get(i);
0612: String token = location.getName();
0613: if (location.isDirectory())
0614: token += "/"; //$NON-NLS-1$
0615: entry.addToken(token);
0616: }
0617: buildModel.getBuild().add(entry);
0618: }
0619: }
0620:
0621: private String addBuildEntry(WorkspaceBuildModel model, String key,
0622: String value) throws CoreException {
0623: IBuild build = model.getBuild(true);
0624: IBuildEntry entry = build.getEntry(key);
0625: if (entry == null) {
0626: entry = model.getFactory().createEntry(key);
0627: entry.addToken(value);
0628: build.add(entry);
0629: }
0630: String[] tokens = entry.getTokens();
0631: return (tokens.length > 0) ? tokens[0] : "src/"; //$NON-NLS-1$
0632: }
0633:
0634: private void linkSourceArchives(IProject project,
0635: IPluginModelBase model, IProgressMonitor monitor)
0636: throws CoreException {
0637:
0638: String[] libraries = getLibraryNames(model, true);
0639: monitor.beginTask(
0640: PDEUIMessages.ImportWizard_operation_copyingSource,
0641: libraries.length);
0642:
0643: SourceLocationManager manager = PDECore.getDefault()
0644: .getSourceLocationManager();
0645: for (int i = 0; i < libraries.length; i++) {
0646: String zipName = ClasspathUtilCore
0647: .getSourceZipName(libraries[i]);
0648: IPath path = new Path(zipName);
0649: if (project.findMember(path) == null) {
0650: IPath srcPath = manager.findSourcePath(model
0651: .getPluginBase(), path);
0652: if (srcPath != null) {
0653: if ("src.zip".equals(zipName) && isJARd(model)) { //$NON-NLS-1$
0654: path = new Path(ClasspathUtilCore
0655: .getSourceZipName(new File(model
0656: .getInstallLocation())
0657: .getName()));
0658: }
0659: IFile zipFile = project.getFile(path.lastSegment());
0660: if (!zipFile.exists()) {
0661: zipFile.createLink(srcPath, IResource.NONE,
0662: new SubProgressMonitor(monitor, 1));
0663: }
0664: }
0665: }
0666: monitor.worked(1);
0667: }
0668: monitor.done();
0669: }
0670:
0671: private void importSourceArchives(IProject project,
0672: IPluginModelBase model, IProgressMonitor monitor)
0673: throws CoreException {
0674:
0675: String[] libraries = getLibraryNames(model, true);
0676: monitor.beginTask(
0677: PDEUIMessages.ImportWizard_operation_copyingSource,
0678: libraries.length);
0679:
0680: SourceLocationManager manager = PDECore.getDefault()
0681: .getSourceLocationManager();
0682: for (int i = 0; i < libraries.length; i++) {
0683: String zipName = ClasspathUtilCore
0684: .getSourceZipName(libraries[i]);
0685: IPath path = new Path(zipName);
0686: if (project.findMember(path) == null) {
0687: IPath srcPath = manager.findSourcePath(model
0688: .getPluginBase(), path);
0689: if (srcPath != null) {
0690: if ("src.zip".equals(zipName) && isJARd(model)) { //$NON-NLS-1$
0691: path = new Path(ClasspathUtilCore
0692: .getSourceZipName(new File(model
0693: .getInstallLocation())
0694: .getName()));
0695: }
0696: importArchive(project, new File(srcPath
0697: .toOSString()), path);
0698: }
0699: }
0700: monitor.worked(1);
0701: }
0702: monitor.done();
0703: }
0704:
0705: private String[] getLibraryNames(IPluginModelBase model,
0706: boolean expand) {
0707: IPluginLibrary[] libraries = model.getPluginBase()
0708: .getLibraries();
0709: ArrayList list = new ArrayList();
0710: for (int i = 0; i < libraries.length; i++) {
0711: if (expand)
0712: list.add(ClasspathUtilCore
0713: .expandLibraryName(libraries[i].getName()));
0714: else
0715: list.add(libraries[i].getName());
0716: }
0717: if (libraries.length == 0 && isJARd(model))
0718: list.add("."); //$NON-NLS-1$
0719: return (String[]) list.toArray(new String[list.size()]);
0720: }
0721:
0722: private void extractJARdPlugin(IProject project,
0723: IPluginModelBase model, IProgressMonitor monitor)
0724: throws CoreException {
0725: ZipFile zipFile = null;
0726: try {
0727: zipFile = new ZipFile(model.getInstallLocation());
0728: ZipFileStructureProvider provider = new ZipFileStructureProvider(
0729: zipFile);
0730: if (!containsCode(provider)) {
0731: extractZipFile(new File(model.getInstallLocation()),
0732: project.getFullPath(), monitor);
0733: return;
0734: }
0735: ArrayList collected = new ArrayList();
0736: collectNonJavaResources(provider, provider.getRoot(),
0737: collected);
0738: importContent(provider.getRoot(), project.getFullPath(),
0739: provider, collected, monitor);
0740:
0741: File file = new File(model.getInstallLocation());
0742: if (hasEmbeddedSource(provider)
0743: && fImportType == IMPORT_WITH_SOURCE) {
0744: collected = new ArrayList();
0745: collectJavaFiles(provider, provider.getRoot(),
0746: collected);
0747: importContent(provider.getRoot(),
0748: project.getFullPath(), provider, collected,
0749: monitor);
0750: collected = new ArrayList();
0751: collectJavaResources(provider, provider.getRoot(),
0752: collected);
0753: importContent(provider.getRoot(), project.getFullPath()
0754: .append("src"), provider, collected, monitor); //$NON-NLS-1$
0755: } else {
0756: if (fImportType == IMPORT_BINARY_WITH_LINKS) {
0757: project.getFile(file.getName()).createLink(
0758: new Path(file.getAbsolutePath()),
0759: IResource.NONE, null);
0760: } else {
0761: importArchive(project, file, new Path(file
0762: .getName()));
0763: }
0764: if (!hasEmbeddedSource(provider)) {
0765: if (fImportType == IMPORT_BINARY_WITH_LINKS) {
0766: linkSourceArchives(project, model,
0767: new SubProgressMonitor(monitor, 1));
0768: } else {
0769: importSourceArchives(project, model,
0770: new SubProgressMonitor(monitor, 1));
0771: }
0772: }
0773: }
0774: if (fImportType != IMPORT_WITH_SOURCE) {
0775: modifyBundleClasspathHeader(project, model);
0776: } else {
0777: removeSignedHeaders(project);
0778: }
0779: setPermissions(model, project);
0780: } catch (IOException e) {
0781: IStatus status = new Status(IStatus.ERROR, PDEPlugin
0782: .getPluginId(), IStatus.ERROR, e.getMessage(), e);
0783: throw new CoreException(status);
0784: } finally {
0785: if (zipFile != null) {
0786: try {
0787: zipFile.close();
0788: } catch (IOException e) {
0789: }
0790: }
0791: }
0792: }
0793:
0794: private void modifyBundleClasspathHeader(IProject project,
0795: IPluginModelBase base) {
0796: IFile file = project.getFile(JarFile.MANIFEST_NAME);
0797: if (file.exists()) {
0798: WorkspaceBundleModel bmodel = new WorkspaceBundleModel(file);
0799: IBundle bundle = bmodel.getBundle();
0800: String classpath = bundle
0801: .getHeader(org.osgi.framework.Constants.BUNDLE_CLASSPATH);
0802: if (classpath == null) {
0803: bundle.setHeader(
0804: org.osgi.framework.Constants.BUNDLE_CLASSPATH,
0805: ClasspathUtilCore.getFilename(base));
0806: } else {
0807: try {
0808: ManifestElement[] elements = ManifestElement
0809: .parseHeader(
0810: org.osgi.framework.Constants.BUNDLE_CLASSPATH,
0811: classpath);
0812: StringBuffer buffer = new StringBuffer();
0813: for (int i = 0; i < elements.length; i++) {
0814: if (buffer.length() > 0) {
0815: buffer.append(","); //$NON-NLS-1$
0816: buffer.append(System
0817: .getProperty("line.separator")); //$NON-NLS-1$
0818: buffer.append(" "); //$NON-NLS-1$
0819: }
0820: if (elements[i].getValue().equals(".")) //$NON-NLS-1$
0821: buffer.append(ClasspathUtilCore
0822: .getFilename(base));
0823: else
0824: buffer.append(elements[i].getValue());
0825: }
0826: bundle
0827: .setHeader(
0828: org.osgi.framework.Constants.BUNDLE_CLASSPATH,
0829: buffer.toString());
0830: } catch (BundleException e) {
0831: }
0832: }
0833: bmodel.save();
0834: }
0835: }
0836:
0837: private void removeSignedHeaders(IProject project) {
0838: IFile file = project.getFile(JarFile.MANIFEST_NAME);
0839: if (!file.exists())
0840: return;
0841: WorkspaceBundleModel model = new WorkspaceBundleModel(file);
0842: model.save();
0843: }
0844:
0845: private IProject findProject(String id) {
0846: IPluginModelBase model = PluginRegistry.findModel(id);
0847: if (model != null) {
0848: IResource resource = model.getUnderlyingResource();
0849: if (resource != null)
0850: return resource.getProject();
0851: }
0852: return PDEPlugin.getWorkspace().getRoot().getProject(id);
0853: }
0854:
0855: private boolean queryReplace(IProject project)
0856: throws OperationCanceledException {
0857: switch (fReplaceQuery.doQuery(NLS.bind(
0858: PDEUIMessages.ImportWizard_messages_exists, project
0859: .getName()))) {
0860: case IImportQuery.CANCEL:
0861: throw new OperationCanceledException();
0862: case IImportQuery.NO:
0863: return false;
0864: }
0865: return true;
0866: }
0867:
0868: private boolean queryExecutionEnvironment(String message)
0869: throws OperationCanceledException {
0870: switch (fExecutionQuery.doQuery(message)) {
0871: case IImportQuery.CANCEL:
0872: throw new OperationCanceledException();
0873: case IImportQuery.NO:
0874: return false;
0875: }
0876: return true;
0877: }
0878:
0879: private void setProjectDescription(IProject project,
0880: IPluginModelBase model) throws CoreException {
0881: IProjectDescription desc = project.getDescription();
0882: if (!desc.hasNature(PDE.PLUGIN_NATURE))
0883: CoreUtility.addNatureToProject(project, PDE.PLUGIN_NATURE,
0884: null);
0885: if (needsJavaNature(project, model)
0886: && !desc.hasNature(JavaCore.NATURE_ID))
0887: CoreUtility.addNatureToProject(project, JavaCore.NATURE_ID,
0888: null);
0889: }
0890:
0891: private boolean needsJavaNature(IProject project,
0892: IPluginModelBase model) {
0893: if (model.getPluginBase().getLibraries().length > 0)
0894: return true;
0895:
0896: BundleDescription desc = model.getBundleDescription();
0897: if (desc != null) {
0898: if (desc.getExportPackages().length > 0)
0899: return true;
0900: if (desc.getRequiredBundles().length > 0)
0901: return true;
0902: if (desc.getImportPackages().length > 0)
0903: return true;
0904: }
0905: return false;
0906: }
0907:
0908: private boolean isExempt(IPluginModelBase model) {
0909: String id = model.getPluginBase().getId();
0910: if ("org.apache.ant".equals(id) //$NON-NLS-1$
0911: || "org.eclipse.osgi.util".equals(id) //$NON-NLS-1$
0912: || "org.eclipse.osgi.services".equals(id) //$NON-NLS-1$
0913: || "org.eclipse.core.runtime.compatibility.registry".equals(id)) //$NON-NLS-1$
0914: return true;
0915:
0916: if ("org.eclipse.swt".equals(id) && !isJARd(model)) //$NON-NLS-1$
0917: return true;
0918: return false;
0919: }
0920:
0921: private boolean isJARd(IPluginModelBase model) {
0922: return new File(model.getInstallLocation()).isFile();
0923: }
0924:
0925: private void setPermissions(IPluginModelBase model, IProject project) {
0926: try {
0927: if (!Platform.getOS().equals(Constants.OS_WIN32)
0928: && model instanceof IFragmentModel) {
0929: IFragment fragment = ((IFragmentModel) model)
0930: .getFragment();
0931: if ("org.eclipse.swt".equals(fragment.getPluginId())) { //$NON-NLS-1$
0932: IResource[] children = project.members();
0933: for (int i = 0; i < children.length; i++) {
0934: if (children[i] instanceof IFile
0935: && isInterestingResource(children[i]
0936: .getName())) {
0937: Runtime
0938: .getRuntime()
0939: .exec(
0940: new String[] {
0941: "chmod", "755", children[i].getLocation().toOSString() }).waitFor(); //$NON-NLS-1$ //$NON-NLS-2$
0942: }
0943: }
0944: }
0945: }
0946: } catch (CoreException e) {
0947: } catch (InterruptedException e) {
0948: } catch (IOException e) {
0949: }
0950: }
0951:
0952: private boolean isInterestingResource(String name) {
0953: return name.endsWith(".jnilib") //$NON-NLS-1$
0954: || name.endsWith(".sl") //$NON-NLS-1$
0955: || name.endsWith(".a") //$NON-NLS-1$
0956: || name.indexOf(".so") != -1; //$NON-NLS-1$
0957: }
0958:
0959: private IFragment[] getFragmentsFor(IPluginModelBase model) {
0960: ArrayList result = new ArrayList();
0961: for (int i = 0; i < fModels.length; i++) {
0962: if (fModels[i] instanceof IFragmentModel) {
0963: HostSpecification spec = fModels[i]
0964: .getBundleDescription().getHost();
0965: BundleDescription host = spec == null ? null
0966: : (BundleDescription) spec.getSupplier();
0967: if (model.getBundleDescription().equals(host)) {
0968: result.add(((IFragmentModel) fModels[i])
0969: .getFragment());
0970: }
0971: }
0972: }
0973: return (IFragment[]) result
0974: .toArray(new IFragment[result.size()]);
0975: }
0976:
0977: private void importJarFromFragment(IProject project,
0978: IFragment fragment, String name) throws CoreException {
0979: IPath jarPath = new Path(ClasspathUtilCore
0980: .expandLibraryName(name));
0981: File jar = new File(fragment.getModel().getInstallLocation(),
0982: jarPath.toString());
0983: if (jar.exists()) {
0984: importArchive(project, jar, jarPath);
0985: }
0986: }
0987:
0988: private void importSourceFromFragment(IProject project,
0989: IFragment fragment, String name) throws CoreException {
0990: IPath jarPath = new Path(ClasspathUtilCore
0991: .expandLibraryName(name));
0992: IPath srcPath = new Path(ClasspathUtilCore
0993: .getSourceZipName(jarPath.toString()));
0994: SourceLocationManager manager = PDECore.getDefault()
0995: .getSourceLocationManager();
0996: File srcFile = manager.findSourceFile(fragment, srcPath);
0997: if (srcFile != null) {
0998: importArchive(project, srcFile, srcPath);
0999: }
1000: }
1001:
1002: protected void collectNonJavaResources(
1003: ZipFileStructureProvider provider, Object element,
1004: ArrayList collected) {
1005: super .collectNonJavaResources(provider, element, collected);
1006: if (fImportType != IMPORT_WITH_SOURCE)
1007: return;
1008: // filter the resources we get back to include only relevant resource files
1009: ListIterator li = collected.listIterator();
1010: while (li.hasNext()) {
1011: ZipEntry ze = (ZipEntry) li.next();
1012: String name = ze.getName();
1013: // filter out signature files - bug 175756
1014: if (name.startsWith("META-INF/") && (name.endsWith(".RSA") || name.endsWith(".DSA") || name.endsWith(".SF"))) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
1015: li.remove();
1016: }
1017: }
1018:
1019: }
|