/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.motorola.studio.android.common.utilities; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.preference.IPreferenceNode; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.jface.preference.PreferenceManager; import org.eclipse.sequoyah.localization.tools.datamodel.LocaleInfo; import org.eclipse.sequoyah.localization.tools.datamodel.LocalizationFile; import org.eclipse.sequoyah.localization.tools.datamodel.LocalizationFileBean; import org.eclipse.sequoyah.localization.tools.datamodel.StringLocalizationFile; import org.eclipse.sequoyah.localization.tools.datamodel.node.StringArrayNode; import org.eclipse.sequoyah.localization.tools.datamodel.node.StringNode; import org.eclipse.sequoyah.localization.tools.extensions.classes.ILocalizationSchema; import org.eclipse.sequoyah.localization.tools.managers.LocalizationManager; import org.eclipse.sequoyah.localization.tools.managers.ProjectLocalizationManager; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.console.ConsolePlugin; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IOConsole; import org.eclipse.ui.console.IOConsoleOutputStream; import org.eclipse.ui.internal.browser.WebBrowserEditor; import org.eclipse.ui.internal.browser.WebBrowserEditorInput; import org.eclipse.ui.internal.dialogs.WorkbenchPreferenceDialog; import org.osgi.framework.Bundle; import com.motorola.studio.android.common.CommonPlugin; import com.motorola.studio.android.common.IAndroidConstants; import com.motorola.studio.android.common.exception.AndroidException; import com.motorola.studio.android.common.log.StudioLogger; import com.motorola.studio.android.common.utilities.i18n.UtilitiesNLS; import com.motorola.studio.android.manifest.AndroidProjectManifestFile; import com.motorola.studio.android.model.manifest.AndroidManifestFile; /** * Class that contains methods to do common tasks through the Eclipse Platform */ @SuppressWarnings("restriction") public class EclipseUtils { private static final String STUDIO_ANDROID_CONSOLE_ID = "Studio for Android"; private static final String ORG_ECLIPSE_UI_NET_NET_PREFERENCES = "org.eclipse.ui.net.NetPreferences"; //$NON-NLS-1$ private static final String ORG_ECLIPSE_EQUINOX_SECURE_STORAGE_PREFERENCES = "org.eclipse.equinox.security.ui.storage"; //$NON-NLS-1$ private static final String LOCALIZATION_FILE_TYPE = "org.eclipse.sequoyah.localization.android.datamodel.AndroidStringLocalizationFile"; //$NON-NLS-1$ /** * Shows an error dialog * @param dialogTitle * The dialog title * @param dialogMessage * The dialog message * @param status * The IStatus object containing the error */ public static void showErrorDialog(final String dialogTitle, final String dialogMessage, final IStatus status) { PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { public void run() { Shell aShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); Shell shell = new Shell(aShell); Rectangle parentSize = aShell.getParent() != null ? aShell.getParent().getBounds() : shell .getBounds(); ErrorDialog errorDlg = new ErrorDialog(shell, dialogTitle, dialogMessage, status, IStatus.ERROR); Rectangle dialogSize = shell.getBounds(); int x = ((parentSize.width - dialogSize.width) / 2) + parentSize.x; int y = ((parentSize.height - dialogSize.height) / 2) + parentSize.y; shell.setLocation(x, y); errorDlg.open(); } }); } /** * Shows an information dialog * @param dialogTitle * The dialog title * @param dialogMessage * The dialog message * @param buttonLabels * The labels to be displayed as buttons in the dialog, or * <code>null</code> to have only an "OK" button. * * @return The code of the button pressed by the user */ public static int showInformationDialog(String dialogTitle, String dialogMessage, String[] buttonLabels) { return showInformationDialog(dialogTitle, dialogMessage, null, buttonLabels, MessageDialog.INFORMATION); } public static int showInformationDialog(String dialogTitle, String dialogMessage, String[] buttonLabels, int dialogImageType) { return showInformationDialog(dialogTitle, dialogMessage, null, buttonLabels, dialogImageType); } /** * Shows an information dialog * @param dialogTitle * The dialog title * @param dialogMessage * The dialog message * @param detailsMessage * The details message * @param buttonLabels * The labels to be displayed as buttons in the dialog, or * <code>null</code> to have only an "OK" button. * @param dialogImageType * The image to be displayed right before the dialogMessage * * @return The code of the button pressed by the user */ public static int showInformationDialogWithDetails(String dialogTitle, String dialogMessage, String detailsMessage, String[] buttonLabels) { return showInformationDialog(dialogTitle, dialogMessage, detailsMessage, buttonLabels, MessageDialog.INFORMATION); } private static int showInformationDialog(final String dialogTitle, final String dialogMessage, final String detailsMessage, final String[] buttonLabels, final int dialogImageType) { final int[] returnCode = new int[1]; PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { public void run() { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); Rectangle parentSize; if (shell.getParent() != null) { parentSize = shell.getParent().getBounds(); } else { parentSize = shell.getBounds(); } MessageDialog dlg; String[] internButtonLabels = buttonLabels; if (internButtonLabels == null) { internButtonLabels = new String[] { "OK" }; } if (detailsMessage == null) { dlg = new MessageDialog(shell, dialogTitle, null, dialogMessage, dialogImageType, internButtonLabels, 0); } else { dlg = new MessageDialog(shell, dialogTitle, null, dialogMessage, dialogImageType, internButtonLabels, 0) { @Override protected Control createCustomArea(Composite parent) { final Composite main = new Composite(parent, parent.getStyle()); GridLayout layout = new GridLayout(); main.setLayout(layout); GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); main.setLayoutData(data); final Button detailsButton = new Button(main, SWT.PUSH); detailsButton.setText(UtilitiesNLS.UI_EclipseUtils_OpenDetails); data = new GridData(SWT.RIGHT, SWT.CENTER, true, false); detailsButton.setLayoutData(data); detailsButton.addSelectionListener(new SelectionAdapter() { private Label detailsText; @Override public void widgetSelected(SelectionEvent e) { if ((detailsText != null) && !detailsText.isDisposed()) { detailsButton .setText(UtilitiesNLS.UI_EclipseUtils_OpenDetails); detailsText.dispose(); } else { detailsButton .setText(UtilitiesNLS.UI_EclipseUtils_CloseDetails); detailsText = new Label(main, SWT.WRAP | SWT.BORDER); detailsText.setText(detailsMessage); GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); detailsText.setLayoutData(data); GridDataFactory .fillDefaults() .align(SWT.FILL, SWT.BEGINNING) .grab(true, false) .hint(convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH), SWT.DEFAULT).applyTo(detailsText); } getShell().pack(); } }); return main; } }; } Rectangle dialogSize = shell.getBounds(); int x = ((parentSize.width - dialogSize.width) / 2) + parentSize.x; int y = ((parentSize.height - dialogSize.height) / 2) + parentSize.y; shell.setLocation(x, y); returnCode[0] = dlg.open(); } }); return returnCode[0]; } /** * Display a yes/no question dialog box * * @param title * The title of the dialog box * @param message * The error message * @param display * the parent display * @return true if OK was clicked. */ public final static boolean displayPrompt(final Display display, final String title, final String message) { /* * Sometimes we need to ask the user what he wants to do. */ final boolean[] result = new boolean[1]; display.syncExec(new Runnable() { public void run() { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); result[0] = MessageDialog.openQuestion(shell, title, message); } }); return result[0]; } /** * Opens a Yes/No dialog * * @param dialogTitle * The dialog title * @param dialogMessage * The dialog message * * @return true if the user answers yes and false otherwise */ public static boolean openYesNoDialog(final String dialogTitle, final String dialogMessage) { final Boolean[] answer = new Boolean[1]; PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { public void run() { Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); MessageBox msgBox = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.YES | SWT.NO); msgBox.setText(dialogTitle); msgBox.setMessage(dialogMessage); answer[0] = msgBox.open() == SWT.YES; } }); return answer[0]; } /** * Show the error message for the given AndroidException * * @param e * The AndroidException that generated the error to be displayed. */ public static void showErrorDialog(AndroidException e) { String title = UtilitiesNLS.ERR_Gen_ErrorTitle; showErrorDialog(title, e.getMessage()); } /** * Show the error message using the given title and message * * @param title * of the error dialog * @param message * to be displayed in the error dialog. */ public static void showErrorDialog(final String title, final String message) { Display.getDefault().asyncExec(new Runnable() { public void run() { IWorkbenchWindow ww = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); MessageDialog.openError(ww.getShell(), title, message); } }); } /** * Show an information message using the given title and message * * @param title * of the dialog * @param message * to be displayed in the dialog. */ public static void showInformationDialog(final String title, final String message) { Display.getDefault().asyncExec(new Runnable() { public void run() { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); Shell shell = ww.getShell(); MessageDialog.openInformation(shell, title, message); } }); } /** * Show a warning message using the given title and message * * @param title * of the dialog * @param message * to be displayed in the dialog. */ public static void showWarningDialog(final String title, final String message) { Display.getDefault().asyncExec(new Runnable() { public void run() { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); Shell shell = ww.getShell(); MessageDialog.openWarning(shell, title, message); } }); } /** * Show a question message using the given title and message * * @param title * of the dialog * @param message * to be displayed in the dialog. */ public static boolean showQuestionDialog(final String title, final String message) { class BooleanWrapper { public boolean bool = false; } final BooleanWrapper boolWrapper = new BooleanWrapper(); Display.getDefault().syncExec(new Runnable() { public void run() { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); Shell shell = ww.getShell(); boolWrapper.bool = MessageDialog.openQuestion(shell, title, message); } }); return boolWrapper.bool; } /** * Show a question message using the given title and message * * @param title * of the dialog * @param message * to be displayed in the dialog. */ public static int showQuestionWithCancelDialog(final String title, final String message) { class IntWrapper { public int diagReturn = 0; } final IntWrapper intWrapper = new IntWrapper(); Display.getDefault().syncExec(new Runnable() { public void run() { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); Shell shell = ww.getShell(); MessageDialog dialog = new MessageDialog(shell, title, null, message, MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }, 0); int diagResults = dialog.open(); switch (diagResults) { case 0: intWrapper.diagReturn = SWT.YES; break; case 1: intWrapper.diagReturn = SWT.NO; break; case 2: default: intWrapper.diagReturn = SWT.CANCEL; break; } } }); return intWrapper.diagReturn; } /** * Show a question message using the given title and message * * @param title * of the dialog * @param message * to be displayed in the dialog. */ public static int showQuestionYesAllCancelDialog(final String title, final String message) { class IntWrapper { public int diagReturn = 0; } final IntWrapper intWrapper = new IntWrapper(); Display.getDefault().syncExec(new Runnable() { public void run() { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); Shell shell = ww.getShell(); MessageDialog dialog = new MessageDialog(shell, title, null, message, MessageDialog.QUESTION, new String[] { IDialogConstants.YES_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL }, 0); int diagResults = dialog.open(); switch (diagResults) { case 0: intWrapper.diagReturn = IDialogConstants.YES_ID; break; case 1: intWrapper.diagReturn = IDialogConstants.YES_TO_ALL_ID; break; case 2: default: intWrapper.diagReturn = IDialogConstants.NO_ID; break; } } }); return intWrapper.diagReturn; } /** * Returns a plugin attribute using the extension as parameter. * * @param extensionId * the extension from which the attribute should be collected * @param elementName * the extension element * * @return The executable class associated to the provided element * * @throws CoreException */ public static Object getExecutable(String extensionId, String elementName) throws CoreException { Object executable = null; IExtensionRegistry registry = Platform.getExtensionRegistry(); IExtension fromExtension = registry.getExtension(extensionId); if ((fromExtension != null) && (elementName != null)) { IConfigurationElement[] elements = fromExtension.getConfigurationElements(); for (IConfigurationElement element : elements) { if (elementName.equals(element.getName())) { executable = element.createExecutableExtension("class"); } } } return executable; } /** * Returns an array of extensions that are plugged in a provided extension * point * * @param extensionPointId * the id of the extension point to look for extensions at * * @return an array containing the plugins plugged at the extension point */ public static IExtension[] getInstalledPlugins(String extensionPointId) { IExtensionRegistry registry = Platform.getExtensionRegistry(); IExtensionPoint extensionPoint = registry.getExtensionPoint(extensionPointId); IExtension[] pluggedExtensions; if (extensionPoint != null) { pluggedExtensions = extensionPoint.getExtensions(); } else { pluggedExtensions = new IExtension[0]; } return pluggedExtensions; } /** * Retrieves a view object, showing it at the IDE if hidden * * @param viewId * The identifier of the view to be shown * * @return The view that was just opened, or a reference to an already * opened view * * @throws PartInitException * If the view cannot be shown at the workbench part */ public static IViewPart showView(final String viewId) throws PartInitException { final Object[] tempObj = new Object[1]; Display.getDefault().syncExec(new Runnable() { public void run() { IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (activeWindow != null) { IWorkbenchPage activePage = activeWindow.getActivePage(); if (activePage != null) { try { tempObj[0] = activePage.showView(viewId); } catch (PartInitException e) { tempObj[0] = e; } } } } }); if (tempObj[0] instanceof PartInitException) { throw (PartInitException) tempObj[0]; } return (IViewPart) tempObj[0]; } /** * Retrieves a view object from the active window, but do not show if it is * hidden * * @param viewId * The identifier of the view to be retrieved * * @return A reference to the view identified by viewId if available; null * otherwise */ public static IViewPart getActiveView(final String viewId) { final Object[] tempObj = new Object[1]; Display.getDefault().syncExec(new Runnable() { public void run() { IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (activeWindow != null) { IWorkbenchPage activePage = activeWindow.getActivePage(); if (activePage != null) { IViewReference ref = activePage.findViewReference(viewId); if (ref != null) { IViewPart part = ref.getView(false); tempObj[0] = part; } } } } }); return (IViewPart) tempObj[0]; } /** * Retrieves a view object, but do not show it if hidden * * @param viewId * The identifier of the view object to be retrieved * * @return A collection of views with provided id that are being shown in * any opened perspective */ public static Collection<IViewPart> getAllOpenedViewsWithId(final String viewId) { final Collection<IViewPart> openedViews = new LinkedHashSet<IViewPart>(); Display.getDefault().syncExec(new Runnable() { public void run() { IWorkbenchWindow[] allWindows = PlatformUI.getWorkbench().getWorkbenchWindows(); for (IWorkbenchWindow window : allWindows) { IWorkbenchPage[] allPagesInWindow = window.getPages(); for (IWorkbenchPage page : allPagesInWindow) { IViewPart view = page.findView(viewId); if (view != null) { openedViews.add(view); } } } } }); return openedViews; } /** * Retrieves all editor objects * * @return A collection of all editors */ public static Collection<IEditorPart> getAllOpenedEditors() { final Collection<IEditorPart> editors = new LinkedHashSet<IEditorPart>(); Display.getDefault().syncExec(new Runnable() { public void run() { IWorkbenchWindow[] allWindows = PlatformUI.getWorkbench().getWorkbenchWindows(); for (IWorkbenchWindow window : allWindows) { IWorkbenchPage[] allPagesInWindow = window.getPages(); for (IWorkbenchPage page : allPagesInWindow) { IEditorReference[] editorRefs = page.getEditorReferences(); for (IEditorReference editorRef : editorRefs) { editors.add(editorRef.getEditor(false)); } } } } }); return editors; } /** * Retrieves the page for the given editor * * @param editor * * @return A page */ public static IWorkbenchPage getPageForEditor(final IEditorPart editor) { final Object[] tempObj = new Object[1]; Display.getDefault().syncExec(new Runnable() { public void run() { IWorkbenchWindow[] allWindows = PlatformUI.getWorkbench().getWorkbenchWindows(); for (IWorkbenchWindow window : allWindows) { IWorkbenchPage[] allPagesInWindow = window.getPages(); for (IWorkbenchPage page : allPagesInWindow) { if (page.findEditor(editor.getEditorInput()) != null) { tempObj[0] = page; break; } } } } }); return (IWorkbenchPage) tempObj[0]; } /** * Open a web browser editor to display the given URL. If there is already * an opened Web Browser Editor for the given URL, it is activated and a new * one is NOT opened. * * @param wantedUrl * URL to be opened. * @return the opened Web Browser Editor */ public static IEditorReference openedWebEditor(IWorkbenchPage page, URL wantedUrl) { IEditorReference wantedWebEditor = null; if (page != null) { for (IEditorReference editor : page.getEditorReferences()) { if (WebBrowserEditor.WEB_BROWSER_EDITOR_ID.equals(editor.getId())) { try { WebBrowserEditorInput webEditorInput = (WebBrowserEditorInput) editor.getEditorInput(); URL openedURL = webEditorInput.getURL(); if ((openedURL != null) && openedURL.equals(wantedUrl)) { wantedWebEditor = editor; break; } } catch (Exception e) { StudioLogger.error(EclipseUtils.class, "Failed to get URL displayed by the opened Web Editor"); } } } } if (wantedWebEditor != null) { StudioLogger .debug(EclipseUtils.class, "There is already an opened Web Browser Editor displaying the wanted URL. Simply activate it."); page.activate(wantedWebEditor.getEditor(true)); } else { StudioLogger.debug(EclipseUtils.class, "Open new Web Browser Editor for: " + wantedUrl); WebBrowserEditorInput input = new WebBrowserEditorInput(wantedUrl); WebBrowserEditor.open(input); } return wantedWebEditor; } /** * Retrieves the install location on the filesystem based on the given plug-in identifier * @param identifier the plug-in id. * @return A string containing the install path for the bundle with id - identifier. */ public static String getInstallLocation(String identifier) { return getInstallLocation(Platform.getBundle(identifier)); } /** * Retrieves the install location for the given bundle. * @param bundle * @return the bundle install location. */ public static String getInstallLocation(Bundle bundle) { String installLocation = ""; try { URL locationUrl = FileLocator.find(bundle, new Path("/"), null); URL fileUrl = FileLocator.toFileURL(locationUrl); installLocation = (new File(fileUrl.getFile())).getAbsolutePath(); } catch (Exception e) { StudioLogger.error(EclipseUtils.class, "Error finding install location for bundle: " + bundle.getBundleId(), e); } return installLocation; } /** * Open the preference page with the specified ID * @param nodeID the id of preference page to show */ @SuppressWarnings("unchecked") public static void openPreference(Shell shell, String nodeID) { // Makes the network preferences dialog manager PreferenceManager manager = PlatformUI.getWorkbench().getPreferenceManager(); IPreferenceNode networkNode = null; for (IPreferenceNode node : (List<IPreferenceNode>) manager .getElements(PreferenceManager.PRE_ORDER)) { if (node.getId().equals(nodeID)) { networkNode = node; break; } } PreferenceManager prefMan = new PreferenceManager(); if (networkNode != null) { prefMan.addToRoot(networkNode); } PreferenceDialog preferencesDialog = new WorkbenchPreferenceDialog(shell, prefMan); preferencesDialog.create(); preferencesDialog.open(); } /** * Convenience method to open the preferences dialog with the secure storage preference page */ public static void openSecureStoragePreferences(Shell shell) { openPreference(shell, ORG_ECLIPSE_EQUINOX_SECURE_STORAGE_PREFERENCES); } /** * Convenience method to open the preferences dialog with the network preferences preference page */ public static void openNetworkPreferences(Shell shell) { openPreference(shell, ORG_ECLIPSE_UI_NET_NET_PREFERENCES); } /** * Looks for the most severe {@link Status} within a {@link MultiStatus}. * @param errorStatus. * @return the most severe status of them all. */ public static IStatus findMostSevereError(final MultiStatus errorStatus) { IStatus mostSevere = null; if (!errorStatus.isOK()) { for (IStatus status : errorStatus.getChildren()) { if (mostSevere == null) { mostSevere = status; } if (status.getSeverity() > mostSevere.getSeverity()) { mostSevere = status; } } } return mostSevere; } /** * Reads a resource located inside the plugin, such as a template file. * @param resourcePath - The path to the resource. * @return An array of bytes from the resource * @throws IOException */ public static String readEmbeddedResource(Bundle bundle, String resourcePath) { InputStream is = null; BufferedReader bufferedReader = null; String embeddedResourcePath = null; try { URL url = bundle.getEntry((new StringBuilder("/")).append(resourcePath).toString()); if (url != null) { is = url.openStream(); } if (is != null) { bufferedReader = new BufferedReader(new InputStreamReader(is)); StringBuilder result = new StringBuilder(bufferedReader.readLine()); String line; while ((line = bufferedReader.readLine()) != null) { result.append('\n'); result.append(line); } embeddedResourcePath = result.toString(); } } catch (IOException ioEx) { StudioLogger .error(CommonPlugin.class, "Error while reading an embedded resource", ioEx); //$NON-NLS-1$ } finally { if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e) { //Do nothing. } } if (is != null) { try { is.close(); } catch (IOException e) { //Do nothing. } } } return embeddedResourcePath; } /** * Gets the default package from project. * @param javaProject * @return the project's default package. * @throws JavaModelException */ public static IPackageFragment getDefaultPackageFragment(IJavaProject javaProject) throws JavaModelException { IPackageFragment pack = null; AndroidManifestFile manifest = null; if ((javaProject != null) && javaProject.isOpen()) { // First, tries to get the default package from the AndroidManifest.xml file try { manifest = AndroidProjectManifestFile.getFromProject(javaProject.getProject()); } catch (AndroidException e) { // Do nothing } catch (CoreException e) { // Do nothing } if (manifest != null) { String defaultPackage = manifest.getManifestNode().getPackageName(); if ((defaultPackage != null) && (defaultPackage.trim().length() > 0)) { IPackageFragment[] allPacks = javaProject.getPackageFragments(); if (allPacks != null) { for (IPackageFragment frag : allPacks) { if (frag.getElementName().equals(defaultPackage)) { pack = frag; break; } } } } } // If the default package could not get from the AndroidManifest.xml file, search for // one in the project if (pack == null) { IPackageFragment[] packs = javaProject.getPackageFragments(); if (packs != null) { for (int i = 0; (i < packs.length) && (pack == null); i++) { if (packs[i].getKind() != IPackageFragmentRoot.K_BINARY) { if (!isInsideGenFolder(packs[i]) && !packs[i].isDefaultPackage() && packs[i].getElementName().contains(".") && packs[i].exists()) //$NON-NLS-1$ { pack = packs[i]; break; } } } } } } return pack; } /** * Checks if a package fragment is inside the "gen" folder * @param fragment The package fragment to be checked * @return true if the package fragment is inside the "gen" folder or false otherwise */ private static boolean isInsideGenFolder(IPackageFragment fragment) { boolean isInside = (fragment.getParent() instanceof IPackageFragmentRoot) && fragment.getParent().getElementName() .equals(IAndroidConstants.GEN_SRC_FOLDER); return isInside; } /** * This method adds a list of paths to all projects classpaths settings. * @param javaProjects List of projects that will have the classpath changed * @param libsPaths List of lib paths to be added to Projects' classpaths * @param monitor Monitor to track progress or null if it's not necessary. * @return IStatus The status of the operation. This method stops processing at the first error found. */ public static IStatus addLibsToProjects(List<IJavaProject> javaProjects, List<IPath> libsPaths, IProgressMonitor monitor) { SubMonitor subMonitor = SubMonitor.convert(monitor); subMonitor.beginTask(UtilitiesNLS.ProjectUtils_AddLibsProgress_ConfiguringClassPaths, ((javaProjects.size() * 2) + libsPaths.size()) * 1000); IStatus status = Status.OK_STATUS; IClasspathEntry[] classPathEntries = new IClasspathEntry[libsPaths.size()]; int i = 0; subMonitor.subTask(UtilitiesNLS.ProjectUtils_AddLibsProgress_PreparingPaths); for (IPath libPath : libsPaths) { IClasspathEntry classpathEntry = JavaCore.newLibraryEntry(libPath, null, null); classPathEntries[i] = classpathEntry; i++; subMonitor.worked(1000); } subMonitor.subTask(UtilitiesNLS.ProjectUtils_AddLibsProgress_ConfiguringProjects); for (IJavaProject javaProject : javaProjects) { IClasspathEntry[] rawClasspath; try { rawClasspath = javaProject.getRawClasspath(); int length = rawClasspath.length; int newEntriesLength = classPathEntries.length; int newLenght = length + newEntriesLength; IClasspathEntry[] newClassPath = new IClasspathEntry[newLenght]; System.arraycopy(rawClasspath, 0, newClassPath, 0, length); //Copy the existent classPath to the new array. System.arraycopy(classPathEntries, 0, newClassPath, length, newEntriesLength); //Copy the new entries to the new array subMonitor.worked(1000); javaProject.setRawClasspath(newClassPath, subMonitor.newChild(1000)); // Set the Project's classpath. } catch (JavaModelException e) { status = new Status(IStatus.ERROR, CommonPlugin.PLUGIN_ID, UtilitiesNLS.ProjectUtils_AddLibsProgress_ErrorSettingClasspaths, e); break; } } subMonitor.done(); return status; } /** * Verifies if a given libPath is already available on the project classpath. * @param javaProject * @param libPath * @return true if present, false otherwise */ public static boolean isLibOnClasspath(IJavaProject javaProject, IPath libPath) { try { IClasspathEntry[] rawClasspath = javaProject.getRawClasspath(); for (IClasspathEntry classpathEntry : rawClasspath) { if (classpathEntry.getPath().equals(libPath)) { return true; } } } catch (JavaModelException e) { return false; } return false; } /** * Add strings and array to string.xml file * @param project * @param strings string entries to add * @param arrays array entries to add * @param monitor array entries to add * @throws CoreException * @throws IOException */ public static void createOrUpdateDictionaryFile(IProject project, Map<String, String> strings, Map<String, List<String>> arrays, IProgressMonitor monitor) throws IOException, CoreException { List<StringNode> stringNodes = new ArrayList<StringNode>(); List<StringArrayNode> arrayNodes = new ArrayList<StringArrayNode>(); if (strings != null) { Set<String> stringSet = strings.keySet(); for (String key : stringSet) { String strValue = strings.get(key); stringNodes.add(new StringNode(key, strValue)); } } if (arrays != null) { Set<String> arraySet = arrays.keySet(); for (String key : arraySet) { List<String> arrayValues = arrays.get(key); StringArrayNode strArray = new StringArrayNode(key); for (String value : arrayValues) { strArray.addValue(value); } arrayNodes.add(strArray); } } createOrUpdateDictionaryFile(project, stringNodes, arrayNodes, monitor); return; } /** * Add strings and array to string.xml file * @param project * @param strings string entries to add * @param arrays array entries to add * @param monitor array entries to add * @throws CoreException * @throws IOException */ public static void createOrUpdateDictionaryFile(IProject project, List<StringNode> strings, List<StringArrayNode> arrays, IProgressMonitor monitor) throws IOException, CoreException { int taskSize = strings != null ? strings.size() : 0; taskSize += arrays != null ? arrays.size() : 0; monitor.beginTask(UtilitiesNLS.UI_ProjectCreationSupport_Creating_Strings_Task, (taskSize * 100) + 100); IFile projectStringXmlFile = project.getFile(IAndroidConstants.RES_DIR + IAndroidConstants.VALUES_DIR + IAndroidConstants.STRINGS_FILE); LocalizationFile locFile = null; if (projectStringXmlFile.exists()) { ProjectLocalizationManager projManager = LocalizationManager.getInstance().getProjectLocalizationManager(project, true); //load localization file locFile = projManager.getProjectLocalizationSchema().loadFile(LOCALIZATION_FILE_TYPE, projectStringXmlFile); if (locFile.getLocalizationProject() == null) { locFile.setLocalizationProject(projManager.getLocalizationProject()); } //add new string nodes for (StringNode strNode : strings) { ((StringLocalizationFile) locFile).addStringNode(strNode); } List<StringArrayNode> currentArrays = ((StringLocalizationFile) locFile).getStringArrays(); List<StringArrayNode> newArrays = new ArrayList<StringArrayNode>(); newArrays.addAll(currentArrays); //add new array nodes for (StringArrayNode strArray : arrays) { newArrays.add(strArray); } ((StringLocalizationFile) locFile).setStringArrayNodes(newArrays); //update file LocalizationManager.getInstance().getLocalizationSchema(project).updateFile(locFile); } else { ILocalizationSchema locSchema = LocalizationManager.getInstance().getLocalizationSchema(project); LocalizationFileBean bean = new LocalizationFileBean(LOCALIZATION_FILE_TYPE, projectStringXmlFile, new LocaleInfo(), strings, arrays); locFile = locSchema.createLocalizationFile(bean); locSchema.createLocalizationFile(locFile); } } /** * Retrieves the Studio console {@link IOConsoleOutputStream}. The console with name: STUDIO_ANDROID_CONSOLE_ID * @param activate boolean stating whether the console must be activated or not, brought to front. * @return the {@link IOConsoleOutputStream} for the Studio console. */ public static IOConsoleOutputStream getStudioConsoleOutputStream(boolean activate) { IConsole activeConsole = null; IConsole[] consoles = ConsolePlugin.getDefault().getConsoleManager().getConsoles(); for (IConsole console : consoles) { if (console.getName().equals(STUDIO_ANDROID_CONSOLE_ID)) { activeConsole = console; } } if (activeConsole == null) { activeConsole = new IOConsole(STUDIO_ANDROID_CONSOLE_ID, null); ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { activeConsole }); } if (activate) { ((IOConsole) activeConsole).activate(); } IOConsoleOutputStream consoleOut = ((IOConsole) activeConsole).newOutputStream(); return consoleOut; } }