X-Git-Url: http://secure.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 <code>IBuffer</code> */
-	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 <code>IBuffer</code> */
+		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 <code>public</code> 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 <code>public</code> 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)
 	 */