org.chromium.debug.core/src/org/chromium/debug/core/util/ChromiumDebugPluginUtil.java
changeset 2 e4420d2515f1
child 276 f2f4a1259de8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.chromium.debug.core/src/org/chromium/debug/core/util/ChromiumDebugPluginUtil.java	Wed Dec 23 17:13:18 2009 -0800
@@ -0,0 +1,247 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.debug.core.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.net.URI;
+
+import org.chromium.debug.core.ChromiumDebugPlugin;
+import org.chromium.debug.core.efs.ChromiumScriptFileSystem;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * A utility for interaction with the Eclipse workspace.
+ */
+public class ChromiumDebugPluginUtil {
+
+  public static final String CHROMIUM_EXTENSION = "chromium"; //$NON-NLS-1$
+
+  public static final String JS_DEBUG_PROJECT_NATURE = "org.chromium.debug.core.jsnature"; //$NON-NLS-1$
+
+  public static final String CHROMIUM_EXTENSION_SUFFIX = "." + CHROMIUM_EXTENSION; //$NON-NLS-1$
+
+  private static final String PROJECT_EXPLORER_ID = "org.eclipse.ui.navigator.ProjectExplorer"; //$NON-NLS-1$
+
+  /**
+   * Brings up the "Project Explorer" view in the active workbench window.
+   */
+  public static void openProjectExplorerView() {
+    Display.getDefault().asyncExec(new Runnable() {
+      public void run() {
+        IWorkbench workbench = PlatformUI.getWorkbench();
+        IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+        if (window == null) {
+          if (workbench.getWorkbenchWindowCount() == 1) {
+            window = workbench.getWorkbenchWindows()[0];
+          }
+        }
+        if (window != null) {
+          try {
+            window.getActivePage().showView(PROJECT_EXPLORER_ID);
+          } catch (PartInitException e) {
+            // ignore
+          }
+        }
+      }
+    });
+  }
+
+  /**
+   * Creates an empty workspace project with the name starting with the given projectNameBase.
+   * Created project is guaranteed to be new in EFS, but workspace may happen to
+   * alreay have project with such url (left uncleaned from previous runs). Such project
+   * silently gets deleted.
+   * @param projectNameBase project name template
+   * @return the newly created project, or {@code null} if the creation failed
+   */
+  public static IProject createEmptyProject(String projectNameBase) {
+    URI projectUri;
+    String projectName;
+    try {
+      for (int uniqueNumber = 0; ; uniqueNumber++) {
+        String projectNameTry;
+        if (uniqueNumber == 0) {
+          projectNameTry = projectNameBase;
+        } else {
+          projectNameTry = projectNameBase + " (" + uniqueNumber + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        URI projectUriTry = ChromiumScriptFileSystem.getFileStoreUri(
+            new Path(null, "/" + projectNameTry)); //$NON-NLS-1$
+        IFileStore projectStore = EFS.getStore(projectUriTry);
+        if (projectStore.fetchInfo().exists()) {
+          continue;
+        } else {
+          projectUri = projectUriTry;
+          projectName = projectNameTry;
+          break;
+        }
+      }
+    } catch (CoreException e) {
+      ChromiumDebugPlugin.log(e);
+      return null;
+    }
+    IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+    IProjectDescription description =
+        ResourcesPlugin.getWorkspace().newProjectDescription(projectName);
+    description.setLocationURI(projectUri);
+    description.setNatureIds(new String[] { JS_DEBUG_PROJECT_NATURE });
+    try {
+      if (project.exists()) {
+        project.delete(true, null);
+      }
+
+      project.create(description, null);
+      project.open(null);
+
+      return project;
+    } catch (CoreException e) {
+      ChromiumDebugPlugin.log(e);
+    }
+
+    return null;
+  }
+
+
+  /**
+   * Removes virtual project which was created for debug session. Does its job
+   * asynchronously.
+   */
+  public static void deleteVirtualProjectAsync(final IProject debugProject) {
+    Job job = new Job("Remove virtual project") {
+      @Override
+      protected IStatus run(IProgressMonitor monitor) {
+        URI projectUri = debugProject.getLocationURI();
+        try {
+          IFileStore projectStore = EFS.getStore(projectUri);
+          if (projectStore.fetchInfo().exists()) {
+            projectStore.delete(EFS.NONE, null);
+          }
+          debugProject.delete(true, null);
+        } catch (CoreException e) {
+          ChromiumDebugPlugin.log(e);
+          return new Status(IStatus.ERROR, ChromiumDebugPlugin.PLUGIN_ID,
+              "Failed to delete virtual project");
+        }
+        return Status.OK_STATUS;
+      }
+    };
+
+    job.schedule();
+  }
+
+  /**
+   * @param projectName to check for existence
+   * @return whether the project named projectName exists.
+   */
+  public static boolean projectExists(String projectName) {
+    IWorkspace ws = ResourcesPlugin.getWorkspace();
+    IProject proj = ws.getRoot().getProject(projectName);
+    return proj.exists();
+  }
+
+  /**
+   * Creates an empty file with the given filename in the given project.
+   *
+   * @param project to create the file in
+   * @param filename the base file name to create (will be sanitized for
+   *        illegal chars and, in the case of a name clash, suffixed with "(N)")
+   * @return the result of IFile.getName(), or {@code null} if the creation
+   *         has failed
+   */
+  public static IFile createFile(IProject project, String filename) {
+    String patchedName = new File(filename).getName().replace('?', '_'); // simple name
+    String uniqueName = patchedName;
+
+    // TODO(apavlov): refactor this?
+    for (int i = 1; i < 1000; ++i) {
+      String filePathname = uniqueName + CHROMIUM_EXTENSION_SUFFIX;
+      IFile file = project.getFile(filePathname);
+
+      if (file.exists()) {
+        uniqueName = new StringBuilder(patchedName)
+            .append(" (") //$NON-NLS-1$
+            .append(i)
+            .append(')')
+            .toString();
+      } else {
+        try {
+          file.create(new ByteArrayInputStream("".getBytes()), false, null); //$NON-NLS-1$
+        } catch (CoreException e) {
+          ChromiumDebugPlugin.log(e);
+          return null;
+        }
+        return file;
+      }
+    }
+
+    // Can we have 1000 same-named files?
+    return null;
+  }
+
+  /**
+   * Writes data into a resource with the given resourceName residing in the
+   * source folder of the given project. The previous file content is lost.
+   * Temporarily resets the "read-only" file attribute if one is present.
+   *
+   * @param file to set contents for
+   * @param data to write into the file
+   * @throws CoreException
+   */
+  public static void writeFile(IFile file, String data) throws CoreException {
+    if (file != null && file.exists()) {
+      ResourceAttributes resourceAttributes = file.getResourceAttributes();
+      if (resourceAttributes.isReadOnly()) {
+        resourceAttributes.setReadOnly(false);
+        file.setResourceAttributes(resourceAttributes);
+      }
+      file.setContents(new ByteArrayInputStream(data.getBytes()), IFile.FORCE, null);
+      resourceAttributes.setReadOnly(true);
+      file.setResourceAttributes(resourceAttributes);
+    }
+  }
+
+  public static boolean isInteger(String value) {
+    try {
+      Integer.parseInt(value);
+      return true;
+    } catch (NumberFormatException e) {
+      return false;
+    }
+  }
+
+  /**
+   * The container where the script sources should be put.
+   *
+   * @param project where the launch configuration stores the scripts
+   * @return the script source container
+   */
+  public static IContainer getSourceContainer(IProject project) {
+    return project;
+  }
+
+  private ChromiumDebugPluginUtil() {
+    // not instantiable
+  }
+}