Java tutorial
/* * Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License, Version 1.0, * which accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html * */ package net.rim.ejde.internal.util; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileFilter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import net.rim.ejde.internal.core.ContextManager; import net.rim.ejde.internal.core.IConstants; import net.rim.ejde.internal.core.IRIMMarker; import net.rim.ejde.internal.model.BlackBerryProject; import net.rim.ejde.internal.model.BlackBerryProjectCoreNature; import net.rim.ejde.internal.model.BlackBerryProperties; import net.rim.ejde.internal.model.BlackBerryPropertiesFactory; import net.rim.ejde.internal.ui.dialogs.PreprocessHookInstallDialog; import net.rim.ide.OSUtils; import net.rim.ide.core.Util; import net.rim.sdk.resourceutil.ResourceCollection; import net.rim.sdk.resourceutil.ResourceCollectionFactory; import net.rim.sdk.resourceutil.ResourceConstants; import net.rim.sdk.resourceutil.ResourceElement; import net.rim.sdk.resourceutil.ResourceLocale; import org.apache.log4j.Logger; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.mapping.ResourceMapping; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaModelMarker; 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.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.browser.IWebBrowser; import org.eclipse.ui.browser.IWorkbenchBrowserSupport; import org.eclipse.ui.ide.ResourceUtil; import org.osgi.framework.Bundle; /** * Helper class for projects * * @author jkeshavarzi */ public class ProjectUtils { private static final Logger logger = Logger.getLogger(ProjectUtils.class); /** * Finds the given project in the workspace. * * @param projectName * Name of the project to find. * @return The IProject if it was found, null otherwise. */ public static IProject getProject(String projectName) { IProject projects[] = ResourcesPlugin.getWorkspace().getRoot().getProjects(); for (IProject project : projects) { if (project.getName().equalsIgnoreCase(projectName)) { return project; } } return null; } /** * Locates all the source folders represented by type IPackageFragmentRoot.K_SOURCE for the given project. * * @param project * The IProject to search for source folders. * @return An IPackageFragmentRoot array containing each K_SOURCE fragment found for the given project. */ public static IPackageFragmentRoot[] getProjectSourceFolders(IProject project) { IJavaProject iJavaProject = JavaCore.create(project); ArrayList<IPackageFragmentRoot> sourceRoots = new ArrayList<IPackageFragmentRoot>(); if (iJavaProject.exists() && iJavaProject.isOpen()) { try { IPackageFragmentRoot[] roots = iJavaProject.getAllPackageFragmentRoots(); for (IPackageFragmentRoot root : roots) { if (IPackageFragmentRoot.K_SOURCE == root.getKind()) { sourceRoots.add(root); } } } catch (JavaModelException e) { logger.error("findProjectSources: Could not retrieve project sources:", e); //$NON-NLS-1$ return new IPackageFragmentRoot[0]; } } return sourceRoots.toArray(new IPackageFragmentRoot[sourceRoots.size()]); } /** * Checks the given project for a file with the given name * * @param project * - The IProject to search for the file * @param name * - The name of the file to search for * @param isPrefix * - Indicates whether the passed in file name should be treated as a prefix when searching * @return The found IFile object, or null if nothing was found */ public static IFile getProjectIFile(IProject project, String name, Boolean isPrefix) { IFile file = null; // source folders IPackageFragmentRoot roots[] = getProjectSourceFolders(project); for (IPackageFragmentRoot root : roots) { try { IJavaElement elements[] = root.getChildren(); for (IJavaElement element : elements) { if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) { IPackageFragment packageFragment = (IPackageFragment) element; Object packageChildren[] = packageFragment.getNonJavaResources(); for (Object child : packageChildren) { if (child instanceof IFile) { IFile childFile = (IFile) child; if (isPrefix.booleanValue()) { if (childFile.getName().startsWith(name)) { return childFile; } } else { if (childFile.getName().equals(name)) { return childFile; } } } } } } } catch (JavaModelException e) { logger.error("getProjectIFile: error"); } } return file; } /** * Get all files found in project * * @param project * - The IProject to retrieve files * @return A IFile array containing all found files within the passed in project */ public static IFile[] getProjectFiles(IProject project) { ArrayList<IFile> files = new ArrayList<IFile>(); // source folders IPackageFragmentRoot roots[] = getProjectSourceFolders(project); for (IPackageFragmentRoot root : roots) { try { IJavaElement sourceElements[] = root.getChildren(); for (IJavaElement sourceElement : sourceElements) { if (sourceElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) { IPackageFragment packageFragment = (IPackageFragment) sourceElement; IJavaElement packageElements[] = packageFragment.getChildren(); for (IJavaElement packageElement : packageElements) { if (packageElement instanceof IFile) { files.add((IFile) packageElement); } } } } } catch (JavaModelException e) { logger.error("getProjectFiles: error"); } } return files.toArray(new IFile[files.size()]); } /** * Returns the set of all referenced IProjects for a given IProject * * @param project * the given IProject * @return the array of referenced IProjects, calculated recursively * @throws CoreException * if an error occurs while computing referenced projects */ public static Set<IProject> getAllReferencedProjects(IProject project) throws CoreException { Set<IProject> referencedProjects = new HashSet<IProject>(); addReferencedProjects(project, referencedProjects); return referencedProjects; } private static void addReferencedProjects(IProject project, Set<IProject> references) throws CoreException { if (project.isOpen()) { IJavaProject javaProject = JavaCore.create(project); String[] requiredProjectNames = javaProject.getRequiredProjectNames(); IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); IProject requiredProject = null; for (String projectName : requiredProjectNames) { requiredProject = workspaceRoot.getProject(projectName); if (requiredProject.exists() && requiredProject.isOpen() && !references.contains(requiredProject)) { references.add(requiredProject); addReferencedProjects(requiredProject, references); } } } } /** * Returns the array of all referenced IJavaProjects for a given IJavaProject * * @param project * the given IJavaProject * @return the array of referenced IJavaProjects, calculated recursively * @throws CoreException * if an error occurs while computing referenced projects */ public static List<IJavaProject> getAllReferencedJavaProjects(IJavaProject project) throws CoreException { Set<IProject> referencedProjects = new HashSet<IProject>(); List<IJavaProject> refJavaProjects = new ArrayList<IJavaProject>(); addReferencedProjects(project.getProject(), referencedProjects); for (IProject proj : referencedProjects) { refJavaProjects.add(JavaCore.create(proj)); } return refJavaProjects; } /** * Returns the array of all referenced projects for a given <code>bbProject</code>. * <p> * <b>If the <code>bbProject</code> depends on some java projects, we created BB projects on-the-fly for those java * projects.</b> * * @param bbProject * the given BlackBerryProject * @return the array of referenced BlackBerryProjects, calculated recursively * @throws CoreException * if an error occurs while computing referenced projects */ public static List<BlackBerryProject> getAllReferencedProjects(BlackBerryProject bbProject) throws CoreException { Set<IProject> referencedProjects = new HashSet<IProject>(); List<BlackBerryProject> refJavaProjects = new ArrayList<BlackBerryProject>(); addReferencedProjects(bbProject.getProject(), referencedProjects); for (IProject proj : referencedProjects) { BlackBerryProperties properties = null; final IJavaProject javaProject = JavaCore.create(proj); if (proj.hasNature(BlackBerryProjectCoreNature.NATURE_ID)) { properties = ContextManager.PLUGIN.getBBProperties(proj.getName(), false); if (properties == null) { continue; } } else { // create a BB properties for a java project on-the-fly properties = BlackBerryPropertiesFactory.createBlackBerryProperties(javaProject); ; } refJavaProjects.add(new BlackBerryProject(javaProject, properties)); } return refJavaProjects; } /** * Determines whether a given IJavaProject represents a parent our of a list of selected projects * * @param project * the given IJavaProject * @param selectedProjects * the selection of IJavaProjects * @return */ public static boolean isParentProject(IJavaProject project, List<IJavaProject> selectedProjects) { IProject eclipseProj = project.getProject(); IProject[] projects = eclipseProj.getReferencingProjects(); for (IProject refProject : projects) { if (selectedProjects.contains(JavaCore.create(refProject))) { return false; } } return true; } /** * Returns the set of all referenced IJavaProjects for a list of objects supposed to be IJavaProject * * @param javaProjects * the list of objects supposed to be of type IJavaProject * @return the set of referenced IJavaProjects, included the IJavaProjects themselves, calculated recursively * @throws CoreException * if an error occurs while computing referenced projects */ public static Set<IJavaProject> getAllJavaProjects(List<Object> javaProjects) throws CoreException { Set<IJavaProject> allJavaProjects = new HashSet<IJavaProject>(); Set<IProject> allProjects = new HashSet<IProject>(); for (Object obj : javaProjects) { if (obj instanceof IJavaProject) { IProject currentProject = ((IJavaProject) obj).getProject(); allProjects.add(currentProject); addReferencedProjects(currentProject, allProjects); for (IProject p : allProjects) { allJavaProjects.add(JavaCore.create(p)); } } } return allJavaProjects; } /** * Gets a file that exists in an Eclipse project. * <p> * TODO: Someone can probably optimize this method better. Like using some of the IWorkspaceRoot.find*() methods... * * @param project * the Eclipse project the file belongs to * @param file * the File which is in the Eclipse project * @return the Eclipse resource file associated with the file */ public static IResource getResource(IProject project, File file) { IJavaProject javaProject = JavaCore.create(project); IPath filePath = new Path(file.getAbsolutePath()); try { IClasspathEntry[] classpathEntries = javaProject.getResolvedClasspath(true); IFile input = null; // Look for a source folder for (IClasspathEntry classpathEntry : classpathEntries) { if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { // Try to resolve the source container IWorkspaceRoot workspaceRoot = project.getWorkspace().getRoot(); IResource resource = workspaceRoot.findMember(classpathEntry.getPath()); if (resource instanceof IContainer) { IContainer sourceContainer = (IContainer) resource; File sourceContainerFile = resource.getLocation().toFile(); IPath sourceFolderPath = new Path(sourceContainerFile.getAbsolutePath()); // See if the file path is within this source folder // path if (sourceFolderPath.isPrefixOf(filePath)) { int segmentCount = sourceFolderPath.segmentCount(); IPath relativePath = filePath.removeFirstSegments(segmentCount); input = sourceContainer.getFile(relativePath); break; } } } } return input; } catch (JavaModelException e) { e.printStackTrace(); return null; } } /** * Gets selected IJavaProjects from the selection. * * @param selection * The <code>StructuredSelection</code> * @return <code>IJavaProject</code> */ public static IJavaProject[] getSelectProjects(StructuredSelection selection) { StructuredSelection ss = selection; List<IJavaProject> projects = new ArrayList<IJavaProject>(); Object p = null; Iterator<Object> i = ss.iterator(); while (i.hasNext()) { p = i.next(); if (p instanceof IJavaProject) { try { // we only package BB projects if (((IJavaProject) p).getProject().hasNature(BlackBerryProjectCoreNature.NATURE_ID)) { projects.add((IJavaProject) p); } } catch (CoreException e) { logger.error(e.getMessage()); } } else if (p instanceof IProject) { try { // we only package BB projects if (((IProject) p).hasNature(BlackBerryProjectCoreNature.NATURE_ID)) { projects.add(JavaCore.create((IProject) p)); } } catch (CoreException e) { logger.error(e.getMessage()); } } } return projects.toArray(new IJavaProject[projects.size()]); } /** * Gets the IPath of the .project file of the given <code>project</code>. * * @param project * @return */ public static IPath getProjectDescriptionFilePath(IProject project) { IFile iFile = project.getFile(".project"); return iFile.getLocation(); } public static LinkedHashSet<BlackBerryProject> getProjectsByBuildOrder(Set<BlackBerryProject> selectedProjects) throws CoreException { Set<BlackBerryProject> allProjects = new HashSet<BlackBerryProject>(); for (BlackBerryProject project : selectedProjects) { if (project != null) { allProjects.addAll(ProjectUtils.getAllReferencedProjects(project)); allProjects.add(project); } } LinkedHashSet<BlackBerryProject> sortedProjects = new LinkedHashSet<BlackBerryProject>(allProjects.size()); Map<String, Boolean> visitHistory = new HashMap<String, Boolean>(allProjects.size()); for (BlackBerryProject project : allProjects) { ProjectUtils.visitNode(project, visitHistory, sortedProjects); } return sortedProjects; } private static void visitNode(BlackBerryProject rootNode, Map<String, Boolean> visitHistory, Set<BlackBerryProject> sortedProjects) throws CoreException { Boolean visited = visitHistory.get(rootNode.getElementName()); if (visited == null) { visitHistory.put(rootNode.getElementName(), Boolean.TRUE); for (BlackBerryProject childNode : ProjectUtils.getAllReferencedProjects(rootNode)) { ProjectUtils.visitNode(childNode, visitHistory, sortedProjects); } sortedProjects.add(rootNode); } } /** * Gets non-BlackBerry projects in the given <code>javaProjects</code>. * * @param javaProjects * @return */ public static List<IJavaProject> getNonBBJavaProjects(List<IJavaProject> javaProjects) { List<IJavaProject> nonBBProjects = new ArrayList<IJavaProject>(); for (IJavaProject javaProject : javaProjects) { try { if (!javaProject.getProject().hasNature(BlackBerryProjectCoreNature.NATURE_ID)) { nonBBProjects.add(javaProject); } } catch (CoreException e) { logger.error(e.getMessage()); continue; } } return nonBBProjects; } /** * Gets non-BlackBerry java projects which have JDE compatibility problem in the given <code>javaProjects</code>. * * @param javaProjects * non-BlackBerry java projects * @return */ public static List<IJavaProject> getJavaProjectsContainJDKCompatibilityProblem( List<IJavaProject> javaProjects) { List<IJavaProject> projectWithProblem = new ArrayList<IJavaProject>(); for (IJavaProject javaProject : javaProjects) { if (hasJDKCompatibilityProblem(javaProject)) { projectWithProblem.add(javaProject); } } return projectWithProblem; } /** * Checks if the given <code>javaProject</code> has compatibility problem. * * @param javaProject * @return */ public static boolean hasJDKCompatibilityProblem(IJavaProject javaProject) { final Map map = javaProject.getOptions(true); if (map.size() > 0) { String value = (String) map.get(JavaCore.COMPILER_COMPLIANCE); if (!value.equalsIgnoreCase(JavaCore.VERSION_1_4)) { return true; } value = (String) map.get(JavaCore.COMPILER_SOURCE); if (!value.equalsIgnoreCase(JavaCore.VERSION_1_3)) { return true; } value = (String) map.get(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM); if (!value.equalsIgnoreCase(JavaCore.VERSION_1_2)) { return true; } } return false; } /** * Returns all BlackBerry project in workspace. * * @return All BlackBerry projects * @throws CoreException */ public static Set<IProject> getAllBBProjectsAndDependencies() { IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); List<IProject> bbProjects = new ArrayList<IProject>(); for (IProject project : allProjects) { if (NatureUtils.hasBBNature(project)) { bbProjects.add(project); } } Set<IProject> bbAndDependentProjects = new HashSet<IProject>(); bbAndDependentProjects.addAll(bbProjects); try { bbAndDependentProjects.addAll(ProjectUtils.getAllReferencedProjects(bbProjects)); } catch (CoreException e) { logger.error("", e); } return bbAndDependentProjects; } /** * Checks if the given <code>project</code> is dependent by any checked project in the <code>checkedProjects</code> but is not * in the <code>dependentProjects</code>. * * @param project * @param checkedProjects * @param dependentProjects * @return Project the first project which depends on the given <code>project</code>. */ public static IProject isDependedByOthers(IProject project, List<IProject> checkedProjects, Set<IProject> dependentProjects) { for (Object obj : checkedProjects) { IProject checkedProject = (IProject) obj; if (!dependentProjects.contains(checkedProject)) { Set<IProject> depProjects; try { depProjects = ProjectUtils.getAllReferencedProjects(checkedProject); } catch (CoreException e) { logger.error("", e); return null; } for (IProject depProject : depProjects) { if (project.equals(depProject)) { return checkedProject; } } } } return null; } /** * Returns the VM assigned to build the given project. * * @param project * The <code>IJavaProject</code> * @return <code>IVMInstall</code> */ public static IVMInstall getVMForProject(IJavaProject project) { IVMInstall vm = null; try { vm = JavaRuntime.getVMInstall(project); } catch (CoreException e) { logger.debug("", e); } return vm; } /** * Returns list of BlackBerryProject for the given iprojects. * * @param iprojects * @return List of <code>BlackBerryProject</code> */ public static Set<BlackBerryProject> getBlackBerryProjects(Set<IProject> iprojects) { Set<BlackBerryProject> bbProjects = new HashSet<BlackBerryProject>(); for (IProject iproject : iprojects) { BlackBerryProperties properties = null; final IJavaProject javaProject = JavaCore.create(iproject); if (NatureUtils.hasBBNature(iproject)) { properties = ContextManager.PLUGIN.getBBProperties(iproject.getName(), false); if (properties == null) { continue; } } else { // create a BB properties for a java project on-the-fly properties = BlackBerryPropertiesFactory.createBlackBerryProperties(javaProject); ; } bbProjects.add(new BlackBerryProject(javaProject, properties)); } return bbProjects; } /** * Checks if the given <code>project</code> is depended by any BlackBerry project. * * @param project * @return */ public static boolean isDependedByBBProject(IProject project) { IProject[] referedProjects = project.getReferencingProjects(); for (IProject referedProject : referedProjects) { try { if (referedProject.hasNature(BlackBerryProjectCoreNature.NATURE_ID)) { return true; } if (isDependedByBBProject(referedProject)) { return true; } } catch (CoreException e) { logger.error(e.getMessage()); } } return false; } /** * Returns the set of all referenced IProjects for the given projects. * * @param projects * the given projects * @return the set of referenced IProjects, calculated recursively * @throws CoreException * if an error occurs while computing referenced projects */ public static Set<IProject> getAllReferencedProjects(List<IProject> projects) throws CoreException { Set<IProject> referencedProjects = new HashSet<IProject>(); for (IProject project : projects) { referencedProjects.addAll(getAllReferencedProjects(project)); } return referencedProjects; } /** * Extracts the BB projects from the given <code>workingSets</code>. * * @param workingSets * The selected workingsets. * @return BB projects in the selected workingsets. */ public static HashSet<BlackBerryProject> extractBBProjects(IWorkingSet[] workingSets) { HashSet<BlackBerryProject> projects = new HashSet<BlackBerryProject>(); if (workingSets != null) { BlackBerryProject bbProject = null; for (IWorkingSet workingSet : workingSets) { Object[] selection = workingSet.getElements(); for (Object element : selection) { IResource resource = ResourceUtil.getResource(element); if (resource != null) { bbProject = createBBProject(resource.getProject()); if (bbProject != null) { projects.add(bbProject); } } else { ResourceMapping mapping = ResourceUtil.getResourceMapping(element); if (mapping != null) { IProject[] theProjects = mapping.getProjects(); for (IProject theProject : theProjects) { bbProject = createBBProject(theProject); if (bbProject != null) { projects.add(bbProject); } } } } } } } return projects; } /** * Creates a BlackBerryProject instance for the given <code>iProject</code>. * * @param iProject * @return The BlackBerryProject instance for the given <code>iProject</code> or <code>null</code> if the * <code>iProject</code> does not have BB nature or any exception has occurred. */ static public BlackBerryProject createBBProject(IProject iProject) { try { // we only package BB projects if (!iProject.hasNature(BlackBerryProjectCoreNature.NATURE_ID)) { return null; } } catch (CoreException e) { logger.error(e.getMessage()); return null; } BlackBerryProperties properties = null; properties = ContextManager.PLUGIN.getBBProperties(iProject.getProject().getName(), false); if (properties == null) { return null; } return new BlackBerryProject(JavaCore.create(iProject), properties); } static public List<String> getContents(File file) { List<String> contents = new ArrayList<String>(); BufferedReader input = null; try { input = new BufferedReader(new FileReader(file)); String line = null; // not declared within while loop while ((line = input.readLine()) != null) { contents.add(line); } } catch (IOException e) { logger.error(e); } finally { if (input != null) { try { input.close(); } catch (IOException e) { logger.error(e); } } } return contents; } static public void commitContents(File file, List<String> contents) { BufferedWriter output = null; try { output = new BufferedWriter(new FileWriter(file)); for (int i = 0; i < contents.size(); i++) { output.write(contents.get(i)); output.newLine(); } output.flush(); } catch (IOException e) { logger.error(e); } finally { if (output != null) { try { output.close(); } catch (IOException e) { logger.error(e); } } } } static private IStatus updateEclipseConfig() { IPath configFilePath = new Path(Platform.getInstallLocation().getURL().getPath()); if (OSUtils.isMac()) { configFilePath = configFilePath.append(File.separator + "Eclipse.app" + File.separator + "Contents" + File.separator + "MacOS" + File.separator); } configFilePath = configFilePath.append("eclipse.ini"); File configFile = configFilePath.toFile(); if (!configFile.exists()) { logger.error(NLS.bind(Messages.PreprocessHookEclipseIniNotFoundErr, configFile.getPath())); return StatusFactory.createErrorStatus( NLS.bind(Messages.PreprocessHookEclipseIniNotFoundErr, configFile.getPath())); } try { List<String> contents = getContents(configFile); String osgiConfigString = "-Dosgi.framework.extensions="; String osgiString = IConstants.EMPTY_STRING; int osgiConfigLineIndex = -1; // "-Dosgi.framework.extensions=" is a JVM argument, we have to add it after "-vmargs" line int vmargIndex = -1; boolean bundleExisting = false; String line; for (int i = 0; i < contents.size(); i++) { line = contents.get(i); if (line.trim().equals("-vmargs")) { vmargIndex = i; } else if (line.trim().startsWith(osgiConfigString)) { if (line.indexOf(IConstants.PREPROCESSING_HOOK_FRGMENT_ID) > 0) { bundleExisting = true; } osgiConfigLineIndex = i; osgiString = line; } } if (osgiConfigLineIndex < 0) { // "-Dosgi.framework.extensions=" is not there osgiString = osgiConfigString + IConstants.PREPROCESSING_HOOK_FRGMENT_ID; contents.add(vmargIndex + 1, osgiString); } else { if (bundleExisting) { // "-Dosgi.framework.extensions=" is there, we should recomment users to re-install ejde return StatusFactory.createErrorStatus(Messages.PreprocessHookCanNotBeConfiguredErr); } else { contents.set(osgiConfigLineIndex, osgiString + "," + IConstants.PREPROCESSING_HOOK_FRGMENT_ID); } } commitContents(configFile, contents); return Status.OK_STATUS; } catch (Exception ex) { logger.error(ex.getMessage()); return StatusFactory.createErrorStatus(ex.getMessage()); } } /** * Install the preprocess hook. We do not need to actually add anything to the configuration.ini. We just need to restart the * eclipse. */ static public void setPreprocessorHook() { if (PreprocessHookInstallDialog.isDialogOn()) { return; } PreprocessHookInstallDialog.setIsDialogOn(true); // need to clean the workspace after restart ContextManager.getDefault().getPreferenceStore().setValue(IConstants.NEED_CLEAN_WORKSPACE_KEY, true); Display.getDefault().asyncExec(new Runnable() { public void run() { int result = PreprocessHookInstallDialog.openQuestion(Messages.PreprocessHookInstallDialogTitle, Messages.PreprocessHookInstallDialog_Text); if (result == IDialogConstants.OK_ID) { IStatus status = updateEclipseConfig(); if (status.isOK()) { PlatformUI.getWorkbench().restart(); } else { MessageDialog.openError(ContextManager.getActiveWorkbenchShell(), Messages.ErrorHandler_DIALOG_TITLE, status.getMessage()); } } } }); } /** * Open the project startup page if it's not already opened * */ public static void openStartupPage() { Bundle bundle = Platform.getBundle(ContextManager.PLUGIN_ID); //IConstants.DOC_PLUGIN_ID ); IPath pagePath = new Path(IConstants.START_UP_PAGE); IPath folderPath = new Path(IConstants.START_UP_FOLDER); IPath htmlFolderPath = new Path(IConstants.HTML_PAGE_FOLDER); // may be empty URL pageUrl = FileLocator.find(bundle, pagePath, null); URL folderUrl = FileLocator.find(bundle, folderPath, null); URL htmlFolderUrl = FileLocator.find(bundle, htmlFolderPath, null); IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport(); try { // extract necessary files from jar into a cache, otherwise the images will not be // displayed proplerly FileLocator.toFileURL(folderUrl); // Since startup page links to html page, we need to extract html content as well FileLocator.toFileURL(htmlFolderUrl); pageUrl = FileLocator.toFileURL(pageUrl); IWebBrowser browser = support.createBrowser( IWorkbenchBrowserSupport.AS_EDITOR | IWorkbenchBrowserSupport.NAVIGATION_BAR | IWorkbenchBrowserSupport.LOCATION_BAR | IWorkbenchBrowserSupport.STATUS, IConstants.BROWSER_ID, null, null); browser.openURL(pageUrl); } catch (PartInitException e) { logger.error("Could not open the start up page in the editor part", e); //$NON-NLS-1$ } catch (IOException e) { logger.error("Unable to convert URL", e); //$NON-NLS-1$ } } /** * Checks if the active workspace contains any projects * * @return */ public static boolean containsProjects() { IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); return projects.length > 0; } /** * Checks if all projects are closed in the active workspace * * @return */ public static boolean isAllBBProjectsClosed() { List<IProject> projects = Arrays.asList(ResourcesPlugin.getWorkspace().getRoot().getProjects()); if (!projects.isEmpty()) { for (IProject project : projects) { if (project.isOpen() && NatureUtils.hasBBNature(project)) { return false; } } } return true; } /** * Use a simple breadth-first algorithm to check if the given <code>folder</code> and its children folders have bee updated * after the <code>lastModifiedTimeStamp</code>. * * @param folder * @param lastModifiedTimeStamp * @return */ public static boolean hasFolderBeenUpdated(File folder, long lastModifiedTimeStamp) { File[] folders; SimpleQueue queue = new SimpleQueue(); queue.offer(folder); File elementFolder; while ((elementFolder = (File) queue.poll()) != null) { if (elementFolder.lastModified() > lastModifiedTimeStamp) { return true; } folders = elementFolder.listFiles(new FileFilterImpl()); for (int i = 0; i < folders.length; i++) { queue.offer(folders[i]); } } return false; } static private class FileFilterImpl implements FileFilter { @Override public boolean accept(File pathname) { if (pathname.isDirectory()) { return true; } return false; } } /** * This is a simple implementation of Queue. * * */ static public class SimpleQueue { Vector<Object> _vector; public SimpleQueue() { _vector = new Vector<Object>(); } /** * Gets the first element and remove it from the queue. * * @return */ public synchronized Object poll() { if (_vector.isEmpty()) { return null; } return _vector.remove(0); } /** * Gets the first element but not remove it from the queue. * * @return */ public synchronized Object peak() { if (_vector.isEmpty()) { return null; } return _vector.get(0); } /** * Adds an element to the bottom of the queue. * * @param obj */ public synchronized void offer(Object obj) { _vector.addElement(obj); } } /** * Check if the projects in the given <code>project</code> have any critical problems. * * @param project * @return */ public static boolean hasCriticalProblems(IProject project) { if (project == null) { return false; } try { IMarker[] markers = project.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE); if (markers.length > 0) { for (IMarker marker : markers) { if (isCriticalProblem(marker)) { return true; } } } return false; } catch (CoreException e) { logger.error(e); return true; } } /** * Check if the projects in the given <code>resource</code> have any error of the given <code>types</code>. * * @param resource * @return */ public static boolean hasError(IResource resource, String[] types) { if (resource == null) { return false; } try { IMarker[] markers = resource.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE); if (markers.length > 0) { for (IMarker marker : markers) { Integer severity = (Integer) marker.getAttribute(IMarker.SEVERITY); if (severity != null) { if (severity.intValue() >= IMarker.SEVERITY_ERROR && typeMatch(marker, types)) { return true; } } } } return false; } catch (CoreException e) { logger.error(e); return true; } } public static boolean typeMatch(IMarker marker, String[] types) { for (int i = 0; i < types.length; i++) { try { if (marker.isSubtypeOf(types[i])) { return true; } } catch (CoreException e) { logger.error(e.getMessage()); } } return false; } /** * Check if the marker is a critical problem. * * @param marker * @return * @throws CoreException */ public static boolean isCriticalProblem(IMarker marker) throws CoreException { Integer severity = (Integer) marker.getAttribute(IMarker.SEVERITY); if (severity != null) { // TODO need to improve this rule return (severity.intValue() >= IMarker.SEVERITY_ERROR) && (marker.getType().equals(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER) || (marker.isSubtypeOf(IRIMMarker.BLACKBERRY_PROBLEM) && !marker.getType().equals(IRIMMarker.PACKAGING_PROBLEM))); } return false; } /** * Get the map of all found resource collections in the given project and the projects it depends on. */ static public Map<String, RRHFile> getProjectResources(BlackBerryProject bbProject) { logger.trace("****** Get resource for " + bbProject.getProject().getName()); Map<String, RRHFile> rrhFileMap = new HashMap<String, RRHFile>(); List<IJavaProject> projects = null; try { projects = getAllReferencedJavaProjects(bbProject); projects.add(0, bbProject.getJavaProject()); for (IJavaProject javaProject : projects) { getResourceFilesRecursively(javaProject, rrhFileMap); } } catch (CoreException e) { logger.error(e); } return rrhFileMap; } static protected void getResourceFilesRecursively(IJavaProject javaProject, Map<String, RRHFile> rrhFileMap) throws CoreException { // search for rrh files in the project FileVisitor visitor = new FileVisitor(IConstants.RRH_FILE_EXTENSION, false); javaProject.getProject().accept(visitor); List<IFile> rrhFiles = visitor.getFiles(); String fileNameWithPackage, fileName; Hashtable<String, String> constantsTable; for (IFile file : rrhFiles) { fileNameWithPackage = PackageUtils.getRRHPackageID(file.getLocation().toFile()); fileName = file.getName(); fileNameWithPackage += "." + fileName.substring(0, fileName.indexOf(ResourceConstants.RRH_SUFFIX)); if (rrhFileMap.get(fileNameWithPackage) != null) { logger.debug("Found duplicated rrh file: " + fileNameWithPackage); } else { constantsTable = getKeysFromRRHFile(file.getLocation().toOSString()); if (constantsTable != null) { rrhFileMap.put(fileNameWithPackage, new RRHFile(fileNameWithPackage, file, constantsTable)); } } } // search for rrh interfaces in the jar files imported by the project InternalProjectUtils.getResourcesFromJars(javaProject, rrhFileMap); } /** * Get key&value pairs from the rrh file </code>rrhFilePath</code>. * * @param rrhFilePath * @return * @throws CoreException */ public static Hashtable<String, String> getKeysFromRRHFile(String rrhFilePath) throws CoreException { if (rrhFilePath == null || !new File(rrhFilePath).exists()) { return null; } Hashtable<String, String> headerKey2Id = new Hashtable<String, String>(); Util.parseRRHFile(rrhFilePath, headerKey2Id); ResourceCollection rc = null; try { rc = ResourceCollectionFactory.newResourceCollection(rrhFilePath); ResourceLocale rootLocale = rc.getLocale(""); //$NON-NLS-1$ if (rootLocale != null) { ResourceElement[] elements = rootLocale.getResourceElements(); for (ResourceElement element : elements) { // Only allow single value keys in the title and description fields if (element.isMulti()) { headerKey2Id.remove(element.getKey()); } } } return headerKey2Id; } catch (Exception e) { logger.error(e.getMessage()); //$NON-NLS-1$ return new Hashtable<String, String>(); } } /** * Obtain the allowed startup tiers as an int array. * * @return startup tiers as an int array. */ public static int[] getStartupTiers() { return StartupTiers.getAllowedTiers(); } /** * Obtain the allowed startup tiers as a String array. * * @return startup tiers as a String array */ public static String[] getStartupTierStrings() { int[] allowedTiers = StartupTiers.getAllowedTiers(); String[] tiers = new String[allowedTiers.length]; for (int i = 0; i < allowedTiers.length; i++) { tiers[i] = String.valueOf(allowedTiers[i]); } return tiers; } public static List<IFile> getProtectedFiles(IProject project) throws CoreException { FileVisitor visitor = new FileVisitor(IConstants.JAVA_EXTENSION, false); project.accept(visitor); return visitor.getFiles(); } public static List<IFile> getKeyFiles(IProject project) throws CoreException { KeyFileVisitor visitor = new KeyFileVisitor(); project.accept(visitor); return visitor.getFiles(); } protected static class FileVisitor implements IResourceVisitor { IJavaProject _javaProject; String _fileExtension; boolean _shouldOnClassPath; List<IFile> _files; public FileVisitor(String fileExtension, boolean shouldOnClassPath) { _fileExtension = fileExtension; _shouldOnClassPath = shouldOnClassPath; _files = new ArrayList<IFile>(); } public boolean visit(IResource resource) throws CoreException { if (!(resource instanceof IFile)) { return shouldBeSourceRoot(resource); } String extension = resource.getFileExtension(); if (extension != null && extension.equalsIgnoreCase(_fileExtension)) { if (_javaProject == null) { _javaProject = JavaCore.create(resource.getProject()); } if (_shouldOnClassPath) { if (_javaProject.isOnClasspath(resource)) { _files.add((IFile) resource); } } else { _files.add((IFile) resource); } } return false; } private boolean shouldBeSourceRoot(IResource resource) { if (resource instanceof IProject) { return true; } if (PackageUtils.isUnderSrcFolder(resource)) { return true; } return false; } public List<IFile> getFiles() { return _files; } } /** * Gets all the projects in the current workspace which refer to the given <code>projects</code> including the * <code>projects</code> themselves. * * @param projects * @return */ public static Set<IProject> getAllReferencingProjects(IProject[] projects) { Set<IProject> allProjects = new HashSet<IProject>(); IProject[] referencedProjects; for (IProject project : projects) { allProjects.add(project); referencedProjects = project.getReferencingProjects(); for (int i = 0; i < referencedProjects.length; i++) { allProjects.add(referencedProjects[i]); } } return allProjects; } private static class KeyFileVisitor implements IResourceVisitor { List<IFile> _files; public KeyFileVisitor() { _files = new ArrayList<IFile>(); } public boolean visit(IResource resource) throws CoreException { if (!(resource instanceof IFile)) { return shouldBeSourceRoot(resource); } String extension = resource.getFileExtension(); if (extension != null) { if (extension.equalsIgnoreCase(IConstants.KEY_FILE_EXTENSION)) { _files.add((IFile) resource); } } return false; } private boolean shouldBeSourceRoot(IResource resource) { if (resource instanceof IProject) { return true; } if (PackageUtils.isUnderSrcFolder(resource)) { return true; } return false; } public List<IFile> getFiles() { return _files; } } /** * This class hold the key information for a rrh file. * * */ static public class RRHFile { IFile _file; String _resourceClassName; Hashtable<String, String> _keyTable; public RRHFile(String resourceClassName, IFile file, Hashtable<String, String> keyTable) { _resourceClassName = resourceClassName; _file = file; _keyTable = keyTable; } public IFile getFile() { return _file; } public Hashtable<String, String> getKeyTalbe() { if (_keyTable == null && _file != null) { try { _keyTable = getKeysFromRRHFile(_file.getLocation().toOSString()); } catch (CoreException e) { logger.error(e); } } return _keyTable; } public String getResourceClassName() { return _resourceClassName; } } /** * Returns the highest VM used by given projects. * * @param projects * The collection of <code>BlackBerryProject</code> * @return The <code>IVMInstall</code> */ public static IVMInstall getVMForProjects(Collection<BlackBerryProject> projects) { IVMInstall targetVM = null; List<IVMInstall> availableVMs = VMUtils.getInstalledBBVMs(); for (BlackBerryProject project : projects) { IVMInstall vm = ProjectUtils.getVMForProject(project); // The VM must be available if (vm != null && availableVMs.contains(vm)) { if (targetVM != null) { // use the highest version of VM if (vm.getId().compareTo(targetVM.getId()) > 0) { targetVM = vm; } } else { targetVM = vm; } } } if (targetVM == null) { targetVM = VMUtils.getDefaultBBVM(); } return targetVM; } /** * Returns the JVM version as conventional last token * * @param iproj * @return -like "6.0.0" */ public static String getVMVersionForProject(IProject iproj) { String ver = ""; IVMInstall ivmi = ProjectUtils.getVMForProject(JavaCore.create(iproj)); if (ivmi != null) { ver = ivmi.getId().substring(ivmi.getId().lastIndexOf(' ') + 1); } return ver; } /** * Create the given <code>file</code> if it does not exist. Also, this methods creates the parent folder if it does not exist. * * @param file * @return A File instance if the file has been successfully created otherwise return <code>null</code>. */ public static File createFile(File file) { if (!file.exists()) { File parent = file.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } try { file.createNewFile(); } catch (IOException e) { logger.error(e); } } if (!file.exists()) { return null; } return file; } }