1 /*******************************************************************************
2  * Copyright (c) 2000, 2015 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.IContainer;
22 import org.eclipse.core.resources.IFolder;
23 import org.eclipse.core.resources.IProject;
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.resources.ResourcesPlugin;
26 import org.eclipse.core.runtime.IStatus;
27 import org.eclipse.core.runtime.Status;
28 import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
29 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
30 import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer;
31 import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
32 import org.eclipse.jdt.launching.JavaRuntime;
33 import org.eclipse.jface.action.IAction;
34 import org.eclipse.jface.viewers.ILabelProvider;
35 import org.eclipse.jface.viewers.ITreeContentProvider;
36 import org.eclipse.jface.viewers.Viewer;
37 import org.eclipse.jface.viewers.ViewerFilter;
38 import org.eclipse.jface.window.Window;
39 import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
40 import org.eclipse.ui.dialogs.ISelectionStatusValidator;
41 import org.eclipse.ui.model.WorkbenchContentProvider;
42 import org.eclipse.ui.model.WorkbenchLabelProvider;
43 import org.eclipse.ui.views.navigator.ResourceComparator;
44 
45 /**
46  * Adds an internal folder to the runtime class path.
47  */
48 public class AddFolderAction extends RuntimeClasspathAction {
49 
50 	/**
51 	 * provides a filter to remove the files from the ElementSelectionDialog
52 	 *
53 	 * @since 3.2
54 	 *
55 	 */
56 	class FileFilter extends ViewerFilter {
57 		@Override
select(Viewer viewer, Object parentElement, Object element)58 		public boolean select(Viewer viewer, Object parentElement, Object element) {
59 			if(element instanceof IProject) {
60 				return true;
61 			}
62 			if(element instanceof IFolder) {
63 				return true;
64 			}
65 			return false;
66 		}
67 
68 	}
69 
AddFolderAction(IClasspathViewer viewer)70 	public AddFolderAction(IClasspathViewer viewer) {
71 		super(ActionMessages.AddFolderAction_Add__Folders_1, viewer);
72 	}
73 
74 	/**
75 	 * Prompts for folder(s) to add.
76 	 *
77 	 * @see IAction#run()
78 	 */
79 	@Override
run()80 	public void run() {
81 
82 		ISelectionStatusValidator validator= new ISelectionStatusValidator() {
83 			List<IResource> fAlreadySelected = getSelectedFolders();
84 			@Override
85 			public IStatus validate(Object[] selection) {
86 				for (Object s : selection) {
87 					if (!(s instanceof IContainer)) {
88 						return new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), IJavaDebugUIConstants.INTERNAL_ERROR, "Selection must be a folder", null);  //$NON-NLS-1$
89 					} else if (fAlreadySelected.contains(s)) {
90 						return new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), IJavaDebugUIConstants.INTERNAL_ERROR, "Classpath already includes selected folder(s).", null);  //$NON-NLS-1$
91 					}
92 
93 				}
94 				return new Status(IStatus.OK, JDIDebugPlugin.getUniqueIdentifier(), 0, "", null); //$NON-NLS-1$
95 			}
96 		};
97 
98 		ILabelProvider lp= new WorkbenchLabelProvider();
99 		ITreeContentProvider cp= new WorkbenchContentProvider();
100 
101 		ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(getShell(), lp, cp);
102 		dialog.addFilter(new FileFilter());
103         dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
104 		dialog.setValidator(validator);
105 		dialog.setTitle(ActionMessages.AddFolderAction_Folder_Selection_4);
106 		dialog.setMessage(ActionMessages.AddFolderAction_Choose_folders_to_add__5);
107 		dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
108 
109 		if (dialog.open() == Window.OK) {
110 			Object[] elements= dialog.getResult();
111 			IRuntimeClasspathEntry[] res= new IRuntimeClasspathEntry[elements.length];
112 			for (int i= 0; i < res.length; i++) {
113 				IResource elem= (IResource)elements[i];
114 				res[i]= JavaRuntime.newArchiveRuntimeClasspathEntry(elem);
115 			}
116 			getViewer().addEntries(res);
117 		}
118 
119 	}
120 
121 	/**
122 	 * Returns a list of resources of currently selected folders
123 	 * @return the list of {@link IResource}s
124 	 */
getSelectedFolders()125 	protected List<IResource> getSelectedFolders() {
126 		List<IRuntimeClasspathEntry> list = getEntriesAsList();
127 		List<IResource> folders = new ArrayList<>();
128 		Iterator<IRuntimeClasspathEntry> iter = list.iterator();
129 		while (iter.hasNext()) {
130 			IRuntimeClasspathEntry entry = iter.next();
131 			if (entry.getType() == IRuntimeClasspathEntry.ARCHIVE) {
132 				IResource res = entry.getResource();
133 				if (res != null && res instanceof IContainer) {
134 					folders.add(res);
135 				}
136 			}
137 		}
138 		return folders;
139 	}
140 
141 	@Override
getActionType()142 	protected int getActionType() {
143 		return ADD;
144 	}
145 }
146