X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/DocumentAdapter.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/DocumentAdapter.java index 70e1767..85dacc1 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/DocumentAdapter.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/DocumentAdapter.java @@ -13,26 +13,34 @@ package net.sourceforge.phpeclipse.phpeditor; import java.util.ArrayList; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; import net.sourceforge.phpdt.core.BufferChangedEvent; import net.sourceforge.phpdt.core.IBuffer; import net.sourceforge.phpdt.core.IBufferChangedListener; import net.sourceforge.phpdt.core.IOpenable; import net.sourceforge.phpdt.core.JavaModelException; +import net.sourceforge.phpeclipse.PHPeclipsePlugin; +import org.eclipse.core.filebuffers.FileBuffers; +import org.eclipse.core.filebuffers.ITextFileBuffer; +import org.eclipse.core.filebuffers.ITextFileBufferManager; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; 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.NullProgressMonitor; import org.eclipse.jface.text.Assert; import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.DefaultLineTracker; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentListener; -import org.eclipse.jface.text.ILineTracker; -import org.eclipse.jface.text.IRegion; import org.eclipse.swt.widgets.Display; @@ -49,158 +57,125 @@ public class DocumentAdapter implements IBuffer, IDocumentListener { * Internal implementation of a NULL instanceof IBuffer. */ static private class NullBuffer implements IBuffer { - public void addBufferChangedListener(IBufferChangedListener listener) {} - public void append(char[] text) {} - public void append(String text) {} - public void close() {} - - public char getChar(int position) { - return 0; - } - - public char[] getCharacters() { - return null; - } - - public String getContents() { - return null; - } - - public int getLength() { - return 0; - } - - public IOpenable getOwner() { - return null; - } - - public String getText(int offset, int length) { - return null; - } - - public IResource getUnderlyingResource() { - return null; - } - - public boolean hasUnsavedChanges() { - return false; - } - - public boolean isClosed() { - return false; - } - - public boolean isReadOnly() { - return true; - } - + public char getChar(int position) { return 0; } + public char[] getCharacters() { return null; } + public String getContents() { return null; } + public int getLength() { return 0; } + public IOpenable getOwner() { return null; } + public String getText(int offset, int length) { return null; } + public IResource getUnderlyingResource() { return null; } + public boolean hasUnsavedChanges() { return false; } + public boolean isClosed() { return false; } + public boolean isReadOnly() { return true; } public void removeBufferChangedListener(IBufferChangedListener listener) {} - public void replace(int position, int length, char[] text) {} - public void replace(int position, int length, String text) {} - public void save(IProgressMonitor progress, boolean force) throws JavaModelException {} - public void setContents(char[] contents) {} - public void setContents(String contents) {} - }; - - - /** NULL implementing IBuffer */ - public final static IBuffer NULL= new NullBuffer(); - - - /** - * Executes a document set content call in the ui thread. - */ - protected class DocumentSetCommand implements Runnable { - - private String fContents; - - public void run() { - fDocument.set(fContents); } - public void set(String contents) { - fContents= contents; - Display.getDefault().syncExec(this); - } - }; - /** - * Executes a document replace call in the ui thread. - */ - protected class DocumentReplaceCommand implements Runnable { + /** NULL implementing IBuffer */ + public final static IBuffer NULL= new NullBuffer(); + - private int fOffset; - private int fLength; - private String fText; + /** + * Executes a document set content call in the ui thread. + */ + protected class DocumentSetCommand implements Runnable { + + private String fContents; + + public void run() { + fDocument.set(fContents); + } - public void run() { - try { - fDocument.replace(fOffset, fLength, fText); - } catch (BadLocationException x) { - // ignore + public void set(String contents) { + fContents= contents; + Display.getDefault().syncExec(this); } } - public void replace(int offset, int length, String text) { - fOffset= offset; - fLength= length; - fText= text; - Display.getDefault().syncExec(this); + /** + * Executes a document replace call in the ui thread. + */ + protected class DocumentReplaceCommand implements Runnable { + + private int fOffset; + private int fLength; + private String fText; + + public void run() { + try { + fDocument.replace(fOffset, fLength, fText); + } catch (BadLocationException x) { + // ignore + } + } + + public void replace(int offset, int length, String text) { + fOffset= offset; + fLength= length; + fText= text; + Display.getDefault().syncExec(this); + } } - }; + + private static final boolean DEBUG_LINE_DELIMITERS= true; private IOpenable fOwner; + private IFile fFile; + private ITextFileBuffer fTextFileBuffer; private IDocument fDocument; + private DocumentSetCommand fSetCmd= new DocumentSetCommand(); private DocumentReplaceCommand fReplaceCmd= new DocumentReplaceCommand(); - private Object fProviderKey; - private PHPDocumentProvider fProvider; - private String fLineDelimiter; - private ILineTracker fLineTracker; + private Set fLegalLineDelimiters; private List fBufferListeners= new ArrayList(3); - private IStatus fStatus; + /** * This method is public for test purposes only. */ - public DocumentAdapter(IOpenable owner, IDocument document, ILineTracker lineTracker, PHPDocumentProvider provider, Object providerKey) { - - Assert.isNotNull(document); - Assert.isNotNull(lineTracker); + public DocumentAdapter(IOpenable owner, IFile file) { fOwner= owner; - fDocument= document; - fLineTracker= lineTracker; - fProvider= provider; - fProviderKey= providerKey; + fFile= file; - fDocument.addPrenotifiedDocumentListener(this); + initialize(); } - /** - * Sets the status of this document adapter. - */ - public void setStatus(IStatus status) { - fStatus= status; + private void initialize() { + ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager(); + IPath location= fFile.getFullPath(); + try { + manager.connect(location, new NullProgressMonitor()); + fTextFileBuffer= manager.getTextFileBuffer(location); + fDocument= fTextFileBuffer.getDocument(); + } catch (CoreException x) { + fStatus= x.getStatus(); + fDocument= manager.createEmptyDocument(location); + } + fDocument.addPrenotifiedDocumentListener(this); } /** * Returns the status of this document adapter. */ public IStatus getStatus() { - return fStatus; + if (fStatus != null) + return fStatus; + if (fTextFileBuffer != null) + return fTextFileBuffer.getStatus(); + return null; } /** @@ -211,80 +186,7 @@ public class DocumentAdapter implements IBuffer, IDocumentListener { public IDocument getDocument() { return fDocument; } - - /** - * Returns the line delimiter of this buffer. As a document has a set of - * valid line delimiters, this set must be reduced to size 1. - */ - protected String getLineDelimiter() { - - if (fLineDelimiter == null) { - - try { - fLineDelimiter= fDocument.getLineDelimiter(0); - } catch (BadLocationException x) { - } - - if (fLineDelimiter == null) { - /* - * Follow up fix for: 1GF5UU0: ITPJUI:WIN2000 - "Organize Imports" in java editor inserts lines in wrong format - * The line delimiter must always be a legal document line delimiter. - */ - String sysLineDelimiter= System.getProperty("line.separator"); //$NON-NLS-1$ - String[] delimiters= fDocument.getLegalLineDelimiters(); - Assert.isTrue(delimiters.length > 0); - for (int i= 0; i < delimiters.length; i++) { - if (delimiters[i].equals(sysLineDelimiter)) { - fLineDelimiter= sysLineDelimiter; - break; - } - } - - if (fLineDelimiter == null) { - // system line delimiter is not a legal document line delimiter - fLineDelimiter= delimiters[0]; - } - } - } - return fLineDelimiter; - } - - /** - * Converts the given string to the line delimiter of this buffer. - * This method is public for test purposes only. - */ - public String normalize(String text) { - fLineTracker.set(text); - - int lines= fLineTracker.getNumberOfLines(); - if (lines <= 1) - return text; - - StringBuffer buffer= new StringBuffer(text); - - try { - IRegion previous= fLineTracker.getLineInformation(0); - for (int i= 1; i < lines; i++) { - int lastLineEnd= previous.getOffset() + previous.getLength(); - int lineStart= fLineTracker.getLineInformation(i).getOffset(); - fLineTracker.replace(lastLineEnd, lineStart - lastLineEnd, getLineDelimiter()); - buffer.replace(lastLineEnd, lineStart, getLineDelimiter()); - previous= fLineTracker.getLineInformation(i); - } - - // last line - String delimiter= fLineTracker.getLineDelimiter(lines -1); - if (delimiter != null && delimiter.length() > 0) - buffer.replace(previous.getOffset() + previous.getLength(), buffer.length(), getLineDelimiter()); - - return buffer.toString(); - } catch (BadLocationException x) { - } - - return text; - } - /* * @see IBuffer#addBufferChangedListener(IBufferChangedListener) */ @@ -313,7 +215,10 @@ public class DocumentAdapter implements IBuffer, IDocumentListener { * @see IBuffer#append(String) */ public void append(String text) { - fReplaceCmd.replace(fDocument.getLength(), 0, normalize(text)); + if (DEBUG_LINE_DELIMITERS) { + validateLineDelimiters(text); + } + fReplaceCmd.replace(fDocument.getLength(), 0, text); } /* @@ -328,6 +233,16 @@ public class DocumentAdapter implements IBuffer, IDocumentListener { fDocument= null; d.removePrenotifiedDocumentListener(this); + if (fTextFileBuffer != null) { + ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager(); + try { + manager.disconnect(fTextFileBuffer.getLocation(), new NullProgressMonitor()); + } catch (CoreException x) { + // ignore + } + fTextFileBuffer= null; + } + fireBufferChanged(new BufferChangedEvent(this, 0, 0, null)); fBufferListeners.clear(); } @@ -369,7 +284,7 @@ public class DocumentAdapter implements IBuffer, IDocumentListener { * @see IBuffer#getOwner() */ public IOpenable getOwner() { - return (IOpenable) fOwner; + return fOwner; } /* @@ -387,14 +302,14 @@ public class DocumentAdapter implements IBuffer, IDocumentListener { * @see IBuffer#getUnderlyingResource() */ public IResource getUnderlyingResource() { - return fProvider != null ? fProvider.getUnderlyingResource(fProviderKey) : null; + return fFile; } /* * @see IBuffer#hasUnsavedChanges() */ public boolean hasUnsavedChanges() { - return fProvider != null ? fProvider.canSaveDocument(fProviderKey) : false; + return fTextFileBuffer != null ? fTextFileBuffer.isDirty() : false; } /* @@ -423,19 +338,21 @@ public class DocumentAdapter implements IBuffer, IDocumentListener { * @see IBuffer#replace(int, int, String) */ public void replace(int position, int length, String text) { - fReplaceCmd.replace(position, length, normalize(text)); + if (DEBUG_LINE_DELIMITERS) { + validateLineDelimiters(text); + } + fReplaceCmd.replace(position, length, text); } /* * @see IBuffer#save(IProgressMonitor, boolean) */ public void save(IProgressMonitor progress, boolean force) throws JavaModelException { - if (fProvider != null) { - try { - fProvider.saveDocumentContent(progress, fProviderKey, fDocument, force); - } catch (CoreException e) { - throw new JavaModelException(e); - } + try { + if (fTextFileBuffer != null) + fTextFileBuffer.commit(progress, force); + } catch (CoreException e) { + throw new JavaModelException(e); } } @@ -460,14 +377,62 @@ public class DocumentAdapter implements IBuffer, IDocumentListener { } else { // set only if different - String newContents= normalize(contents); - int newLength= newContents.length(); + if (DEBUG_LINE_DELIMITERS) { + validateLineDelimiters(contents); + } - if (oldLength != newLength || !newContents.equals(fDocument.get())) - fSetCmd.set(newContents); + if (!contents.equals(fDocument.get())) + fSetCmd.set(contents); } } + + private void validateLineDelimiters(String contents) { + + if (fLegalLineDelimiters == null) { + // collect all line delimiters in the document + HashSet existingDelimiters= new HashSet(); + + for (int i= fDocument.getNumberOfLines() - 1; i >= 0; i-- ) { + try { + String curr= fDocument.getLineDelimiter(i); + if (curr != null) { + existingDelimiters.add(curr); + } + } catch (BadLocationException e) { + PHPeclipsePlugin.log(e); + } + } + if (existingDelimiters.isEmpty()) { + return; // first insertion of a line delimiter: no test + } + fLegalLineDelimiters= existingDelimiters; + + } + + DefaultLineTracker tracker= new DefaultLineTracker(); + tracker.set(contents); + + int lines= tracker.getNumberOfLines(); + if (lines <= 1) + return; + + for (int i= 0; i < lines; i++) { + try { + String curr= tracker.getLineDelimiter(i); + if (curr != null && !fLegalLineDelimiters.contains(curr)) { + StringBuffer buf= new StringBuffer("New line delimiter added to new code: "); //$NON-NLS-1$ + for (int k= 0; k < curr.length(); k++) { + buf.append(String.valueOf((int) curr.charAt(k))); + } + PHPeclipsePlugin.log(new Exception(buf.toString())); + } + } catch (BadLocationException e) { + PHPeclipsePlugin.log(e); + } + } + } + /* * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent) */