/* * Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html * * 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.google.dart.tools.ui.theme.preferences; import com.google.common.io.CharStreams; import com.google.dart.tools.core.DartCore; import com.google.dart.tools.deploy.Activator; import org.apache.commons.lang3.StringUtils; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.URI; /** * Helper for creating, manipulating and disposing a temporary project. This exists in the workspace * for a short time but the user should never see it. */ public class TemporaryProject { public static final String DEFAULT_NAME = "CodeColoringSample"; static void deleteProject(IProject project) throws CoreException { final int MAX_FAILURES = 10; int failureCount = 0; while (true) { try { project.delete(true, true, null); return; } catch (CoreException ce) { failureCount++; if (failureCount >= MAX_FAILURES) { throw ce; } Runtime.getRuntime().gc(); Runtime.getRuntime().runFinalization(); } } } private final IProject project; /** * Creates new new temporary project with default name. */ public TemporaryProject() throws CoreException { this(DEFAULT_NAME); } /** * Creates new temporary project with the given name. */ public TemporaryProject(final String name) throws CoreException { final IWorkspace workspace = ResourcesPlugin.getWorkspace(); IWorkspaceRoot root = workspace.getRoot(); final String projectName = findUniqueName(root, name); project = root.getProject(projectName); workspace.run(new IWorkspaceRunnable() { @Override public void run(IProgressMonitor monitor) throws CoreException { // delete project if (project.exists()) { deleteProject(project); } // create project project.create(null); project.open(null); // set description IProjectDescription description = createProjectDescription(project); project.setDescription(description, IResource.FORCE, null); } }, null); } public IFolder createFolder(String path) throws Exception { String[] parts = StringUtils.split(path, "/"); IContainer container = project; for (String part : parts) { IFolder folder = container.getFolder(new Path(part)); if (!folder.exists()) { folder.create(true, true, null); } container = folder; } return (IFolder) container; } /** * Disposes allocated resources and deletes project. */ public void dispose() throws CoreException { try { if (project.exists()) { project.close(null); } } catch (Throwable e) { } // do dispose deleteProject(project); } /** * @return the {@link IFile} on given path, not <code>null</code>, but may not exist. */ public IFile getFile(String path) { return project.getFile(new Path(path)); } /** * @return the {@link String} content of the {@link IFile} with given path. */ public String getFileString(String path) throws Exception { IFile file = getFile(path); Reader reader = new InputStreamReader(file.getContents(), file.getCharset()); try { return CharStreams.toString(reader); } finally { reader.close(); } } /** * @return the underlying {@link IProject}. */ public IProject getProject() { return project; } /** * Creates or updates {@link IFile} with content of the given {@link InputStream}. */ public IFile setFileContent(String path, InputStream stream) throws CoreException { IFile file = getFile(path); if (file.exists()) { file.setContents(stream, true, false, null); } else { file.create(stream, true, null); file.setCharset("UTF-8", null); } return file; } /** * Creates or updates with {@link String} content of the {@link IFile}. */ public IFile setFileContent(String path, String content) throws IOException, CoreException { byte[] bytes = content.getBytes("UTF-8"); InputStream stream = new ByteArrayInputStream(bytes); return setFileContent(path, stream); } /** * Creates or updates CompilationUnit at given path. */ public IFile setUnitContent(String path, String content) throws IOException, CoreException { IFile file = setFileContent(path, content); return file; } private IProjectDescription createProjectDescription(IProject project) { URI location = null; try { File tempFile = File.createTempFile("DartEditor", null); File tempDir = tempFile.getParentFile(); tempFile.delete(); tempDir.mkdirs(); location = tempDir.toURI(); } catch (IOException ex) { Activator.logError(ex); } IWorkspace workspace = ResourcesPlugin.getWorkspace(); IProjectDescription description = workspace.newProjectDescription(project.getName()); description.setLocationURI(location); description.setNatureIds(new String[] {DartCore.DART_PROJECT_NATURE}); ICommand command = description.newCommand(); command.setBuilderName(DartCore.DART_BUILDER_ID); description.setBuildSpec(new ICommand[] {command}); return description; } private String findUniqueName(IWorkspaceRoot root, String initialName) { String name = initialName; int n = 0; while (true) { IProject p = root.getProject(name); if (!p.exists()) { return name; } n += 1; name = initialName + String.valueOf(n); } } }