/* * (c) Copyright IBM Corp. 2000, 2001. * All Rights Reserved. */ package net.sourceforge.phpdt.internal.corext.textmanipulation; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; import net.sourceforge.phpdt.internal.corext.util.IOCloser; import net.sourceforge.phpdt.internal.ui.PHPStatusConstants; import net.sourceforge.phpeclipse.PHPeclipsePlugin; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; 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.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.util.Assert; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; /* package */ class TextBufferFactory { private IDocumentProvider fDocumentProvider; private Map fFileValueMap; private Map fBufferValueMap; private static class Value { TextBuffer buffer; FileEditorInput input; IDocument document; IAnnotationModel annotationModel; int references; public Value(TextBuffer b, FileEditorInput i, IDocument d, IAnnotationModel m) { buffer= b; input= i; document= d; annotationModel= m; } } public TextBufferFactory() { // XXX http://dev.eclipse.org/bugs/show_bug.cgi?id=5170 // Need way to map a file to a document without knowing any kind of document provider. this(PHPeclipsePlugin.getDefault().getCompilationUnitDocumentProvider()); } public TextBufferFactory(IDocumentProvider provider) { fDocumentProvider= provider; Assert.isNotNull(fDocumentProvider); fFileValueMap= new HashMap(5); fBufferValueMap= new HashMap(5); } public TextBuffer acquire(IFile file) throws CoreException { FileEditorInput input= new FileEditorInput(file); Value value= (Value)fFileValueMap.get(input); if (value != null) { value.references++; return value.buffer; } fDocumentProvider.connect(input); IDocument document= fDocumentProvider.getDocument(input); IAnnotationModel annotationModel= fDocumentProvider.getAnnotationModel(input); annotationModel.connect(document); value= new Value(new TextBuffer(document), input, document, annotationModel); fFileValueMap.put(input, value); fBufferValueMap.put(value.buffer, value); value.references++; return value.buffer; } public void release(TextBuffer buffer) { final Value value= (Value)fBufferValueMap.get(buffer); if (value == null) return; value.references--; if (value.references == 0) { buffer.release(); value.annotationModel.disconnect(value.document); fDocumentProvider.disconnect(value.input); fFileValueMap.remove(value.input); fBufferValueMap.remove(buffer); } } public void commitChanges(TextBuffer buffer, boolean force, IProgressMonitor pm) throws CoreException { final Value value= (Value)fBufferValueMap.get(buffer); if (value == null) return; boolean save= force || fDocumentProvider.mustSaveDocument(value.input); if (save) { IWorkspaceRunnable action= new IWorkspaceRunnable() { public void run(IProgressMonitor pm) throws CoreException { fDocumentProvider.aboutToChange(value.input); fDocumentProvider.saveDocument(pm, value.input, value.document, true); } }; try { ResourcesPlugin.getWorkspace().run(action, pm); } finally { fDocumentProvider.changed(value.input); } } } public TextBuffer create(IFile file) throws CoreException { FileEditorInput input= new FileEditorInput(file); IDocument document= fDocumentProvider.getDocument(input); if (document != null) { return new TextBuffer(new Document(document.get())); } else { return createFromFile(file); } } private TextBuffer createFromFile(IFile file) throws CoreException { IDocument document; // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=19319 InputStream stream= file.getContents(); InputStreamReader in= null; try { document= new Document(); in= new InputStreamReader(new BufferedInputStream(stream), ResourcesPlugin.getEncoding()); StringBuffer buffer= new StringBuffer(); char[] readBuffer= new char[2048]; int n= in.read(readBuffer); while (n > 0) { buffer.append(readBuffer, 0, n); n= in.read(readBuffer); } document.set(buffer.toString()); return new TextBuffer(document); } catch (IOException x) { IStatus s= new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), PHPStatusConstants.INTERNAL_ERROR, x.getMessage(), x); throw new CoreException(s); } finally { IOCloser.perform(in, stream); } } public TextBuffer create(String content) { return new TextBuffer(new Document(content)); } public void save(TextBuffer buffer, IProgressMonitor pm) throws CoreException { Value value= (Value)fBufferValueMap.get(buffer); if (value == null) throwNotManaged(); fDocumentProvider.saveDocument(pm, value.input, value.document, true); } public void aboutToChange(TextBuffer buffer) throws CoreException { Value value= (Value)fBufferValueMap.get(buffer); if (value == null) throwNotManaged(); fDocumentProvider.aboutToChange(value.input); } public void changed(TextBuffer buffer) throws CoreException { Value value= (Value)fBufferValueMap.get(buffer); if (value == null) throwNotManaged(); fDocumentProvider.changed(value.input); } private void throwNotManaged() throws CoreException { IStatus s= new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), PHPStatusConstants.INTERNAL_ERROR, TextManipulationMessages.getString("TextBufferFactory.bufferNotManaged"), null); //$NON-NLS-1$ throw new CoreException(s); } }