|
What this is
Other links
The source code/******************************************************************************* * Copyright (c) 2000, 2008 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.pde.internal.ui.wizards.imports; import java.io.File; import java.io.IOException; import java.util.*; import java.util.jar.JarFile; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.*; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager; import org.eclipse.osgi.service.environment.Constants; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.service.resolver.HostSpecification; import org.eclipse.osgi.util.ManifestElement; import org.eclipse.osgi.util.NLS; import org.eclipse.pde.core.build.IBuild; import org.eclipse.pde.core.build.IBuildEntry; import org.eclipse.pde.core.plugin.*; import org.eclipse.pde.internal.core.*; import org.eclipse.pde.internal.core.build.WorkspaceBuildModel; import org.eclipse.pde.internal.core.bundle.WorkspaceBundleModel; import org.eclipse.pde.internal.core.ibundle.IBundle; import org.eclipse.pde.internal.core.natures.PDE; import org.eclipse.pde.internal.core.util.CoreUtility; import org.eclipse.pde.internal.ui.PDEPlugin; import org.eclipse.pde.internal.ui.PDEUIMessages; import org.eclipse.swt.widgets.Display; import org.eclipse.team.core.RepositoryProvider; import org.eclipse.team.core.TeamException; import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider; import org.osgi.framework.BundleException; /** * Imports one or more plugins into the workspace. There are three different * ways to import a plugin: as binary, as binary with linked source, * and as source. */ public class PluginImportOperation extends JarImportOperation { public static final int IMPORT_BINARY = 1; public static final int IMPORT_BINARY_WITH_LINKS = 2; public static final int IMPORT_WITH_SOURCE = 3; private IPluginModelBase[] fModels; private int fImportType; private IImportQuery fReplaceQuery; private Hashtable fProjectClasspaths = new Hashtable(); private boolean fForceAutobuild; private IImportQuery fExecutionQuery; private boolean fLaunchedConfigurations = false; private ArrayList fAffectedPlugins; public interface IImportQuery { public static final int CANCEL = 0; public static final int NO = 1; public static final int YES = 2; int doQuery(String message); } /** * Constructor * @param models models of plugins to import * @param importType one of three types specified by constants, binary, binary with links, source * @param replaceQuery defines what to do if the project already exists in the workspace * @param executionQuery defines what to do if the project requires an unsupported execution environment */ public PluginImportOperation(IPluginModelBase[] models, int importType, IImportQuery replaceQuery, IImportQuery executionQuery) { fModels = models; fImportType = importType; fReplaceQuery = replaceQuery; fExecutionQuery = executionQuery; fAffectedPlugins = new ArrayList(models.length); } /** * Constructor * @param models models of plugins to import * @param importType one of three types specified by constants, binary, binary with links, source * @param replaceQuery defines what to do if the project already exists in the workspace * @param executionQuery defines what to do if the project requires an unsupported execution environment * @param forceAutobuild whether to force a build after the import */ public PluginImportOperation(IPluginModelBase[] models, int importType, IImportQuery replaceQuery, IImportQuery executionQuery, boolean forceAutobuild) { this(models, importType, replaceQuery, executionQuery); fForceAutobuild = forceAutobuild; } /* (non-Javadoc) * @see org.eclipse.core.resources.IWorkspaceRunnable#run(org.eclipse.core.runtime.IProgressMonitor) */ public void run(IProgressMonitor monitor) throws CoreException, OperationCanceledException { if (monitor == null) { monitor = new NullProgressMonitor(); } monitor.beginTask(PDEUIMessages.ImportWizard_operation_creating, fModels.length + 1); try { MultiStatus multiStatus = new MultiStatus(PDEPlugin.getPluginId(), IStatus.OK, PDEUIMessages.ImportWizard_operation_multiProblem, null); for (int i = 0; i < fModels.length; i++) { try { importPlugin(fModels[i], new SubProgressMonitor(monitor, 1)); } catch (CoreException e) { multiStatus.merge(e.getStatus()); } if (monitor.isCanceled()) { setClasspaths(new SubProgressMonitor(monitor, 1)); throw new OperationCanceledException(); } } setClasspaths(new SubProgressMonitor(monitor, 1)); if (!ResourcesPlugin.getWorkspace().isAutoBuilding() && fForceAutobuild) runBuildJob(); if (!multiStatus.isOK()) throw new CoreException(multiStatus); } finally { monitor.done(); if (!fAffectedPlugins.isEmpty()) { final Display display = Display.getDefault(); display.syncExec(new Runnable() { public void run() { PluginImportFinishDialog dialog = new PluginImportFinishDialog(display.getActiveShell()); dialog.setTitle(PDEUIMessages.PluginImportInfoDialog_title); dialog.setMessage(PDEUIMessages.PluginImportInfoDialog_message); dialog.setInput(fAffectedPlugins); dialog.open(); } }); } } } /** * Starts a job that will build the workspace */ private void runBuildJob() { Job buildJob = new Job(PDEUIMessages.CompilersConfigurationBlock_building) { public boolean belongsTo(Object family) { return ResourcesPlugin.FAMILY_AUTO_BUILD == family; } protected IStatus run(IProgressMonitor monitor) { try { PDEPlugin.getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor); } catch (CoreException e) { } return Status.OK_STATUS; } }; buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule()); buildJob.schedule(); } /** * Sets the raw classpath of projects that need to be updated * @param monitor * @throws JavaModelException if a classpath could not be set */ private void setClasspaths(IProgressMonitor monitor) throws JavaModelException { monitor.beginTask("", fProjectClasspaths.size()); //$NON-NLS-1$ Enumeration keys = fProjectClasspaths.keys(); while (keys.hasMoreElements()) { IProject project = (IProject) keys.nextElement(); IClasspathEntry[] classpath = (IClasspathEntry[]) fProjectClasspaths.get(project); monitor.subTask(project.getName()); JavaCore.create(project).setRawClasspath(classpath, new SubProgressMonitor(monitor, 1)); } } /** * This method starts the import of a specific plugin. Checks if the execution * environment is supported and also checks if the project already exists and * needs to be replaced. * @param model model representing the plugin to import * @param monitor progress monitor * @throws CoreException if a problem occurs while importing a plugin */ private void importPlugin(IPluginModelBase model, IProgressMonitor monitor) throws CoreException { String id = model.getPluginBase().getId(); monitor.beginTask(NLS.bind(PDEUIMessages.ImportWizard_operation_creating2, id), 6); try { BundleDescription desc = model.getBundleDescription(); if (desc != null) { IExecutionEnvironmentsManager manager = JavaRuntime.getExecutionEnvironmentsManager(); String[] envs = desc.getExecutionEnvironments(); boolean found = false; for (int i = 0; i < envs.length; i++) { if (manager.getEnvironment(envs[i]) != null) { found = true; break; } } if (envs.length > 0 && !found) { String message = NLS.bind(PDEUIMessages.PluginImportOperation_executionEnvironment, id, envs[0]); if (!queryExecutionEnvironment(message)) return; } } IProject project = findProject(id); if (project.exists() || new File(project.getParent().getLocation().toFile(), project.getName()).exists()) { if (!queryReplace(project)) return; if (RepositoryProvider.isShared(project)) RepositoryProvider.unmap(project); if (!project.exists()) project.create(new SubProgressMonitor(monitor, 1)); if (!safeDeleteCheck(project, monitor)) { fAffectedPlugins.add(model); return; } //bug 212755 try { project.delete(true, true, monitor); } catch (CoreException e) { fAffectedPlugins.add(model); return; } } project.create(monitor); if (!project.isOpen()) project.open(monitor); monitor.worked(1); switch (fImportType) { case IMPORT_BINARY : importAsBinary(project, model, true, new SubProgressMonitor(monitor, 4)); break; case IMPORT_BINARY_WITH_LINKS : if (id.startsWith("org.eclipse.swt") && !isJARd(model)) { //$NON-NLS-1$ importAsBinary(project, model, true, monitor); } else { importAsBinaryWithLinks(project, model, new SubProgressMonitor(monitor, 4)); } break; case IMPORT_WITH_SOURCE : if (isExempt(model)) { importAsBinary(project, model, true, new SubProgressMonitor(monitor, 4)); } else { importAsSource(project, model, new SubProgressMonitor(monitor, 4)); } } setProjectDescription(project, model); if (project.hasNature(JavaCore.NATURE_ID) && project.findMember(".classpath") == null) //$NON-NLS-1$ fProjectClasspaths.put(project, ClasspathComputer.getClasspath(project, model, true, false)); } catch (CoreException e) { PDEPlugin.logException(e); } finally { monitor.done(); } } // Returns the name of any projects the currently exist with same id and version. Otherwise it returns a default naming convention protected String getProjectName(IPluginModelBase model) { String id = model.getPluginBase().getId(); String version = model.getPluginBase().getVersion(); ModelEntry entry = PluginRegistry.findEntry(id); if (entry != null) { IPluginModelBase[] existingModels = entry.getWorkspaceModels(); for (int i = 0; i < existingModels.length; i++) { String existingVersion = existingModels[i].getPluginBase().getVersion(); if (version.equals(existingVersion)) { IResource res = existingModels[i].getUnderlyingResource(); if (res != null) return res.getProject().getName(); } } } return id + "_" + version; //$NON-NLS-1$ } // returns true if it is safe to delete the project. It is not safe to delete if // one of its libraries is locked by a running launch configuration. private boolean safeDeleteCheck(IProject project, IProgressMonitor monitor) { if (!fLaunchedConfigurations) return true; IPluginModelBase base = PluginRegistry.findModel(project); if (base != null) { IPluginLibrary[] libraries = base.getPluginBase().getLibraries(); for (int i = 0; i < libraries.length; i++) { IResource res = project.findMember(libraries[i].getName()); if (res != null) try { if (!(ResourcesPlugin.getWorkspace().delete(new IResource[] {res}, true, monitor).isOK())) return false; } catch (CoreException e) { return false; } } } return true; } /** * Imports the contents of the plugin and adds links to the source location(s). * @param project destination project of the import * @param model model representing the plugin to import * @param monitor progress monitor * @throws CoreException if there is a problem completing the import */ private void importAsBinaryWithLinks(IProject project, IPluginModelBase model, IProgressMonitor monitor) throws CoreException { if (isJARd(model)) { extractJARdPlugin(project, model, monitor); } else { File installLocation = new File(model.getInstallLocation()); File[] items = installLocation.listFiles(); if (items != null) { monitor.beginTask(PDEUIMessages.PluginImportOperation_linking, items.length + 1); for (int i = 0; i < items.length; i++) { File sourceFile = items[i]; String name = sourceFile.getName(); if (sourceFile.isDirectory()) { project.getFolder(name).createLink(new Path(sourceFile.getPath()), IResource.NONE, new SubProgressMonitor(monitor, 1)); } else { if (!name.equals(".project")) { //$NON-NLS-1$ project.getFile(name).createLink(new Path(sourceFile.getPath()), IResource.NONE, new SubProgressMonitor(monitor, 1)); } else { // if the binary project with links has a .project file, copy it instead of linking (allows us to edit it) ArrayList filesToImport = new ArrayList(1); filesToImport.add(sourceFile); importContent(installLocation, project.getFullPath(), FileSystemStructureProvider.INSTANCE, filesToImport, new SubProgressMonitor(monitor, 1)); } } } } linkSourceArchives(project, model, new SubProgressMonitor(monitor, 1)); } try { RepositoryProvider.map(project, PDECore.BINARY_REPOSITORY_PROVIDER); } catch (TeamException e) { } } /** * Imports the contents of the plugin and imports source files as binary files that will not be compiled. * @param project destination project of the import * @param model model representing the plugin to import * @param markAsBinary whether to mark the project as a binary project * @param monitor progress monitor * @throws CoreException if there is a problem completing the import */ private void importAsBinary(IProject project, IPluginModelBase model, boolean markAsBinary, IProgressMonitor monitor) throws CoreException { monitor.beginTask("", 4); //$NON-NLS-1$ if (isJARd(model)) { extractJARdPlugin(project, model, new SubProgressMonitor(monitor, 3)); } else { importContent(new File(model.getInstallLocation()), project.getFullPath(), FileSystemStructureProvider.INSTANCE, null, new SubProgressMonitor(monitor, 1)); importSourceArchives(project, model, new SubProgressMonitor(monitor, 1)); // make sure all libraries have been imported // if any are missing, check in fragments IFragment[] fragments = getFragmentsFor(model); IPluginLibrary[] libraries = model.getPluginBase().getLibraries(); IProgressMonitor fragmentMonitor = new SubProgressMonitor(monitor, 1); fragmentMonitor.beginTask("", libraries.length); //$NON-NLS-1$ for (int i = 0; i < libraries.length; i++) { String libraryName = libraries[i].getName(); if (ClasspathUtilCore.containsVariables(libraryName) && !project.exists(new Path(ClasspathUtilCore.expandLibraryName(libraryName)))) { for (int j = 0; j < fragments.length; j++) { importJarFromFragment(project, fragments[j], libraryName); importSourceFromFragment(project, fragments[j], libraryName, new SubProgressMonitor(monitor, 1)); } } else { monitor.worked(1); } } } if (markAsBinary) { project.setPersistentProperty(PDECore.EXTERNAL_PROJECT_PROPERTY, PDECore.BINARY_PROJECT_VALUE); importAdditionalResources(project, model, new SubProgressMonitor(monitor, 1)); } else { monitor.done(); } } /** * Imports the contents of the plugin and imports source files to source folders that will be compiled. * @param project destination project of the import * @param model model representing the plugin to import * @param monitor progress monitor * @throws CoreException if there is a problem completing the import */ private void importAsSource(IProject project, IPluginModelBase model, SubProgressMonitor monitor) throws CoreException { monitor.beginTask("", 4); //$NON-NLS-1$ importAsBinary(project, model, false, new SubProgressMonitor(monitor, 2)); List list = importAdditionalResources(project, model, new SubProgressMonitor(monitor, 1)); WorkspaceBuildModel buildModel = new WorkspaceBuildModel(project.getFile("build.properties")); //$NON-NLS-1$ if (!isJARd(model) || containsCode(new File(model.getInstallLocation()))) { String[] libraries = getLibraryNames(model, false); if (libraries.length == 0) libraries = new String[] {"."}; //$NON-NLS-1$ for (int i = 0; i < libraries.length; i++) { if (ClasspathUtilCore.containsVariables(libraries[i])) continue; String name = ClasspathUtilCore.expandLibraryName(libraries[i]); IPath libraryPath = (name.equals(".") && isJARd(model)) //$NON-NLS-1$ ? new Path(new File(model.getInstallLocation()).getName()) : new Path(name); IResource jarFile = project.findMember(libraryPath); if (jarFile != null) { String srcName = ClasspathUtilCore.getSourceZipName(libraryPath.lastSegment()); IResource srcZip = jarFile.getProject().findMember(srcName); if (srcZip == null) { int extIndex = srcName.lastIndexOf('.'); if (extIndex != -1) { srcZip = jarFile.getProject().findMember(srcName.substring(0, extIndex)); } } // srcZip == null if plug-in has embedded source // if it jarred, all necessary files already in src folder if (srcZip == null && libraries[i].equals(".") && !isJARd(model)) //$NON-NLS-1$ // if src does not exist (and returns null), then must not be plug-in with embedded source srcZip = jarFile.getProject().findMember("src"); //$NON-NLS-1$ if (srcZip != null) { String jarName = libraries[i].equals(".") ? "" : libraryPath.removeFileExtension().lastSegment(); //$NON-NLS-1$ //$NON-NLS-2$ String folder = addBuildEntry(buildModel, "source." + libraries[i], "src" + (jarName.length() == 0 ? "/" : "-" + jarName + "/")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ IFolder dest = jarFile.getProject().getFolder(folder); if (srcZip instanceof IFolder) { // if the source (srcZip) equals the destination folder (dest), then we don't want to delete/copy since every // is already where it needs to be. This happens when importing source bundles in folder format declaring source with ext. point. (bug 214542) if (!srcZip.equals(dest)) { if (dest.exists()) { dest.delete(true, null); } ((IFolder) srcZip).move(dest.getFullPath(), true, new SubProgressMonitor(monitor, 1)); } } else if (srcZip instanceof IFile) { if (!dest.exists()) { dest.create(true, true, null); } extractZipFile(srcZip.getLocation().toFile(), dest.getFullPath(), new SubProgressMonitor(monitor, 1)); srcZip.delete(true, null); } else monitor.worked(1); if (jarFile instanceof IFile) { if (isJARd(model)) { extractJavaResources(jarFile.getLocation().toFile(), dest, new SubProgressMonitor(monitor, 1)); } else { extractResources(jarFile.getLocation().toFile(), dest, new SubProgressMonitor(monitor, 1)); } jarFile.delete(true, null); } else { moveBinaryContents((IContainer) jarFile, dest, new SubProgressMonitor(monitor, 1)); } } } else if (name.equals(".") && project.getFolder("src").exists()) { //$NON-NLS-1$ //$NON-NLS-2$ addBuildEntry(buildModel, "source..", "src/"); //$NON-NLS-1$ //$NON-NLS-2$ } } } configureBinIncludes(buildModel, model, project); if (list.size() > 0) configureSrcIncludes(buildModel, list); buildModel.save(); } /** * Moves the binary files from the source container to the folder destination. * Moves any file that isn't a .class file * @param srcFolder container to move from * @param dest folder to move to * @param monitor progress monitor */ private void moveBinaryContents(IContainer srcFolder, IFolder dest, IProgressMonitor monitor) { try { // get all the folders for which we want to search IResource[] children = dest.members(); ArrayList validFolders = new ArrayList(); for (int i = 0; i < children.length; i++) if (children[i] instanceof IFolder) { String folderName = children[i].getName(); IResource folder = srcFolder.findMember(folderName); if (folder != null && folder instanceof IFolder) validFolders.add(folder); } monitor.beginTask(new String(), validFolders.size()); ListIterator li = validFolders.listIterator(); while (li.hasNext()) { IFolder folder = (IFolder) li.next(); int pathSegments = folder.getProjectRelativePath().segmentCount() - 1; Stack stack = new Stack(); IResource[] resources = folder.members(); for (int i = 0; i < resources.length; i++) stack.push(resources[i]); while (!stack.isEmpty()) { IResource res = (IResource) stack.pop(); if (res instanceof IFile) { if (!res.getName().endsWith(".class")) { //$NON-NLS-1$ String pathName = res.getProjectRelativePath().removeFirstSegments(pathSegments).toString(); IFile destFile = dest.getFile(pathName); if (!destFile.getParent().exists()) { CoreUtility.createFolder((IFolder) destFile.getParent()); } // file might exist if previous project was deleted without removing underlying resources if (destFile.exists()) destFile.delete(true, null); res.move(destFile.getFullPath(), true, null); } } else { resources = ((IFolder) res).members(); for (int i = 0; i < resources.length; i++) stack.push(resources[i]); } } folder.delete(true, null); monitor.worked(1); } } catch (CoreException e) { } } /** * Searches source locations for files to import to the new project, will ignore * src.zip. * @param project destination project of the import * @param model model representing the plugin to import * @param monitor progress monitor * @return list of imported files * @throws CoreException if there is a problem completing the import */ private List importAdditionalResources(IProject project, IPluginModelBase model, SubProgressMonitor monitor) throws CoreException { SourceLocationManager manager = PDECore.getDefault().getSourceLocationManager(); File location = manager.findSourcePlugin(model.getPluginBase()); if (location != null) { ArrayList list = new ArrayList(); if (location.isDirectory()) { Object root = location; File[] children = location.listFiles(); if (children != null) { for (int i = 0; i < children.length; i++) { String name = children[i].getName(); if (!project.exists(new Path(name)) && !"src.zip".equals(name)) { //$NON-NLS-1$ list.add(children[i]); } } importContent(root, project.getFullPath(), FileSystemStructureProvider.INSTANCE, list, monitor); ArrayList srcEntryList = new ArrayList(list.size()); for (ListIterator iterator = list.listIterator(); iterator.hasNext();) { File current = (File) iterator.next(); String entry = current.getName(); if (current.isDirectory()) { entry += "/"; //$NON-NLS-1$ } srcEntryList.add(entry); } return srcEntryList; } } else if (location.isFile()) { ZipFile zipFile = null; try { zipFile = new ZipFile(location); ZipFileStructureProvider zipProvider = new ZipFileStructureProvider(zipFile); Object root = zipProvider.getRoot(); collectAdditionalResources(zipProvider, root, list, project); importContent(root, project.getFullPath(), zipProvider, list, monitor); ArrayList srcEntryList = new ArrayList(list.size()); for (Iterator iterator = list.iterator(); iterator.hasNext();) { ZipEntry current = (ZipEntry) iterator.next(); String entry = current.getName(); srcEntryList.add(entry); } return srcEntryList; } catch (IOException e) { IStatus status = new Status(IStatus.ERROR, PDEPlugin.getPluginId(), IStatus.ERROR, e.getMessage(), e); throw new CoreException(status); } finally { if (zipFile != null) { try { zipFile.close(); } catch (IOException e) { } } } } } return new ArrayList(0); } private void configureBinIncludes(WorkspaceBuildModel buildModel, IPluginModelBase model, IProject project) throws CoreException { IBuild build = buildModel.getBuild(true); IBuildEntry entry = build.getEntry("bin.includes"); //$NON-NLS-1$ HashMap libraryDirs = getSourceDirectories(build); if (entry == null) { entry = buildModel.getFactory().createEntry("bin.includes"); //$NON-NLS-1$ File location = new File(model.getInstallLocation()); if (location.isDirectory()) { File[] files = location.listFiles(); for (int i = 0; i < files.length; i++) { String token = files[i].getName(); if ((project.findMember(token) == null) && (build.getEntry(IBuildEntry.JAR_PREFIX + token) == null)) continue; if (files[i].isDirectory()) { token = token + "/"; //$NON-NLS-1$ if (libraryDirs.containsKey(token)) token = libraryDirs.get(token).toString(); } entry.addToken(token); } } else { String[] tokens = getTopLevelResources(location); for (int i = 0; i < tokens.length; i++) { IResource res = project.findMember(tokens[i]); if ((res == null) && (build.getEntry(IBuildEntry.JAR_PREFIX + tokens[i]) == null)) continue; if ((res instanceof IFolder) && (libraryDirs.containsKey(tokens[i]))) continue; entry.addToken(tokens[i]); } } buildModel.getBuild().add(entry); } } private HashMap getSourceDirectories(IBuild build) { HashMap set = new HashMap(); IBuildEntry[] entries = build.getBuildEntries(); for (int i = 0; i < entries.length; i++) { String name = entries[i].getName(); if (name.startsWith(IBuildEntry.JAR_PREFIX)) { name = name.substring(7); String[] tokens = entries[i].getTokens(); for (int j = 0; j < tokens.length; j++) { set.put(tokens[j], name); } } } return set; } private void configureSrcIncludes(WorkspaceBuildModel buildModel, List list) throws CoreException { IBuildEntry entry = buildModel.getBuild(true).getEntry("src.includes"); //$NON-NLS-1$ if (entry == null) { entry = buildModel.getFactory().createEntry("src.includes"); //$NON-NLS-1$ for (int i = 0; i < list.size(); i++) { entry.addToken(list.get(i).toString()); } buildModel.getBuild().add(entry); } } private String addBuildEntry(WorkspaceBuildModel model, String key, String value) throws CoreException { IBuild build = model.getBuild(true); IBuildEntry entry = build.getEntry(key); if (entry == null) { entry = model.getFactory().createEntry(key); entry.addToken(value); build.add(entry); } String[] tokens = entry.getTokens(); return (tokens.length > 0) ? tokens[0] : "src/"; //$NON-NLS-1$ } /** * Creates links in the project to the source locations for the various libraries. * If the source for all libraries is in a single bundle, one link is created * @param project destination project of the import * @param model model representing the plugin to import * @param monitor progress monitor * @throws CoreException if there is a problem completing the import */ private void linkSourceArchives(IProject project, IPluginModelBase model, IProgressMonitor monitor) throws CoreException { String[] libraries = getLibraryNames(model, true); monitor.beginTask(PDEUIMessages.ImportWizard_operation_copyingSource, libraries.length); SourceLocationManager manager = PDECore.getDefault().getSourceLocationManager(); if (manager.hasBundleManifestLocation(model.getPluginBase())) { IPath srcPath = manager.findSourcePath(model.getPluginBase(), null); if (srcPath != null) { // Source for all libraries is in the same bundle, just create one link to the source bundle IPath path = new Path(project.getName() + "src.zip"); //$NON-NLS-1$ IFile srcFile = project.getFile(path.lastSegment()); if (!srcFile.exists()) { srcFile.createLink(srcPath, IResource.NONE, new SubProgressMonitor(monitor, 1)); } } monitor.worked(libraries.length); } else { for (int i = 0; i < libraries.length; i++) { String zipName = ClasspathUtilCore.getSourceZipName(libraries[i]); IPath path = new Path(zipName); if (project.findMember(path) == null) { IPath srcPath = manager.findSourcePath(model.getPluginBase(), path); if (srcPath != null) { if ("src.zip".equals(zipName) && isJARd(model)) { //$NON-NLS-1$ path = new Path(ClasspathUtilCore.getSourceZipName(new File(model.getInstallLocation()).getName())); } IFile zipFile = project.getFile(path.lastSegment()); if (!zipFile.exists()) { zipFile.createLink(srcPath, IResource.NONE, new SubProgressMonitor(monitor, 1)); } } } monitor.worked(1); } } monitor.done(); } private void importSourceArchives(IProject project, IPluginModelBase model, IProgressMonitor monitor) throws CoreException { String[] libraries = getLibraryNames(model, true); monitor.beginTask(PDEUIMessages.ImportWizard_operation_copyingSource, libraries.length); SourceLocationManager manager = PDECore.getDefault().getSourceLocationManager(); Set roots = null; if (manager.hasBundleManifestLocation(model.getPluginBase())) roots = manager.findSourceRoots(model.getPluginBase()); for (int i = 0; i < libraries.length; i++) { String zipName = ClasspathUtilCore.getSourceZipName(libraries[i]); IPath path = new Path(zipName); if (project.findMember(path) == null) { // if we are importing the source through a sourceBundle header... if (roots != null) { IPath sourceLocation = manager.findSourcePath(model.getPluginBase(), null); String currentRoot = ".".equals(libraries[i]) ? "." : path.removeFileExtension().toString(); //$NON-NLS-1$ //$NON-NLS-2$ if (roots.contains(currentRoot)) { if (".".equals(currentRoot)) { //$NON-NLS-1$ // Save to a special folder name based on the install location IPath sourceName = getDefaultSourceNameForProject(model); sourceName = sourceName.removeFileExtension(); IFolder dest = project.getFolder(sourceName); if (!dest.exists()) { dest.create(true, true, null); } // List all of the other source roots so they are not included when importing source from the root, ".", of the jar Set allBundleRoots = manager.findAllSourceRootsInSourceLocation(model.getPluginBase()); List rootsToExclude = new ArrayList(allBundleRoots.size() - 1); for (Iterator iterator2 = allBundleRoots.iterator(); iterator2.hasNext();) { String rootString = (String) iterator2.next(); if (!".".equals(rootString)) { //$NON-NLS-1$ rootsToExclude.add(new Path(rootString)); } } // Extract folders containing java source extractJavaSource(new File(sourceLocation.toOSString()), rootsToExclude, dest, monitor); } else { // Extract the specific library from it's folder extractResourcesFromFolder(new File(sourceLocation.toOSString()), new Path(currentRoot), project, monitor); } } } else { IPath srcPath = manager.findSourcePath(model.getPluginBase(), path); if (srcPath != null) { if ("src.zip".equals(zipName) && isJARd(model)) { //$NON-NLS-1$ path = getDefaultSourceNameForProject(model); } importArchive(project, new File(srcPath.toOSString()), path); } } } monitor.worked(1); } monitor.done(); } /** * Creates a path representing a zip file that is named based on the plugin install location. * Used to replace src.zip with a more unique and meaningful name. * @param model model that the src.zip containg source for * @return a new path describing the zip file */ private IPath getDefaultSourceNameForProject(IPluginModelBase model) { return new Path(ClasspathUtilCore.getSourceZipName(new File(model.getInstallLocation()).getName())); } private String[] getLibraryNames(IPluginModelBase model, boolean expand) { IPluginLibrary[] libraries = model.getPluginBase().getLibraries(); ArrayList list = new ArrayList(); for (int i = 0; i < libraries.length; i++) { if (expand) list.add(ClasspathUtilCore.expandLibraryName(libraries[i].getName())); else list.add(libraries[i].getName()); } if (libraries.length == 0 && isJARd(model)) list.add("."); //$NON-NLS-1$ return (String[]) list.toArray(new String[list.size()]); } private void extractJARdPlugin(IProject project, IPluginModelBase model, IProgressMonitor monitor) throws CoreException { ZipFile zipFile = null; try { zipFile = new ZipFile(model.getInstallLocation()); ZipFileStructureProvider provider = new ZipFileStructureProvider(zipFile); if (!containsCode(provider)) { extractZipFile(new File(model.getInstallLocation()), project.getFullPath(), monitor); return; } ArrayList collected = new ArrayList(); collectNonJavaResources(provider, provider.getRoot(), collected); importContent(provider.getRoot(), project.getFullPath(), provider, collected, monitor); File file = new File(model.getInstallLocation()); if (hasEmbeddedSource(provider) && fImportType == IMPORT_WITH_SOURCE) { collected = new ArrayList(); collectJavaFiles(provider, provider.getRoot(), collected); importContent(provider.getRoot(), project.getFullPath(), provider, collected, monitor); collected = new ArrayList(); collectJavaResources(provider, provider.getRoot(), collected); importContent(provider.getRoot(), project.getFullPath().append("src"), provider, collected, monitor); //$NON-NLS-1$ } else { if (fImportType == IMPORT_BINARY_WITH_LINKS) { project.getFile(file.getName()).createLink(new Path(file.getAbsolutePath()), IResource.NONE, null); } else { importArchive(project, file, new Path(file.getName())); } if (!hasEmbeddedSource(provider)) { if (fImportType == IMPORT_BINARY_WITH_LINKS) { linkSourceArchives(project, model, new SubProgressMonitor(monitor, 1)); } else { importSourceArchives(project, model, new SubProgressMonitor(monitor, 1)); } } } if (fImportType != IMPORT_WITH_SOURCE) { modifyBundleClasspathHeader(project, model); } else { removeSignedHeaders(project); } setPermissions(model, project); } catch (IOException e) { IStatus status = new Status(IStatus.ERROR, PDEPlugin.getPluginId(), IStatus.ERROR, e.getMessage(), e); throw new CoreException(status); } finally { if (zipFile != null) { try { zipFile.close(); } catch (IOException e) { } } } } private void modifyBundleClasspathHeader(IProject project, IPluginModelBase base) { IFile file = project.getFile(JarFile.MANIFEST_NAME); if (file.exists()) { WorkspaceBundleModel bmodel = new WorkspaceBundleModel(file); IBundle bundle = bmodel.getBundle(); String classpath = bundle.getHeader(org.osgi.framework.Constants.BUNDLE_CLASSPATH); if (classpath == null) { bundle.setHeader(org.osgi.framework.Constants.BUNDLE_CLASSPATH, ClasspathUtilCore.getFilename(base)); } else { try { ManifestElement[] elements = ManifestElement.parseHeader(org.osgi.framework.Constants.BUNDLE_CLASSPATH, classpath); StringBuffer buffer = new StringBuffer(); for (int i = 0; i < elements.length; i++) { if (buffer.length() > 0) { buffer.append(","); //$NON-NLS-1$ buffer.append(System.getProperty("line.separator")); //$NON-NLS-1$ buffer.append(" "); //$NON-NLS-1$ } if (elements[i].getValue().equals(".")) //$NON-NLS-1$ buffer.append(ClasspathUtilCore.getFilename(base)); else buffer.append(elements[i].getValue()); } bundle.setHeader(org.osgi.framework.Constants.BUNDLE_CLASSPATH, buffer.toString()); } catch (BundleException e) { } } bmodel.save(); } } private void removeSignedHeaders(IProject project) { IFile file = project.getFile(JarFile.MANIFEST_NAME); if (!file.exists()) return; WorkspaceBundleModel model = new WorkspaceBundleModel(file); model.save(); } private IProject findProject(String id) { IPluginModelBase model = PluginRegistry.findModel(id); if (model != null) { IResource resource = model.getUnderlyingResource(); if (resource != null) return resource.getProject(); } return PDEPlugin.getWorkspace().getRoot().getProject(id); } private boolean queryReplace(IProject project) throws OperationCanceledException { switch (fReplaceQuery.doQuery(NLS.bind(PDEUIMessages.ImportWizard_messages_exists, project.getName()))) { case IImportQuery.CANCEL : throw new OperationCanceledException(); case IImportQuery.NO : return false; } return true; } private boolean queryExecutionEnvironment(String message) throws OperationCanceledException { switch (fExecutionQuery.doQuery(message)) { case IImportQuery.CANCEL : throw new OperationCanceledException(); case IImportQuery.NO : return false; } return true; } private void setProjectDescription(IProject project, IPluginModelBase model) throws CoreException { IProjectDescription desc = project.getDescription(); if (!desc.hasNature(PDE.PLUGIN_NATURE)) CoreUtility.addNatureToProject(project, PDE.PLUGIN_NATURE, null); if (needsJavaNature(project, model) && !desc.hasNature(JavaCore.NATURE_ID)) CoreUtility.addNatureToProject(project, JavaCore.NATURE_ID, null); } private boolean needsJavaNature(IProject project, IPluginModelBase model) { if (model.getPluginBase().getLibraries().length > 0) return true; BundleDescription desc = model.getBundleDescription(); if (desc != null) { if (desc.getExportPackages().length > 0) return true; if (desc.getRequiredBundles().length > 0) return true; if (desc.getImportPackages().length > 0) return true; } return false; } private boolean isExempt(IPluginModelBase model) { String id = model.getPluginBase().getId(); if ("org.apache.ant".equals(id) //$NON-NLS-1$ || "org.eclipse.osgi.util".equals(id) //$NON-NLS-1$ || "org.eclipse.osgi.services".equals(id) //$NON-NLS-1$ || "org.eclipse.core.runtime.compatibility.registry".equals(id)) //$NON-NLS-1$ return true; if ("org.eclipse.swt".equals(id) && !isJARd(model)) //$NON-NLS-1$ return true; return false; } private boolean isJARd(IPluginModelBase model) { return new File(model.getInstallLocation()).isFile(); } private void setPermissions(IPluginModelBase model, IProject project) { try { if (!Platform.getOS().equals(Constants.OS_WIN32) && model instanceof IFragmentModel) { IFragment fragment = ((IFragmentModel) model).getFragment(); if ("org.eclipse.swt".equals(fragment.getPluginId())) { //$NON-NLS-1$ IResource[] children = project.members(); for (int i = 0; i < children.length; i++) { if (children[i] instanceof IFile && isInterestingResource(children[i].getName())) { Runtime.getRuntime().exec(new String[] {"chmod", "755", children[i].getLocation().toOSString()}).waitFor(); //$NON-NLS-1$ //$NON-NLS-2$ } } } } } catch (CoreException e) { } catch (InterruptedException e) { } catch (IOException e) { } } private boolean isInterestingResource(String name) { return name.endsWith(".jnilib") //$NON-NLS-1$ || name.endsWith(".sl") //$NON-NLS-1$ || name.endsWith(".a") //$NON-NLS-1$ || name.indexOf(".so") != -1; //$NON-NLS-1$ } private IFragment[] getFragmentsFor(IPluginModelBase model) { ArrayList result = new ArrayList(); for (int i = 0; i < fModels.length; i++) { if (fModels[i] instanceof IFragmentModel) { HostSpecification spec = fModels[i].getBundleDescription().getHost(); BundleDescription host = spec == null ? null : (BundleDescription) spec.getSupplier(); if (model.getBundleDescription().equals(host)) { result.add(((IFragmentModel) fModels[i]).getFragment()); } } } return (IFragment[]) result.toArray(new IFragment[result.size()]); } private void importJarFromFragment(IProject project, IFragment fragment, String name) throws CoreException { IPath jarPath = new Path(ClasspathUtilCore.expandLibraryName(name)); File jar = new File(fragment.getModel().getInstallLocation(), jarPath.toString()); if (jar.exists()) { importArchive(project, jar, jarPath); } } /** * Imports the source for a library from a fragment. * @param project destination project of the import * @param fragment fragment to import the library from * @param libraryName name of the library to import, * @param monitor progress monitor * @throws CoreException if there is a problem completing the import */ private void importSourceFromFragment(IProject project, IFragment fragment, String libraryName, IProgressMonitor monitor) throws CoreException { try { IPath jarPath = new Path(ClasspathUtilCore.expandLibraryName(libraryName)); String zipName = ClasspathUtilCore.getSourceZipName(jarPath.toString()); IPath path = new Path(zipName); if (project.findMember(path) == null) { SourceLocationManager manager = PDECore.getDefault().getSourceLocationManager(); IPath srcPath = manager.findSourcePath(fragment, path); if (srcPath != null) { if (manager.hasBundleManifestLocation(fragment)) { // Extract the specific library from it's folder extractResourcesFromFolder(new File(srcPath.toOSString()), path.removeFileExtension(), project, monitor); } else { importArchive(project, new File(srcPath.toOSString()), path); } } } } finally { monitor.done(); } } protected void collectAdditionalResources(ZipFileStructureProvider provider, Object element, ArrayList collected, IProject project) { collectAdditionalResources(provider, element, collected); ListIterator li = collected.listIterator(); while (li.hasNext()) { ZipEntry ze = (ZipEntry) li.next(); String name = ze.getName(); // only import the entries that don't already exist if (project.findMember(name) != null) { li.remove(); } } } protected void collectNonJavaResources(ZipFileStructureProvider provider, Object element, ArrayList collected) { super.collectNonJavaResources(provider, element, collected); if (fImportType != IMPORT_WITH_SOURCE) return; // filter the resources we get back to include only relevant resource files ListIterator li = collected.listIterator(); while (li.hasNext()) { ZipEntry ze = (ZipEntry) li.next(); String name = ze.getName(); // filter out signature files - bug 175756 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$ li.remove(); } } public void setLaunchedConfiguration(boolean launchedConfiguration) { fLaunchedConfigurations = launchedConfiguration; } } |
... this post is sponsored by my books ... | |
![]() #1 New Release! |
![]() FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.