1 11 package org.eclipse.jdt.internal.ui.wizards.buildpaths; 12 13 import java.lang.reflect.InvocationTargetException ; 14 import java.util.ArrayList ; 15 import java.util.Arrays ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 19 import org.eclipse.core.runtime.CoreException; 20 import org.eclipse.core.runtime.IPath; 21 import org.eclipse.core.runtime.IProgressMonitor; 22 import org.eclipse.core.runtime.OperationCanceledException; 23 import org.eclipse.core.runtime.SubProgressMonitor; 24 25 import org.eclipse.core.resources.ResourcesPlugin; 26 27 import org.eclipse.swt.SWT; 28 import org.eclipse.swt.custom.CLabel; 29 import org.eclipse.swt.layout.GridData; 30 import org.eclipse.swt.widgets.Composite; 31 import org.eclipse.swt.widgets.Control; 32 import org.eclipse.swt.widgets.Shell; 33 34 import org.eclipse.jface.dialogs.Dialog; 35 import org.eclipse.jface.dialogs.IDialogConstants; 36 import org.eclipse.jface.dialogs.MessageDialog; 37 import org.eclipse.jface.dialogs.ProgressMonitorDialog; 38 import org.eclipse.jface.operation.IRunnableWithProgress; 39 import org.eclipse.jface.resource.JFaceResources; 40 import org.eclipse.jface.viewers.IDoubleClickListener; 41 import org.eclipse.jface.viewers.ISelection; 42 import org.eclipse.jface.viewers.ISelectionChangedListener; 43 import org.eclipse.jface.viewers.StructuredSelection; 44 import org.eclipse.jface.viewers.Viewer; 45 import org.eclipse.jface.viewers.ViewerComparator; 46 import org.eclipse.jface.window.Window; 47 48 import org.eclipse.jdt.core.IClasspathEntry; 49 import org.eclipse.jdt.core.IJavaModel; 50 import org.eclipse.jdt.core.IJavaProject; 51 import org.eclipse.jdt.core.JavaCore; 52 import org.eclipse.jdt.core.JavaModelException; 53 54 import org.eclipse.jdt.internal.ui.JavaPlugin; 55 import org.eclipse.jdt.internal.ui.util.CoreUtility; 56 import org.eclipse.jdt.internal.ui.util.ExceptionHandler; 57 import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages; 58 import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField; 59 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener; 60 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IListAdapter; 61 import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil; 62 import org.eclipse.jdt.internal.ui.wizards.dialogfields.ListDialogField; 63 64 65 public class VariableBlock { 66 67 private ListDialogField fVariablesList; 68 private Control fControl; 69 private CLabel fWarning; 70 private boolean fHasChanges; 71 72 private List fSelectedElements; 73 private boolean fAskToBuild; 74 private final boolean fEditOnDoubleclick; 75 76 77 public VariableBlock(boolean inPreferencePage, String initSelection) { 78 79 fSelectedElements= new ArrayList (0); 80 fEditOnDoubleclick= inPreferencePage; 81 fAskToBuild= true; 82 83 String [] buttonLabels= new String [] { 84 NewWizardMessages.VariableBlock_vars_add_button, 85 NewWizardMessages.VariableBlock_vars_edit_button, 86 NewWizardMessages.VariableBlock_vars_remove_button 87 }; 88 89 VariablesAdapter adapter= new VariablesAdapter(); 90 91 CPVariableElementLabelProvider labelProvider= new CPVariableElementLabelProvider(inPreferencePage); 92 93 fVariablesList= new ListDialogField(adapter, buttonLabels, labelProvider); 94 fVariablesList.setDialogFieldListener(adapter); 95 fVariablesList.setLabelText(NewWizardMessages.VariableBlock_vars_label); 96 fVariablesList.setRemoveButtonIndex(2); 97 98 fVariablesList.enableButton(1, false); 99 100 fVariablesList.setViewerComparator(new ViewerComparator() { 101 public int compare(Viewer viewer, Object e1, Object e2) { 102 if (e1 instanceof CPVariableElement && e2 instanceof CPVariableElement) { 103 return getComparator().compare(((CPVariableElement)e1).getName(), ((CPVariableElement)e2).getName()); 104 } 105 return super.compare(viewer, e1, e2); 106 } 107 }); 108 refresh(initSelection); 109 } 110 111 public boolean hasChanges() { 112 return fHasChanges; 113 } 114 115 public void setChanges(boolean hasChanges) { 116 fHasChanges= hasChanges; 117 } 118 119 public Control createContents(Composite parent) { 120 Composite composite= new Composite(parent, SWT.NONE); 121 composite.setFont(parent.getFont()); 122 123 LayoutUtil.doDefaultLayout(composite, new DialogField[] { fVariablesList }, true, 0, 0); 124 LayoutUtil.setHorizontalGrabbing(fVariablesList.getListControl(null)); 125 126 fWarning= new CLabel(composite, SWT.NONE); 127 fWarning.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, fVariablesList.getNumberOfControls() - 1, 1)); 128 129 fControl= composite; 130 updateDeprecationWarning(); 131 132 return composite; 133 } 134 135 public void addDoubleClickListener(IDoubleClickListener listener) { 136 fVariablesList.getTableViewer().addDoubleClickListener(listener); 137 } 138 139 public void addSelectionChangedListener(ISelectionChangedListener listener) { 140 fVariablesList.getTableViewer().addSelectionChangedListener(listener); 141 } 142 143 144 private Shell getShell() { 145 if (fControl != null) { 146 return fControl.getShell(); 147 } 148 return JavaPlugin.getActiveWorkbenchShell(); 149 } 150 151 private class VariablesAdapter implements IDialogFieldListener, IListAdapter { 152 153 155 public void customButtonPressed(ListDialogField field, int index) { 156 switch (index) { 157 case 0: 158 editEntries(null); 159 break; 160 case 1: 161 List selected= field.getSelectedElements(); 162 editEntries((CPVariableElement)selected.get(0)); 163 break; 164 } 165 } 166 167 public void selectionChanged(ListDialogField field) { 168 doSelectionChanged(field); 169 } 170 171 public void doubleClicked(ListDialogField field) { 172 if (fEditOnDoubleclick) { 173 List selected= field.getSelectedElements(); 174 if (canEdit(selected, containsReadOnly(selected))) { 175 editEntries((CPVariableElement) selected.get(0)); 176 } 177 } 178 } 179 180 182 public void dialogFieldChanged(DialogField field) { 183 } 184 185 } 186 187 private boolean containsReadOnly(List selected) { 188 for (int i= selected.size()-1; i >= 0; i--) { 189 if (((CPVariableElement)selected.get(i)).isReadOnly()) { 190 return true; 191 } 192 } 193 return false; 194 } 195 196 private boolean canEdit(List selected, boolean containsReadOnly) { 197 return selected.size() == 1 && !containsReadOnly; 198 } 199 200 private void doSelectionChanged(DialogField field) { 201 List selected= fVariablesList.getSelectedElements(); 202 boolean containsReadOnly= containsReadOnly(selected); 203 204 fVariablesList.enableButton(1, canEdit(selected, containsReadOnly)); 206 fVariablesList.enableButton(2, !containsReadOnly); 208 209 fSelectedElements= selected; 210 updateDeprecationWarning(); 211 } 212 213 private void updateDeprecationWarning() { 214 if (fWarning == null || fWarning.isDisposed()) 215 return; 216 217 for (Iterator iter= fSelectedElements.iterator(); iter.hasNext();) { 218 CPVariableElement element= (CPVariableElement) iter.next(); 219 String deprecationMessage= element.getDeprecationMessage(); 220 if (deprecationMessage != null) { 221 fWarning.setText(deprecationMessage); 222 fWarning.setImage(JFaceResources.getImage(Dialog.DLG_IMG_MESSAGE_WARNING)); 223 return; 224 } 225 } 226 fWarning.setText(null); 227 fWarning.setImage(null); 228 } 229 230 private void editEntries(CPVariableElement entry) { 231 List existingEntries= fVariablesList.getElements(); 232 233 VariableCreationDialog dialog= new VariableCreationDialog(getShell(), entry, existingEntries); 234 if (dialog.open() != Window.OK) { 235 return; 236 } 237 CPVariableElement newEntry= dialog.getClasspathElement(); 238 if (entry == null) { 239 fVariablesList.addElement(newEntry); 240 entry= newEntry; 241 fHasChanges= true; 242 } else { 243 boolean hasChanges= !(entry.getName().equals(newEntry.getName()) && entry.getPath().equals(newEntry.getPath())); 244 if (hasChanges) { 245 fHasChanges= true; 246 entry.setName(newEntry.getName()); 247 entry.setPath(newEntry.getPath()); 248 fVariablesList.refresh(); 249 } 250 } 251 fVariablesList.selectElements(new StructuredSelection(entry)); 252 } 253 254 public List getSelectedElements() { 255 return fSelectedElements; 256 } 257 258 public boolean performOk() { 259 ArrayList removedVariables= new ArrayList (); 260 ArrayList changedVariables= new ArrayList (); 261 removedVariables.addAll(Arrays.asList(JavaCore.getClasspathVariableNames())); 262 263 List changedElements= fVariablesList.getElements(); 265 for (int i= changedElements.size()-1; i >= 0; i--) { 266 CPVariableElement curr= (CPVariableElement) changedElements.get(i); 267 if (curr.isReadOnly()) { 268 changedElements.remove(curr); 269 } else { 270 IPath path= curr.getPath(); 271 IPath prevPath= JavaCore.getClasspathVariable(curr.getName()); 272 if (prevPath != null && prevPath.equals(path)) { 273 changedElements.remove(curr); 274 } else { 275 changedVariables.add(curr.getName()); 276 } 277 } 278 removedVariables.remove(curr.getName()); 279 } 280 int steps= changedElements.size() + removedVariables.size(); 281 if (steps > 0) { 282 283 boolean needsBuild= false; 284 if (fAskToBuild && doesChangeRequireFullBuild(removedVariables, changedVariables)) { 285 String title= NewWizardMessages.VariableBlock_needsbuild_title; 286 String message= NewWizardMessages.VariableBlock_needsbuild_message; 287 288 MessageDialog buildDialog= new MessageDialog(getShell(), title, null, message, MessageDialog.QUESTION, new String [] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }, 2); 289 int res= buildDialog.open(); 290 if (res != 0 && res != 1) { 291 return false; 292 } 293 needsBuild= (res == 0); 294 } 295 296 final VariableBlockRunnable runnable= new VariableBlockRunnable(removedVariables, changedElements); 297 final ProgressMonitorDialog dialog= new ProgressMonitorDialog(getShell()); 298 try { 299 dialog.run(true, true, runnable); 300 } catch (InvocationTargetException e) { 301 ExceptionHandler.handle(new InvocationTargetException (new NullPointerException ()), getShell(), NewWizardMessages.VariableBlock_variableSettingError_titel, NewWizardMessages.VariableBlock_variableSettingError_message); 302 return false; 303 } catch (InterruptedException e) { 304 return false; 305 } 306 307 if (needsBuild) { 308 CoreUtility.getBuildJob(null).schedule(); 309 } 310 } 311 return true; 312 } 313 314 private boolean doesChangeRequireFullBuild(List removed, List changed) { 315 try { 316 IJavaModel model= JavaCore.create(ResourcesPlugin.getWorkspace().getRoot()); 317 IJavaProject[] projects= model.getJavaProjects(); 318 for (int i= 0; i < projects.length; i++) { 319 IClasspathEntry[] entries= projects[i].getRawClasspath(); 320 for (int k= 0; k < entries.length; k++) { 321 IClasspathEntry curr= entries[k]; 322 if (curr.getEntryKind() == IClasspathEntry.CPE_VARIABLE) { 323 String var= curr.getPath().segment(0); 324 if (removed.contains(var) || changed.contains(var)) { 325 return true; 326 } 327 } 328 } 329 } 330 } catch (JavaModelException e) { 331 return true; 332 } 333 return false; 334 } 335 336 private class VariableBlockRunnable implements IRunnableWithProgress { 337 private List fToRemove; 338 private List fToChange; 339 340 public VariableBlockRunnable(List toRemove, List toChange) { 341 fToRemove= toRemove; 342 fToChange= toChange; 343 } 344 345 348 public void run(IProgressMonitor monitor) throws InvocationTargetException , InterruptedException { 349 monitor.beginTask(NewWizardMessages.VariableBlock_operation_desc, 1); 350 try { 351 setVariables(monitor); 352 353 } catch (CoreException e) { 354 throw new InvocationTargetException (e); 355 } catch (OperationCanceledException e) { 356 throw new InterruptedException (); 357 } finally { 358 monitor.done(); 359 } 360 } 361 362 public void setVariables(IProgressMonitor monitor) throws JavaModelException, CoreException { 363 int nVariables= fToChange.size() + fToRemove.size(); 364 365 String [] names= new String [nVariables]; 366 IPath[] paths= new IPath[nVariables]; 367 int k= 0; 368 369 for (int i= 0; i < fToChange.size(); i++) { 370 CPVariableElement curr= (CPVariableElement) fToChange.get(i); 371 names[k]= curr.getName(); 372 paths[k]= curr.getPath(); 373 k++; 374 } 375 for (int i= 0; i < fToRemove.size(); i++) { 376 names[k]= (String ) fToRemove.get(i); 377 paths[k]= null; 378 k++; 379 } 380 JavaCore.setClasspathVariables(names, paths, new SubProgressMonitor(monitor, 1)); 381 } 382 } 383 384 388 public void setAskToBuild(boolean askToBuild) { 389 fAskToBuild= askToBuild; 390 } 391 392 395 public void refresh(String initSelection) { 396 CPVariableElement initSelectedElement= null; 397 398 String [] entries= JavaCore.getClasspathVariableNames(); 399 ArrayList elements= new ArrayList (entries.length); 400 for (int i= 0; i < entries.length; i++) { 401 String name= entries[i]; 402 CPVariableElement elem; 403 IPath entryPath= JavaCore.getClasspathVariable(name); 404 if (entryPath != null) { 405 elem= new CPVariableElement(name, entryPath); 406 elements.add(elem); 407 if (name.equals(initSelection)) { 408 initSelectedElement= elem; 409 } 410 } else { 411 JavaPlugin.logErrorMessage("VariableBlock: Classpath variable with null value: " + name); } 413 } 414 415 fVariablesList.setElements(elements); 416 417 if (initSelectedElement != null) { 418 ISelection sel= new StructuredSelection(initSelectedElement); 419 fVariablesList.selectElements(sel); 420 } else { 421 fVariablesList.selectFirstElement(); 422 } 423 424 fHasChanges= false; 425 } 426 427 public void setSelection(String elementName) { 428 for (int i= 0; i < fVariablesList.getSize(); i++) { 429 CPVariableElement elem= (CPVariableElement) fVariablesList.getElement(i); 430 if (elem.getName().equals(elementName)) { 431 fVariablesList.selectElements(new StructuredSelection(elem)); 432 return; 433 } 434 } 435 } 436 437 438 } 439 | Popular Tags |