blob: d59cc6f49ddac22f4714a1e974935a83cd6a52d6 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2007, 2020 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ltk.model.core.impl;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.IDocument;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.internal.ltk.core.LtkCorePlugin;
import org.eclipse.statet.ltk.core.SourceContent;
import org.eclipse.statet.ltk.model.core.element.SourceUnit;
/**
* BasicWorkingBuffer using {@link ITextFileBuffer} and following JFace UI rules.
* <p>
* Usually used for editors / the editor context.</p>
*/
@NonNullByDefault
public class FileBufferWorkingBuffer extends BasicWorkingBuffer {
private @Nullable ITextFileBuffer fileBuffer;
public FileBufferWorkingBuffer(final SourceUnit unit) {
super(unit);
}
@Override
protected final byte getContentMode() {
return DOCUMENT;
}
@Override
protected @Nullable AbstractDocument createDocument(final SubMonitor m) {
ITextFileBuffer fileBuffer= null;
switch (detectResourceMode()) {
case IFILE:
{ final IPath path= ((IFile)this.unit.getResource()).getFullPath();
try {
FileBuffers.getTextFileBufferManager().connect(path, LocationKind.IFILE, m);
fileBuffer= FileBuffers.getTextFileBufferManager().getTextFileBuffer(path, LocationKind.IFILE);
}
catch (final CoreException e) {
LtkCorePlugin.log(new Status(IStatus.ERROR, LtkCorePlugin.BUNDLE_ID, -1,
"An error occurred when allocating the document of the file buffer.",
e ));
}
break;
}
case FILESTORE:
{ final IFileStore store= (IFileStore)this.unit.getResource();
try {
FileBuffers.getTextFileBufferManager().connectFileStore(store, m);
fileBuffer= FileBuffers.getTextFileBufferManager().getFileStoreTextFileBuffer(store);
}
catch (final CoreException e) {
LtkCorePlugin.log(new Status(IStatus.ERROR, LtkCorePlugin.BUNDLE_ID, -1,
"An error occurred when allocating the document of the file buffer.",
e ));
}
break;
}
default:
return super.createDocument(m);
}
this.fileBuffer= fileBuffer;
if (fileBuffer != null) {
final IDocument fileDoc= fileBuffer.getDocument();
if (fileDoc instanceof AbstractDocument) {
return (AbstractDocument)fileDoc;
}
}
return null;
}
private @Nullable ITextFileBuffer getBuffer() {
synchronized (this) {
final ITextFileBuffer fileBuffer= this.fileBuffer;
if (fileBuffer != null) {
return fileBuffer;
}
}
switch (getResourceMode()) {
case IFILE:
{ final IPath path= ((IFile)this.unit.getResource()).getFullPath();
return FileBuffers.getTextFileBufferManager().getTextFileBuffer(path, LocationKind.IFILE);
}
case FILESTORE:
{ final IFileStore store= (IFileStore)this.unit.getResource();
return FileBuffers.getTextFileBufferManager().getFileStoreTextFileBuffer(store);
}
default:
return null;
}
}
@Override
protected SourceContent createContent(final SubMonitor m) {
if (detectResourceMode() > 0) {
final ITextFileBuffer buffer= getBuffer();
if (buffer != null) {
return createContentFromDocument(buffer.getDocument());
}
}
return super.createContent(m);
}
@Override
public void releaseDocument(final IProgressMonitor monitor) {
if (this.fileBuffer != null) {
try {
final SubMonitor m= SubMonitor.convert(monitor);
switch (getResourceMode()) {
case IFILE:
{ final IPath path= ((IFile)this.unit.getResource()).getFullPath();
FileBuffers.getTextFileBufferManager().disconnect(path, LocationKind.IFILE, m);
break;
}
case FILESTORE:
{ final IFileStore store= (IFileStore)this.unit.getResource();
FileBuffers.getTextFileBufferManager().disconnectFileStore(store, m);
break;
}
default:
break;
}
}
catch (final CoreException e) {
LtkCorePlugin.log(new Status(IStatus.ERROR, LtkCorePlugin.BUNDLE_ID, -1,
"An error occurred when releasing the document of the file buffer.", e ));
}
finally {
this.fileBuffer= null;
super.releaseDocument(monitor);
}
}
else {
super.releaseDocument(monitor);
}
}
@Override
public boolean checkState(final boolean validate, final IProgressMonitor monitor) {
final ITextFileBuffer buffer= this.fileBuffer;
if (buffer != null) {
if (!validate && !buffer.isStateValidated()) {
return true;
}
if (validate && !buffer.isStateValidated()) {
try {
buffer.validateState(monitor, IWorkspace.VALIDATE_PROMPT);
}
catch (final CoreException e) {
LtkCorePlugin.log(new Status(IStatus.ERROR, LtkCorePlugin.BUNDLE_ID, -1,
"An error occurred when validating file buffer state.", e ));
}
}
}
return super.checkState(validate, monitor);
}
@Override
public boolean isSynchronized() {
if (detectResourceMode() > 0) {
final ITextFileBuffer buffer= getBuffer();
if (buffer != null) {
return !buffer.isDirty();
}
}
return true;
}
}