org.chromium.debug.core/src/org/chromium/debug/core/util/ChromiumDebugPluginUtil.java
changeset 2 e4420d2515f1
child 276 f2f4a1259de8
equal deleted inserted replaced
1:ef76fc2ac88c 2:e4420d2515f1
       
     1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
       
     2 // Use of this source code is governed by a BSD-style license that can be
       
     3 // found in the LICENSE file.
       
     4 
       
     5 package org.chromium.debug.core.util;
       
     6 
       
     7 import java.io.ByteArrayInputStream;
       
     8 import java.io.File;
       
     9 import java.net.URI;
       
    10 
       
    11 import org.chromium.debug.core.ChromiumDebugPlugin;
       
    12 import org.chromium.debug.core.efs.ChromiumScriptFileSystem;
       
    13 import org.eclipse.core.filesystem.EFS;
       
    14 import org.eclipse.core.filesystem.IFileStore;
       
    15 import org.eclipse.core.resources.IContainer;
       
    16 import org.eclipse.core.resources.IFile;
       
    17 import org.eclipse.core.resources.IProject;
       
    18 import org.eclipse.core.resources.IProjectDescription;
       
    19 import org.eclipse.core.resources.IWorkspace;
       
    20 import org.eclipse.core.resources.ResourceAttributes;
       
    21 import org.eclipse.core.resources.ResourcesPlugin;
       
    22 import org.eclipse.core.runtime.CoreException;
       
    23 import org.eclipse.core.runtime.IProgressMonitor;
       
    24 import org.eclipse.core.runtime.IStatus;
       
    25 import org.eclipse.core.runtime.Path;
       
    26 import org.eclipse.core.runtime.Status;
       
    27 import org.eclipse.core.runtime.jobs.Job;
       
    28 import org.eclipse.swt.widgets.Display;
       
    29 import org.eclipse.ui.IWorkbench;
       
    30 import org.eclipse.ui.IWorkbenchWindow;
       
    31 import org.eclipse.ui.PartInitException;
       
    32 import org.eclipse.ui.PlatformUI;
       
    33 
       
    34 /**
       
    35  * A utility for interaction with the Eclipse workspace.
       
    36  */
       
    37 public class ChromiumDebugPluginUtil {
       
    38 
       
    39   public static final String CHROMIUM_EXTENSION = "chromium"; //$NON-NLS-1$
       
    40 
       
    41   public static final String JS_DEBUG_PROJECT_NATURE = "org.chromium.debug.core.jsnature"; //$NON-NLS-1$
       
    42 
       
    43   public static final String CHROMIUM_EXTENSION_SUFFIX = "." + CHROMIUM_EXTENSION; //$NON-NLS-1$
       
    44 
       
    45   private static final String PROJECT_EXPLORER_ID = "org.eclipse.ui.navigator.ProjectExplorer"; //$NON-NLS-1$
       
    46 
       
    47   /**
       
    48    * Brings up the "Project Explorer" view in the active workbench window.
       
    49    */
       
    50   public static void openProjectExplorerView() {
       
    51     Display.getDefault().asyncExec(new Runnable() {
       
    52       public void run() {
       
    53         IWorkbench workbench = PlatformUI.getWorkbench();
       
    54         IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
       
    55         if (window == null) {
       
    56           if (workbench.getWorkbenchWindowCount() == 1) {
       
    57             window = workbench.getWorkbenchWindows()[0];
       
    58           }
       
    59         }
       
    60         if (window != null) {
       
    61           try {
       
    62             window.getActivePage().showView(PROJECT_EXPLORER_ID);
       
    63           } catch (PartInitException e) {
       
    64             // ignore
       
    65           }
       
    66         }
       
    67       }
       
    68     });
       
    69   }
       
    70 
       
    71   /**
       
    72    * Creates an empty workspace project with the name starting with the given projectNameBase.
       
    73    * Created project is guaranteed to be new in EFS, but workspace may happen to
       
    74    * alreay have project with such url (left uncleaned from previous runs). Such project
       
    75    * silently gets deleted.
       
    76    * @param projectNameBase project name template
       
    77    * @return the newly created project, or {@code null} if the creation failed
       
    78    */
       
    79   public static IProject createEmptyProject(String projectNameBase) {
       
    80     URI projectUri;
       
    81     String projectName;
       
    82     try {
       
    83       for (int uniqueNumber = 0; ; uniqueNumber++) {
       
    84         String projectNameTry;
       
    85         if (uniqueNumber == 0) {
       
    86           projectNameTry = projectNameBase;
       
    87         } else {
       
    88           projectNameTry = projectNameBase + " (" + uniqueNumber + ")"; //$NON-NLS-1$ //$NON-NLS-2$
       
    89         }
       
    90         URI projectUriTry = ChromiumScriptFileSystem.getFileStoreUri(
       
    91             new Path(null, "/" + projectNameTry)); //$NON-NLS-1$
       
    92         IFileStore projectStore = EFS.getStore(projectUriTry);
       
    93         if (projectStore.fetchInfo().exists()) {
       
    94           continue;
       
    95         } else {
       
    96           projectUri = projectUriTry;
       
    97           projectName = projectNameTry;
       
    98           break;
       
    99         }
       
   100       }
       
   101     } catch (CoreException e) {
       
   102       ChromiumDebugPlugin.log(e);
       
   103       return null;
       
   104     }
       
   105     IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
       
   106     IProjectDescription description =
       
   107         ResourcesPlugin.getWorkspace().newProjectDescription(projectName);
       
   108     description.setLocationURI(projectUri);
       
   109     description.setNatureIds(new String[] { JS_DEBUG_PROJECT_NATURE });
       
   110     try {
       
   111       if (project.exists()) {
       
   112         project.delete(true, null);
       
   113       }
       
   114 
       
   115       project.create(description, null);
       
   116       project.open(null);
       
   117 
       
   118       return project;
       
   119     } catch (CoreException e) {
       
   120       ChromiumDebugPlugin.log(e);
       
   121     }
       
   122 
       
   123     return null;
       
   124   }
       
   125 
       
   126 
       
   127   /**
       
   128    * Removes virtual project which was created for debug session. Does its job
       
   129    * asynchronously.
       
   130    */
       
   131   public static void deleteVirtualProjectAsync(final IProject debugProject) {
       
   132     Job job = new Job("Remove virtual project") {
       
   133       @Override
       
   134       protected IStatus run(IProgressMonitor monitor) {
       
   135         URI projectUri = debugProject.getLocationURI();
       
   136         try {
       
   137           IFileStore projectStore = EFS.getStore(projectUri);
       
   138           if (projectStore.fetchInfo().exists()) {
       
   139             projectStore.delete(EFS.NONE, null);
       
   140           }
       
   141           debugProject.delete(true, null);
       
   142         } catch (CoreException e) {
       
   143           ChromiumDebugPlugin.log(e);
       
   144           return new Status(IStatus.ERROR, ChromiumDebugPlugin.PLUGIN_ID,
       
   145               "Failed to delete virtual project");
       
   146         }
       
   147         return Status.OK_STATUS;
       
   148       }
       
   149     };
       
   150 
       
   151     job.schedule();
       
   152   }
       
   153 
       
   154   /**
       
   155    * @param projectName to check for existence
       
   156    * @return whether the project named projectName exists.
       
   157    */
       
   158   public static boolean projectExists(String projectName) {
       
   159     IWorkspace ws = ResourcesPlugin.getWorkspace();
       
   160     IProject proj = ws.getRoot().getProject(projectName);
       
   161     return proj.exists();
       
   162   }
       
   163 
       
   164   /**
       
   165    * Creates an empty file with the given filename in the given project.
       
   166    *
       
   167    * @param project to create the file in
       
   168    * @param filename the base file name to create (will be sanitized for
       
   169    *        illegal chars and, in the case of a name clash, suffixed with "(N)")
       
   170    * @return the result of IFile.getName(), or {@code null} if the creation
       
   171    *         has failed
       
   172    */
       
   173   public static IFile createFile(IProject project, String filename) {
       
   174     String patchedName = new File(filename).getName().replace('?', '_'); // simple name
       
   175     String uniqueName = patchedName;
       
   176 
       
   177     // TODO(apavlov): refactor this?
       
   178     for (int i = 1; i < 1000; ++i) {
       
   179       String filePathname = uniqueName + CHROMIUM_EXTENSION_SUFFIX;
       
   180       IFile file = project.getFile(filePathname);
       
   181 
       
   182       if (file.exists()) {
       
   183         uniqueName = new StringBuilder(patchedName)
       
   184             .append(" (") //$NON-NLS-1$
       
   185             .append(i)
       
   186             .append(')')
       
   187             .toString();
       
   188       } else {
       
   189         try {
       
   190           file.create(new ByteArrayInputStream("".getBytes()), false, null); //$NON-NLS-1$
       
   191         } catch (CoreException e) {
       
   192           ChromiumDebugPlugin.log(e);
       
   193           return null;
       
   194         }
       
   195         return file;
       
   196       }
       
   197     }
       
   198 
       
   199     // Can we have 1000 same-named files?
       
   200     return null;
       
   201   }
       
   202 
       
   203   /**
       
   204    * Writes data into a resource with the given resourceName residing in the
       
   205    * source folder of the given project. The previous file content is lost.
       
   206    * Temporarily resets the "read-only" file attribute if one is present.
       
   207    *
       
   208    * @param file to set contents for
       
   209    * @param data to write into the file
       
   210    * @throws CoreException
       
   211    */
       
   212   public static void writeFile(IFile file, String data) throws CoreException {
       
   213     if (file != null && file.exists()) {
       
   214       ResourceAttributes resourceAttributes = file.getResourceAttributes();
       
   215       if (resourceAttributes.isReadOnly()) {
       
   216         resourceAttributes.setReadOnly(false);
       
   217         file.setResourceAttributes(resourceAttributes);
       
   218       }
       
   219       file.setContents(new ByteArrayInputStream(data.getBytes()), IFile.FORCE, null);
       
   220       resourceAttributes.setReadOnly(true);
       
   221       file.setResourceAttributes(resourceAttributes);
       
   222     }
       
   223   }
       
   224 
       
   225   public static boolean isInteger(String value) {
       
   226     try {
       
   227       Integer.parseInt(value);
       
   228       return true;
       
   229     } catch (NumberFormatException e) {
       
   230       return false;
       
   231     }
       
   232   }
       
   233 
       
   234   /**
       
   235    * The container where the script sources should be put.
       
   236    *
       
   237    * @param project where the launch configuration stores the scripts
       
   238    * @return the script source container
       
   239    */
       
   240   public static IContainer getSourceContainer(IProject project) {
       
   241     return project;
       
   242   }
       
   243 
       
   244   private ChromiumDebugPluginUtil() {
       
   245     // not instantiable
       
   246   }
       
   247 }