1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.motorola.studio.android.common.utilities; 17 18 import java.io.BufferedReader; 19 import java.io.File; 20 import java.io.IOException; 21 import java.io.InputStream; 22 import java.io.InputStreamReader; 23 import java.net.URL; 24 import java.util.ArrayList; 25 import java.util.Collection; 26 import java.util.LinkedHashSet; 27 import java.util.List; 28 import java.util.Map; 29 import java.util.Set; 30 31 import org.eclipse.core.resources.IFile; 32 import org.eclipse.core.resources.IProject; 33 import org.eclipse.core.runtime.CoreException; 34 import org.eclipse.core.runtime.FileLocator; 35 import org.eclipse.core.runtime.IConfigurationElement; 36 import org.eclipse.core.runtime.IExtension; 37 import org.eclipse.core.runtime.IExtensionPoint; 38 import org.eclipse.core.runtime.IExtensionRegistry; 39 import org.eclipse.core.runtime.IPath; 40 import org.eclipse.core.runtime.IProgressMonitor; 41 import org.eclipse.core.runtime.IStatus; 42 import org.eclipse.core.runtime.MultiStatus; 43 import org.eclipse.core.runtime.Path; 44 import org.eclipse.core.runtime.Platform; 45 import org.eclipse.core.runtime.Status; 46 import org.eclipse.core.runtime.SubMonitor; 47 import org.eclipse.jdt.core.IClasspathEntry; 48 import org.eclipse.jdt.core.IJavaProject; 49 import org.eclipse.jdt.core.IPackageFragment; 50 import org.eclipse.jdt.core.IPackageFragmentRoot; 51 import org.eclipse.jdt.core.JavaCore; 52 import org.eclipse.jdt.core.JavaModelException; 53 import org.eclipse.jface.dialogs.ErrorDialog; 54 import org.eclipse.jface.dialogs.IDialogConstants; 55 import org.eclipse.jface.dialogs.MessageDialog; 56 import org.eclipse.jface.layout.GridDataFactory; 57 import org.eclipse.jface.preference.IPreferenceNode; 58 import org.eclipse.jface.preference.PreferenceDialog; 59 import org.eclipse.jface.preference.PreferenceManager; 60 import org.eclipse.sequoyah.localization.tools.datamodel.LocaleInfo; 61 import org.eclipse.sequoyah.localization.tools.datamodel.LocalizationFile; 62 import org.eclipse.sequoyah.localization.tools.datamodel.LocalizationFileBean; 63 import org.eclipse.sequoyah.localization.tools.datamodel.StringLocalizationFile; 64 import org.eclipse.sequoyah.localization.tools.datamodel.node.StringArrayNode; 65 import org.eclipse.sequoyah.localization.tools.datamodel.node.StringNode; 66 import org.eclipse.sequoyah.localization.tools.extensions.classes.ILocalizationSchema; 67 import org.eclipse.sequoyah.localization.tools.managers.LocalizationManager; 68 import org.eclipse.sequoyah.localization.tools.managers.ProjectLocalizationManager; 69 import org.eclipse.swt.SWT; 70 import org.eclipse.swt.events.SelectionAdapter; 71 import org.eclipse.swt.events.SelectionEvent; 72 import org.eclipse.swt.graphics.Rectangle; 73 import org.eclipse.swt.layout.GridData; 74 import org.eclipse.swt.layout.GridLayout; 75 import org.eclipse.swt.widgets.Button; 76 import org.eclipse.swt.widgets.Composite; 77 import org.eclipse.swt.widgets.Control; 78 import org.eclipse.swt.widgets.Display; 79 import org.eclipse.swt.widgets.Label; 80 import org.eclipse.swt.widgets.MessageBox; 81 import org.eclipse.swt.widgets.Shell; 82 import org.eclipse.ui.IEditorPart; 83 import org.eclipse.ui.IEditorReference; 84 import org.eclipse.ui.IViewPart; 85 import org.eclipse.ui.IViewReference; 86 import org.eclipse.ui.IWorkbench; 87 import org.eclipse.ui.IWorkbenchPage; 88 import org.eclipse.ui.IWorkbenchWindow; 89 import org.eclipse.ui.PartInitException; 90 import org.eclipse.ui.PlatformUI; 91 import org.eclipse.ui.console.ConsolePlugin; 92 import org.eclipse.ui.console.IConsole; 93 import org.eclipse.ui.console.IOConsole; 94 import org.eclipse.ui.console.IOConsoleOutputStream; 95 import org.eclipse.ui.internal.browser.WebBrowserEditor; 96 import org.eclipse.ui.internal.browser.WebBrowserEditorInput; 97 import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceDialog; 98 import org.osgi.framework.Bundle; 99 100 import com.motorola.studio.android.common.CommonPlugin; 101 import com.motorola.studio.android.common.IAndroidConstants; 102 import com.motorola.studio.android.common.exception.AndroidException; 103 import com.motorola.studio.android.common.log.StudioLogger; 104 import com.motorola.studio.android.common.utilities.i18n.UtilitiesNLS; 105 import com.motorola.studio.android.manifest.AndroidProjectManifestFile; 106 import com.motorola.studio.android.model.manifest.AndroidManifestFile; 107 108 /** 109 * Class that contains methods to do common tasks through the Eclipse Platform 110 */ 111 @SuppressWarnings("restriction") 112 public class EclipseUtils 113 { 114 115 private static final String STUDIO_ANDROID_CONSOLE_ID = "Studio for Android"; 116 117 private static final String ORG_ECLIPSE_UI_NET_NET_PREFERENCES = 118 "org.eclipse.ui.net.NetPreferences"; //$NON-NLS-1$ 119 120 private static final String ORG_ECLIPSE_EQUINOX_SECURE_STORAGE_PREFERENCES = 121 "org.eclipse.equinox.security.ui.storage"; //$NON-NLS-1$ 122 123 private static final String LOCALIZATION_FILE_TYPE = 124 "org.eclipse.sequoyah.localization.android.datamodel.AndroidStringLocalizationFile"; //$NON-NLS-1$ 125 126 /** 127 * Shows an error dialog 128 * @param dialogTitle 129 * The dialog title 130 * @param dialogMessage 131 * The dialog message 132 * @param status 133 * The IStatus object containing the error 134 */ 135 public static void showErrorDialog(final String dialogTitle, final String dialogMessage, 136 final IStatus status) 137 { 138 PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() 139 { 140 public void run() 141 { 142 Shell aShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); 143 144 Shell shell = new Shell(aShell); 145 146 Rectangle parentSize = 147 aShell.getParent() != null ? aShell.getParent().getBounds() : shell 148 .getBounds(); 149 150 ErrorDialog errorDlg = 151 new ErrorDialog(shell, dialogTitle, dialogMessage, status, IStatus.ERROR); 152 153 Rectangle dialogSize = shell.getBounds(); 154 155 int x = ((parentSize.width - dialogSize.width) / 2) + parentSize.x; 156 int y = ((parentSize.height - dialogSize.height) / 2) + parentSize.y; 157 158 shell.setLocation(x, y); 159 160 errorDlg.open(); 161 } 162 163 }); 164 } 165 166 /** 167 * Shows an information dialog 168 * @param dialogTitle 169 * The dialog title 170 * @param dialogMessage 171 * The dialog message 172 * @param buttonLabels 173 * The labels to be displayed as buttons in the dialog, or 174 * <code>null</code> to have only an "OK" button. 175 * 176 * @return The code of the button pressed by the user 177 */ 178 public static int showInformationDialog(String dialogTitle, String dialogMessage, 179 String[] buttonLabels) 180 { 181 return showInformationDialog(dialogTitle, dialogMessage, null, buttonLabels, 182 MessageDialog.INFORMATION); 183 } 184 185 public static int showInformationDialog(String dialogTitle, String dialogMessage, 186 String[] buttonLabels, int dialogImageType) 187 { 188 return showInformationDialog(dialogTitle, dialogMessage, null, buttonLabels, 189 dialogImageType); 190 } 191 192 /** 193 * Shows an information dialog 194 * @param dialogTitle 195 * The dialog title 196 * @param dialogMessage 197 * The dialog message 198 * @param detailsMessage 199 * The details message 200 * @param buttonLabels 201 * The labels to be displayed as buttons in the dialog, or 202 * <code>null</code> to have only an "OK" button. 203 * @param dialogImageType 204 * The image to be displayed right before the dialogMessage 205 * 206 * @return The code of the button pressed by the user 207 */ 208 public static int showInformationDialogWithDetails(String dialogTitle, String dialogMessage, 209 String detailsMessage, String[] buttonLabels) 210 { 211 return showInformationDialog(dialogTitle, dialogMessage, detailsMessage, buttonLabels, 212 MessageDialog.INFORMATION); 213 } 214 215 private static int showInformationDialog(final String dialogTitle, final String dialogMessage, 216 final String detailsMessage, final String[] buttonLabels, final int dialogImageType) 217 { 218 final int[] returnCode = new int[1]; 219 PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() 220 { 221 public void run() 222 { 223 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); 224 225 Rectangle parentSize; 226 if (shell.getParent() != null) 227 { 228 parentSize = shell.getParent().getBounds(); 229 } 230 else 231 { 232 233 parentSize = shell.getBounds(); 234 } 235 236 MessageDialog dlg; 237 String[] internButtonLabels = buttonLabels; 238 if (internButtonLabels == null) 239 { 240 internButtonLabels = new String[] 241 { 242 "OK" 243 }; 244 } 245 246 if (detailsMessage == null) 247 { 248 dlg = 249 new MessageDialog(shell, dialogTitle, null, dialogMessage, 250 dialogImageType, internButtonLabels, 0); 251 } 252 else 253 { 254 dlg = 255 new MessageDialog(shell, dialogTitle, null, dialogMessage, 256 dialogImageType, internButtonLabels, 0) 257 { 258 @Override 259 protected Control createCustomArea(Composite parent) 260 { 261 final Composite main = new Composite(parent, parent.getStyle()); 262 GridLayout layout = new GridLayout(); 263 main.setLayout(layout); 264 GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); 265 main.setLayoutData(data); 266 267 final Button detailsButton = new Button(main, SWT.PUSH); 268 detailsButton.setText(UtilitiesNLS.UI_EclipseUtils_OpenDetails); 269 data = new GridData(SWT.RIGHT, SWT.CENTER, true, false); 270 detailsButton.setLayoutData(data); 271 detailsButton.addSelectionListener(new SelectionAdapter() 272 { 273 private Label detailsText; 274 275 @Override 276 public void widgetSelected(SelectionEvent e) 277 { 278 if ((detailsText != null) && !detailsText.isDisposed()) 279 { 280 detailsButton 281 .setText(UtilitiesNLS.UI_EclipseUtils_OpenDetails); 282 detailsText.dispose(); 283 } 284 else 285 { 286 detailsButton 287 .setText(UtilitiesNLS.UI_EclipseUtils_CloseDetails); 288 detailsText = 289 new Label(main, SWT.WRAP | SWT.BORDER); 290 detailsText.setText(detailsMessage); 291 GridData data = 292 new GridData(SWT.FILL, SWT.FILL, true, true); 293 detailsText.setLayoutData(data); 294 GridDataFactory 295 .fillDefaults() 296 .align(SWT.FILL, SWT.BEGINNING) 297 .grab(true, false) 298 .hint(convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH), 299 SWT.DEFAULT).applyTo(detailsText); 300 } 301 getShell().pack(); 302 } 303 }); 304 305 return main; 306 } 307 }; 308 } 309 310 Rectangle dialogSize = shell.getBounds(); 311 312 int x = ((parentSize.width - dialogSize.width) / 2) + parentSize.x; 313 int y = ((parentSize.height - dialogSize.height) / 2) + parentSize.y; 314 315 shell.setLocation(x, y); 316 317 returnCode[0] = dlg.open(); 318 } 319 }); 320 321 return returnCode[0]; 322 } 323 324 /** 325 * Display a yes/no question dialog box 326 * 327 * @param title 328 * The title of the dialog box 329 * @param message 330 * The error message 331 * @param display 332 * the parent display 333 * @return true if OK was clicked. 334 */ 335 public final static boolean displayPrompt(final Display display, final String title, 336 final String message) 337 { 338 /* 339 * Sometimes we need to ask the user what he wants to do. 340 */ 341 final boolean[] result = new boolean[1]; 342 display.syncExec(new Runnable() 343 { 344 345 public void run() 346 { 347 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); 348 result[0] = MessageDialog.openQuestion(shell, title, message); 349 } 350 }); 351 return result[0]; 352 } 353 354 /** 355 * Opens a Yes/No dialog 356 * 357 * @param dialogTitle 358 * The dialog title 359 * @param dialogMessage 360 * The dialog message 361 * 362 * @return true if the user answers yes and false otherwise 363 */ 364 public static boolean openYesNoDialog(final String dialogTitle, final String dialogMessage) 365 { 366 final Boolean[] answer = new Boolean[1]; 367 368 PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() 369 { 370 371 public void run() 372 { 373 Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); 374 MessageBox msgBox = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.YES | SWT.NO); 375 msgBox.setText(dialogTitle); 376 msgBox.setMessage(dialogMessage); 377 378 answer[0] = msgBox.open() == SWT.YES; 379 } 380 }); 381 382 return answer[0]; 383 } 384 385 /** 386 * Show the error message for the given AndroidException 387 * 388 * @param e 389 * The AndroidException that generated the error to be displayed. 390 */ 391 public static void showErrorDialog(AndroidException e) 392 { 393 String title = UtilitiesNLS.ERR_Gen_ErrorTitle; 394 showErrorDialog(title, e.getMessage()); 395 } 396 397 /** 398 * Show the error message using the given title and message 399 * 400 * @param title 401 * of the error dialog 402 * @param message 403 * to be displayed in the error dialog. 404 */ 405 public static void showErrorDialog(final String title, final String message) 406 { 407 Display.getDefault().asyncExec(new Runnable() 408 { 409 410 public void run() 411 { 412 IWorkbenchWindow ww = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 413 MessageDialog.openError(ww.getShell(), title, message); 414 } 415 }); 416 } 417 418 /** 419 * Show an information message using the given title and message 420 * 421 * @param title 422 * of the dialog 423 * @param message 424 * to be displayed in the dialog. 425 */ 426 public static void showInformationDialog(final String title, final String message) 427 { 428 Display.getDefault().asyncExec(new Runnable() 429 { 430 431 public void run() 432 { 433 IWorkbench workbench = PlatformUI.getWorkbench(); 434 IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); 435 Shell shell = ww.getShell(); 436 MessageDialog.openInformation(shell, title, message); 437 } 438 }); 439 } 440 441 /** 442 * Show a warning message using the given title and message 443 * 444 * @param title 445 * of the dialog 446 * @param message 447 * to be displayed in the dialog. 448 */ 449 public static void showWarningDialog(final String title, final String message) 450 { 451 Display.getDefault().asyncExec(new Runnable() 452 { 453 454 public void run() 455 { 456 IWorkbench workbench = PlatformUI.getWorkbench(); 457 IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); 458 Shell shell = ww.getShell(); 459 MessageDialog.openWarning(shell, title, message); 460 } 461 }); 462 } 463 464 /** 465 * Show a question message using the given title and message 466 * 467 * @param title 468 * of the dialog 469 * @param message 470 * to be displayed in the dialog. 471 */ 472 public static boolean showQuestionDialog(final String title, final String message) 473 { 474 class BooleanWrapper 475 { 476 public boolean bool = false; 477 } 478 479 final BooleanWrapper boolWrapper = new BooleanWrapper(); 480 Display.getDefault().syncExec(new Runnable() 481 { 482 483 public void run() 484 { 485 IWorkbench workbench = PlatformUI.getWorkbench(); 486 IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); 487 Shell shell = ww.getShell(); 488 boolWrapper.bool = MessageDialog.openQuestion(shell, title, message); 489 } 490 }); 491 492 return boolWrapper.bool; 493 } 494 495 /** 496 * Show a question message using the given title and message 497 * 498 * @param title 499 * of the dialog 500 * @param message 501 * to be displayed in the dialog. 502 */ 503 public static int showQuestionWithCancelDialog(final String title, final String message) 504 { 505 class IntWrapper 506 { 507 public int diagReturn = 0; 508 } 509 510 final IntWrapper intWrapper = new IntWrapper(); 511 Display.getDefault().syncExec(new Runnable() 512 { 513 514 public void run() 515 { 516 IWorkbench workbench = PlatformUI.getWorkbench(); 517 IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); 518 Shell shell = ww.getShell(); 519 MessageDialog dialog = 520 new MessageDialog(shell, title, null, message, MessageDialog.QUESTION, 521 new String[] 522 { 523 IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, 524 IDialogConstants.CANCEL_LABEL 525 }, 0); 526 int diagResults = dialog.open(); 527 switch (diagResults) 528 { 529 case 0: 530 intWrapper.diagReturn = SWT.YES; 531 break; 532 case 1: 533 intWrapper.diagReturn = SWT.NO; 534 break; 535 case 2: 536 default: 537 intWrapper.diagReturn = SWT.CANCEL; 538 break; 539 } 540 } 541 }); 542 543 return intWrapper.diagReturn; 544 } 545 546 /** 547 * Show a question message using the given title and message 548 * 549 * @param title 550 * of the dialog 551 * @param message 552 * to be displayed in the dialog. 553 */ 554 public static int showQuestionYesAllCancelDialog(final String title, final String message) 555 { 556 class IntWrapper 557 { 558 public int diagReturn = 0; 559 } 560 561 final IntWrapper intWrapper = new IntWrapper(); 562 Display.getDefault().syncExec(new Runnable() 563 { 564 565 public void run() 566 { 567 IWorkbench workbench = PlatformUI.getWorkbench(); 568 IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); 569 Shell shell = ww.getShell(); 570 MessageDialog dialog = 571 new MessageDialog(shell, title, null, message, MessageDialog.QUESTION, 572 new String[] 573 { 574 IDialogConstants.YES_LABEL, 575 IDialogConstants.YES_TO_ALL_LABEL, 576 IDialogConstants.NO_LABEL 577 }, 0); 578 int diagResults = dialog.open(); 579 switch (diagResults) 580 { 581 case 0: 582 intWrapper.diagReturn = IDialogConstants.YES_ID; 583 break; 584 case 1: 585 intWrapper.diagReturn = IDialogConstants.YES_TO_ALL_ID; 586 break; 587 case 2: 588 default: 589 intWrapper.diagReturn = IDialogConstants.NO_ID; 590 break; 591 } 592 } 593 }); 594 595 return intWrapper.diagReturn; 596 } 597 598 /** 599 * Returns a plugin attribute using the extension as parameter. 600 * 601 * @param extensionId 602 * the extension from which the attribute should be collected 603 * @param elementName 604 * the extension element 605 * 606 * @return The executable class associated to the provided element 607 * 608 * @throws CoreException 609 */ 610 public static Object getExecutable(String extensionId, String elementName) throws CoreException 611 { 612 Object executable = null; 613 614 IExtensionRegistry registry = Platform.getExtensionRegistry(); 615 IExtension fromExtension = registry.getExtension(extensionId); 616 617 if ((fromExtension != null) && (elementName != null)) 618 { 619 IConfigurationElement[] elements = fromExtension.getConfigurationElements(); 620 621 for (IConfigurationElement element : elements) 622 { 623 if (elementName.equals(element.getName())) 624 { 625 executable = element.createExecutableExtension("class"); 626 } 627 } 628 } 629 630 return executable; 631 } 632 633 /** 634 * Returns an array of extensions that are plugged in a provided extension 635 * point 636 * 637 * @param extensionPointId 638 * the id of the extension point to look for extensions at 639 * 640 * @return an array containing the plugins plugged at the extension point 641 */ 642 public static IExtension[] getInstalledPlugins(String extensionPointId) 643 { 644 IExtensionRegistry registry = Platform.getExtensionRegistry(); 645 IExtensionPoint extensionPoint = registry.getExtensionPoint(extensionPointId); 646 IExtension[] pluggedExtensions; 647 648 if (extensionPoint != null) 649 { 650 pluggedExtensions = extensionPoint.getExtensions(); 651 } 652 else 653 { 654 pluggedExtensions = new IExtension[0]; 655 } 656 657 return pluggedExtensions; 658 } 659 660 /** 661 * Retrieves a view object, showing it at the IDE if hidden 662 * 663 * @param viewId 664 * The identifier of the view to be shown 665 * 666 * @return The view that was just opened, or a reference to an already 667 * opened view 668 * 669 * @throws PartInitException 670 * If the view cannot be shown at the workbench part 671 */ 672 public static IViewPart showView(final String viewId) throws PartInitException 673 { 674 final Object[] tempObj = new Object[1]; 675 676 Display.getDefault().syncExec(new Runnable() 677 { 678 679 public void run() 680 { 681 IWorkbenchWindow activeWindow = 682 PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 683 if (activeWindow != null) 684 { 685 IWorkbenchPage activePage = activeWindow.getActivePage(); 686 if (activePage != null) 687 { 688 try 689 { 690 tempObj[0] = activePage.showView(viewId); 691 } 692 catch (PartInitException e) 693 { 694 tempObj[0] = e; 695 } 696 } 697 } 698 } 699 }); 700 701 if (tempObj[0] instanceof PartInitException) 702 { 703 throw (PartInitException) tempObj[0]; 704 } 705 706 return (IViewPart) tempObj[0]; 707 } 708 709 /** 710 * Retrieves a view object from the active window, but do not show if it is 711 * hidden 712 * 713 * @param viewId 714 * The identifier of the view to be retrieved 715 * 716 * @return A reference to the view identified by viewId if available; null 717 * otherwise 718 */ 719 public static IViewPart getActiveView(final String viewId) 720 { 721 final Object[] tempObj = new Object[1]; 722 723 Display.getDefault().syncExec(new Runnable() 724 { 725 726 public void run() 727 { 728 IWorkbenchWindow activeWindow = 729 PlatformUI.getWorkbench().getActiveWorkbenchWindow(); 730 if (activeWindow != null) 731 { 732 IWorkbenchPage activePage = activeWindow.getActivePage(); 733 if (activePage != null) 734 { 735 IViewReference ref = activePage.findViewReference(viewId); 736 if (ref != null) 737 { 738 IViewPart part = ref.getView(false); 739 tempObj[0] = part; 740 } 741 742 } 743 } 744 } 745 }); 746 747 return (IViewPart) tempObj[0]; 748 } 749 750 /** 751 * Retrieves a view object, but do not show it if hidden 752 * 753 * @param viewId 754 * The identifier of the view object to be retrieved 755 * 756 * @return A collection of views with provided id that are being shown in 757 * any opened perspective 758 */ 759 public static Collection<IViewPart> getAllOpenedViewsWithId(final String viewId) 760 { 761 final Collection<IViewPart> openedViews = new LinkedHashSet<IViewPart>(); 762 763 Display.getDefault().syncExec(new Runnable() 764 { 765 766 public void run() 767 { 768 IWorkbenchWindow[] allWindows = PlatformUI.getWorkbench().getWorkbenchWindows(); 769 for (IWorkbenchWindow window : allWindows) 770 { 771 IWorkbenchPage[] allPagesInWindow = window.getPages(); 772 773 for (IWorkbenchPage page : allPagesInWindow) 774 { 775 IViewPart view = page.findView(viewId); 776 if (view != null) 777 { 778 openedViews.add(view); 779 } 780 } 781 } 782 } 783 }); 784 785 return openedViews; 786 } 787 788 /** 789 * Retrieves all editor objects 790 * 791 * @return A collection of all editors 792 */ 793 public static Collection<IEditorPart> getAllOpenedEditors() 794 { 795 final Collection<IEditorPart> editors = new LinkedHashSet<IEditorPart>(); 796 797 Display.getDefault().syncExec(new Runnable() 798 { 799 800 public void run() 801 { 802 IWorkbenchWindow[] allWindows = PlatformUI.getWorkbench().getWorkbenchWindows(); 803 for (IWorkbenchWindow window : allWindows) 804 { 805 IWorkbenchPage[] allPagesInWindow = window.getPages(); 806 807 for (IWorkbenchPage page : allPagesInWindow) 808 { 809 IEditorReference[] editorRefs = page.getEditorReferences(); 810 for (IEditorReference editorRef : editorRefs) 811 { 812 editors.add(editorRef.getEditor(false)); 813 } 814 } 815 } 816 } 817 }); 818 819 return editors; 820 } 821 822 /** 823 * Retrieves the page for the given editor 824 * 825 * @param editor 826 * 827 * @return A page 828 */ 829 public static IWorkbenchPage getPageForEditor(final IEditorPart editor) 830 { 831 832 final Object[] tempObj = new Object[1]; 833 834 Display.getDefault().syncExec(new Runnable() 835 { 836 837 public void run() 838 { 839 IWorkbenchWindow[] allWindows = PlatformUI.getWorkbench().getWorkbenchWindows(); 840 for (IWorkbenchWindow window : allWindows) 841 { 842 IWorkbenchPage[] allPagesInWindow = window.getPages(); 843 844 for (IWorkbenchPage page : allPagesInWindow) 845 { 846 if (page.findEditor(editor.getEditorInput()) != null) 847 { 848 tempObj[0] = page; 849 break; 850 } 851 } 852 } 853 } 854 }); 855 856 return (IWorkbenchPage) tempObj[0]; 857 } 858 859 /** 860 * Open a web browser editor to display the given URL. If there is already 861 * an opened Web Browser Editor for the given URL, it is activated and a new 862 * one is NOT opened. 863 * 864 * @param wantedUrl 865 * URL to be opened. 866 * @return the opened Web Browser Editor 867 */ 868 public static IEditorReference openedWebEditor(IWorkbenchPage page, URL wantedUrl) 869 { 870 IEditorReference wantedWebEditor = null; 871 872 if (page != null) 873 { 874 for (IEditorReference editor : page.getEditorReferences()) 875 { 876 if (WebBrowserEditor.WEB_BROWSER_EDITOR_ID.equals(editor.getId())) 877 { 878 try 879 { 880 WebBrowserEditorInput webEditorInput = 881 (WebBrowserEditorInput) editor.getEditorInput(); 882 URL openedURL = webEditorInput.getURL(); 883 if ((openedURL != null) && openedURL.equals(wantedUrl)) 884 { 885 wantedWebEditor = editor; 886 break; 887 } 888 } 889 catch (Exception e) 890 { 891 StudioLogger.error(EclipseUtils.class, 892 "Failed to get URL displayed by the opened Web Editor"); 893 } 894 } 895 } 896 } 897 898 if (wantedWebEditor != null) 899 { 900 StudioLogger 901 .debug(EclipseUtils.class, 902 "There is already an opened Web Browser Editor displaying the wanted URL. Simply activate it."); 903 page.activate(wantedWebEditor.getEditor(true)); 904 } 905 else 906 { 907 StudioLogger.debug(EclipseUtils.class, "Open new Web Browser Editor for: " + wantedUrl); 908 WebBrowserEditorInput input = new WebBrowserEditorInput(wantedUrl); 909 910 WebBrowserEditor.open(input); 911 } 912 913 return wantedWebEditor; 914 } 915 916 /** 917 * Retrieves the install location on the filesystem based on the given plug-in identifier 918 * @param identifier the plug-in id. 919 * @return A string containing the install path for the bundle with id - identifier. 920 */ 921 public static String getInstallLocation(String identifier) 922 { 923 return getInstallLocation(Platform.getBundle(identifier)); 924 } 925 926 /** 927 * Retrieves the install location for the given bundle. 928 * @param bundle 929 * @return the bundle install location. 930 */ 931 public static String getInstallLocation(Bundle bundle) 932 { 933 String installLocation = ""; 934 try 935 { 936 URL locationUrl = FileLocator.find(bundle, new Path("/"), null); 937 URL fileUrl = FileLocator.toFileURL(locationUrl); 938 installLocation = (new File(fileUrl.getFile())).getAbsolutePath(); 939 } 940 catch (Exception e) 941 { 942 StudioLogger.error(EclipseUtils.class, "Error finding install location for bundle: " 943 + bundle.getBundleId(), e); 944 } 945 return installLocation; 946 } 947 948 /** 949 * Open the preference page with the specified ID 950 * @param nodeID the id of preference page to show 951 */ 952 @SuppressWarnings("unchecked") 953 public static void openPreference(Shell shell, String nodeID) 954 { 955 // Makes the network preferences dialog manager 956 PreferenceManager manager = PlatformUI.getWorkbench().getPreferenceManager(); 957 IPreferenceNode networkNode = null; 958 for (IPreferenceNode node : (List<IPreferenceNode>) manager 959 .getElements(PreferenceManager.PRE_ORDER)) 960 { 961 if (node.getId().equals(nodeID)) 962 { 963 networkNode = node; 964 break; 965 } 966 } 967 PreferenceManager prefMan = new PreferenceManager(); 968 if (networkNode != null) 969 { 970 prefMan.addToRoot(networkNode); 971 } 972 PreferenceDialog preferencesDialog = new WorkbenchPreferenceDialog(shell, prefMan); 973 preferencesDialog.create(); 974 preferencesDialog.open(); 975 } 976 977 /** 978 * Convenience method to open the preferences dialog with the secure storage preference page 979 */ 980 public static void openSecureStoragePreferences(Shell shell) 981 { 982 openPreference(shell, ORG_ECLIPSE_EQUINOX_SECURE_STORAGE_PREFERENCES); 983 } 984 985 /** 986 * Convenience method to open the preferences dialog with the network preferences preference page 987 */ 988 public static void openNetworkPreferences(Shell shell) 989 { 990 openPreference(shell, ORG_ECLIPSE_UI_NET_NET_PREFERENCES); 991 } 992 993 /** 994 * Looks for the most severe {@link Status} within a {@link MultiStatus}. 995 * @param errorStatus. 996 * @return the most severe status of them all. 997 */ 998 public static IStatus findMostSevereError(final MultiStatus errorStatus) 999 { 1000 IStatus mostSevere = null; 1001 if (!errorStatus.isOK()) 1002 { 1003 for (IStatus status : errorStatus.getChildren()) 1004 { 1005 if (mostSevere == null) 1006 { 1007 mostSevere = status; 1008 } 1009 if (status.getSeverity() > mostSevere.getSeverity()) 1010 { 1011 mostSevere = status; 1012 } 1013 } 1014 } 1015 return mostSevere; 1016 } 1017 1018 /** 1019 * Reads a resource located inside the plugin, such as a template file. 1020 * @param resourcePath - The path to the resource. 1021 * @return An array of bytes from the resource 1022 * @throws IOException 1023 */ 1024 public static String readEmbeddedResource(Bundle bundle, String resourcePath) 1025 { 1026 1027 InputStream is = null; 1028 BufferedReader bufferedReader = null; 1029 String embeddedResourcePath = null; 1030 try 1031 { 1032 1033 URL url = bundle.getEntry((new StringBuilder("/")).append(resourcePath).toString()); 1034 if (url != null) 1035 { 1036 is = url.openStream(); 1037 } 1038 1039 if (is != null) 1040 { 1041 bufferedReader = new BufferedReader(new InputStreamReader(is)); 1042 StringBuilder result = new StringBuilder(bufferedReader.readLine()); 1043 String line; 1044 while ((line = bufferedReader.readLine()) != null) 1045 { 1046 result.append('\n'); 1047 result.append(line); 1048 } 1049 embeddedResourcePath = result.toString(); 1050 } 1051 } 1052 catch (IOException ioEx) 1053 { 1054 1055 StudioLogger 1056 .error(CommonPlugin.class, "Error while reading an embedded resource", ioEx); //$NON-NLS-1$ 1057 1058 } 1059 finally 1060 { 1061 if (bufferedReader != null) 1062 { 1063 try 1064 { 1065 bufferedReader.close(); 1066 } 1067 catch (IOException e) 1068 { 1069 //Do nothing. 1070 } 1071 } 1072 if (is != null) 1073 { 1074 try 1075 { 1076 is.close(); 1077 } 1078 catch (IOException e) 1079 { 1080 //Do nothing. 1081 } 1082 } 1083 } 1084 1085 return embeddedResourcePath; 1086 } 1087 1088 /** 1089 * Gets the default package from project. 1090 * @param javaProject 1091 * @return the project's default package. 1092 * @throws JavaModelException 1093 */ 1094 public static IPackageFragment getDefaultPackageFragment(IJavaProject javaProject) 1095 throws JavaModelException 1096 { 1097 IPackageFragment pack = null; 1098 AndroidManifestFile manifest = null; 1099 1100 if ((javaProject != null) && javaProject.isOpen()) 1101 { 1102 // First, tries to get the default package from the AndroidManifest.xml file 1103 try 1104 { 1105 manifest = AndroidProjectManifestFile.getFromProject(javaProject.getProject()); 1106 } 1107 catch (AndroidException e) 1108 { 1109 // Do nothing 1110 } 1111 catch (CoreException e) 1112 { 1113 // Do nothing 1114 } 1115 1116 if (manifest != null) 1117 { 1118 String defaultPackage = manifest.getManifestNode().getPackageName(); 1119 1120 if ((defaultPackage != null) && (defaultPackage.trim().length() > 0)) 1121 { 1122 IPackageFragment[] allPacks = javaProject.getPackageFragments(); 1123 1124 if (allPacks != null) 1125 { 1126 for (IPackageFragment frag : allPacks) 1127 { 1128 if (frag.getElementName().equals(defaultPackage)) 1129 { 1130 pack = frag; 1131 break; 1132 } 1133 } 1134 } 1135 } 1136 } 1137 1138 // If the default package could not get from the AndroidManifest.xml file, search for 1139 // one in the project 1140 if (pack == null) 1141 { 1142 IPackageFragment[] packs = javaProject.getPackageFragments(); 1143 if (packs != null) 1144 { 1145 for (int i = 0; (i < packs.length) && (pack == null); i++) 1146 { 1147 if (packs[i].getKind() != IPackageFragmentRoot.K_BINARY) 1148 { 1149 if (!isInsideGenFolder(packs[i]) && !packs[i].isDefaultPackage() 1150 && packs[i].getElementName().contains(".") && packs[i].exists()) //$NON-NLS-1$ 1151 { 1152 pack = packs[i]; 1153 break; 1154 } 1155 } 1156 } 1157 } 1158 } 1159 } 1160 1161 return pack; 1162 } 1163 1164 /** 1165 * Checks if a package fragment is inside the "gen" folder 1166 * @param fragment The package fragment to be checked 1167 * @return true if the package fragment is inside the "gen" folder or false otherwise 1168 */ 1169 private static boolean isInsideGenFolder(IPackageFragment fragment) 1170 { 1171 boolean isInside = 1172 (fragment.getParent() instanceof IPackageFragmentRoot) 1173 && fragment.getParent().getElementName() 1174 .equals(IAndroidConstants.GEN_SRC_FOLDER); 1175 1176 return isInside; 1177 } 1178 1179 /** 1180 * This method adds a list of paths to all projects classpaths settings. 1181 * @param javaProjects List of projects that will have the classpath changed 1182 * @param libsPaths List of lib paths to be added to Projects' classpaths 1183 * @param monitor Monitor to track progress or null if it's not necessary. 1184 * @return IStatus The status of the operation. This method stops processing at the first error found. 1185 */ 1186 public static IStatus addLibsToProjects(List<IJavaProject> javaProjects, List<IPath> libsPaths, 1187 IProgressMonitor monitor) 1188 { 1189 SubMonitor subMonitor = SubMonitor.convert(monitor); 1190 subMonitor.beginTask(UtilitiesNLS.ProjectUtils_AddLibsProgress_ConfiguringClassPaths, 1191 ((javaProjects.size() * 2) + libsPaths.size()) * 1000); 1192 IStatus status = Status.OK_STATUS; 1193 IClasspathEntry[] classPathEntries = new IClasspathEntry[libsPaths.size()]; 1194 int i = 0; 1195 subMonitor.subTask(UtilitiesNLS.ProjectUtils_AddLibsProgress_PreparingPaths); 1196 for (IPath libPath : libsPaths) 1197 { 1198 IClasspathEntry classpathEntry = JavaCore.newLibraryEntry(libPath, null, null); 1199 classPathEntries[i] = classpathEntry; 1200 i++; 1201 subMonitor.worked(1000); 1202 } 1203 1204 subMonitor.subTask(UtilitiesNLS.ProjectUtils_AddLibsProgress_ConfiguringProjects); 1205 for (IJavaProject javaProject : javaProjects) 1206 { 1207 IClasspathEntry[] rawClasspath; 1208 try 1209 { 1210 rawClasspath = javaProject.getRawClasspath(); 1211 int length = rawClasspath.length; 1212 int newEntriesLength = classPathEntries.length; 1213 int newLenght = length + newEntriesLength; 1214 IClasspathEntry[] newClassPath = new IClasspathEntry[newLenght]; 1215 1216 System.arraycopy(rawClasspath, 0, newClassPath, 0, length); //Copy the existent classPath to the new array. 1217 System.arraycopy(classPathEntries, 0, newClassPath, length, newEntriesLength); //Copy the new entries to the new array 1218 subMonitor.worked(1000); 1219 javaProject.setRawClasspath(newClassPath, subMonitor.newChild(1000)); // Set the Project's classpath. 1220 } 1221 catch (JavaModelException e) 1222 { 1223 status = 1224 new Status(IStatus.ERROR, CommonPlugin.PLUGIN_ID, 1225 UtilitiesNLS.ProjectUtils_AddLibsProgress_ErrorSettingClasspaths, e); 1226 break; 1227 } 1228 } 1229 subMonitor.done(); 1230 return status; 1231 } 1232 1233 /** 1234 * Verifies if a given libPath is already available on the project classpath. 1235 * @param javaProject 1236 * @param libPath 1237 * @return true if present, false otherwise 1238 */ 1239 public static boolean isLibOnClasspath(IJavaProject javaProject, IPath libPath) 1240 { 1241 try 1242 { 1243 IClasspathEntry[] rawClasspath = javaProject.getRawClasspath(); 1244 for (IClasspathEntry classpathEntry : rawClasspath) 1245 { 1246 if (classpathEntry.getPath().equals(libPath)) 1247 { 1248 return true; 1249 } 1250 } 1251 } 1252 catch (JavaModelException e) 1253 { 1254 return false; 1255 } 1256 return false; 1257 } 1258 1259 /** 1260 * Add strings and array to string.xml file 1261 * @param project 1262 * @param strings string entries to add 1263 * @param arrays array entries to add 1264 * @param monitor array entries to add 1265 * @throws CoreException 1266 * @throws IOException 1267 */ 1268 public static void createOrUpdateDictionaryFile(IProject project, Map<String, String> strings, 1269 Map<String, List<String>> arrays, IProgressMonitor monitor) throws IOException, 1270 CoreException 1271 { 1272 List<StringNode> stringNodes = new ArrayList<StringNode>(); 1273 List<StringArrayNode> arrayNodes = new ArrayList<StringArrayNode>(); 1274 1275 if (strings != null) 1276 { 1277 Set<String> stringSet = strings.keySet(); 1278 for (String key : stringSet) 1279 { 1280 String strValue = strings.get(key); 1281 stringNodes.add(new StringNode(key, strValue)); 1282 } 1283 } 1284 if (arrays != null) 1285 { 1286 Set<String> arraySet = arrays.keySet(); 1287 for (String key : arraySet) 1288 { 1289 List<String> arrayValues = arrays.get(key); 1290 StringArrayNode strArray = new StringArrayNode(key); 1291 for (String value : arrayValues) 1292 { 1293 strArray.addValue(value); 1294 } 1295 arrayNodes.add(strArray); 1296 } 1297 } 1298 createOrUpdateDictionaryFile(project, stringNodes, arrayNodes, monitor); 1299 return; 1300 } 1301 1302 /** 1303 * Add strings and array to string.xml file 1304 * @param project 1305 * @param strings string entries to add 1306 * @param arrays array entries to add 1307 * @param monitor array entries to add 1308 * @throws CoreException 1309 * @throws IOException 1310 */ 1311 public static void createOrUpdateDictionaryFile(IProject project, List<StringNode> strings, 1312 List<StringArrayNode> arrays, IProgressMonitor monitor) throws IOException, 1313 CoreException 1314 { 1315 int taskSize = strings != null ? strings.size() : 0; 1316 taskSize += arrays != null ? arrays.size() : 0; 1317 1318 monitor.beginTask(UtilitiesNLS.UI_ProjectCreationSupport_Creating_Strings_Task, 1319 (taskSize * 100) + 100); 1320 1321 IFile projectStringXmlFile = 1322 project.getFile(IAndroidConstants.RES_DIR + IAndroidConstants.VALUES_DIR 1323 + IAndroidConstants.STRINGS_FILE); 1324 1325 LocalizationFile locFile = null; 1326 1327 if (projectStringXmlFile.exists()) 1328 { 1329 1330 ProjectLocalizationManager projManager = 1331 LocalizationManager.getInstance().getProjectLocalizationManager(project, true); 1332 1333 //load localization file 1334 locFile = 1335 projManager.getProjectLocalizationSchema().loadFile(LOCALIZATION_FILE_TYPE, 1336 projectStringXmlFile); 1337 if (locFile.getLocalizationProject() == null) 1338 { 1339 locFile.setLocalizationProject(projManager.getLocalizationProject()); 1340 } 1341 1342 //add new string nodes 1343 for (StringNode strNode : strings) 1344 { 1345 ((StringLocalizationFile) locFile).addStringNode(strNode); 1346 } 1347 List<StringArrayNode> currentArrays = 1348 ((StringLocalizationFile) locFile).getStringArrays(); 1349 List<StringArrayNode> newArrays = new ArrayList<StringArrayNode>(); 1350 newArrays.addAll(currentArrays); 1351 1352 //add new array nodes 1353 for (StringArrayNode strArray : arrays) 1354 { 1355 newArrays.add(strArray); 1356 } 1357 ((StringLocalizationFile) locFile).setStringArrayNodes(newArrays); 1358 1359 //update file 1360 LocalizationManager.getInstance().getLocalizationSchema(project).updateFile(locFile); 1361 } 1362 else 1363 { 1364 ILocalizationSchema locSchema = 1365 LocalizationManager.getInstance().getLocalizationSchema(project); 1366 1367 LocalizationFileBean bean = 1368 new LocalizationFileBean(LOCALIZATION_FILE_TYPE, projectStringXmlFile, 1369 new LocaleInfo(), strings, arrays); 1370 1371 locFile = locSchema.createLocalizationFile(bean); 1372 1373 locSchema.createLocalizationFile(locFile); 1374 1375 } 1376 } 1377 1378 /** 1379 * Retrieves the Studio console {@link IOConsoleOutputStream}. The console with name: STUDIO_ANDROID_CONSOLE_ID 1380 * @param activate boolean stating whether the console must be activated or not, brought to front. 1381 * @return the {@link IOConsoleOutputStream} for the Studio console. 1382 */ 1383 public static IOConsoleOutputStream getStudioConsoleOutputStream(boolean activate) 1384 { 1385 IConsole activeConsole = null; 1386 IConsole[] consoles = ConsolePlugin.getDefault().getConsoleManager().getConsoles(); 1387 for (IConsole console : consoles) 1388 { 1389 if (console.getName().equals(STUDIO_ANDROID_CONSOLE_ID)) 1390 { 1391 activeConsole = console; 1392 } 1393 } 1394 1395 if (activeConsole == null) 1396 { 1397 activeConsole = new IOConsole(STUDIO_ANDROID_CONSOLE_ID, null); 1398 ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] 1399 { 1400 activeConsole 1401 }); 1402 } 1403 if (activate) 1404 { 1405 ((IOConsole) activeConsole).activate(); 1406 } 1407 IOConsoleOutputStream consoleOut = ((IOConsole) activeConsole).newOutputStream(); 1408 return consoleOut; 1409 } 1410 1411 } 1412