intial source from http://www.sf.net/projects/wdte
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpeclipse / ui / editor / I18NDocumentProvider.java
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/I18NDocumentProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpeclipse/ui/editor/I18NDocumentProvider.java
new file mode 100644 (file)
index 0000000..7aaf2ed
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2002-2004 Widespace, OU and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://solareclipse.sourceforge.net/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     Igor Malinin - initial contribution
+ * 
+ * $Id: I18NDocumentProvider.java,v 1.1 2004-09-02 18:26:30 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.ui.editor;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+
+import org.eclipse.core.resources.IFile;
+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.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IStorageEditorInput;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ContainerGenerator;
+import org.eclipse.ui.editors.text.FileDocumentProvider;
+import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
+
+/**
+ * @author Igor Malinin
+ */
+public class I18NDocumentProvider extends FileDocumentProvider {
+
+       private static final char BOM = 0xFEFF;
+
+       /*
+        * @see org.eclipse.ui.editors.text.StorageDocumentProvider#setDocumentContent(IDocument,
+        *      InputStream, String)
+        */
+       protected void setDocumentContent(IDocument document,
+                       InputStream contentStream, String encoding) throws CoreException {
+               Reader in = null;
+
+               try {
+                       if (encoding == null) {
+                               encoding = getDefaultEncoding();
+                       }
+
+                       in = new InputStreamReader(contentStream, encoding);
+
+                       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);
+                       }
+
+                       if (buffer.length() > 0 && buffer.charAt(0) == BOM) {
+                               buffer.deleteCharAt(0);
+                       }
+
+                       document.set(buffer.toString());
+               } catch (IOException x) {
+                       String msg = x.getMessage();
+                       if (msg == null) {
+                               msg = ""; //$NON-NLS-1$
+                       }
+
+                       IStatus s = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID,
+                                       IStatus.OK, msg, x);
+
+                       throw new CoreException(s);
+               } finally {
+                       if (in != null) try {
+                               in.close();
+                       } catch (IOException x) {
+                       }
+               }
+       }
+
+       /*
+        * @see org.eclipse.ui.texteditor.AbstractDocumentProvider#doSaveDocument(IProgressMonitor,
+        *      Object, IDocument, boolean)
+        */
+       protected void doSaveDocument(IProgressMonitor monitor, Object element,
+                       IDocument document, boolean overwrite) throws CoreException {
+               if (!(element instanceof IFileEditorInput)) {
+                       super.doSaveDocument(monitor, element, document, overwrite);
+                       return;
+               }
+
+               IFileEditorInput input = (IFileEditorInput) element;
+
+               try {
+                       String content = document.get();
+
+                       String encoding = getDeclaredEncoding(new ByteArrayInputStream(
+                                       content.getBytes("ISO-8859-1")));
+
+                       if (encoding == null) {
+                               encoding = super.getEncoding(element);
+                               if (encoding == null /* || !encoding.startsWith("UTF-16") */) {
+                                       encoding = getDefaultEncoding();
+                               }
+                       } else {
+                               setEncoding(element, encoding);
+                       }
+
+                       if (encoding.startsWith("UTF-16")) {
+                               content = BOM + content;
+                       }
+
+                       InputStream stream;
+                       try {
+                               stream = new ByteArrayInputStream(content.getBytes(encoding));
+                       } catch (UnsupportedEncodingException e) {
+                               IStatus s = new Status(
+                                               IStatus.ERROR,
+                                               PlatformUI.PLUGIN_ID,
+                                               IStatus.OK,
+                                               EditorMessages
+                                                               .getString("I18NDocumentProvider.error.encoding"),
+                                               e);
+
+                               throw new CoreException(s);
+                       }
+
+                       IFile file = input.getFile();
+                       if (file.exists()) {
+                               FileInfo info = (FileInfo) getElementInfo(element);
+
+                               if (info != null && !overwrite) {
+                                       checkSynchronizationState(info.fModificationStamp, file);
+                               }
+
+                               // inform about the upcoming content change
+                               fireElementStateChanging(element);
+
+                               try {
+                                       file.setContents(stream, overwrite, true, monitor);
+                               } catch (CoreException x) {
+                                       // inform about failure
+                                       fireElementStateChangeFailed(element);
+                                       throw x;
+                               } catch (RuntimeException x) {
+                                       // inform about failure
+                                       fireElementStateChangeFailed(element);
+                                       throw x;
+                               }
+
+                               // If here, the editor state will be flipped to "not dirty".
+                               // Thus, the state changing flag will be reset.
+
+                               if (info != null) {
+                                       ResourceMarkerAnnotationModel model = (ResourceMarkerAnnotationModel) info.fModel;
+
+                                       model.updateMarkers(info.fDocument);
+
+                                       info.fModificationStamp = computeModificationStamp(file);
+                               }
+                       } else {
+                               try {
+                                       monitor.beginTask(EditorMessages
+                                                       .getString("I18NDocumentProvider.task.saving"), //$NON-NLS-1$
+                                                       2000);
+
+                                       ContainerGenerator generator = new ContainerGenerator(file
+                                                       .getParent().getFullPath());
+
+                                       generator.generateContainer(new SubProgressMonitor(monitor,
+                                                       1000));
+
+                                       file.create(stream, false, new SubProgressMonitor(monitor,
+                                                       1000));
+                               } finally {
+                                       monitor.done();
+                               }
+                       }
+               } catch (IOException x) {
+                       IStatus s = new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID,
+                                       IStatus.OK, x.getMessage(), x);
+
+                       throw new CoreException(s);
+               }
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#getEncoding(Object)
+        */
+       public String getEncoding(Object element) {
+               String encoding = super.getEncoding(element);
+               if (encoding != null) {
+                       return encoding;
+               }
+
+               if (element instanceof IStorageEditorInput) {
+                       IStorageEditorInput sei = (IStorageEditorInput) element;
+
+                       try {
+                               InputStream in = sei.getStorage().getContents();
+                               try {
+                                       encoding = getDeclaredEncoding(in);
+                               } finally {
+                                       in.close();
+                               }
+                       } catch (CoreException e) {
+                       } catch (IOException e) {
+                       }
+
+                       if (encoding == null) {
+                               encoding = getDefaultEncoding();
+                       }
+
+                       setEncoding(element, encoding);
+               }
+
+               return encoding;
+       }
+
+       /*
+        * @see org.eclipse.ui.editors.text.IStorageDocumentProvider#setEncoding(Object,
+        *      String)
+        */
+       public void setEncoding(Object element, String encoding) {
+               if (encoding == null) {
+                       encoding = getDefaultEncoding();
+               }
+
+               super.setEncoding(element, encoding);
+       }
+
+       /**
+        * Tries to determine encoding from contents of the stream. Returns <code>null</code>
+        * if encoding is unknown.
+        */
+       public String getDeclaredEncoding(InputStream in) throws IOException {
+               return getBOMEncoding(in);
+       }
+
+       /**
+        * Tries to determine encoding from the byte order mark. Returns <code>null</code>
+        * if encoding is unknown.
+        */
+       private String getBOMEncoding(InputStream in) throws IOException {
+               int first = in.read();
+               if (first < 0) {
+                       return null;
+               }
+
+               int second = in.read();
+               if (second < 0) {
+                       return null;
+               }
+
+               // look for the UTF-16 Byte Order Mark (BOM)
+               if (first == 0xFE && second == 0xFF) {
+                       return "UTF-16BE";
+               }
+
+               if (first == 0xFF && second == 0xFE) {
+                       return "UTF-16LE";
+               }
+
+               int third = in.read();
+               if (third < 0) {
+                       return null;
+               }
+
+               // look for the UTF-8 BOM
+               if (first == 0xEF && second == 0xBB && third == 0xBF) {
+                       return "UTF-8";
+               }
+
+               return null;
+       }
+}