1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.adt.internal.wizards.templates; 18 19 import com.android.annotations.NonNull; 20 import com.android.ide.eclipse.adt.AdtPlugin; 21 import com.android.ide.eclipse.adt.AdtUtils; 22 import com.google.common.io.Closeables; 23 import com.google.common.io.Files; 24 import com.google.common.io.InputSupplier; 25 26 import org.eclipse.core.resources.IContainer; 27 import org.eclipse.core.resources.IFile; 28 import org.eclipse.core.resources.IFolder; 29 import org.eclipse.core.resources.IResource; 30 import org.eclipse.core.resources.ResourcesPlugin; 31 import org.eclipse.core.runtime.CoreException; 32 import org.eclipse.core.runtime.IPath; 33 import org.eclipse.core.runtime.IProgressMonitor; 34 import org.eclipse.core.runtime.OperationCanceledException; 35 import org.eclipse.core.runtime.SubProgressMonitor; 36 import org.eclipse.ltk.core.refactoring.Change; 37 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 38 import org.eclipse.ltk.core.refactoring.resource.ResourceChange; 39 40 import java.io.File; 41 import java.io.FileInputStream; 42 import java.io.InputStream; 43 import java.net.URI; 44 45 /** Change which lazily copies a file */ 46 public class CreateFileChange extends ResourceChange { 47 private String mName; 48 private final IPath mPath; 49 private final File mSource; 50 51 CreateFileChange(@NonNull String name, @NonNull IPath workspacePath, File source) { 52 mName = name; 53 mPath = workspacePath; 54 mSource = source; 55 } 56 57 @Override 58 protected IResource getModifiedResource() { 59 return ResourcesPlugin.getWorkspace().getRoot().getFile(mPath); 60 } 61 62 @Override 63 public String getName() { 64 return mName; 65 } 66 67 @Override 68 public RefactoringStatus isValid(IProgressMonitor pm) 69 throws CoreException, OperationCanceledException { 70 RefactoringStatus result = new RefactoringStatus(); 71 IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(mPath); 72 URI location = file.getLocationURI(); 73 if (location == null) { 74 result.addFatalError("Unknown location " + file.getFullPath().toString()); 75 return result; 76 } 77 return result; 78 } 79 80 @SuppressWarnings("resource") // Eclipse doesn't know about Guava's Closeables.closeQuietly 81 @Override 82 public Change perform(IProgressMonitor pm) throws CoreException { 83 InputSupplier<FileInputStream> supplier = Files.newInputStreamSupplier(mSource); 84 InputStream is = null; 85 try { 86 pm.beginTask("Creating file", 3); 87 IFile file = (IFile) getModifiedResource(); 88 89 IContainer parent = file.getParent(); 90 if (parent != null && !parent.exists()) { 91 IFolder folder = ResourcesPlugin.getWorkspace().getRoot().getFolder( 92 parent.getFullPath()); 93 AdtUtils.ensureExists(folder); 94 } 95 96 is = supplier.getInput(); 97 file.create(is, false, new SubProgressMonitor(pm, 1)); 98 pm.worked(1); 99 } catch (Exception ioe) { 100 AdtPlugin.log(ioe, null); 101 } finally { 102 Closeables.closeQuietly(is); 103 pm.done(); 104 } 105 return null; 106 } 107 } 108