1 /******************************************************************************* 2 * Copyright (c) 2000, 2019 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Microsoft Corporation - copied to jdt.core.manipulation 14 *******************************************************************************/ 15 package org.eclipse.jdt.internal.corext.refactoring.nls.changes; 16 17 import java.io.ByteArrayInputStream; 18 import java.io.IOException; 19 import java.io.InputStream; 20 import java.io.UnsupportedEncodingException; 21 import java.net.URI; 22 23 import org.eclipse.core.filesystem.EFS; 24 import org.eclipse.core.filesystem.IFileInfo; 25 26 import org.eclipse.core.runtime.Assert; 27 import org.eclipse.core.runtime.CoreException; 28 import org.eclipse.core.runtime.IPath; 29 import org.eclipse.core.runtime.IProgressMonitor; 30 import org.eclipse.core.runtime.OperationCanceledException; 31 import org.eclipse.core.runtime.Platform; 32 import org.eclipse.core.runtime.SubProgressMonitor; 33 import org.eclipse.core.runtime.content.IContentType; 34 35 import org.eclipse.core.resources.IFile; 36 import org.eclipse.core.resources.IResource; 37 import org.eclipse.core.resources.ResourcesPlugin; 38 39 import org.eclipse.ltk.core.refactoring.Change; 40 import org.eclipse.ltk.core.refactoring.RefactoringStatus; 41 import org.eclipse.ltk.core.refactoring.resource.DeleteResourceChange; 42 import org.eclipse.ltk.core.refactoring.resource.ResourceChange; 43 44 import org.eclipse.jdt.core.IJavaModelStatusConstants; 45 import org.eclipse.jdt.core.JavaModelException; 46 47 import org.eclipse.jdt.internal.corext.util.Messages; 48 49 import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels; 50 51 public class CreateFileChange extends ResourceChange { 52 53 private String fChangeName; 54 55 private IPath fPath; 56 private String fSource; 57 private String fEncoding; 58 private boolean fExplicitEncoding; 59 private long fStampToRestore; 60 CreateFileChange(IPath path, String source, String encoding)61 public CreateFileChange(IPath path, String source, String encoding) { 62 this(path, source, encoding, IResource.NULL_STAMP); 63 } 64 CreateFileChange(IPath path, String source, String encoding, long stampToRestore)65 public CreateFileChange(IPath path, String source, String encoding, long stampToRestore) { 66 Assert.isNotNull(path, "path"); //$NON-NLS-1$ 67 Assert.isNotNull(source, "source"); //$NON-NLS-1$ 68 fPath= path; 69 fSource= source; 70 fEncoding= encoding; 71 fExplicitEncoding= fEncoding != null; 72 fStampToRestore= stampToRestore; 73 } 74 75 /* 76 private CreateFileChange(IPath path, String source, String encoding, long stampToRestore, boolean explicit) { 77 Assert.isNotNull(path, "path"); //$NON-NLS-1$ 78 Assert.isNotNull(source, "source"); //$NON-NLS-1$ 79 Assert.isNotNull(encoding, "encoding"); //$NON-NLS-1$ 80 fPath= path; 81 fSource= source; 82 fEncoding= encoding; 83 fStampToRestore= stampToRestore; 84 fExplicitEncoding= explicit; 85 } 86 */ 87 setEncoding(String encoding, boolean explicit)88 protected void setEncoding(String encoding, boolean explicit) { 89 Assert.isNotNull(encoding, "encoding"); //$NON-NLS-1$ 90 fEncoding= encoding; 91 fExplicitEncoding= explicit; 92 } 93 94 @Override getName()95 public String getName() { 96 if (fChangeName == null) 97 return Messages.format(NLSChangesMessages.createFile_Create_file, BasicElementLabels.getPathLabel(fPath, false)); 98 else 99 return fChangeName; 100 } 101 setName(String name)102 public void setName(String name) { 103 fChangeName= name; 104 } 105 setSource(String source)106 protected void setSource(String source) { 107 fSource= source; 108 } 109 getSource()110 protected String getSource() { 111 return fSource; 112 } 113 setPath(IPath path)114 protected void setPath(IPath path) { 115 fPath= path; 116 } 117 getPath()118 protected IPath getPath() { 119 return fPath; 120 } 121 122 @Override getModifiedResource()123 protected IResource getModifiedResource() { 124 return ResourcesPlugin.getWorkspace().getRoot().getFile(fPath); 125 } 126 127 @Override isValid(IProgressMonitor pm)128 public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException { 129 RefactoringStatus result= new RefactoringStatus(); 130 IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(fPath); 131 132 URI location= file.getLocationURI(); 133 if (location == null) { 134 result.addFatalError(Messages.format( 135 NLSChangesMessages.CreateFileChange_error_unknownLocation, 136 BasicElementLabels.getPathLabel(file.getFullPath(), false))); 137 return result; 138 } 139 140 IFileInfo jFile= EFS.getStore(location).fetchInfo(); 141 if (jFile.exists()) { 142 result.addFatalError(Messages.format( 143 NLSChangesMessages.CreateFileChange_error_exists, 144 BasicElementLabels.getPathLabel(file.getFullPath(), false))); 145 return result; 146 } 147 return result; 148 } 149 150 @Override perform(IProgressMonitor pm)151 public Change perform(IProgressMonitor pm) throws CoreException, OperationCanceledException { 152 153 InputStream is= null; 154 try { 155 pm.beginTask(NLSChangesMessages.createFile_creating_resource, 3); 156 157 initializeEncoding(); 158 IFile file= getOldFile(new SubProgressMonitor(pm, 1)); 159 /* 160 if (file.exists()) { 161 CompositeChange composite= new CompositeChange(getName()); 162 composite.add(new DeleteFileChange(file)); 163 composite.add(new CreateFileChange(fPath, fSource, fEncoding, fStampToRestore, fExplicitEncoding)); 164 pm.worked(1); 165 return composite.perform(new SubProgressMonitor(pm, 1)); 166 } else { */ 167 try { 168 is= new ByteArrayInputStream(fSource.getBytes(fEncoding)); 169 file.create(is, false, new SubProgressMonitor(pm, 1)); 170 if (fStampToRestore != IResource.NULL_STAMP) { 171 file.revertModificationStamp(fStampToRestore); 172 } 173 if (fExplicitEncoding) { 174 file.setCharset(fEncoding, new SubProgressMonitor(pm, 1)); 175 } else { 176 pm.worked(1); 177 } 178 return new DeleteResourceChange(file.getFullPath(), true); 179 } catch (UnsupportedEncodingException e) { 180 throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); 181 } 182 } finally { 183 try { 184 if (is != null) 185 is.close(); 186 } catch (IOException ioe) { 187 throw new JavaModelException(ioe, IJavaModelStatusConstants.IO_EXCEPTION); 188 } finally { 189 pm.done(); 190 } 191 } 192 } 193 getOldFile(IProgressMonitor pm)194 protected IFile getOldFile(IProgressMonitor pm) throws OperationCanceledException { 195 pm.beginTask("", 1); //$NON-NLS-1$ 196 try { 197 return ResourcesPlugin.getWorkspace().getRoot().getFile(fPath); 198 } finally { 199 pm.done(); 200 } 201 } 202 initializeEncoding()203 private void initializeEncoding() { 204 if (fEncoding == null) { 205 fExplicitEncoding= false; 206 IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(fPath); 207 if (file != null) { 208 try { 209 if (file.exists()) { 210 fEncoding= file.getCharset(false); 211 if (fEncoding == null) { 212 fEncoding= file.getCharset(true); 213 } else { 214 fExplicitEncoding= true; 215 } 216 } else { 217 IContentType contentType= Platform.getContentTypeManager().findContentTypeFor(file.getName()); 218 if (contentType != null) 219 fEncoding= contentType.getDefaultCharset(); 220 if (fEncoding == null) 221 fEncoding= file.getCharset(true); 222 } 223 } catch (CoreException e) { 224 fEncoding= ResourcesPlugin.getEncoding(); 225 fExplicitEncoding= true; 226 } 227 } else { 228 fEncoding= ResourcesPlugin.getEncoding(); 229 fExplicitEncoding= true; 230 } 231 } 232 Assert.isNotNull(fEncoding); 233 } 234 } 235