1 /******************************************************************************* 2 * Copyright (c) 2000, 2012 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jdt.internal.debug.ui.actions; 15 16 17 import java.util.ArrayList; 18 import java.util.Iterator; 19 import java.util.List; 20 21 import org.eclipse.core.resources.IProject; 22 import org.eclipse.core.resources.IResource; 23 import org.eclipse.core.resources.IWorkspaceRoot; 24 import org.eclipse.core.resources.ResourcesPlugin; 25 import org.eclipse.core.runtime.CoreException; 26 import org.eclipse.core.runtime.MultiStatus; 27 import org.eclipse.jdt.core.IClasspathContainer; 28 import org.eclipse.jdt.core.IClasspathEntry; 29 import org.eclipse.jdt.core.IJavaModel; 30 import org.eclipse.jdt.core.IJavaProject; 31 import org.eclipse.jdt.core.JavaCore; 32 import org.eclipse.jdt.core.JavaModelException; 33 import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants; 34 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; 35 import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer; 36 import org.eclipse.jdt.launching.IRuntimeClasspathEntry; 37 import org.eclipse.jdt.launching.JavaRuntime; 38 import org.eclipse.jface.action.IAction; 39 import org.eclipse.jface.viewers.IStructuredSelection; 40 import org.eclipse.jface.window.Window; 41 import org.eclipse.ui.actions.SelectionListenerAction; 42 43 /** 44 * Adds a project to the runtime class path. 45 */ 46 public class AddProjectAction extends RuntimeClasspathAction { 47 48 49 AddProjectAction(IClasspathViewer viewer)50 public AddProjectAction(IClasspathViewer viewer) { 51 super(ActionMessages.AddProjectAction_Add_Project_1, viewer); 52 } 53 54 /** 55 * Prompts for a project to add. 56 * 57 * @see IAction#run() 58 */ 59 @Override run()60 public void run() { 61 List<IJavaProject> projects = getPossibleAdditions(); 62 ProjectSelectionDialog dialog= new ProjectSelectionDialog(getShell(),projects); 63 dialog.setTitle(ActionMessages.AddProjectAction_Project_Selection_2); 64 MultiStatus status = new MultiStatus(JDIDebugUIPlugin.getUniqueIdentifier(), IJavaDebugUIConstants.INTERNAL_ERROR, "One or more exceptions occurred while adding projects.", null); //$NON-NLS-1$ 65 66 if (dialog.open() == Window.OK) { 67 Object[] selections = dialog.getResult(); 68 69 List<IJavaProject> additions = new ArrayList<>(selections.length); 70 try { 71 for (Object selection : selections) { 72 IJavaProject jp = (IJavaProject) selection; 73 if (dialog.isAddRequiredProjects()) { 74 collectRequiredProjects(jp, additions); 75 } else { 76 additions.add(jp); 77 } 78 } 79 } catch (JavaModelException e) { 80 status.add(e.getStatus()); 81 } 82 83 List<IRuntimeClasspathEntry> runtimeEntries = new ArrayList<>(additions.size()); 84 Iterator<IJavaProject> iter = additions.iterator(); 85 while (iter.hasNext()) { 86 IJavaProject jp = iter.next(); 87 runtimeEntries.add(JavaRuntime.newProjectRuntimeClasspathEntry(jp)); 88 if (dialog.isAddExportedEntries()) { 89 try { 90 collectExportedEntries(jp, runtimeEntries); 91 } catch (CoreException e) { 92 status.add(e.getStatus()); 93 } 94 } 95 } 96 IRuntimeClasspathEntry[] entries = runtimeEntries.toArray(new IRuntimeClasspathEntry[runtimeEntries.size()]); 97 getViewer().addEntries(entries); 98 } 99 100 if (!status.isOK()) { 101 JDIDebugUIPlugin.statusDialog(status); 102 } 103 } 104 105 /** 106 * @see SelectionListenerAction#updateSelection(IStructuredSelection) 107 */ 108 @Override updateSelection(IStructuredSelection selection)109 protected boolean updateSelection(IStructuredSelection selection) { 110 return getViewer().updateSelection(getActionType(), selection) && !getPossibleAdditions().isEmpty(); 111 } 112 113 @Override getActionType()114 protected int getActionType() { 115 return ADD; 116 } 117 118 /** 119 * Returns the possible projects that can be added 120 * @return the list of projects 121 */ getPossibleAdditions()122 protected List<IJavaProject> getPossibleAdditions() { 123 IJavaProject[] projects; 124 IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); 125 try { 126 projects= JavaCore.create(root).getJavaProjects(); 127 } catch (JavaModelException e) { 128 JDIDebugUIPlugin.log(e); 129 projects= new IJavaProject[0]; 130 } 131 List<IJavaProject> remaining = new ArrayList<>(); 132 for (IJavaProject project : projects) { 133 remaining.add(project); 134 } 135 List<IJavaProject> alreadySelected = new ArrayList<>(); 136 for (IRuntimeClasspathEntry entry : getViewer().getEntries()) { 137 if (entry.getType() == IRuntimeClasspathEntry.PROJECT) { 138 IResource res = root.findMember(entry.getPath()); 139 IJavaProject jp = (IJavaProject)JavaCore.create(res); 140 alreadySelected.add(jp); 141 } 142 } 143 remaining.removeAll(alreadySelected); 144 return remaining; 145 } 146 147 /** 148 * Adds all projects required by <code>proj</code> to the list 149 * <code>res</code> 150 * 151 * @param proj the project for which to compute required 152 * projects 153 * @param res the list to add all required projects too 154 * @throws JavaModelException if there is a problem accessing the Java model 155 */ collectRequiredProjects(IJavaProject proj, List<IJavaProject> res)156 protected void collectRequiredProjects(IJavaProject proj, List<IJavaProject> res) throws JavaModelException { 157 if (!res.contains(proj)) { 158 res.add(proj); 159 160 IJavaModel model= proj.getJavaModel(); 161 162 for (IClasspathEntry curr : proj.getRawClasspath()) { 163 if (curr.getEntryKind() == IClasspathEntry.CPE_PROJECT) { 164 IJavaProject ref= model.getJavaProject(curr.getPath().segment(0)); 165 if (ref.exists()) { 166 collectRequiredProjects(ref, res); 167 } 168 } 169 } 170 } 171 } 172 173 /** 174 * Adds all exported entries defined by <code>proj</code> to the list 175 * <code>runtimeEntries</code>. 176 * 177 * @param proj the project 178 * @param runtimeEntries the entries 179 * @throws CoreException if an exception occurs 180 */ collectExportedEntries(IJavaProject proj, List<IRuntimeClasspathEntry> runtimeEntries)181 protected void collectExportedEntries(IJavaProject proj, List<IRuntimeClasspathEntry> runtimeEntries) throws CoreException { 182 for (IClasspathEntry entry : proj.getRawClasspath()) { 183 if (entry.isExported()) { 184 IRuntimeClasspathEntry rte = null; 185 switch (entry.getEntryKind()) { 186 case IClasspathEntry.CPE_CONTAINER: 187 IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), proj); 188 int kind = 0; 189 switch (container.getKind()) { 190 case IClasspathContainer.K_APPLICATION: 191 kind = IRuntimeClasspathEntry.USER_CLASSES; 192 break; 193 case IClasspathContainer.K_SYSTEM: 194 kind = IRuntimeClasspathEntry.BOOTSTRAP_CLASSES; 195 break; 196 case IClasspathContainer.K_DEFAULT_SYSTEM: 197 kind = IRuntimeClasspathEntry.STANDARD_CLASSES; 198 break; 199 } 200 rte = JavaRuntime.newRuntimeContainerClasspathEntry(entry.getPath(), kind, proj); 201 break; 202 case IClasspathEntry.CPE_LIBRARY: 203 rte = JavaRuntime.newArchiveRuntimeClasspathEntry(entry.getPath()); 204 rte.setSourceAttachmentPath(entry.getSourceAttachmentPath()); 205 rte.setSourceAttachmentRootPath(entry.getSourceAttachmentRootPath()); 206 break; 207 case IClasspathEntry.CPE_PROJECT: 208 String name = entry.getPath().segment(0); 209 IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject(name); 210 if (p.exists()) { 211 IJavaProject jp = JavaCore.create(p); 212 if (jp.exists()) { 213 rte = JavaRuntime.newProjectRuntimeClasspathEntry(jp); 214 } 215 } 216 break; 217 case IClasspathEntry.CPE_VARIABLE: 218 rte = JavaRuntime.newVariableRuntimeClasspathEntry(entry.getPath()); 219 break; 220 default: 221 break; 222 } 223 if (rte != null) { 224 if (!runtimeEntries.contains(rte)) { 225 runtimeEntries.add(rte); 226 } 227 } 228 } 229 } 230 } 231 } 232