blob: 2aa6bc42cb584384940dbed0265f7696199289a8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 SAP AG.
* 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
*
* Contributors:
* Eduard Bartsch (SAP AG) - initial API and implementation
* Mathias Kinzler (SAP AG) - initial API and implementation
*******************************************************************************/
package org.eclipse.core.internal.resources.semantic.cacheservice;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import org.eclipse.core.resources.semantic.SemanticResourceException;
import org.eclipse.core.resources.semantic.SemanticResourceStatusCode;
import org.eclipse.core.resources.semantic.spi.Util;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
class TemporaryFileHandle implements ITemporaryContentHandle {
private final File file;
private final File cacheFile;
private final IPath path;
private final boolean appendMode;
private final long appendPosition;
private final OutputStream outputStream;
private final FileHandleFactory factory;
/**
* The "normal" instance
*
* @param factory
* @param path
* @param file
* @param cacheFile
* @param outputStream
*/
public TemporaryFileHandle(FileHandleFactory factory, IPath path, File file, File cacheFile, OutputStream outputStream) {
this.factory = factory;
this.path = path;
this.file = file;
this.cacheFile = cacheFile;
this.appendMode = false;
this.appendPosition = -1l;
this.outputStream = outputStream;
}
/**
* The "appending" instance
*
* @param factory
* @param path
* @param cacheFile
* @param outputStream
*/
public TemporaryFileHandle(FileHandleFactory factory, IPath path, File cacheFile, OutputStream outputStream) {
this.factory = factory;
this.path = path;
this.file = cacheFile;
this.cacheFile = cacheFile;
this.appendMode = true;
this.appendPosition = this.file.length();
this.outputStream = outputStream;
}
public File getFile() {
return this.file;
}
public void commit(long timestamp) throws CoreException {
try {
this.outputStream.flush();
this.outputStream.close();
} catch (IOException e) {
// TODO 0.1: cleanup when append mode
if (!this.appendMode) {
// in append mode, we write to the cache directly, so we can't
// delete
// delete temporary content
this.factory.tryDelete(this.file);
}
throw new SemanticResourceException(SemanticResourceStatusCode.FILECACHE_ERROR_WRITING_CONTENT, new Path(this.file
.getAbsolutePath()), MessageFormat.format(Messages.TemporaryFileHandle_OsCloseErrorOnCommit_XMSG, this.file
.getAbsolutePath()), e);
}
if (!this.appendMode) {
this.factory.doRename(this.getFile(), this.cacheFile);
}
if (!this.cacheFile.setLastModified(timestamp)) {
throw new SemanticResourceException(SemanticResourceStatusCode.FILECACHE_ERROR_SETTING_TIMESTAMP, new Path(this.cacheFile
.getAbsolutePath()), MessageFormat.format(Messages.TemporaryFileHandle_TimstampSetOnCommit_XMSG, this.cacheFile
.getAbsolutePath()));
}
// TODO 0.1: non-millisecond accuracy systems
// long lastModified = this.cacheFile.lastModified();
// if (lastModified != timestamp) {
// throw new SemanticResourceException(SemanticResourceStatusCode.FILECACHE_ERROR_SETTING_TIMESTAMP, new Path(this.cacheFile
// .getAbsolutePath()), MessageFormat.format(Messages.TemporaryFileHandle_TimstampSetOnCommit_XMSG, this.cacheFile
// .getAbsolutePath()));
// }
}
public IPath getKey() {
return this.path;
}
public long getAppendPosition() {
return this.appendPosition;
}
public void flush() throws IOException {
this.outputStream.flush();
}
public void write(byte[] b, int off, int len) throws IOException {
this.outputStream.write(b, off, len);
}
public void write(byte[] b) throws IOException {
this.outputStream.write(b);
}
public void write(int b) throws IOException {
this.outputStream.write(b);
}
public void setContents(InputStream input, IProgressMonitor monitor) throws CoreException {
Util.transferStreams(input, this.outputStream, monitor);
}
}