1 11 package org.eclipse.ant.internal.ui.preferences; 12 13 import java.io.File ; 14 import java.net.MalformedURLException ; 15 import java.net.URL ; 16 import java.util.ArrayList ; 17 import java.util.Arrays ; 18 import java.util.Collections ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 22 import org.eclipse.ant.core.IAntClasspathEntry; 23 import org.eclipse.ant.internal.ui.AntUIPlugin; 24 import org.eclipse.ant.internal.ui.IAntUIConstants; 25 import org.eclipse.ant.internal.ui.IAntUIPreferenceConstants; 26 import org.eclipse.ant.internal.ui.launchConfigurations.VariableInputDialog; 27 import org.eclipse.core.resources.IFile; 28 import org.eclipse.core.resources.ResourcesPlugin; 29 import org.eclipse.core.runtime.IPath; 30 import org.eclipse.core.runtime.IStatus; 31 import org.eclipse.core.runtime.Path; 32 import org.eclipse.core.runtime.Status; 33 import org.eclipse.core.variables.VariablesPlugin; 34 import org.eclipse.jdt.internal.debug.ui.actions.ArchiveFilter; 35 import org.eclipse.jface.dialogs.IDialogConstants; 36 import org.eclipse.jface.dialogs.IDialogSettings; 37 import org.eclipse.jface.dialogs.MessageDialogWithToggle; 38 import org.eclipse.jface.viewers.ILabelProvider; 39 import org.eclipse.jface.viewers.ISelectionChangedListener; 40 import org.eclipse.jface.viewers.IStructuredSelection; 41 import org.eclipse.jface.viewers.ITreeContentProvider; 42 import org.eclipse.jface.viewers.SelectionChangedEvent; 43 import org.eclipse.jface.viewers.TreeViewer; 44 import org.eclipse.jface.viewers.ViewerFilter; 45 import org.eclipse.jface.window.Window; 46 import org.eclipse.swt.SWT; 47 import org.eclipse.swt.events.KeyAdapter; 48 import org.eclipse.swt.events.KeyEvent; 49 import org.eclipse.swt.events.SelectionAdapter; 50 import org.eclipse.swt.events.SelectionEvent; 51 import org.eclipse.swt.events.SelectionListener; 52 import org.eclipse.swt.graphics.Image; 53 import org.eclipse.swt.layout.GridData; 54 import org.eclipse.swt.layout.GridLayout; 55 import org.eclipse.swt.widgets.Button; 56 import org.eclipse.swt.widgets.Composite; 57 import org.eclipse.swt.widgets.DirectoryDialog; 58 import org.eclipse.swt.widgets.FileDialog; 59 import org.eclipse.swt.widgets.Tree; 60 import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; 61 import org.eclipse.ui.dialogs.ISelectionStatusValidator; 62 import org.eclipse.ui.model.WorkbenchContentProvider; 63 import org.eclipse.ui.model.WorkbenchLabelProvider; 64 import org.eclipse.ui.views.navigator.ResourceComparator; 65 66 public class AntClasspathBlock { 67 68 private static final String [] TOOLS= new String [] {"tools.jar"}; 70 private TreeViewer treeViewer; 71 private AntClasspathContentProvider antContentProvider; 72 73 private Button upButton; 74 private Button downButton; 75 private Button removeButton; 76 77 private AntClasspathLabelProvider labelProvider = new AntClasspathLabelProvider(this); 78 private Button addFolderButton; 79 private Button addJARButton; 80 private Button addExternalJARButton; 81 private Button addVariableButton; 82 private Button antHomeButton; 83 84 private String antHome; 85 86 private IDialogSettings dialogSettings = AntUIPlugin.getDefault().getDialogSettings(); 87 88 private IAntBlockContainer container; 89 90 private int validated= 2; 91 92 private IClasspathEntry currentParent; 93 94 private SelectionListener selectionListener= new SelectionAdapter() { 95 public void widgetSelected(SelectionEvent e) { 96 Object source = e.getSource(); 97 if (source == addJARButton) { 98 addJars(); 99 } else if (source == addExternalJARButton) { 100 addExternalJars(); 101 } else if (source == addFolderButton) { 102 addFolder(); 103 } else if (upButton == source) { 104 handleMoveUp(); 105 } else if (downButton == source) { 106 handleMoveDown(); 107 } else if (removeButton == source) { 108 remove(); 109 } else if (addVariableButton == source) { 110 addVariable(); 111 } else if (antHomeButton == source) { 112 browseAntHome(); 113 } 114 } 115 }; 116 117 public void setContainer(IAntBlockContainer container) { 118 this.container= container; 119 } 120 121 private void addButtonsToButtonGroup(Composite parent) { 122 123 124 addJARButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_addJarButtonTitle); 125 addJARButton.addSelectionListener(selectionListener); 126 127 addExternalJARButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_42); 128 addExternalJARButton.addSelectionListener(selectionListener); 129 addFolderButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_addFolderButtonTitle); 130 addFolderButton.addSelectionListener(selectionListener); 131 132 addVariableButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_2); 133 addVariableButton.addSelectionListener(selectionListener); 134 135 antHomeButton= container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_30); 136 antHomeButton.addSelectionListener(selectionListener); 137 138 removeButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_removeButtonTitle); 139 removeButton.addSelectionListener(selectionListener); 140 141 upButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_upButtonTitle); 142 upButton.addSelectionListener(selectionListener); 143 downButton = container.createPushButton(parent, AntPreferencesMessages.AntClasspathBlock_downButtonTitle); 144 downButton.addSelectionListener(selectionListener); 145 } 146 147 153 private List getOrderedSelection(IClasspathEntry parent) { 154 List targets = new ArrayList (); 155 List selection = ((IStructuredSelection)treeViewer.getSelection()).toList(); 156 IAntClasspathEntry[] entries = parent.getEntries(); 157 for (int i = 0; i < entries.length; i++) { 158 IAntClasspathEntry target = entries[i]; 159 if (selection.contains(target)) { 160 targets.add(target); 161 } 162 } 163 return targets; 164 } 165 166 private void handleMoveDown() { 167 List targets = getOrderedSelection(currentParent); 168 List list= new ArrayList (Arrays.asList(currentParent.getEntries())); 169 int bottom = list.size() - 1; 170 int index = 0; 171 for (int i = targets.size() - 1; i >= 0; i--) { 172 Object target = targets.get(i); 173 index = list.indexOf(target); 174 if (index < bottom) { 175 bottom = index + 1; 176 Object temp = list.get(bottom); 177 list.set(bottom, target); 178 list.set(index, temp); 179 } 180 bottom = index; 181 } 182 finishMove(list); 183 } 184 185 private void finishMove(List list) { 186 AntClasspathContentProvider viewerContentProvider = (AntClasspathContentProvider) treeViewer.getContentProvider(); 187 viewerContentProvider.setEntries(currentParent, list); 188 treeViewer.refresh(); 189 treeViewer.setSelection(treeViewer.getSelection()); 190 updateContainer(); 191 } 192 193 private void handleMoveUp() { 194 List targets = getOrderedSelection(currentParent); 195 int top = 0; 196 int index = 0; 197 List list= new ArrayList (Arrays.asList(currentParent.getEntries())); 198 Iterator entries = targets.iterator(); 199 while (entries.hasNext()) { 200 Object target = entries.next(); 201 index = list.indexOf(target); 202 if (index > top) { 203 top = index - 1; 204 Object temp = list.get(top); 205 list.set(top, target); 206 list.set(index, temp); 207 } 208 top = index; 209 } 210 211 finishMove(list); 212 } 213 214 private void remove() { 215 AntClasspathContentProvider viewerContentProvider = (AntClasspathContentProvider) treeViewer.getContentProvider(); 216 IStructuredSelection sel = (IStructuredSelection) treeViewer.getSelection(); 217 viewerContentProvider.remove(sel); 218 updateContainer(); 219 } 220 221 224 private void addFolder() { 225 String lastUsedPath = dialogSettings.get(IAntUIConstants.DIALOGSTORE_LASTFOLDER); 226 if (lastUsedPath == null) { 227 lastUsedPath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString(); 228 } 229 DirectoryDialog dialog = new DirectoryDialog(treeViewer.getControl().getShell()); 230 dialog.setMessage(AntPreferencesMessages.AntClasspathBlock_1); 231 dialog.setFilterPath(lastUsedPath); 232 String result = dialog.open(); 233 if (result != null) { 234 try { 235 URL url = new URL ("file:" + result + "/"); ((AntClasspathContentProvider)treeViewer.getContentProvider()).add(currentParent, url); 237 } catch (MalformedURLException e) { 238 } 239 } 240 treeViewer.setSelection(treeViewer.getSelection()); 241 dialogSettings.put(IAntUIConstants.DIALOGSTORE_LASTFOLDER, result); 242 updateContainer(); 243 } 244 245 private void addExternalJars() { 246 String lastUsedPath = dialogSettings.get(IAntUIConstants.DIALOGSTORE_LASTEXTJAR); 247 if (lastUsedPath == null) { 248 lastUsedPath = ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString(); 249 } 250 FileDialog dialog = new FileDialog(treeViewer.getControl().getShell(), SWT.MULTI); 251 dialog.setFilterExtensions(new String [] { "*.jar;*.zip" }); dialog.setFilterPath(lastUsedPath); 253 254 String result = dialog.open(); 255 if (result == null) { 256 return; 257 } 258 IPath filterPath = new Path(dialog.getFilterPath()); 259 String [] results = dialog.getFileNames(); 260 AntClasspathContentProvider contentProvider= (AntClasspathContentProvider)treeViewer.getContentProvider(); 261 contentProvider.setRefreshEnabled(false); 262 for (int i = 0; i < results.length; i++) { 263 String jarName = results[i]; 264 try { 265 IPath path = filterPath.append(jarName).makeAbsolute(); 266 URL url = new URL ("file:" + path.toOSString()); contentProvider.add(currentParent, url); 268 } catch (MalformedURLException e) { 269 } 270 } 271 contentProvider.setRefreshEnabled(true); 272 273 treeViewer.setSelection(treeViewer.getSelection()); 274 dialogSettings.put(IAntUIConstants.DIALOGSTORE_LASTEXTJAR, filterPath.toOSString()); 275 updateContainer(); 276 } 277 278 private void addJars() { 279 List allEntries= new ArrayList (); 280 if (currentParent != null) { 281 allEntries.addAll(Arrays.asList(currentParent.getEntries())); 282 } else { 283 Object [] entries= antContentProvider.getModel().getEntries(ClasspathModel.USER); 284 if (entries != null) { 285 allEntries.addAll(Arrays.asList(entries)); 286 } 287 } 288 289 ViewerFilter filter= new ArchiveFilter(allEntries); 290 291 ILabelProvider lp= new WorkbenchLabelProvider(); 292 ITreeContentProvider cp= new WorkbenchContentProvider(); 293 294 ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(treeViewer.getControl().getShell(), lp, cp); 295 dialog.setTitle(AntPreferencesMessages.AntClasspathBlock_44); 296 dialog.setMessage(AntPreferencesMessages.AntClasspathBlock_45); 297 dialog.addFilter(filter); 298 dialog.setInput(ResourcesPlugin.getWorkspace().getRoot()); 299 dialog.setComparator(new ResourceComparator(ResourceComparator.NAME)); 300 301 ISelectionStatusValidator validator= new ISelectionStatusValidator() { 302 public IStatus validate(Object [] selection) { 303 if (selection.length == 0) { 304 return new Status(IStatus.ERROR, AntUIPlugin.getUniqueIdentifier(), 0, "", null); } 306 for (int i= 0; i < selection.length; i++) { 307 if (!(selection[i] instanceof IFile)) { 308 return new Status(IStatus.ERROR, AntUIPlugin.getUniqueIdentifier(), 0, "", null); } 310 } 311 return new Status(IStatus.OK, AntUIPlugin.getUniqueIdentifier(), 0, "", null); } 313 }; 314 dialog.setValidator(validator); 315 316 if (dialog.open() == Window.OK) { 317 Object [] elements= dialog.getResult(); 318 AntClasspathContentProvider contentProvider= (AntClasspathContentProvider)treeViewer.getContentProvider(); 319 contentProvider.setRefreshEnabled(false); 320 for (int i = 0; i < elements.length; i++) { 321 IFile file = (IFile)elements[i]; 322 String varExpression= VariablesPlugin.getDefault().getStringVariableManager().generateVariableExpression("workspace_loc", file.getFullPath().toString()); contentProvider.add(currentParent, varExpression); 324 } 325 contentProvider.setRefreshEnabled(true); 326 updateContainer(); 327 } 328 } 329 330 private void updateContainer() { 331 validated= 0; 332 container.update(); 333 } 334 335 338 private void createButtonGroup(Composite top) { 339 Composite buttonGroup = new Composite(top, SWT.NONE); 340 GridLayout layout = new GridLayout(); 341 layout.marginHeight = 0; 342 layout.marginWidth = 0; 343 buttonGroup.setLayout(layout); 344 buttonGroup.setLayoutData(new GridData(GridData.FILL_VERTICAL)); 345 buttonGroup.setFont(top.getFont()); 346 347 addButtonsToButtonGroup(buttonGroup); 348 } 349 350 private void createClasspathTree(Composite parent) { 351 Tree tree = new Tree(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER); 352 GridData data = new GridData(GridData.FILL_BOTH); 353 data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH; 354 data.heightHint = tree.getItemHeight(); 355 tree.setLayoutData(data); 356 tree.setFont(parent.getFont()); 357 358 tree.addKeyListener(new KeyAdapter() { 359 public void keyPressed(KeyEvent event) { 360 if (event.character == SWT.DEL && event.stateMask == 0) { 361 remove(); 362 } 363 } 364 }); 365 366 antContentProvider = new AntClasspathContentProvider(); 367 treeViewer = new TreeViewer(tree); 368 treeViewer.setContentProvider(antContentProvider); 369 treeViewer.setLabelProvider(labelProvider); 370 treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { 371 public void selectionChanged(SelectionChangedEvent event) { 372 tableSelectionChanged((IStructuredSelection) event.getSelection(), 373 (AntClasspathContentProvider) treeViewer.getContentProvider()); 374 } 375 }); 376 } 377 378 public void createContents(Composite parent) { 379 createClasspathTree(parent); 380 createButtonGroup(parent); 381 382 tableSelectionChanged((IStructuredSelection)treeViewer.getSelection(), antContentProvider); 383 } 384 385 private void tableSelectionChanged(IStructuredSelection selection, AntClasspathContentProvider contentProvider) { 386 387 boolean notEmpty= !selection.isEmpty(); 388 boolean first= !notEmpty; 389 boolean last= !notEmpty; 390 boolean canRemove= true; 391 boolean canAdd= notEmpty; 392 boolean canMove= true; 393 if (!resolveCurrentParent(selection)) { 394 canAdd= false; 396 canMove= false; 397 canRemove= false; 398 } else { 399 Iterator selected = selection.iterator(); 400 while (selected.hasNext()) { 401 IClasspathEntry element = (IClasspathEntry) selected.next(); 402 403 if (element instanceof GlobalClasspathEntries) { 404 GlobalClasspathEntries global= (GlobalClasspathEntries)element; 405 canRemove= global.canBeRemoved(); 406 canAdd= global.getType() != ClasspathModel.CONTRIBUTED; 407 canMove= false; 408 } 409 IClasspathEntry parent= element.getParent(); 410 if (parent instanceof GlobalClasspathEntries) { 411 canAdd= ((GlobalClasspathEntries)parent).getType() != ClasspathModel.CONTRIBUTED; 412 canRemove= canAdd; 413 canMove= canAdd; 414 } 415 Object [] childEntries = contentProvider.getChildren(parent); 416 List entries = Arrays.asList(childEntries); 417 int lastEntryIndex = entries.size() - 1; 418 if (!first && entries.indexOf(element) == 0) { 419 first= true; 420 } 421 if (!last && entries.indexOf(element) == lastEntryIndex) { 422 last= true; 423 } 424 } 425 } 426 427 addJARButton.setEnabled(canAdd); 428 addExternalJARButton.setEnabled(canAdd); 429 addFolderButton.setEnabled(canAdd); 430 addVariableButton.setEnabled(canAdd); 431 removeButton.setEnabled(notEmpty && canRemove); 432 upButton.setEnabled(canMove && !first); 433 downButton.setEnabled(canMove && !last); 434 } 435 436 private boolean resolveCurrentParent(IStructuredSelection selection) { 437 currentParent= null; 438 Iterator selected= selection.iterator(); 439 440 while (selected.hasNext()) { 441 Object element = selected.next(); 442 if (element instanceof ClasspathEntry) { 443 IClasspathEntry parent= ((IClasspathEntry)element).getParent(); 444 if (currentParent != null) { 445 if (!currentParent.equals(parent)) { 446 return false; 447 } 448 } else { 449 currentParent= parent; 450 } 451 } else { 452 if (currentParent != null) { 453 if (!currentParent.equals(element)) { 454 return false; 455 } 456 } else { 457 currentParent= (IClasspathEntry)element; 458 } 459 } 460 } 461 return true; 462 } 463 464 private File validateAntHome(String path) { 465 File rootDir = null; 466 boolean invalid= true; 467 if (path.length() > 0) { 468 rootDir= new File (path, "lib"); File parentDir= rootDir.getParentFile(); 470 if (parentDir == null || !parentDir.exists()) { 471 container.setErrorMessage(AntPreferencesMessages.AntClasspathBlock_56); 472 } else if (!rootDir.exists()) { 473 container.setErrorMessage(AntPreferencesMessages.AntClasspathBlock_7); 474 } else { 475 invalid= false; 476 } 477 } else { 478 container.setErrorMessage(AntPreferencesMessages.AntClasspathBlock_57); 479 } 480 if (invalid) { 481 setValidated(); 482 return null; 483 } 484 container.setErrorMessage(null); 485 return rootDir; 486 } 487 488 private void browseAntHome() { 489 String lastUsedPath= dialogSettings.get(IAntUIConstants.DIALOGSTORE_LASTANTHOME); 490 if (lastUsedPath == null) { 491 lastUsedPath= ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString(); 492 } 493 DirectoryDialog dialog = new DirectoryDialog(treeViewer.getControl().getShell()); 494 dialog.setMessage(AntPreferencesMessages.AntClasspathBlock_3); 495 dialog.setFilterPath(lastUsedPath); 496 String path = dialog.open(); 497 if (path == null) { 498 return; 499 } 500 antHome= path; 501 if (path.length() > 0) { 502 File rootDir = new File (path, "lib"); setAntHome(rootDir); 504 } else { 505 updateContainer(); 506 } 507 dialogSettings.put(IAntUIConstants.DIALOGSTORE_LASTANTHOME, path); 508 } 509 510 private void setAntHome(File rootDir) { 511 AntClasspathContentProvider contentProvider = (AntClasspathContentProvider) treeViewer.getContentProvider(); 512 contentProvider.setRefreshEnabled(false); 513 contentProvider.removeAllGlobalAntClasspathEntries(); 514 String [] names = rootDir.list(); 515 if (names != null) { 516 Arrays.sort(names); 517 for (int i = 0; i < names.length; i++) { 518 File file = new File (rootDir, names[i]); 519 if (file.isFile() && file.getPath().endsWith(".jar")) { try { 521 URL url = new URL ("file:" + file.getAbsolutePath()); contentProvider.add(ClasspathModel.ANT_HOME, url); 523 } catch (MalformedURLException e) { 524 } 525 } 526 } 527 } 528 529 contentProvider.setRefreshEnabled(true); 530 updateContainer(); 531 } 532 533 public String getAntHome() { 534 return antHome; 535 } 536 537 public void initializeAntHome(String antHomeString) { 538 antHome= antHomeString; 539 } 540 541 public void setInput(ClasspathModel model) { 542 treeViewer.setInput(model); 543 validated= 0; 544 } 545 546 public boolean validateAntHome() { 547 validated++; 548 return validateAntHome(antHome) != null; 549 } 550 551 public Image getClasspathImage() { 552 return labelProvider.getClasspathImage(); 553 } 554 555 public boolean validateToolsJAR() { 556 validated++; 557 boolean check= AntUIPlugin.getDefault().getPreferenceStore().getBoolean(IAntUIPreferenceConstants.ANT_TOOLS_JAR_WARNING); 558 if (check && !AntUIPlugin.isMacOS()) { 559 Object [] entries= antContentProvider.getModel().getEntries(ClasspathModel.ANT_HOME); 560 boolean valid= !JARPresent(entries, TOOLS).isEmpty(); 561 if (!valid) { 562 entries= antContentProvider.getModel().getEntries(ClasspathModel.GLOBAL_USER); 563 valid= !JARPresent(entries, TOOLS).isEmpty(); 564 if (!valid) { 565 entries= antContentProvider.getModel().getEntries(ClasspathModel.USER); 566 valid= !JARPresent(entries, TOOLS).isEmpty(); 567 if (!valid) { 568 MessageDialogWithToggle dialog= MessageDialogWithToggle.openYesNoQuestion(AntUIPlugin.getActiveWorkbenchWindow().getShell(), AntPreferencesMessages.AntClasspathBlock_31, AntPreferencesMessages.AntClasspathBlock_32, AntPreferencesMessages.AntClasspathBlock_33, false, AntUIPlugin.getDefault().getPreferenceStore(), IAntUIPreferenceConstants.ANT_TOOLS_JAR_WARNING); 569 valid= dialog.getReturnCode() == IDialogConstants.YES_ID; 570 } 571 } 572 } 573 if (!valid) { 574 container.setErrorMessage(AntPreferencesMessages.AntClasspathBlock_34); 575 setValidated(); 576 } 577 return valid; 578 } 579 return true; 580 } 581 582 private List JARPresent(Object [] classpathEntries, String [] suffixes) { 583 if (classpathEntries == null) { 584 return Collections.EMPTY_LIST; 585 } 586 List found= new ArrayList (2); 587 for (int i = 0; i < classpathEntries.length; i++) { 588 String file; 589 Object entry = classpathEntries[i]; 590 if (entry instanceof URL ) { 591 file= ((URL )entry).getFile(); 592 } else { 593 file= entry.toString(); 594 } 595 for (int j = 0; j < suffixes.length; j++) { 596 String suffix = suffixes[j]; 597 if (file.endsWith(suffix)) { 598 found.add(suffix); 599 } 600 } 601 } 602 return found; 603 } 604 605 public boolean isValidated() { 606 return validated >= 2; 607 } 608 609 public void setValidated() { 610 validated= 2; 611 } 612 613 private void addVariable() { 614 VariableInputDialog inputDialog = new VariableInputDialog(treeViewer.getControl().getShell()); 615 inputDialog.open(); 616 String variableString= inputDialog.getVariableString(); 617 if (variableString != null && variableString.trim().length() > 0) { 618 ((AntClasspathContentProvider)treeViewer.getContentProvider()).add(currentParent, variableString); 619 treeViewer.setSelection(treeViewer.getSelection()); 620 updateContainer(); 621 } 622 } 623 } 624 | Popular Tags |