/******************************************************************************* * Copyright (c) 2009 Andrey Loskutov. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * Contributor: Andrey Loskutov - initial API and implementation *******************************************************************************/ package de.loskutov.anyedit.compare; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.eclipse.compare.BufferedContent; import org.eclipse.compare.CompareUI; import org.eclipse.compare.IEditableContent; import org.eclipse.compare.IEditableContentExtension; import org.eclipse.compare.IModificationDate; import org.eclipse.compare.ITypedElement; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.filesystem.provider.FileInfo; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Shell; import de.loskutov.anyedit.AnyEditToolsPlugin; /** * Content for external files without document support. * @author Andrey */ public class ExternalFileStreamContent extends BufferedContent implements StreamContent, IEditableContent, IModificationDate, IEditableContentExtension { protected boolean dirty; private final ContentWrapper content; public ExternalFileStreamContent(ContentWrapper content) { super(); this.content = content; } @Override public void setContent(byte[] contents) { dirty = true; super.setContent(contents); } @Override public Image getImage() { return CompareUI.getImage(content.getFileExtension()); } @Override public boolean commitChanges(IProgressMonitor pm) throws CoreException { if (!dirty) { return true; } byte[] bytes = getContent(); FileOutputStream fos = null; try { fos = new FileOutputStream(content.getFile()); fos.write(bytes); return true; } catch (IOException e) { AnyEditToolsPlugin.errorDialog( "Can't store compare buffer to external file: " + content.getFile(), e); } finally { try { if (fos != null) { fos.close(); } } catch (IOException e) { // ignore } } return false; } @Override protected InputStream createStream() throws CoreException { FileInputStream fis; try { fis = new FileInputStream(content.getFile()); return fis; } catch (FileNotFoundException e) { return null; } } @Override public boolean isDirty() { return dirty; } @Override public String getName() { return content.getName(); } @Override public String getFullName() { return content.getFullName(); } @Override public String getType() { return content.getFileExtension(); } @Override public Object[] getChildren() { return new StreamContent[0]; } @Override public boolean isEditable() { return true; } @Override public ITypedElement replace(ITypedElement dest, ITypedElement src) { return null; } @Override public long getModificationDate() { return content.getFile().lastModified(); } @Override public boolean isReadOnly() { return !content.getFile().canWrite(); } @Override public IStatus validateEdit(Shell shell) { File file = content.getFile(); if(file.canWrite()) { return Status.OK_STATUS; } FileInfo fi = new FileInfo(file.getAbsolutePath()); fi.setAttribute(EFS.ATTRIBUTE_READ_ONLY, false); try { IFileStore store = EFS.getStore(URIUtil.toURI(file.getAbsolutePath())); store.putInfo(fi, EFS.SET_ATTRIBUTES, null); } catch (CoreException e) { AnyEditToolsPlugin.logError("Can't make file writable: " + file, e); } if(file.canWrite()) { return Status.OK_STATUS; } return Status.CANCEL_STATUS; } @Override public void dispose() { discardBuffer(); } @Override public boolean isDisposed() { return false; } @Override public void init(AnyeditCompareInput input) { getContent(); } @Override public StreamContent recreate() { return new ExternalFileStreamContent(content); } @Override public Object getAdapter(Class adapter) { return null; } @Override public void setDirty(boolean dirty) { this.dirty = dirty; } }