first version of 'Code Assist" template engine
authorkhartlage <khartlage>
Sun, 8 Dec 2002 22:48:54 +0000 (22:48 +0000)
committerkhartlage <khartlage>
Sun, 8 Dec 2002 22:48:54 +0000 (22:48 +0000)
56 files changed:
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextType.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextTypeRegistry.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/DocumentTemplateContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ITemplateEditor.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/SimpleTemplateVariable.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Template.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateBuffer.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplatePosition.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateSet.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateTranslator.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateVariable.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Templates.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/default-templates.xml [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContext.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContextType.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/GlobalVariables.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaContextType.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaDocContextType.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/Messages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MoveTextEdit.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MultiTextEdit.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/NopTextEdit.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SimpleTextEdit.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SwapTextEdit.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBuffer.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferEditor.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferFactory.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEdit.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNodeComparator.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRange.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRegion.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/UndoMemento.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/IOCloser.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/Strings.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaStatusConstants.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIException.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.properties [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIStatus.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/IJavaCompletionProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProcessor_NotInUseVersion.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProposalComparator.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateContentProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateEngine.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateLabelProvider.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProcessor.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProposal.java [new file with mode: 0644]
net.sourceforge.phpeclipse/src/net/sourceforge/phpeclipse/phpeditor/php/PHPCompletionProcessor.java

diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextType.java
new file mode 100644 (file)
index 0000000..c6c96e3
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+import net.sourceforge.phpdt.internal.corext.textmanipulation.MultiTextEdit;
+import net.sourceforge.phpdt.internal.corext.textmanipulation.NopTextEdit;
+import net.sourceforge.phpdt.internal.corext.textmanipulation.SimpleTextEdit;
+import net.sourceforge.phpdt.internal.corext.textmanipulation.TextBuffer;
+import net.sourceforge.phpdt.internal.corext.textmanipulation.TextBufferEditor;
+import net.sourceforge.phpdt.internal.corext.textmanipulation.TextEdit;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * A context type is a context factory.
+ */
+public abstract class ContextType implements ITemplateEditor {
+
+  /** name of the context type */
+  private final String fName;
+
+  /** variables used by this content type */
+  private final Map fVariables = new HashMap();
+
+  /**
+   * Creates a context type with a name.
+   * 
+   * @param name the name of the context. It has to be unique wrt to other context names.
+   */
+  public ContextType(String name) {
+    fName = name;
+  }
+
+  /**
+   * Returns the name of the context type.
+   */
+  public String getName() {
+    return fName;
+  }
+
+  /**
+   * Adds a template variable to the context type.
+   */
+  public void addVariable(TemplateVariable variable) {
+    fVariables.put(variable.getName(), variable);
+  }
+
+  /**
+   * Removes a template variable from the context type.
+   */
+  public void removeVariable(TemplateVariable variable) {
+    fVariables.remove(variable.getName());
+  }
+
+  /**
+   * Removes all template variables from the context type.
+   */
+  public void removeAllVariables() {
+    fVariables.clear();
+  }
+
+  /**
+   * Returns an iterator for the variables known to the context type.
+   */
+  public Iterator variableIterator() {
+    return fVariables.values().iterator();
+  }
+
+  /**
+   * Creates a template context.
+   */
+  public abstract TemplateContext createContext();
+
+  /*
+   * @see ITemplateEditor#edit(TemplateBuffer)
+   */
+  public void edit(TemplateBuffer templateBuffer, TemplateContext context) throws CoreException {
+    TextBuffer textBuffer = TextBuffer.create(templateBuffer.getString());
+    TemplatePosition[] variables = templateBuffer.getVariables();
+
+    MultiTextEdit positions = variablesToPositions(variables);
+    MultiTextEdit multiEdit = new MultiTextEdit();
+
+    // iterate over all variables and try to resolve them
+    for (int i = 0; i != variables.length; i++) {
+      TemplatePosition variable = variables[i];
+
+      if (variable.isResolved())
+        continue;
+
+      String name = variable.getName();
+      int[] offsets = variable.getOffsets();
+      int length = variable.getLength();
+
+      TemplateVariable evaluator = (TemplateVariable) fVariables.get(name);
+      String value = (evaluator == null) ? null : evaluator.evaluate(context);
+
+      if (value == null)
+        continue;
+
+      variable.setLength(value.length());
+      variable.setResolved(evaluator.isResolved(context));
+
+      for (int k = 0; k != offsets.length; k++)
+        multiEdit.add(SimpleTextEdit.createReplace(offsets[k], length, value));
+    }
+
+    TextBufferEditor editor = new TextBufferEditor(textBuffer);
+    editor.add(positions);
+    editor.add(multiEdit);
+    editor.performEdits(null);
+
+    positionsToVariables(positions, variables);
+
+    templateBuffer.setContent(textBuffer.getContent(), variables);
+  }
+
+  private static MultiTextEdit variablesToPositions(TemplatePosition[] variables) {
+    MultiTextEdit positions = new MultiTextEdit();
+    for (int i = 0; i != variables.length; i++) {
+      int[] offsets = variables[i].getOffsets();
+      for (int j = 0; j != offsets.length; j++)
+        positions.add(new NopTextEdit(offsets[j], 0));
+    }
+
+    return positions;
+  }
+
+  private static void positionsToVariables(MultiTextEdit positions, TemplatePosition[] variables) {
+    Iterator iterator = positions.iterator();
+
+    for (int i = 0; i != variables.length; i++) {
+      TemplatePosition variable = variables[i];
+
+      int[] offsets = new int[variable.getOffsets().length];
+      for (int j = 0; j != offsets.length; j++)
+        offsets[j] = ((TextEdit) iterator.next()).getTextRange().getOffset();
+
+      variable.setOffsets(offsets);
+    }
+  }
+
+  /**
+   * Returns the templates associated with this context type.
+   */
+  public Template[] getTemplates() {
+    Template[] templates = Templates.getInstance().getTemplates();
+
+    Vector vector = new Vector();
+    for (int i = 0; i != templates.length; i++)
+      if (templates[i].getContextTypeName().equals(fName))
+        vector.add(templates[i]);
+
+    return (Template[]) vector.toArray(new Template[vector.size()]);
+  }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextTypeRegistry.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ContextTypeRegistry.java
new file mode 100644 (file)
index 0000000..8247bdc
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.sourceforge.phpdt.internal.corext.template.java.JavaContextType;
+import net.sourceforge.phpdt.internal.corext.template.java.JavaDocContextType;
+
+
+
+/**
+ * A singleton to keep track of all known context types.
+ */
+public class ContextTypeRegistry {
+
+       /** the singleton */
+       private static ContextTypeRegistry fInstance;
+       
+       /** all known context types */
+       private final Map fContextTypes= new HashMap();
+       
+       /**
+        * Returns the single instance of this class.
+        */
+       public static ContextTypeRegistry getInstance() {
+               if (fInstance == null)
+                       fInstance= new ContextTypeRegistry();
+                       
+               return fInstance;       
+       }
+
+       /**
+        * Adds a context type to the registry.
+        */     
+       public void add(ContextType contextType) {
+               fContextTypes.put(contextType.getName(), contextType);
+       }
+       
+       /**
+        * Removes a context type from the registry.
+        */
+       public void remove(ContextType contextType) {
+               fContextTypes.remove(contextType.getName());
+       }
+
+       /**
+        * Returns the context type if the name is valid, <code>null</code> otherwise.
+        */
+       public ContextType getContextType(String name) {
+               return (ContextType) fContextTypes.get(name);
+       }
+       
+       /**
+        * Returns an iterator over the registered context type names.
+        */
+       public Iterator iterator() {
+               return fContextTypes.keySet().iterator();       
+       }
+
+       // XXX bootstrap with java and javadoc context types
+       private ContextTypeRegistry() {
+               add(new JavaContextType());
+               add(new JavaDocContextType());
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/DocumentTemplateContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/DocumentTemplateContext.java
new file mode 100644 (file)
index 0000000..e89d632
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+//import org.eclipse.jdt.internal.corext.Assert;
+
+/**
+ * A typical text based document template context.
+ */
+public abstract class DocumentTemplateContext extends TemplateContext {
+
+       /** The text of the document. */
+       private final IDocument fDocument;
+       /** The completion position. */
+       private final int fCompletionPosition;
+
+       /**
+        * Creates a document template context.
+        */
+       protected DocumentTemplateContext(ContextType type, IDocument document, int completionPosition) {
+               super(type);
+               
+//             Assert.isNotNull(document);
+//             Assert.isTrue(completionPosition >= 0 && completionPosition <= document.getLength());
+               
+               fDocument= document;
+               fCompletionPosition= completionPosition;
+       }
+       
+       public IDocument getDocument() {
+               return fDocument;       
+       }
+       
+       /**
+        * Returns the string of the context.
+        */
+//     public String getString() {
+//             return fDocument.get();
+//     }
+       
+       /**
+        * Returns the completion position within the string of the context.
+        */
+       public int getCompletionPosition() {
+               return fCompletionPosition;     
+       }
+       
+       /**
+        * Returns the keyword which triggered template insertion.
+        */
+       public String getKey() {
+               int offset= getStart();
+               int length= getEnd() - offset;
+               try {
+                       return fDocument.get(offset, length);
+               } catch (BadLocationException e) {
+                       return ""; //$NON-NLS-1$        
+               }
+       }
+
+       /**
+        * Returns the beginning offset of the keyword.
+        */
+       public int getStart() {
+               return fCompletionPosition;             
+       }
+       
+       /**
+        * Returns the end offset of the keyword.
+        */
+       public int getEnd() {
+               return fCompletionPosition;
+       }
+               
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ITemplateEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/ITemplateEditor.java
new file mode 100644 (file)
index 0000000..2698b77
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * A template editor implements an action to edit a template buffer in its context.
+ */
+public interface ITemplateEditor {
+
+       /**
+        * Modifies a template buffer.
+        * 
+        * @param buffer the template buffer
+        * @param context the template context
+        * @throws CoreException if the buffer cannot be successfully modified
+        */
+       void edit(TemplateBuffer buffer, TemplateContext context) throws CoreException;
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/SimpleTemplateVariable.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/SimpleTemplateVariable.java
new file mode 100644 (file)
index 0000000..62b4a7a
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+/**
+ * A simple template variable, which always evaluates to a defined string.
+ */
+public class SimpleTemplateVariable extends TemplateVariable {
+
+       /** The string to which this variable evaluates. */
+       private String fEvaluationString;
+       /** A flag indicating if this variable can be resolved. */
+       private boolean fResolved;
+
+       /*
+        * @see TemplateVariable#TemplateVariable(String, String)
+        */
+       protected SimpleTemplateVariable(String name, String description) {
+               super(name, description);
+       }
+
+       /**
+        * Sets the string to which this variable evaluates.
+        * 
+        * @param evaluationString the evaluation string, may be <code>null</code>.
+        */
+       public final void setEvaluationString(String evaluationString) {
+               fEvaluationString= evaluationString;    
+       }
+
+       /*
+        * @see TemplateVariable#evaluate(TemplateContext)
+        */
+       public String evaluate(TemplateContext context) {
+               return fEvaluationString;
+       }
+
+       /**
+        * Sets the resolved flag.
+        */
+       public final void setResolved(boolean resolved) {
+               fResolved= resolved;
+       }
+
+       /*
+        * @see TemplateVariable#isResolved(TemplateContext)
+        */
+       public boolean isResolved(TemplateContext context) {
+               return fResolved;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Template.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Template.java
new file mode 100644 (file)
index 0000000..2ae617c
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+/**
+ * A template consiting of a name and a pattern.
+ */
+public class Template {
+
+       /** The name of this template */
+       private String fName;
+       /** A description of this template */
+       private String fDescription;
+       /** The name of the context type of this template */
+       private String fContextTypeName;
+       /** The template pattern. */
+       private String fPattern;
+       /** A flag indicating if the template is active or not. */
+       private boolean fEnabled= true;
+
+       /**
+        * Creates an empty template.
+        */
+       public Template() {
+               this("", "", "", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+       }
+       
+       /**
+        * Creates a copy of a template.
+        */
+       public Template(Template template) {
+               this(template.getName(), template.getDescription(), template.getContextTypeName(), template.getPattern());      
+       }
+
+       /**
+        * Creates a template.
+        * 
+        * @param name the name of the template.
+        * @param description the description of the template.
+        * @param contextTypeName the name of the context type in which the template can be applied.
+        * @param pattern the template pattern.
+        */             
+       public Template(String name, String description, String contextTypeName, String pattern) {
+               fName= name;
+               fDescription= description;
+               fContextTypeName= contextTypeName;
+               fPattern= pattern;
+       }
+       
+       /*
+        * @see Object#equals(Object)
+        */
+       public boolean equals(Object object) {
+               if (!(object instanceof Template))
+                       return false;
+                       
+               Template template= (Template) object;
+
+               if (template == this)
+                       return true;            
+
+               return
+                       template.fName.equals(fName) &&
+                       template.fPattern.equals(fPattern) &&
+                       template.fContextTypeName.equals(fContextTypeName);
+       }
+       
+       /*
+        * @see Object#hashCode()
+        */
+       public int hashCode() {
+               return fName.hashCode() ^ fPattern.hashCode() ^ fContextTypeName.hashCode();
+       }
+
+       /**
+        * Sets the description of the template.
+        */
+       public void setDescription(String description) {
+               fDescription= description;
+       }
+       
+       /**
+        * Returns the description of the template.
+        */
+       public String getDescription() {
+               return fDescription;
+       }
+       
+       /**
+        * Sets the name of the context type in which the template can be applied.
+        */
+       public void setContext(String contextTypeName) {
+               fContextTypeName= contextTypeName;
+       }
+       
+       /**
+        * Returns the name of the context type in which the template can be applied.
+        */
+       public String getContextTypeName() {
+               return fContextTypeName;
+       }
+
+       /**
+        * Sets the name of the template.
+        */
+       public void setName(String name) {
+               fName= name;
+       }
+                       
+       /**
+        * Returns the name of the template.
+        */
+       public String getName() {
+               return fName;
+       }
+
+       /**
+        * Sets the pattern of the template.
+        */
+       public void setPattern(String pattern) {
+               fPattern= pattern;
+       }
+               
+       /**
+        * Returns the template pattern.
+        */
+       public String getPattern() {
+               return fPattern;
+       }
+       
+       /**
+        * Sets the enable state of the template.
+        */
+       public void setEnabled(boolean enable) {
+               fEnabled= enable;       
+       }
+       
+       /**
+        * Returns <code>true</code> if template is enabled, <code>false</code> otherwise.
+        */
+       public boolean isEnabled() {
+               return fEnabled;        
+       }
+       
+       /**
+        * Returns <code>true</code> if template matches the prefix and context,
+        * <code>false</code> otherwise.
+        */
+       public boolean matches(String prefix, String contextTypeName) {
+               return 
+                       fEnabled &&
+                       fContextTypeName.equals(contextTypeName) &&
+                       (prefix.length() != 0) &&
+                       fName.toLowerCase().startsWith(prefix.toLowerCase());
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateBuffer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateBuffer.java
new file mode 100644 (file)
index 0000000..9783027
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+import org.eclipse.core.runtime.CoreException;
+
+//import org.eclipse.jdt.internal.corext.Assert;
+
+/**
+ * A template buffer is a container for a string and variables.
+ */
+public final class TemplateBuffer {
+       
+       /** The string of the template buffer */ 
+       private String fString;
+       /** The variable positions of the template buffer */
+       private TemplatePosition[] fVariables;
+       
+       /**
+        * Creates a template buffer.
+        * 
+        * @param string the string
+        * @param variables the variable positions
+        * @throws CoreException for illegal variable positions
+        */
+    public TemplateBuffer(String string, TemplatePosition[] variables) throws CoreException {
+               setContent(string, variables);
+    }
+
+       /**
+        * Sets the content of the template buffer.
+        * 
+        * @param string the string
+        * @param variables the variable positions
+        * @throws CoreException for illegal variable positions
+        */
+       public final void setContent(String string, TemplatePosition[] variables) throws CoreException {
+       //      Assert.isNotNull(string);
+       //      Assert.isNotNull(variables);
+
+               // XXX assert non-overlapping variable properties
+
+               fString= string;
+               fVariables= variables;
+       }
+
+       /**
+        * Returns the string of the template buffer.
+        */
+       public final String getString() {
+               return fString;
+       }
+       
+       /**
+        * Returns the variable positions of the template buffer.
+        */
+       public final TemplatePosition[] getVariables() {
+               return fVariables;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateContext.java
new file mode 100644 (file)
index 0000000..b4ca23d
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * A template context. A template context is associated with a context type.
+ */
+public abstract class TemplateContext {
+
+       /** context type of this context */
+       private final ContextType fContextType;
+
+       /**
+        * Creates a template context of a particular context type.
+        */
+       protected TemplateContext(ContextType contextType) {
+               fContextType= contextType;
+       }
+
+       /**
+        * Returns the context type of this context.
+        */
+       public ContextType getContextType() {
+               return fContextType;   
+       }
+
+       /**
+        * Evaluates the template and returns a template buffer.
+        */
+       public abstract TemplateBuffer evaluate(Template template) throws CoreException;
+       
+       /**
+        * Tests if the specified template can be evaluated in this context.
+        */
+       public abstract boolean canEvaluate(Template template);
+       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.java
new file mode 100644 (file)
index 0000000..9ed4fca
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class TemplateMessages {
+
+       private static final String RESOURCE_BUNDLE= TemplateMessages.class.getName();
+       private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+       private TemplateMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+       
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key   the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */     
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateMessages.properties
new file mode 100644 (file)
index 0000000..3c085d0
--- /dev/null
@@ -0,0 +1,94 @@
+#########################################
+# (c) Copyright IBM Corp. 2000, 2001.
+# All Rights Reserved.
+#########################################
+
+# preference page
+TemplatePreferencePage.error.import=Failed to import templates.
+TemplatePreferencePage.error.export=Failed to export templates.
+TemplatePreferencePage.error.read.title=Reading Templates
+TemplatePreferencePage.error.write.title=Reading Templates
+TemplatePreferencePage.message=&Create, edit or remove templates:
+TemplatePreferencePage.title=Templates
+
+TemplatePreferencePage.new=&New...
+TemplatePreferencePage.edit=&Edit...
+TemplatePreferencePage.import=&Import...
+TemplatePreferencePage.export=E&xport...
+TemplatePreferencePage.export.all=Ex&port All...
+TemplatePreferencePage.remove=&Remove
+TemplatePreferencePage.enable.all=Ena&ble All
+TemplatePreferencePage.disable.all=Di&sable All
+TemplatePreferencePage.editor=Template
+
+TemplatePreferencePage.column.name=Name
+TemplatePreferencePage.column.context=Context
+TemplatePreferencePage.column.description=Description
+
+TemplatePreferencePage.use.code.formatter=Use Code &Formatter
+
+TemplatePreferencePage.import.title=Importing Templates
+TemplatePreferencePage.import.extension=*.xml
+
+TemplatePreferencePage.export.title=Exporting {0} Templates
+TemplatePreferencePage.export.filename=templates.xml
+TemplatePreferencePage.export.extension=*.xml
+
+TemplatePreferencePage.export.exists.title=Exporting Templates
+TemplatePreferencePage.export.exists.message={0} already exists.\nDo you want to replace it?
+
+TemplatePreferencePage.question.create.new.title=Edit Template
+TemplatePreferencePage.question.create.new.message=The name of the template was changed.\nDo you want to create a new template?
+
+TemplatePreferencePage.preview=Preview:
+
+# edit template dialog
+EditTemplateDialog.error.noname=Template name must not be empty.
+EditTemplateDialog.error.adjacent.variables=Template pattern has adjacent variables.
+EditTemplateDialog.title.new=New Template
+EditTemplateDialog.title.edit=Edit Template
+
+EditTemplateDialog.name=&Name:
+EditTemplateDialog.description=&Description:
+EditTemplateDialog.context=&Context:
+EditTemplateDialog.pattern=&Pattern:
+EditTemplateDialog.insert.variable=Insert &Variable...
+
+EditTemplateDialog.undo=&Undo@Ctrl+Z
+EditTemplateDialog.cut=Cu&t@Ctrl+X
+EditTemplateDialog.copy=&Copy@Ctrl+C
+EditTemplateDialog.paste=&Paste@Ctrl+V
+EditTemplateDialog.select.all=Select &All@Ctrl+A
+EditTemplateDialog.content.assist=Insert &Variable...@Ctrl+Space
+
+# template variable dialog
+TemplateVariableDialog.title=Select a template variable.
+TemplateVariableDialog.column.name=Name
+TemplateVariableDialog.column.description=Description
+TemplateVariableDialog.insert=&Insert
+
+TemplateVariableProposal.error.title=Error applying template variable proposal
+TemplateVariableProcessor.error.title=Error creating template variable proposals
+
+# template set
+TemplateSet.error.read=Error occurred while reading templates.
+TemplateSet.error.write=Error occurred while writing templates.
+
+# templates
+Templates.error.title=Error accessing templates.
+Templates.error.read=Error occurred while reading templates.
+Templates.error.write=Error occurred while writing templates.
+
+# template engine
+TemplateEngine.error.title=Could not create template proposals.
+
+# template proposal
+TemplateProposal.delimiter=\ - 
+
+# template evaluator
+TemplateEvaluator.error.title=Template Evaluation Error
+
+# template translator
+TemplateTranslator.error.incomplete.variable=Template has incomplete variables.
+TemplateTranslator.error.invalid.identifier=Template has invalid variable identifiers.
+TemplateSet.error.missing.attribute=Missing required attribute
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplatePosition.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplatePosition.java
new file mode 100644 (file)
index 0000000..9acc561
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+/**
+ * 
+ */
+public class TemplatePosition {
+
+       /** The name of the template position */
+       private final String fName;
+       /** The default value of the template position */
+       private final String fDefaultValue;
+
+       /** The length of the template positions. */
+       private int fLength;
+       /** The offsets of the template positions. */
+       private int[] fOffsets;
+       /** A flag indicating if the template position has been resolved. */
+       private boolean fResolved;
+       
+       /**
+        * Creates a template position.
+        * 
+        * @param name the name of the template position.
+        * @param defaultValue the default value of the position.
+        * @param offsets the array of offsets of the position.
+        * @param the length of the position.
+        */
+       public TemplatePosition(String name, String defaultValue, int[] offsets, int length) {
+               fName= name;
+               fDefaultValue= defaultValue;
+               fOffsets= offsets;
+               fLength= length;
+               fResolved= false;
+       }
+
+       /**
+        * Returns the name of the position.
+        */
+       public String getName() {
+           return fName;
+       }       
+
+       /**
+        * Returns the default value of the position.
+        */
+       public String getDefaultValue() {
+               return fDefaultValue;
+       }
+       
+       /**
+        * Sets the length of the position.
+        */
+       public void setLength(int length) {
+           fLength= length;
+       }
+       
+       /**
+        * Returns the length of the position.
+        */
+       public int getLength() {
+               return fLength;   
+       }
+       
+       /**
+        * Sets the offsets of the position.
+        */
+       public void setOffsets(int[] offsets) {
+               fOffsets= offsets; 
+       }
+       
+       /**
+        * Returns the offsets of the position.
+        */
+       public int[] getOffsets() {
+               return fOffsets;   
+       }
+       
+       /**
+        * Sets the resolved flag of the position.
+        */
+       public void setResolved(boolean resolved) {
+           fResolved= resolved;
+       }       
+
+       /**
+        * Returns <code>true</code> if the position is resolved, <code>false</code> otherwise.
+        */     
+       public boolean isResolved() {
+               return fResolved;   
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateSet.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateSet.java
new file mode 100644 (file)
index 0000000..d7de172
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.apache.xml.serialize.OutputFormat;
+import org.apache.xml.serialize.Serializer;
+import org.apache.xml.serialize.SerializerFactory;
+import org.eclipse.core.runtime.CoreException;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+//import org.eclipse.jdt.internal.ui.JavaUIStatus;
+//import org.eclipse.jdt.internal.ui.JavaUIException;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+/**
+ * <code>TemplateSet</code> manages a collection of templates and makes them
+ * persistent.
+ */
+public class TemplateSet {
+       
+       private static class TemplateComparator implements Comparator {
+               public int compare(Object arg0, Object arg1) {
+                       if (arg0 == arg1)
+                               return 0;
+                       
+                       if (arg0 == null)
+                               return -1;
+                               
+                       Template template0= (Template) arg0;
+                       Template template1= (Template) arg1;
+                       
+                       return template0.getName().compareTo(template1.getName());
+               }
+       }
+
+       private static final String TEMPLATE_TAG= "template"; //$NON-NLS-1$
+       private static final String NAME_ATTRIBUTE= "name"; //$NON-NLS-1$
+       private static final String DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$
+       private static final String CONTEXT_ATTRIBUTE= "context"; //$NON-NLS-1$
+       private static final String ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$
+
+       private List fTemplates= new ArrayList();
+       private Comparator fTemplateComparator= new TemplateComparator();
+       private Template[] fSortedTemplates= new Template[0];
+       
+       /**
+        * Convenience method for reading templates from a file.
+        * 
+        * @see #addFromStream(InputStream)
+        */
+       public void addFromFile(File file) throws CoreException {
+               InputStream stream= null;
+
+               try {
+                       stream= new FileInputStream(file);
+                       addFromStream(stream);
+
+               } catch (IOException e) {
+                       throwReadException(e);
+
+               } finally {
+                       try {
+                               if (stream != null)
+                                       stream.close();
+                       } catch (IOException e) {}
+               }               
+       }
+
+       /**
+        * Reads templates from a XML stream and adds them to the template set.
+        */     
+       public void addFromStream(InputStream stream) throws CoreException {
+               try {
+                       DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+                       DocumentBuilder parser= factory.newDocumentBuilder();           
+                       Document document= parser.parse(new InputSource(stream));
+                       NodeList elements= document.getElementsByTagName(TEMPLATE_TAG);
+                       
+                       int count= elements.getLength();
+                       for (int i= 0; i != count; i++) {
+                               Node node= elements.item(i);                                    
+                               NamedNodeMap attributes= node.getAttributes();
+
+                               if (attributes == null)
+                                       continue;
+
+                               String name= getAttributeValue(attributes, NAME_ATTRIBUTE);
+                               String description= getAttributeValue(attributes, DESCRIPTION_ATTRIBUTE);
+                               String context= getAttributeValue(attributes, CONTEXT_ATTRIBUTE);
+                               Node enabledNode= attributes.getNamedItem(ENABLED_ATTRIBUTE);
+
+                               if (name == null || description == null || context == null)
+                                       throw new SAXException(TemplateMessages.getString("TemplateSet.error.missing.attribute")); //$NON-NLS-1$
+
+                               boolean enabled= (enabledNode == null) || (enabledNode.getNodeValue().equals("true")); //$NON-NLS-1$
+
+                               StringBuffer buffer= new StringBuffer();
+                               NodeList children= node.getChildNodes();
+                               for (int j= 0; j != children.getLength(); j++) {
+                                       String value= children.item(j).getNodeValue();
+                                       if (value != null)
+                                               buffer.append(value);
+                               }
+                               String pattern= buffer.toString().trim();
+
+                               Template template= new Template(name, description, context, pattern);   
+                               template.setEnabled(enabled);
+                               add(template);
+                       }
+       
+                       sort();
+
+               } catch (ParserConfigurationException e) {
+                       throwReadException(e);
+               } catch (IOException e) {
+                       throwReadException(e);
+               } catch (SAXException e) {
+                       throwReadException(e);
+               }
+       }
+       
+       private String getAttributeValue(NamedNodeMap attributes, String name) {
+               Node node= attributes.getNamedItem(name);
+
+               return node == null
+                       ? null
+                       : node.getNodeValue();
+       }
+
+       /**
+        * Convenience method for saving to a file.
+        * 
+        * @see #saveToStream(OutputStream)
+        */
+       public void saveToFile(File file) throws CoreException {
+               OutputStream stream= null;
+
+               try {
+                       stream= new FileOutputStream(file);
+                       saveToStream(stream);
+
+               } catch (IOException e) {
+                       throwWriteException(e);
+
+               } finally {
+                       try {
+                               if (stream != null)
+                                       stream.close();
+                       } catch (IOException e) {}
+               }
+       }
+               
+       /**
+        * Saves the template set as XML.
+        */
+       public void saveToStream(OutputStream stream) throws CoreException {
+               try {
+                       DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+                       DocumentBuilder builder= factory.newDocumentBuilder();          
+                       Document document= builder.newDocument();
+
+                       Node root= document.createElement("templates"); // $NON-NLS-1$ //$NON-NLS-1$
+                       document.appendChild(root);
+                       
+                       for (int i= 0; i != fTemplates.size(); i++) {
+                               Template template= (Template) fTemplates.get(i);
+                               
+                               Node node= document.createElement("template"); // $NON-NLS-1$ //$NON-NLS-1$
+                               root.appendChild(node);
+                               
+                               NamedNodeMap attributes= node.getAttributes();
+                               
+                               Attr name= document.createAttribute(NAME_ATTRIBUTE);
+                               name.setValue(template.getName());
+                               attributes.setNamedItem(name);
+       
+                               Attr description= document.createAttribute(DESCRIPTION_ATTRIBUTE);
+                               description.setValue(template.getDescription());
+                               attributes.setNamedItem(description);
+       
+                               Attr context= document.createAttribute(CONTEXT_ATTRIBUTE);
+                               context.setValue(template.getContextTypeName());
+                               attributes.setNamedItem(context);                       
+
+                               Attr enabled= document.createAttribute(ENABLED_ATTRIBUTE);
+                               enabled.setValue(template.isEnabled() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
+                               attributes.setNamedItem(enabled);
+                               
+                               Text pattern= document.createTextNode(template.getPattern());
+                               node.appendChild(pattern);                      
+                       }               
+                       
+                       OutputFormat format = new OutputFormat();
+                       format.setPreserveSpace(true);
+                       Serializer serializer = SerializerFactory.getSerializerFactory("xml").makeSerializer(stream, format); //$NON-NLS-1$
+                       serializer.asDOMSerializer().serialize(document);
+
+               } catch (ParserConfigurationException e) {
+                       throwWriteException(e);
+               } catch (IOException e) {
+                       throwWriteException(e);
+               }               
+       }
+
+       private static void throwReadException(Throwable t) throws CoreException {
+    PHPeclipsePlugin.log(t);
+//             IStatus status= new JavaUIStatus(JavaStatusConstants.TEMPLATE_IO_EXCEPTION,
+//                     TemplateMessages.getString("TemplateSet.error.read"), t); //$NON-NLS-1$
+//             throw new JavaUIException(status);
+       }
+       
+       private static void throwWriteException(Throwable t) throws CoreException {
+    PHPeclipsePlugin.log(t);
+//             IStatus status= new JavaUIStatus(JavaStatusConstants.TEMPLATE_IO_EXCEPTION,
+//                     TemplateMessages.getString("TemplateSet.error.write"), t); //$NON-NLS-1$
+//             throw new JavaUIException(status);
+       }
+
+       /**
+        * Adds a template to the set.
+        */
+       public void add(Template template) {
+               if (exists(template))
+                       return; // ignore duplicate
+               
+               fTemplates.add(template);
+               sort();
+       }
+
+       private boolean exists(Template template) {
+               for (Iterator iterator = fTemplates.iterator(); iterator.hasNext();) {
+                       Template anotherTemplate = (Template) iterator.next();
+
+                       if (template.equals(anotherTemplate))
+                               return true;
+               }
+               
+               return false;
+       }
+       
+       /**
+        * Removes a template to the set.
+        */     
+       public void remove(Template template) {
+               fTemplates.remove(template);
+               sort();
+       }
+
+       /**
+        * Empties the set.
+        */             
+       public void clear() {
+               fTemplates.clear();
+               sort();
+       }
+       
+       /**
+        * Returns all templates.
+        */
+       public Template[] getTemplates() {
+               return (Template[]) fTemplates.toArray(new Template[fTemplates.size()]);
+       }
+       
+       /**
+        * Returns all templates with a given name.
+        */
+       public Template[] getTemplates(String name) {
+               ArrayList res= new ArrayList();
+               for (Iterator iterator= fTemplates.iterator(); iterator.hasNext();) {
+                       Template curr= (Template) iterator.next();
+                       if (curr.getName().equals(name)) {
+                               res.add(curr);
+                       }
+               }
+               return (Template[]) res.toArray(new Template[res.size()]);
+       }       
+       
+       private void sort() {
+               fSortedTemplates= (Template[]) fTemplates.toArray(new Template[fTemplates.size()]);
+               Arrays.sort(fSortedTemplates, fTemplateComparator);
+       }
+       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateTranslator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateTranslator.java
new file mode 100644 (file)
index 0000000..f2190f0
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * The template translator translates a string into a template buffer.
+ * The EBNF grammer of a valid string is as follows:
+ * 
+ * <p>
+ * template := (text | escape)*.<br />
+ * text := character - dollar.<br />
+ * escape := dollar ('{' identifier '}' | dollar).<br />
+ * dollar := '$'.<br />
+ * </p>
+ */
+public class TemplateTranslator {
+
+       // states
+       private static final int TEXT= 0;
+       private static final int ESCAPE= 1;
+       private static final int IDENTIFIER= 2;
+
+       // tokens
+       private static final char ESCAPE_CHARACTER= '$';
+       private static final char IDENTIFIER_BEGIN= '{';
+       private static final char IDENTIFIER_END= '}';
+
+       /** a buffer for the translation result string */
+    private final StringBuffer fBuffer= new StringBuffer();    
+    /** position offsets of variables */
+    private final Vector fOffsets= new Vector();
+    /** position lengths of variables */
+    private final Vector fLengths= new Vector();
+
+       /** the current parsing state */
+    private int fState;    
+    /** the last translation error */
+    private String fErrorMessage;
+
+       /**
+        * Returns an error message if an error occured for the last translation, <code>null</code>
+        * otherwise.
+        */
+       public String getErrorMessage() {
+           return fErrorMessage;
+       }
+
+       /**
+        * Translates a template string to <code>TemplateBuffer</code>. <code>null</code>
+        * is returned if there was an error. <code>getErrorMessage()</code> retrieves the
+        * associated error message.
+        * 
+        * @param string the string to translate.
+        * @return returns the template buffer corresponding to the string, <code>null</code>
+        *         if there was an error.
+        * @see #getErrorMessage()
+        */
+       public TemplateBuffer translate(String string) throws CoreException {
+
+           fBuffer.setLength(0);
+           fOffsets.clear();
+           fLengths.clear();
+           fState= TEXT;
+           fErrorMessage= null;
+           
+               if (!parse(string))
+                       return null;
+                       
+               switch (fState) {
+               case TEXT:
+                       break;
+               
+               // illegal, but be tolerant
+               case ESCAPE:
+                       fErrorMessage= TemplateMessages.getString("TemplateTranslator.error.incomplete.variable"); //$NON-NLS-1$
+                       fBuffer.append(ESCAPE_CHARACTER);
+                       return null;
+                               
+               // illegal, but be tolerant
+               case IDENTIFIER:
+                       fErrorMessage= TemplateMessages.getString("TemplateTranslator.error.incomplete.variable"); //$NON-NLS-1$
+                       fBuffer.append(ESCAPE_CHARACTER);
+                       return null;            
+               }                       
+               
+               int[] offsets= new int[fOffsets.size()];
+               int[] lengths= new int[fLengths.size()];
+               
+               for (int i= 0; i < fOffsets.size(); i++) {
+                       offsets[i]= ((Integer) fOffsets.get(i)).intValue();
+                       lengths[i]= ((Integer) fLengths.get(i)).intValue();
+               }
+
+               String translatedString= fBuffer.toString();
+               TemplatePosition[] variables= findVariables(translatedString, offsets, lengths);
+
+               return new TemplateBuffer(translatedString, variables);
+       }
+       
+       private static TemplatePosition[] findVariables(String string, int[] offsets, int[] lengths) {
+
+               Map map= new HashMap();
+               
+               for (int i= 0; i != offsets.length; i++) {
+                   int offset= offsets[i];
+                   int length= lengths[i];
+                   
+                   String content= string.substring(offset, offset + length);
+                   Vector vector= (Vector) map.get(content);
+                   if (vector == null) {
+                       vector= new Vector();
+                       map.put(content, vector);
+                   }               
+                   vector.add(new Integer(offset));
+               }
+               
+               TemplatePosition[] variables= new TemplatePosition[map.size()];
+               int k= 0;
+               
+               Set keys= map.keySet();
+               for (Iterator i= keys.iterator(); i.hasNext(); ) {
+                       String name= (String) i.next();                 
+                       Vector vector= (Vector) map.get(name);
+                       
+                       int[] offsets_= new int[vector.size()];
+                       for (int j= 0; j != offsets_.length; j++)
+                               offsets_[j]= ((Integer) vector.get(j)).intValue();
+                               
+                       variables[k]= new TemplatePosition(name, name, offsets_, name.length());
+                       k++;
+               }
+               
+               return variables;
+       }
+
+       /** internal parser */
+       private boolean parse(String string) {
+
+               for (int i= 0; i != string.length(); i++) {
+                   char ch= string.charAt(i);
+                       
+                       switch (fState) {
+                       case TEXT:
+                               switch (ch) {
+                               case ESCAPE_CHARACTER:
+                                       fState= ESCAPE;
+                                       break;
+                                       
+                               default:
+                                       fBuffer.append(ch);
+                                       break;
+                               }
+                               break;
+                               
+                       case ESCAPE:
+                               switch (ch) {
+                               case ESCAPE_CHARACTER:
+                                       fBuffer.append(ch);
+                                       fState= TEXT;
+                                       break;
+                               
+                               case IDENTIFIER_BEGIN:
+                                       fOffsets.add(new Integer(fBuffer.length()));
+                                       fState= IDENTIFIER;
+                                       break;
+                                       
+                               default:
+                                       // illegal single escape character, but be tolerant
+                                       fErrorMessage= TemplateMessages.getString("TemplateTranslator.error.incomplete.variable"); //$NON-NLS-1$
+                                       fBuffer.append(ESCAPE_CHARACTER);
+                                       fBuffer.append(ch);
+                                       fState= TEXT;
+                                       return false;
+                               }
+                               break;
+
+                       case IDENTIFIER:
+                               switch (ch) {
+                               case IDENTIFIER_END:
+                                       int offset = ((Integer) fOffsets.get(fOffsets.size() - 1)).intValue();
+                                       fLengths.add(new Integer(fBuffer.length() - offset));
+                                       fState= TEXT;
+                                       break;
+                               
+                               default:
+                                       if (!Character.isUnicodeIdentifierStart((char) ch) &&
+                                               !Character.isUnicodeIdentifierPart((char) ch))
+                                       {
+                                               // illegal identifier character
+                                               fErrorMessage= TemplateMessages.getString("TemplateTranslator.error.invalid.identifier"); //$NON-NLS-1$
+                                               return false;
+                                       }
+                               
+                                       fBuffer.append(ch);
+                                       break;
+                               }
+                               break;
+                       }
+               }
+               
+               return true;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateVariable.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/TemplateVariable.java
new file mode 100644 (file)
index 0000000..7d3c055
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+/**
+ * A template variable.
+ */
+public abstract class TemplateVariable {
+
+       /** name of the variable */
+       private final String fName;
+
+       /** description of the variable */
+       private final String fDescription;
+       
+       /**
+        * Creates an instance of <code>TemplateVariable</code>.
+        * 
+        * @param name the name of the variable
+        * @param description the description for the variable
+        */
+       protected TemplateVariable(String name, String description) {
+               fName= name;
+               fDescription= description;   
+       }
+       
+       /**
+        * Returns the name of the variable.
+        */
+       public String getName() {
+               return fName;
+       }
+
+       /**
+        * Returns the description for the variable.
+        */
+       public String getDescription() {
+               return fDescription;   
+       }
+
+       /**
+        * Tests if this variable can be evaluated.
+        */
+//     public abstract boolean canEvaluate(TemplateContext context);
+       
+       /**
+        * Evaluates this variable
+        * 
+        * @return the evaluated string, or <code>null</code> if not evaluatable.
+        */
+       public abstract String evaluate(TemplateContext context);
+
+       /**
+        * Returns whether this variable is resolved.
+        * By default, the variable is not resolved.
+        * Clients can overwrite this method to force resolution of the variable.
+        */
+       public boolean isResolved(TemplateContext context) {
+               return false;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Templates.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/Templates.java
new file mode 100644 (file)
index 0000000..71c4c9d
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template;
+
+import java.io.File;
+import java.io.InputStream;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.dialogs.ErrorDialog;
+
+/**
+ * <code>Templates</code> gives access to the available templates.
+ */
+public class Templates extends TemplateSet {
+
+       private static final String DEFAULT_FILE= "default-templates.xml"; //$NON-NLS-1$
+       private static final String TEMPLATE_FILE= "templates.xml"; //$NON-NLS-1$
+
+       /** Singleton. */
+       private static Templates fgTemplates;
+
+       /**
+        * Returns an instance of templates.
+        */
+       public static Templates getInstance() {
+               if (fgTemplates == null)
+                       fgTemplates= create();
+               
+               return fgTemplates;
+       }
+
+       private static Templates create() {
+               Templates templates= new Templates();
+
+               try {                   
+                       File templateFile= getTemplateFile();
+                       if (templateFile.exists()) {
+                               templates.addFromFile(templateFile);
+                       } else {
+                               templates.addFromStream(getDefaultsAsStream());
+                               templates.saveToFile(templateFile);
+                       }
+
+               } catch (CoreException e) {
+                       PHPeclipsePlugin.log(e);
+                       ErrorDialog.openError(null,
+                               TemplateMessages.getString("Templates.error.title"), //$NON-NLS-1$
+                               e.getMessage(), e.getStatus());
+
+                       templates.clear();
+               }
+
+               return templates;
+       }       
+       
+       /**
+        * Resets the template set.
+        */
+       public void reset() throws CoreException {
+               clear();
+               addFromFile(getTemplateFile());
+       }
+
+       /**
+        * Resets the template set with the default templates.
+        */
+       public void restoreDefaults() throws CoreException {
+               clear();
+               addFromStream(getDefaultsAsStream());
+       }
+
+       /**
+        * Saves the template set.
+        */
+       public void save() throws CoreException {                                       
+               saveToFile(getTemplateFile());
+       }
+
+       private static InputStream getDefaultsAsStream() {
+               return Templates.class.getResourceAsStream(DEFAULT_FILE);
+       }
+
+       private static File getTemplateFile() {
+               IPath path= PHPeclipsePlugin.getDefault().getStateLocation();
+               path= path.append(TEMPLATE_FILE);
+               
+               return path.toFile();
+       }
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/default-templates.xml b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/default-templates.xml
new file mode 100644 (file)
index 0000000..cd33d19
--- /dev/null
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+(c) Copyright IBM Corp. 2000, 2001.
+All Rights Reserved.
+-->
+
+<templates>
+
+  <!-- php -->
+
+  <template description="iterate over array" name="for" context="php"
+>for (int ${index} = 0; ${index} &lt; ${array}.length; ${index}++) {
+       ${cursor}
+}</template>
+
+  <template description="iterate over array w/ temporary variable" name="for" context="php"
+>for (int ${index} = 0; ${index} &lt; ${array}.length; ${index}++) {
+       ${array_type} ${array_element} = ${array}[${index}];
+       ${cursor}
+}</template>
+
+  <template description="iterate over collection" name="for" context="php"
+>for (Iterator ${iterator} = ${collection}.iterator(); ${iterator}.hasNext(); ) {
+       ${type} ${element} = (${type}) ${iterator}.next();
+       ${cursor}
+}</template>
+
+  <template description="iterate with enumeration" name="while" context="php"
+>while (${enumeration}.hasMoreElements()) {
+       ${type} ${element} = (${type}) ${enumeration}.nextElement();
+       ${cursor}
+}</template>
+
+  <template description="iterate with iterator" name="while" context="php"
+>while (${iterator}.hasNext()) {
+       ${type} ${element} = (${type}) ${iterator}.next();
+       ${cursor}
+}</template>
+
+  <template description="do while statement" name="do" context="php"
+>do {
+       ${cursor}
+} while (${condition});</template>
+
+  <template description="switch case statement" name="switch" context="php"
+>switch (${key}) {
+       case ${value}:
+               ${cursor}
+               break;
+
+       default:
+               break;
+}</template>
+
+  <template description="if statement" name="if" context="php"
+>if (${condition}) {
+       ${cursor}
+}</template>
+
+  <template description="if else statement" name="ifelse" context="php"
+>if (${condition}) {
+       ${cursor}
+} else {
+       
+}</template>
+
+  <template description="else if block" name="elseif" context="php"
+>else if (${condition}) {
+       ${cursor}
+}</template>
+
+  <template description="else block" name="else" context="php"
+>else {
+       ${cursor}
+}</template>
+
+  <template description="try catch block" name="try" context="php"
+>try {
+       ${cursor}
+} catch (${Exception} e) {
+}</template>
+
+  <template description="catch block" name="catch" context="php"
+>catch (${Exception} e) {
+       ${cursor}
+}</template>
+
+  <template description="main method" name="main" context="php"
+>
+public static void main(String[] args) {
+       ${cursor}
+}</template>
+
+  <template description="public method" name="public_method" context="php"
+>
+public ${return_type} ${name}(${arguments}) {
+       ${cursor}
+}</template>
+
+  <template description="protected method" name="protected_method" context="php"
+>protected ${return_type} ${name}(${arguments}) {
+       ${cursor}
+}</template>
+
+  <template description="private method" name="private_method" context="php"
+>private ${return_type} ${name}(${arguments}) {
+       ${cursor}
+}</template>
+
+  <template description="private static method" name="private_static_method" context="php"
+>private static ${return_type} ${name}(${arguments}) {
+       ${cursor}
+}</template>
+
+  <template description="dynamic type test and cast" name="instanceof" context="php"
+>if (${name} instanceof ${type}) {
+       ${type} ${new_name} = (${type})${name};
+       ${cursor}
+}</template>
+
+  <template description="dynamic cast" name="cast" context="php"
+>${type} ${new_name} = (${type}) ${name};
+</template>
+
+  <template description="create new object" name="new" context="php"
+>${type} ${name} = new ${type}(${arguments});
+</template>
+
+  <template description="lazy creation" name="lazy" context="php"
+>if (${name} == null) {
+       ${name} = new ${type}(${arguments});
+       ${cursor}
+}
+
+return ${name};
+</template>
+
+  <template description="convert collection to array" name="toarray" context="php"
+  >(${type}[]) ${collection}.toArray(new ${type}[${collection}.size()]);</template>
+
+  <template context="php" description="file comment used by the class and interface wizards" enabled="true" name="filecomment">/**
+ * Created on ${date}
+ *
+ * To change this generated comment edit the template variable &quot;filecomment&quot;:
+ * Window&gt;Preferences&gt;Java&gt;Templates.
+ * To enable and disable the creation of file comments go to
+ * Window&gt;Preferences&gt;Java&gt;Code Generation.
+ */</template>
+
+<template name="typecomment" description="type comment used by the class and interface wizards" context="php" enabled="true">/**
+ * @author ${user}
+ *
+ * To change this generated comment edit the template variable &quot;typecomment&quot;:
+ * Window&gt;Preferences&gt;Java&gt;Templates.
+ * To enable and disable the creation of type comments go to
+ * Window&gt;Preferences&gt;Java&gt;Code Generation.
+ */</template> 
+
+  <template description="print to standard out" name="stdout" context="php"
+  >System.out.println(${cursor});</template>
+
+  <template description="print to standard error" name="stderr" context="php"
+  >System.err.println(${cursor});</template>
+
+  <!-- html -->
+
+  <template description="&lt;code&gt;&lt;/code&gt;" name="&lt;code&gt;" context="html"
+  >&lt;code&gt;${cursor}&lt;/code&gt;</template>
+
+  <template description="&lt;code&gt;null&lt;/code&gt;" name="&lt;code&gt;" context="html"
+  >&lt;code&gt;null&lt;/code&gt;</template>
+
+  <template description="&lt;pre&gt;&lt;/pre&gt;" name="&lt;pre&gt;" context="html"
+  >&lt;pre&gt;${cursor}&lt;/pre&gt;</template>
+
+  <template description="&lt;b&gt;&lt;/b&gt;" name="&lt;b&gt;" context="html"
+  >&lt;b&gt;${cursor}&lt;/b&gt;</template>
+
+  <template description="&lt;i&gt;&lt;/i&gt;" name="&lt;i&gt;" context="html"
+  >&lt;i&gt;${cursor}&lt;/i&gt;</template>
+
+  <template description="author name" name="@author" context="html"
+  >@author ${user}</template>
+
+</templates>
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContext.java
new file mode 100644 (file)
index 0000000..dcc8f00
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template.java;
+
+import net.sourceforge.phpdt.internal.corext.template.ContextType;
+import net.sourceforge.phpdt.internal.corext.template.DocumentTemplateContext;
+import net.sourceforge.phpdt.internal.corext.template.Template;
+import net.sourceforge.phpdt.internal.corext.template.TemplateBuffer;
+import net.sourceforge.phpdt.internal.corext.template.TemplateTranslator;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+/**
+ * A compilation unit context.
+ */
+public class CompilationUnitContext extends DocumentTemplateContext {
+
+  /** The platform default line delimiter. */
+  private static final String PLATFORM_LINE_DELIMITER= System.getProperty("line.separator"); //$NON-NLS-1$
+
+       /** The compilation unit, may be <code>null</code>. */
+//     private final ICompilationUnit fCompilationUnit;
+
+       /**
+        * Creates a compilation unit context.
+        * 
+        * @param type   the context type.
+        * @param document the document.
+        * @param completionPosition the completion position within the document.
+        * @param compilationUnit the compilation unit (may be <code>null</code>).
+        */
+       protected CompilationUnitContext(ContextType type, IDocument document, int completionPosition)
+       //,ICompilationUnit compilationUnit)
+       {
+               super(type, document, completionPosition);
+       //      fCompilationUnit= compilationUnit;
+       }
+       
+    /*
+   * @see TemplateContext#canEvaluate(Template templates)
+   */
+  public boolean canEvaluate(Template template) {
+    // return fForceEvaluation || 
+    return template.matches(getKey(), getContextType().getName());
+  }
+  
+    /*
+   * @see TemplateContext#evaluate(Template template)
+   */
+  public TemplateBuffer evaluate(Template template) throws CoreException {
+    if (!canEvaluate(template))
+      return null;
+    
+    TemplateTranslator translator= new TemplateTranslator();
+    TemplateBuffer buffer= translator.translate(template.getPattern());
+
+    getContextType().edit(buffer, this);
+      
+    String lineDelimiter= null;
+    try {
+      lineDelimiter= getDocument().getLineDelimiter(0);
+    } catch (BadLocationException e) {
+    }
+
+    if (lineDelimiter == null)
+      lineDelimiter= PLATFORM_LINE_DELIMITER;
+    
+//    ITemplateEditor formatter= new JavaFormatter(lineDelimiter);
+//    formatter.edit(buffer, this);
+
+    return buffer;
+  }
+  
+  /*
+   * @see DocumentTemplateContext#getCompletionPosition();
+   */
+  public int getStart() {
+    IDocument document= getDocument();
+    try {
+      int start= getCompletionPosition();
+  
+      while ((start != 0) && Character.isUnicodeIdentifierPart(document.getChar(start - 1)))
+        start--;
+        
+      if ((start != 0) && Character.isUnicodeIdentifierStart(document.getChar(start - 1)))
+        start--;
+  
+      return start;
+
+    } catch (BadLocationException e) {
+      return getCompletionPosition(); 
+    }
+  }
+
+  /**
+   * Returns the character before start position of completion.
+   */
+  public char getCharacterBeforeStart() {
+    int start= getStart();
+    
+    try {
+      return start == 0
+        ? ' '
+        : getDocument().getChar(start - 1);
+
+    } catch (BadLocationException e) {
+      return ' ';
+    }
+  }
+       /**
+        * Returns the compilation unit if one is associated with this context, <code>null</code> otherwise.
+        */
+//     public final ICompilationUnit getCompilationUnit() {
+//             return fCompilationUnit;
+//     }
+
+       /**
+        * Returns the enclosing element of a particular element type, <code>null</code>
+        * if no enclosing element of that type exists.
+        */
+//     public IJavaElement findEnclosingElement(int elementType) {
+//             if (fCompilationUnit == null)
+//                     return null;
+//
+//             try {
+//                     IJavaElement element= fCompilationUnit.getElementAt(getStart());
+//                     while (element != null && element.getElementType() != elementType)
+//                             element= element.getParent();
+//                     
+//                     return element;
+//
+//             } catch (JavaModelException e) {
+//                     return null;
+//             }       
+//     }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContextType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/CompilationUnitContextType.java
new file mode 100644 (file)
index 0000000..f0760e3
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template.java;
+
+import org.eclipse.jface.text.IDocument;
+/*
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+*/
+import net.sourceforge.phpdt.internal.corext.template.ContextType;
+import net.sourceforge.phpdt.internal.corext.template.TemplateContext;
+import net.sourceforge.phpdt.internal.corext.template.TemplateVariable;
+
+/**
+ * Compilation unit context type.
+ */
+public abstract class CompilationUnitContextType extends ContextType {
+       
+       /** the document */
+       protected IDocument fDocument;
+
+       /** the completion position within the document string */
+       protected int fPosition;
+
+       /** the associated compilation unit, may be <code>null</code> */
+       //protected ICompilationUnit fCompilationUnit;
+/*
+       protected static class ReturnType extends TemplateVariable {
+               public ReturnType() {
+                       super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.return.type"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.return.type")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+    
+               public String evaluate(TemplateContext context) {
+                       IJavaElement element= ((CompilationUnitContext) context).findEnclosingElement(IJavaElement.METHOD);
+                       if (element == null)
+                               return null;
+
+                       try {
+                               return Signature.toString(((IMethod) element).getReturnType());
+                       } catch (JavaModelException e) {
+                               return null;
+                       }
+               }
+    
+               public boolean isResolved(TemplateContext context) {
+                       return evaluate(context) != null;
+               }               
+       }
+
+       protected static class File extends TemplateVariable {
+               public File() {
+                       super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.file"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.file")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+               public String evaluate(TemplateContext context) {
+                       ICompilationUnit unit= ((CompilationUnitContext) context).getCompilationUnit();
+                       
+                       return (unit == null) ? null : unit.getElementName();
+      return null;
+               }
+               public boolean isResolved(TemplateContext context) {
+                       return evaluate(context) != null;
+               }               
+       }
+
+       protected static class EnclosingJavaElement extends TemplateVariable {
+               protected final int fElementType;
+               
+               public EnclosingJavaElement(String name, String description, int elementType) {
+                       super(name, description);
+                       fElementType= elementType;
+               }
+               public String evaluate(TemplateContext context) {
+                       IJavaElement element= ((CompilationUnitContext) context).findEnclosingElement(fElementType);
+                       return (element == null) ? null : element.getElementName();                     
+               }
+               public boolean isResolved(TemplateContext context) {
+                       return evaluate(context) != null;
+               }
+       }
+       
+       protected static class Method extends EnclosingJavaElement {
+               public Method() {
+                       super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.enclosing.method"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.method"), IJavaElement.METHOD); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+       }
+
+       protected static class Type extends EnclosingJavaElement {
+               public Type() {
+                       super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.enclosing.type"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.type"), IJavaElement.TYPE); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+       }
+
+       protected static class Package extends EnclosingJavaElement {
+               public Package() {
+                       super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.enclosing.package"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.package"), IJavaElement.PACKAGE_FRAGMENT); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+       }       
+
+       protected static class Project extends EnclosingJavaElement {
+               public Project() {
+                       super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.enclosing.project"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.project"), IJavaElement.JAVA_PROJECT); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+       }       
+
+
+       protected static class Arguments extends TemplateVariable {
+               public Arguments() {
+                       super(JavaTemplateMessages.getString("CompilationUnitContextType.variable.name.enclosing.method.arguments"), JavaTemplateMessages.getString("CompilationUnitContextType.variable.description.enclosing.method.arguments")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+               public String evaluate(TemplateContext context) {
+                       IJavaElement element= ((CompilationUnitContext) context).findEnclosingElement(IJavaElement.METHOD);
+                       if (element == null)
+                               return null;
+                               
+                       IMethod method= (IMethod) element;
+                       
+                       try {
+                               String[] arguments= method.getParameterNames();
+                               StringBuffer buffer= new StringBuffer();
+                               
+                               for (int i= 0; i < arguments.length; i++) {
+                                       if (i > 0)
+                                               buffer.append(", "); //$NON-NLS-1$
+                                       buffer.append(arguments[i]);                            
+                               }
+                               
+                               return buffer.toString();
+
+                       } catch (JavaModelException e) {
+                               return null;
+                       }
+               }
+       }
+*/
+
+       /*
+        * @see ContextType#ContextType(String)
+        */
+       public CompilationUnitContextType(String name) {
+               super(name);    
+       }
+
+       /**
+        * Sets context parameters. Needs to be called before createContext().
+        */
+       public void setContextParameters(IDocument document, int position) {//, ICompilationUnit compilationUnit) {
+               fDocument= document;
+               fPosition= position;
+//             fCompilationUnit= compilationUnit;
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/GlobalVariables.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/GlobalVariables.java
new file mode 100644 (file)
index 0000000..2b37134
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template.java;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+import net.sourceforge.phpdt.internal.corext.template.SimpleTemplateVariable;
+import net.sourceforge.phpdt.internal.corext.template.TemplateContext;
+
+import net.sourceforge.phpdt.internal.corext.template.TemplateVariable;
+
+/**
+ * Global variables which are available in any context.
+ */
+public class GlobalVariables {
+
+       /**
+        * The cursor variable determines the cursor placement after template edition.
+        */
+       static class Cursor extends SimpleTemplateVariable {
+               public Cursor() {
+                       super(JavaTemplateMessages.getString("GlobalVariables.variable.name.cursor"), JavaTemplateMessages.getString("GlobalVariables.variable.description.cursor")); //$NON-NLS-1$ //$NON-NLS-2$
+                       setEvaluationString(""); //$NON-NLS-1$
+                       setResolved(true);
+               }
+       }
+
+       /**
+        * The dollar variable inserts an escaped dollar symbol.
+        */
+       static class Dollar extends SimpleTemplateVariable {
+               public Dollar() {
+                       super(JavaTemplateMessages.getString("GlobalVariables.variable.name.dollar"), JavaTemplateMessages.getString("GlobalVariables.variable.description.dollar")); //$NON-NLS-1$ //$NON-NLS-2$
+                       setEvaluationString("$"); //$NON-NLS-1$
+                       setResolved(true);
+               }
+       }
+
+       /**
+        * The date variable evaluates to the current date.
+        */
+       static class Date extends SimpleTemplateVariable {
+               public Date() {
+                       super(JavaTemplateMessages.getString("GlobalVariables.variable.name.date"), JavaTemplateMessages.getString("GlobalVariables.variable.description.date")); //$NON-NLS-1$ //$NON-NLS-2$
+                       setResolved(true);
+               }
+               public String evaluate(TemplateContext context) {
+                       return DateFormat.getDateInstance().format(new java.util.Date());
+               }
+       }               
+
+       /**
+        * The time variable evaluates to the current time.
+        */
+       static class Time extends SimpleTemplateVariable {
+               public Time() {
+                       super(JavaTemplateMessages.getString("GlobalVariables.variable.name.time"), JavaTemplateMessages.getString("GlobalVariables.variable.description.time")); //$NON-NLS-1$ //$NON-NLS-2$
+                       setResolved(true);
+               }
+               public String evaluate(TemplateContext context) {
+                       return DateFormat.getTimeInstance().format(new java.util.Date());
+               }
+       }
+
+       /**
+        * The user variable evaluates to the current user.
+        */
+       static class User extends SimpleTemplateVariable {
+               public User() {
+                       super(JavaTemplateMessages.getString("GlobalVariables.variable.name.user"), JavaTemplateMessages.getString("GlobalVariables.variable.description.user")); //$NON-NLS-1$ //$NON-NLS-2$
+                       setResolved(true);
+               }
+               public String evaluate(TemplateContext context) {
+                       return System.getProperty("user.name"); //$NON-NLS-1$
+               }       
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaContextType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaContextType.java
new file mode 100644 (file)
index 0000000..7c048fa
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template.java;
+
+import java.util.Collection;
+/*
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+*/
+import net.sourceforge.phpdt.internal.corext.template.ContextType;
+import net.sourceforge.phpdt.internal.corext.template.TemplateContext;
+import net.sourceforge.phpdt.internal.corext.template.TemplateVariable;
+
+/**
+ * A context type for java code.
+ */
+public class JavaContextType extends CompilationUnitContextType {
+/*
+       protected static class Array extends TemplateVariable {
+               public Array() {
+                       super(JavaTemplateMessages.getString("JavaContextType.variable.name.array"), JavaTemplateMessages.getString("JavaContextType.variable.description.array")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+           public String evaluate(TemplateContext context) {
+               return ((JavaContext) context).guessArray();
+           }
+       }
+
+       protected static class ArrayType extends TemplateVariable {
+           public ArrayType() {
+               super(JavaTemplateMessages.getString("JavaContextType.variable.name.array.type"), JavaTemplateMessages.getString("JavaContextType.variable.description.array.type")); //$NON-NLS-1$ //$NON-NLS-2$
+           }
+           public String evaluate(TemplateContext context) {
+               return ((JavaContext) context).guessArrayType();
+           }
+       }
+
+       protected static class ArrayElement extends TemplateVariable {
+           public ArrayElement() {
+               super(JavaTemplateMessages.getString("JavaContextType.variable.name.array.element"), JavaTemplateMessages.getString("JavaContextType.variable.description.array.element"));     //$NON-NLS-1$ //$NON-NLS-2$    
+           }
+           public String evaluate(TemplateContext context) {
+               return ((JavaContext) context).guessArrayElement();
+           }       
+       }
+
+       protected static class Index extends TemplateVariable {
+           public Index() {
+               super(JavaTemplateMessages.getString("JavaContextType.variable.name.index"), JavaTemplateMessages.getString("JavaContextType.variable.description.index")); //$NON-NLS-1$ //$NON-NLS-2$
+           }
+           public String evaluate(TemplateContext context) {
+               return ((JavaContext) context).getIndex();
+           }       
+       }
+
+       protected static class Collection extends TemplateVariable {
+           public Collection() {
+                   super(JavaTemplateMessages.getString("JavaContextType.variable.name.collection"), JavaTemplateMessages.getString("JavaContextType.variable.description.collection")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+           public String evaluate(TemplateContext context) {
+               return ((JavaContext) context).guessCollection();
+           }
+       }
+
+       protected static class Iterator extends TemplateVariable {
+           public Iterator() {
+                   super(JavaTemplateMessages.getString("JavaContextType.variable.name.iterator"), JavaTemplateMessages.getString("JavaContextType.variable.description.iterator")); //$NON-NLS-1$ //$NON-NLS-2$
+               }
+           public String evaluate(TemplateContext context) {
+               return ((JavaContext) context).getIterator();
+           }       
+       }
+
+*/     
+
+
+       /**
+        * Creates a java context type.
+        */
+       public JavaContextType() {
+               super("php"); //$NON-NLS-1$
+               
+               // global
+               addVariable(new GlobalVariables.Cursor());
+               addVariable(new GlobalVariables.Dollar());
+               addVariable(new GlobalVariables.Date());
+               addVariable(new GlobalVariables.Time());
+               addVariable(new GlobalVariables.User());
+               
+               // compilation unit
+       /*      addVariable(new File());
+               addVariable(new ReturnType());
+               addVariable(new Method());
+               addVariable(new Type());
+               addVariable(new Package());
+               addVariable(new Project());
+               addVariable(new Arguments());
+
+               // java
+               addVariable(new Array());
+               addVariable(new ArrayType());
+               addVariable(new ArrayElement());
+               addVariable(new Index());
+               addVariable(new Iterator());
+               addVariable(new Collection());*/
+       }
+       
+       /*
+        * @see ContextType#createContext()
+        */     
+       public TemplateContext createContext() {
+               return new CompilationUnitContext(this, fDocument, fPosition); //, fCompilationUnit);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaDocContextType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaDocContextType.java
new file mode 100644 (file)
index 0000000..79c3457
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template.java;
+
+//import org.eclipse.jdt.core.ICompilationUnit;
+
+import net.sourceforge.phpdt.internal.corext.template.ContextType;
+import net.sourceforge.phpdt.internal.corext.template.TemplateContext;
+import net.sourceforge.phpdt.internal.corext.template.TemplateVariable;
+
+/**
+ * A context type for javadoc.
+ */
+public class JavaDocContextType extends CompilationUnitContextType {
+
+       /**
+        * Creates a java context type.
+        */
+       public JavaDocContextType() {
+               super("html"); //$NON-NLS-1$
+               
+               // global
+               addVariable(new GlobalVariables.Cursor());
+               addVariable(new GlobalVariables.Dollar());
+               addVariable(new GlobalVariables.Date());
+               addVariable(new GlobalVariables.Time());
+               addVariable(new GlobalVariables.User());
+               
+               // compilation unit
+       /*      addVariable(new File());
+               addVariable(new Method());
+               addVariable(new ReturnType());
+               addVariable(new Arguments());
+               addVariable(new Type());
+               addVariable(new Package());
+               addVariable(new Project());*/
+       }
+       
+       /*
+        * @see ContextType#createContext()
+        */     
+       public TemplateContext createContext() {
+               return new CompilationUnitContext(this, fDocument, fPosition); //, fCompilationUnit);
+       }
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.java
new file mode 100644 (file)
index 0000000..c2b0fc8
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.template.java;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class JavaTemplateMessages {
+
+       private static final String RESOURCE_BUNDLE= JavaTemplateMessages.class.getName();
+       private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+       private JavaTemplateMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+       
+       /**
+        * Gets a string from the resource bundle and formats it with the argument
+        * 
+        * @param key   the string used to get the bundle value, must not be null
+        */
+       public static String getFormattedString(String key, Object arg) {
+               return MessageFormat.format(getString(key), new Object[] { arg });
+       }
+
+
+       /**
+        * Gets a string from the resource bundle and formats it with arguments
+        */     
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);
+       }
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/template/java/JavaTemplateMessages.properties
new file mode 100644 (file)
index 0000000..05d0d06
--- /dev/null
@@ -0,0 +1,53 @@
+#########################################
+# (c) Copyright IBM Corp. 2000, 2001.
+# All Rights Reserved.
+#########################################
+
+GlobalVariables.variable.description.cursor=The cursor position after editing template variables
+GlobalVariables.variable.description.dollar=The dollar symbol
+GlobalVariables.variable.description.date=Current date
+GlobalVariables.variable.description.time=Current time
+GlobalVariables.variable.description.user=User name
+
+GlobalVariables.variable.name.cursor=cursor
+GlobalVariables.variable.name.dollar=dollar
+GlobalVariables.variable.name.date=date
+GlobalVariables.variable.name.time=time
+GlobalVariables.variable.name.user=user
+
+# GlobalVariables.variable.description.line=Current line number
+
+CompilationUnitContextType.variable.description.file=Filename of compilation unit
+CompilationUnitContextType.variable.description.enclosing.method=Enclosing method name
+CompilationUnitContextType.variable.description.enclosing.type=Enclosing type name
+CompilationUnitContextType.variable.description.enclosing.package=Enclosing package name
+CompilationUnitContextType.variable.description.enclosing.project=Enclosing project name
+CompilationUnitContextType.variable.description.enclosing.method.arguments=Argument names of enclosing method
+CompilationUnitContextType.variable.description.return.type=Enclosing method return type
+
+CompilationUnitContextType.variable.name.file=file
+CompilationUnitContextType.variable.name.enclosing.method=enclosing_method
+CompilationUnitContextType.variable.name.enclosing.type=enclosing_type
+CompilationUnitContextType.variable.name.enclosing.package=enclosing_package
+CompilationUnitContextType.variable.name.enclosing.project=enclosing_project
+CompilationUnitContextType.variable.name.enclosing.method.arguments=enclosing_method_arguments
+CompilationUnitContextType.variable.name.return.type=return_type
+
+JavaContextType.variable.description.array=A proposal for an array
+JavaContextType.variable.description.array.type=A proposal for the element type of an array
+JavaContextType.variable.description.array.element=A proposal for the element name of an array
+JavaContextType.variable.description.index=A proposal for an index (int)
+JavaContextType.variable.description.collection=A proposal for a collection (java.util.Collection)
+JavaContextType.variable.description.iterator=A proposal for an iterator (java.util.Iterator)
+JavaContextType.variable.description.arguments=Method arguments (evaluates to empty string)
+
+JavaContextType.variable.name.array=array
+JavaContextType.variable.name.array.type=array_type
+JavaContextType.variable.name.array.element=array_element
+JavaContextType.variable.name.index=index
+JavaContextType.variable.name.collection=collection
+JavaContextType.variable.name.iterator=iterator
+JavaContextType.variable.name.arguments=Method arguments (evaluates to empty string)
+
+JavaContext.error.title=Template Error
+JavaContext.error.message=java context type missing
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/Messages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/Messages.properties
new file mode 100644 (file)
index 0000000..729774b
--- /dev/null
@@ -0,0 +1,17 @@
+################################################################################
+# Copyright (c) 2002 International Business Machines Corp. and others.
+# All rights reserved. This program and the accompanying materials 
+# are made available under the terms of the Common Public License v0.5 
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v05.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+################################################################################
+
+TextRange.offset=Offset: 
+TextRange.length=\ Length: 
+
+TextBuffer.wrongRange=Replace failed due to wrong range [{0},{1}]
+
+TextBufferFactory.bufferNotManaged=Buffer not managed
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MoveTextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MoveTextEdit.java
new file mode 100644 (file)
index 0000000..77a8db5
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import org.eclipse.core.runtime.CoreException;
+
+
+//import org.eclipse.jdt.internal.corext.Assert;
+
+/**
+ * A text edit that moves text inside a text buffer.
+ */
+public final class MoveTextEdit extends TextEdit {
+       
+       /* package */ static class TargetMark extends NopTextEdit {
+               private MoveTextEdit fMoveTextEdit;
+               public TargetMark(TextRange range, MoveTextEdit edit) {
+                       super(range);
+                       fMoveTextEdit= edit;
+               }
+               /* package */ MoveTextEdit getMoveTextEdit() {
+                       return fMoveTextEdit;
+               }
+               public TextEdit perform(TextBuffer buffer) throws CoreException {
+                       fMoveTextEdit.internalPerform(buffer);
+                       return super.perform(buffer);
+               }
+               public TextEdit copy() {
+       //              Assert.isTrue(false, "This should never happen"); //$NON-NLS-1$
+                       return super.copy();
+               }
+       }
+
+       private TextRange fTarget;
+       private TextRange fSource;
+       private int fPerformCounter;
+
+       /**
+        * Creates a new <code>MoveTextEdit</code>. The text edit doesn't support
+        * overlapping moves. So for a <code>MoveTextEdit</code> <code>destination &lt;= offset && 
+        * offset + length - 1 &lt;= destination</code> must be <code>true</code>.
+        * 
+        * @param offset the offset of the text to be moved
+        * @param length the text length to be moved
+        * @param destination the destination offset
+        */
+       public MoveTextEdit(int offset, int length, int destination) {
+       //      Assert.isTrue(destination <= offset || offset + length <= destination);
+               fSource= new TextRange(offset, length);
+               fTarget= new TextRange(destination);
+       }
+
+       /**
+        * Creates a new <code>MoveTextEdit</code> with the given source and target range.
+        * 
+        * @param source the source
+        * @param target the target
+        */
+       private MoveTextEdit(TextRange source,TextRange target) {
+               fSource= source;
+               fTarget= target;
+       }
+       
+       /**
+        * Returns the move text edit's source range. This method returns the same range
+        * as <code>TextEdit#getTextRange()</code>
+        * 
+        * @return the edit's source range
+        */
+       public TextRange getSourceRange() {
+               return fSource;
+       }
+       
+       /**
+        * Returns the move text edit's target range.
+        * 
+        * @return the edit's target range
+        */
+       public TextRange getTargetRange() {
+               return fTarget;
+       }
+       
+       /* non Java-doc
+        * @see TextEdit#getTextRange()
+        */
+       public TextRange getTextRange() {
+               return fSource;
+       }
+
+       /* non Java-doc
+        * @see TextEdit#connect(TextBufferEditor)
+        */
+       public void connect(TextBufferEditor editor) throws CoreException {
+               editor.add(new TargetMark(fTarget, this));
+       }
+       
+       /* non Java-doc
+        * @see TextEdit#perform(TextBuffer)
+        */
+       public TextEdit perform(TextBuffer buffer) throws CoreException {
+               internalPerform(buffer);
+               return new MoveTextEdit(fTarget, fSource);
+       }
+
+       /* non Java-doc
+        * @see TextEdit#copy()
+        */
+       public TextEdit copy() {
+               TextRange source= getSourceRange();
+               TextRange target= getTargetRange();
+               return new MoveTextEdit(source.fOffset, source.fLength, target.fOffset);
+       }
+       
+       //---- Helper method ---------------------------------------------------------------------------------
+       
+       private void internalPerform(TextBuffer buffer) throws CoreException {
+//             Assert.isTrue(fPerformCounter < 2);
+               if (++fPerformCounter == 2) {
+                       TextRange source= getSourceRange();
+                       TextRange target= getTargetRange();
+                       String current= buffer.getContent(source.fOffset, source.fLength);
+                       buffer.replace(source, ""); //$NON-NLS-1$
+                       buffer.replace(target, current);
+               }
+       }
+       
+       /* package */ boolean isUpMove() {
+               return fSource.fOffset < fTarget.fOffset;
+       }
+       
+       /* package */ boolean isDownMove() {
+               return fSource.fOffset > fTarget.fOffset;
+       }
+       
+       /* package */ TextRange getChildRange() {
+               int offset= fSource.fOffset;
+               int length= fSource.fLength;
+               int destination= fTarget.fOffset;
+               if (destination <= offset)
+                       return new TextRange(destination, offset + length - destination);
+               else
+                       return new TextRange(offset, destination - offset);
+       }       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MultiTextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/MultiTextEdit.java
new file mode 100644 (file)
index 0000000..ae29be5
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.internal.utils.Assert;
+import org.eclipse.core.runtime.CoreException;
+
+
+public class MultiTextEdit {
+
+       private List fChildren;
+
+       /**
+        * Creates a new composite text edit.
+        */
+       public MultiTextEdit() {
+               fChildren= new ArrayList(3);
+       }
+
+       protected MultiTextEdit(List children) throws CoreException {
+               fChildren= new ArrayList(children.size());
+               for (Iterator iter= children.iterator(); iter.hasNext();) {
+                       fChildren.add(((TextEdit)iter.next()).copy());
+               }
+       }
+       
+       protected List getChildren() {
+               return fChildren;
+       }
+       
+       /**
+        * Adds all <code>TextEdits</code> managed by the given multt text edit.
+        * 
+        * @param edit the multi text edit to be added.
+        */
+       public void add(MultiTextEdit edit) {
+               Assert.isNotNull(edit);
+               fChildren.add(edit);
+       }
+       
+       /**
+        * Adds a text edit.
+        * 
+        * @param edit the text edit to be added
+        */
+       public void add(TextEdit edit) {
+               Assert.isNotNull(edit);
+               fChildren.add(edit);
+       }
+       
+       /**
+        * Returns the children managed by this text edit collection.
+        * 
+        * @return the children of this composite text edit
+        */
+       public Iterator iterator() {
+               return fChildren.iterator();
+       }
+
+       /**
+        * Connects this text edit to the given <code>TextBufferEditor</code>. 
+        * Note that this method <b>should only be called</b> by a <code>
+        * TextBufferEditor</code>.
+        *<p>
+        * This default implementation does nothing. Subclasses may override
+        * if needed.
+        *  
+        * @param editor the text buffer editor this text edit has been added to
+        */
+       public void connect(TextBufferEditor editor) throws CoreException {
+               for (Iterator iter= fChildren.iterator(); iter.hasNext();) {
+                       Object element= iter.next();
+                       if (element instanceof TextEdit)
+                               editor.add((TextEdit)element);
+                       else
+                               editor.add((MultiTextEdit)element);
+               }
+       }
+       
+       /**
+     * Creates and returns a copy of this text edit collection. The copy method should
+     * be implemented in a way so that the copy can be added to a different  <code>
+     * TextBuffer</code> without causing any harm to the object from which the copy 
+     * has been created.
+     * 
+     * @return a copy of this object.
+     */
+       public MultiTextEdit copy() throws CoreException {
+               return new MultiTextEdit(fChildren);
+       }
+       
+       /**
+        * Returns the <code>TextRange</code> that this text edit is going to
+        * manipulate. If this method is called before the <code>MultiTextEdit</code>
+        * has been added to a <code>TextBufferEditor</code> it may return <code>
+        * null</code> to indicate this situation.
+        * 
+        * @return the <code>TextRange</code>s this <code>TextEdit is going
+        *      to manipulate
+        */
+       public TextRange getTextRange() {
+               int size= fChildren.size();
+               if (size == 0)
+                       return new TextRange(0,0);
+               TextRange range= ((TextEdit)fChildren.get(0)).getTextRange();
+               int start= range.getOffset();
+               int end= range.getInclusiveEnd();
+               for (int i= 1; i < size; i++) {
+                       range= ((TextEdit)fChildren.get(i)).getTextRange();
+                       start= Math.min(start, range.getOffset());
+                       end= Math.max(end, range.getInclusiveEnd());
+               }
+               return new TextRange(start, end - start + 1);
+       }
+       
+       /**
+        * Returns the element modified by this text edit. The method
+        * may return <code>null</code> if the modification isn't related to a
+        * element or if the content of the modified text buffer doesn't
+        * follow any syntax.
+        * <p>
+        * This default implementation returns <code>null</code>
+        * 
+        * @return the element modified by this text edit
+        */
+       public Object getModifiedElement() {
+               return null;
+       }       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/NopTextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/NopTextEdit.java
new file mode 100644 (file)
index 0000000..083fe0b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * A text edit that does nothing. A <code>NopTextEdit</code> can be used to track
+ * positions when executing <code>TextEdits</code> associated with a <code>
+ * TextBufferEditor</code>.
+ */
+public class NopTextEdit extends TextEdit {
+       
+       private TextRange fTextRange;
+       
+       /**
+        * Creates a new <code>NopTextEdit</code> for the given
+        * offset and length.
+        * 
+        * @param offset the starting offset this text edit is "working on"
+        * @param length the length this text edit is "working on"
+        */
+       public NopTextEdit(int offset, int length) {
+               this(new TextRange(offset, length));
+       }
+       
+       /**
+        * Creates a new <code>NopTextEdit</code> for the given
+        * range.
+        * 
+        * @param range the <code>TextRange</code> this text edit is "working on"
+        */
+       public NopTextEdit(TextRange range) {
+               fTextRange= range;
+       }
+
+       /* non Java-doc
+        * @see TextEdit#getTextRange
+        */     
+       public TextRange getTextRange() {
+               return fTextRange;
+       }
+
+       /* non Java-doc
+        * @see TextEdit#perform
+        */     
+       public TextEdit perform(TextBuffer buffer) throws CoreException {
+               return new NopTextEdit(fTextRange);
+       }
+       
+       /* non Java-doc
+        * @see TextEdit#perform
+        */     
+       public TextEdit copy() {
+               return new NopTextEdit(fTextRange.copy());
+       }       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SimpleTextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SimpleTextEdit.java
new file mode 100644 (file)
index 0000000..1000537
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import org.eclipse.core.runtime.CoreException;
+
+//import org.eclipse.jdt.internal.corext.Assert;
+
+public abstract class SimpleTextEdit extends TextEdit {
+
+       private TextRange fRange;
+       private String fText;
+
+       public static SimpleTextEdit createReplace(int offset, int length, String text) {
+               return new SimpleTextEditImpl(offset, length, text);
+       }
+
+       public static SimpleTextEdit createInsert(int offset, String text) {
+               return new SimpleTextEditImpl(offset, 0, text);
+       }
+       
+       public static SimpleTextEdit createDelete(int offset, int length) {
+               return new SimpleTextEditImpl(offset, length, ""); //$NON-NLS-1$
+       }
+       
+       private final static class SimpleTextEditImpl extends SimpleTextEdit {
+               protected SimpleTextEditImpl(TextRange range, String text) {
+                       super(range, text);
+               }
+               protected SimpleTextEditImpl(int offset, int length, String text) {
+                       super(offset, length, text);
+               }
+               public TextEdit copy() {
+                       return new SimpleTextEditImpl(getTextRange().copy(), getText());
+               }       
+       }
+       
+       protected SimpleTextEdit() {
+               this(TextRange.UNDEFINED, ""); //$NON-NLS-1$
+       }
+       
+       protected SimpleTextEdit(int offset, int length, String text) {
+               this(new TextRange(offset, length), text);
+       }
+       protected SimpleTextEdit(TextRange range, String text) {
+       //      Assert.isNotNull(range);
+       //      Assert.isNotNull(text);
+               fRange= range;
+               fText= text;
+       }
+       
+       /**
+        * Returns the text edit's text
+        * 
+        * @return the text edit's text
+        */
+       public String getText() {
+               return fText;
+       }
+               
+       /**
+        * Sets the text edit's text
+        * <p>
+        * This method should only be called from within the <code>
+        * connect</code> method.
+        * 
+        * @param text the text edit's text
+        */     
+       protected final void setText(String text) {
+               fText= text;
+//             Assert.isNotNull(fText);
+       }
+       
+       /**
+        * Sets the text edit's range.
+        * <p>
+        * This method should only be called from within the <code>
+        * connect</code> method.
+        * 
+        * @param range the text edit's range.
+        */     
+       protected void setTextRange(TextRange range) {
+               fRange= range;
+       //      Assert.isNotNull(fRange);
+       }
+       
+       /* non Java-doc
+        * @see TextEdit#getTextRange
+        */
+       public TextRange getTextRange() {
+               return fRange;
+       }
+       
+       /* non Java-doc
+        * @see TextEdit#doPerform
+        */
+       public final TextEdit perform(TextBuffer buffer) throws CoreException {
+               String current= buffer.getContent(fRange.fOffset, fRange.fLength);
+               buffer.replace(fRange, fText);
+               return new SimpleTextEditImpl(fRange, current);
+       }       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SwapTextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/SwapTextEdit.java
new file mode 100644 (file)
index 0000000..eb0d247
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+
+/**
+ * A <code>SwapTextEdit</code> exchanges to text ranges.
+ */
+public class SwapTextEdit extends MultiTextEdit {
+       /**
+        * Create a new <code>SwapTextEdit</code>
+        * 
+        * @param offset1 the offset of the first text range
+        * @param length1 the length of the first text range
+        * @param offset2 the offset of the second text range
+        * @param length2 the length of the second text range
+        */
+       public SwapTextEdit(int offset1, int length1, int offset2, int length2) {
+               add(new MoveTextEdit(offset1, length1, offset2));
+               add(new MoveTextEdit(offset2, length2, offset1));
+       }
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBuffer.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBuffer.java
new file mode 100644 (file)
index 0000000..c7e2476
--- /dev/null
@@ -0,0 +1,418 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+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 net.sourceforge.phpdt.internal.corext.util.Strings;
+import net.sourceforge.phpdt.internal.ui.JavaStatusConstants;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+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.jface.util.Assert;
+
+//import org.eclipse.jdt.internal.ui.JavaPlugin;
+//import org.eclipse.jdt.internal.ui.JavaStatusConstants;
+
+/**
+ * An implementation of a <code>TextBuffer</code> that is based on <code>ITextSelection</code>
+ * and <code>IDocument</code>.
+ */
+public class TextBuffer {
+
+       private static class DocumentRegion extends TextRegion {
+               IRegion fRegion;
+               public DocumentRegion(IRegion region) {
+                       fRegion= region;
+               }
+               public int getOffset() {
+                       return fRegion.getOffset();
+               }
+               public int getLength() {
+                       return fRegion.getLength();
+               }
+       }
+       
+       public class Block {
+               public String content;
+               public int offsetDelta;
+       }
+       
+       private IDocument fDocument;
+       
+       private static final TextBufferFactory fgFactory= new TextBufferFactory();
+       
+       TextBuffer(IDocument document) {
+               fDocument= document;
+               Assert.isNotNull(fDocument);
+       }
+       
+       /**
+        * Returns the number of characters in this text buffer.
+        *
+        * @return the number of characters in this text buffer
+        */
+       public int getLength() {
+               return fDocument.getLength();
+       }
+       
+       /**
+        * Returns the number of lines in this text buffer.
+        * 
+        * @return the number of lines in this text buffer
+        */
+       public int getNumberOfLines() {
+               return fDocument.getNumberOfLines();
+       }
+       
+       /**
+        * Returns the character at the given offset in this text buffer.
+        *
+        * @param offset a text buffer offset
+        * @return the character at the offset
+        * @exception  IndexOutOfBoundsException  if the <code>offset</code> 
+        *  argument is negative or not less than the length of this text buffer.
+        */
+       public char getChar(int offset) {
+               try {
+                       return fDocument.getChar(offset);
+               } catch (BadLocationException e) {
+                       throw new ArrayIndexOutOfBoundsException(e.getMessage());
+               }
+       }
+       
+       /**
+        * Returns the whole content of the text buffer.
+        *
+        * @return the whole content of the text buffer
+        */
+       public String getContent() {
+               return fDocument.get();
+       }
+       
+       /**
+        * Returns length characters starting from the specified position.
+        *
+        * @return the characters specified by the given text region. Returns <code>
+        *  null</code> if text range is illegal
+        */
+       public String getContent(int start, int length) {
+               try {
+                       return fDocument.get(start, length);
+               } catch (BadLocationException e) {
+                       return null;
+               }
+       }
+       
+       public Block getBlockContent(int start, int length, int tabWidth) {
+               Block result= new Block();
+               StringBuffer buffer= new StringBuffer();
+               int lineOffset= getLineInformationOfOffset(start).getOffset();
+               if (start > lineOffset) {
+                       String line= getContent(lineOffset, start - lineOffset);
+                       String indent= Strings.getIndentString(line, tabWidth);
+                       result.offsetDelta= -indent.length();
+                       buffer.append(indent);
+               }
+               final int end= start + length;
+               TextRegion region= getLineInformationOfOffset(end);
+               lineOffset= region.getOffset();
+               // Cursor is at beginning of next line
+               if (lineOffset == end) {
+                       int lineNumber= getLineOfOffset(lineOffset);
+                       if (lineNumber > 0) {
+                               length= length - getLineDelimiter(lineNumber - 1).length();
+                       }
+               }
+               if (buffer.length() == 0) {
+                       result.content= getContent(start, length);
+               } else {
+                       buffer.append(getContent(start, length));
+                       result.content= buffer.toString();
+               }
+               return result;
+       }
+       
+       /**
+        * Returns the preferred line delimiter to be used for this text buffer.
+        * 
+        * @return the preferred line delimiter
+        */
+       public String getLineDelimiter() {
+               String lineDelimiter= getLineDelimiter(0);
+               if (lineDelimiter == null)
+                       lineDelimiter= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+               return lineDelimiter;
+       }
+       
+       /**
+        * Returns the line delimiter used for the given line number. Returns <code>
+        * null</code> if the line number is out of range.
+        *
+        * @return the line delimiter used by the given line number or <code>null</code>
+        */
+       public String getLineDelimiter(int line) {
+               try {
+                       return fDocument.getLineDelimiter(line);
+               } catch (BadLocationException e) {
+                       return null;
+               }       
+       }
+       
+       /**
+        * Returns the line for the given line number. If there isn't any line for
+        * the given line number, <code>null</code> is returned.
+        *
+        * @return the line for the given line number or <code>null</code>
+        */
+       public String getLineContent(int line) {
+               try {
+                       IRegion region= fDocument.getLineInformation(line);
+                       return fDocument.get(region.getOffset(), region.getLength());
+               } catch (BadLocationException e) {
+                       return null;
+               }
+       }
+       
+       /**
+        * Returns the line indent for the given line. If there isn't any line for the
+        * given line number, <code>-1</code> is returned.
+        * 
+        * @return the line indent for the given line number of <code>-1</code>
+        */
+       public int getLineIndent(int lineNumber, int tabWidth) {
+               return Strings.computeIndent(getLineContent(lineNumber), tabWidth);
+       }
+       
+       /**
+        * Returns a region of the specified line. The region contains  the offset and the 
+        * length of the line excluding the line's delimiter. Returns <code>null</code> 
+        * if the line doesn't exist.
+        *
+        * @param line the line of interest
+        * @return a line description or <code>null</code> if the given line doesn't
+        *  exist
+        */
+       public TextRegion getLineInformation(int line) {
+               try {
+                       return new DocumentRegion(fDocument.getLineInformation(line));
+               } catch (BadLocationException e) {
+                       return null;
+               }       
+       }
+       
+       /**
+        * Returns a line region of the specified offset.  The region contains the offset and 
+        * the length of the line excluding the line's delimiter. Returns <code>null</code> 
+        * if the line doesn't exist.
+        *
+        * @param offset an offset into a line
+        * @return a line description or <code>null</code> if the given line doesn't
+        *  exist
+        */ 
+       public TextRegion getLineInformationOfOffset(int offset) {
+               try {
+                       return new DocumentRegion(fDocument.getLineInformationOfOffset(offset));
+               } catch (BadLocationException e) {
+                       return null;
+               }       
+       }
+       
+       /**
+        * Returns the line number that contains the given position. If there isn't any
+        * line that contains the position, <code>null</code> is returned. The returned 
+        * string is a copy and doesn't contain the line delimiter.
+        *
+        * @return the line that contains the given offset or <code>null</code> if line
+        *  doesn't exist
+        */ 
+       public int getLineOfOffset(int offset) {
+               try {
+                       return fDocument.getLineOfOffset(offset);
+               } catch (BadLocationException e) {
+                       return -1;
+               }
+       }
+
+       /**
+        * Returns the line that contains the given position. If there isn't any
+        * line that contains the position, <code>null</code> is returned. The returned 
+        * string is a copy and doesn't contain the line delimiter.
+        *
+        * @return the line that contains the given offset or <code>null</code> if line
+        *  doesn't exist
+        */ 
+       public String getLineContentOfOffset(int offset) {
+               try {
+                       IRegion region= fDocument.getLineInformationOfOffset(offset);
+                       return fDocument.get(region.getOffset(), region.getLength());
+               } catch (BadLocationException e) {
+                       return null;
+               }
+       }
+
+       /**
+        * Converts the text determined by the region [offset, length] into an array of lines. 
+        * The lines are copies of the original lines and don't contain any line delimiter 
+        * characters.
+        *
+        * @return the text converted into an array of strings. Returns <code>null</code> if the 
+        *  region lies outside the source. 
+        */
+       public String[] convertIntoLines(int offset, int length, boolean lastNewLineCreateEmptyLine) {
+               try {
+                       String text= fDocument.get(offset, length);
+                       ILineTracker tracker= new DefaultLineTracker();
+                       tracker.set(text);
+                       int size= tracker.getNumberOfLines();
+                       int lastLine= size - 1;
+                       List result= new ArrayList(size);
+                       for (int i= 0; i < size; i++) {
+                               IRegion region= tracker.getLineInformation(i);
+                               String line= getContent(offset + region.getOffset(), region.getLength());
+                               if (i < lastLine || !"".equals(line) || lastNewLineCreateEmptyLine) //$NON-NLS-1$
+                                       result.add(line);
+                       }
+                       return (String[]) result.toArray(new String[result.size()]);
+               } catch (BadLocationException e) {
+                       return null;
+               }
+       }
+       
+       /**
+        * Subsitutes the given text for the specified text position
+        *
+        * @param offset the starting offset of the text to be replaced
+        * @param length the length of the text to be replaced
+        * @param text the substitution text
+     * @exception  CoreException  if the text position [offset, length] is invalid.     
+        */
+       public void replace(int offset, int length, String text) throws CoreException {
+               try {
+                       fDocument.replace(offset, length, text);
+               } catch (BadLocationException e) {
+                       IStatus s = new Status(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), JavaStatusConstants.INTERNAL_ERROR, 
+                               TextManipulationMessages.getFormattedString(
+                                       "TextBuffer.wrongRange",  //$NON-NLS-1$
+                                       new Object[] {new Integer(offset), new Integer(length) } ), e);
+                       throw new CoreException(s);
+               }       
+       }
+       
+       public void replace(TextRange range, String text) throws CoreException {
+               replace(range.fOffset, range.fLength, text);
+       }
+
+       //---- Special methods used by the <code>TextBufferEditor</code>
+       
+       /**
+        * Releases this text buffer.
+        */
+       /* package */ void release() {
+       }
+       
+       /* package */ void registerUpdater(IDocumentListener listener) {
+               fDocument.addDocumentListener(listener);
+       }
+       
+       /* package */ void unregisterUpdater(IDocumentListener listener) {
+               fDocument.removeDocumentListener(listener);
+       }
+               
+       //---- Factory methods ----------------------------------------------------------------
+       
+       /**
+        * Acquires a text buffer for the given file. If a text buffer for the given
+        * file already exists, then that one is returned.
+        * 
+        * @param file the file for which a text buffer is requested
+        * @return a managed text buffer for the given file
+        * @exception CoreException if it was not possible to acquire the
+        *      text buffer
+        */
+       public static TextBuffer acquire(IFile file) throws CoreException {
+               return fgFactory.acquire(file);
+       }
+       
+       /**
+        * Releases the given text buffer.
+        * 
+        * @param buffer the text buffer to be released
+        */
+       public static void release(TextBuffer buffer) {
+               fgFactory.release(buffer);
+       }
+
+       /**
+        * Commits the changes made to the given text buffer to the underlying
+        * storage system.
+        * 
+        * @param buffer the text buffer containing the changes to be committed.
+        * @param force if <code>true</code> the text buffer is committed in any case.
+        *      If <code>false</code> the text buffer is <b>ONLY</b> committed if the client 
+        *      is the last one that holds a reference to the text buffer. Clients of this
+        *      method must make sure that they don't call this method from within an <code>
+        *  IWorkspaceRunnable</code>.
+        * @param pm the progress monitor used to report progress if committing is
+        *      necessary
+        */
+       public static void commitChanges(TextBuffer buffer, boolean force, IProgressMonitor pm) throws CoreException {
+               fgFactory.commitChanges(buffer, force, pm);
+       }
+       
+       /**
+        * Creates a new <code>TextBuffer</code> for the given file. The returned
+        * buffer will not be managed. Any subsequent call to <code>create</code>
+        * with the same file will return a different text buffer.
+        * <p>
+        * If the file is currently open in a text editor, the editors content is copied into
+        * the returned <code>TextBuffer</code>. Otherwise the content is read from
+        * disk.
+        * 
+        * @param file the file for which a text buffer is to be created
+        * @return a new unmanaged text buffer
+        * @exception CoreException if it was not possible to create the text buffer
+        */
+       public static TextBuffer create(IFile file) throws CoreException {
+               return fgFactory.create(file);
+       }
+       
+       /**
+        * Creates a new <code>TextBuffer</code> for the string. The returned
+        * buffer will not be managed. Any subsequent call to <code>create</code>
+        * with the identical string will return a different text buffer.
+        * 
+        * @param content the text buffer's content
+        * @return a new unmanaged text buffer
+        */
+       public static TextBuffer create(String content) {
+               return fgFactory.create(content);
+       }
+       
+       // Unclear which methods are needed if we get the new save model. If optimal no
+       // save is needed at all.
+       
+       public static void save(TextBuffer buffer, IProgressMonitor pm) throws CoreException {
+               fgFactory.save(buffer, pm);
+       }
+       
+       public static void aboutToChange(TextBuffer buffer) throws CoreException {
+               fgFactory.aboutToChange(buffer);
+       }
+       
+       public static void changed(TextBuffer buffer) throws CoreException {
+               fgFactory.changed(buffer);
+       }               
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferEditor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferEditor.java
new file mode 100644 (file)
index 0000000..05333c3
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.sourceforge.phpdt.internal.corext.textmanipulation.TextEditNode.RootNode;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+//import org.eclipse.jdt.core.IJavaModelStatusConstants;
+//import org.eclipse.jdt.core.JavaModelException;
+//
+//import org.eclipse.jdt.internal.corext.Assert;
+
+
+/**
+ * A <code>TextBufferEditor</code> manages a set of <code>TextEdit</code>s and applies
+ * them as a whole to a <code>TextBuffer</code>. Added <code>TextEdit</code>s must 
+ * not overlap. The only exception from this rule are insertion point. There can be more than
+ * one insert point at the same text position. Clients should use the method <code>
+ * canPerformEdits</code> to validate if all added text edits follow these rules.
+ * <p>
+ * Clients can attach more than one <code>TextBufferEditor</code> to a single <code>
+ * TextBuffer</code>. If so <code>canPerformEdits</code> validates all text edits from
+ * all text buffer editors working on the same text buffer.
+ */
+public class TextBufferEditor {
+               
+       private TextBuffer fBuffer;
+       private List fEdits;
+       private RootNode fRootNode;
+       private int fNumberOfNodes;
+       private int fConnectCount;
+       private int fMode;
+
+       /* package */ static final int UNDEFINED=       0;
+       /* package */ static final int REDO=                            1;
+       /* package */ static final int UNDO=                    2;
+
+       /**
+        * Creates a new <code>TextBufferEditor</code> for the given 
+        * <code>TextBuffer</code>.
+        * 
+        * @param the text buffer this editor is working on.
+        */
+       public TextBufferEditor(TextBuffer buffer) {
+               fBuffer= buffer;
+       //      Assert.isNotNull(fBuffer);
+               fEdits= new ArrayList();
+       }
+       
+       /**
+        * Returns the text buffer this editor is working on.
+        * 
+        * @return the text buffer this editor is working on
+        */
+       public TextBuffer getTextBuffer() {
+               return fBuffer;
+       }
+       
+       /**
+        * Adds a <code>TextEdit</code> to this text editor. Adding a <code>TextEdit</code>
+        * to a <code>TextBufferEditor</code> transfers ownership of the edit to the editor. So
+        * after a edit has been added to a editor the creator of that edit <b>must</b> not continue
+        * modifing it.
+        * 
+        * @param edit the text edit to be added
+        * @exception CoreException if the text edit can not be added
+        *      to this text buffer editor
+        */
+       public void add(TextEdit edit) throws CoreException {
+       //      Assert.isTrue(fMode == UNDEFINED || fMode == REDO);
+               internalAdd(edit);
+               fMode= REDO;
+       }
+               
+       /**
+        * Adds a <code>MultiTextEdit</code> to this text editor. Adding a <code>MultiTextEdit</code>
+        * to a <code>TextBufferEditor</code> transfers ownership of the edit to the editor. So
+        * after a edit has been added to a editor the creator of that edit <b>must</b> not continue
+        * modifing it.
+        * 
+        * @param edit the multi text edit to be added
+        * @exception CoreException if the multi text edit can not be added
+        *      to this text buffer editor
+        */
+       public void add(MultiTextEdit edit) throws CoreException {
+       //      Assert.isTrue(fMode == UNDEFINED || fMode == REDO);
+               edit.connect(this);
+               fMode= REDO;
+       }
+
+       /**
+        * Adds a <code>UndoMemento</code> to this text editor. Adding a <code>UndoMemento</code>
+        * to a <code>TextBufferEditor</code> transfers ownership of the memento to the editor. So
+        * after a memento has been added to a editor the creator of that memento <b>must</b> not continue
+        * modifing it.
+        * 
+        * @param undo the undo memento to be added
+        * @exception CoreException if the undo memento can not be added
+        *      to this text buffer editor
+        */
+       public void add(UndoMemento undo) throws CoreException {
+       //      Assert.isTrue(fMode == UNDEFINED);
+               List list= undo.fEdits;
+               // Add them reverse since we are adding undos.
+               for (int i= list.size() - 1; i >= 0; i--) {
+                       internalAdd((TextEdit)list.get(i));                     
+               }
+               fMode= undo.fMode;
+       }
+       
+       /**
+        * Checks if the <code>TextEdit</code> added to this text editor can be executed.
+        * 
+        * @return <code>true</code> if the edits can be executed. Return  <code>false
+        *      </code>otherwise. One major reason why text edits cannot be executed
+        *      is a wrong offset or length value of a <code>TextEdit</code>.
+        */
+       public boolean canPerformEdits() {
+               if (fRootNode != null)
+                       return true;
+               fRootNode= buildTree();
+               if (fRootNode == null)
+                       return false;
+               if (fRootNode.validate(fBuffer.getLength()))
+                       return true;
+                       
+               fRootNode= null;
+               return false;
+       }
+       
+       /**
+        * Clears the text buffer editor.
+        */
+       public void clear() {
+               fRootNode= null;
+               fMode= UNDEFINED;
+               fEdits.clear();
+       }
+       
+       /**
+        * Executes the text edits added to this text buffer editor and clears all added
+        * text edits.
+        * 
+        * @param pm a progress monitor to report progress or <code>null</code> if
+        *      no progress is desired.
+        * @return an object representing the undo of the executed <code>TextEdit</code>s
+        * @exception CoreException if the edits cannot be executed
+        */
+       public UndoMemento performEdits(IProgressMonitor pm) throws CoreException {
+               if (pm == null)
+                       pm= new NullProgressMonitor();
+                       
+               int size= fEdits.size();
+               if (size == 0)
+                       return new UndoMemento(fMode == UNDO ? REDO : UNDO);
+                       
+               if (fRootNode == null) {
+                       fRootNode= buildTree();
+                       if (fRootNode == null || !fRootNode.validate(fBuffer.getLength())) {
+       //                      throw new JavaModelException(null, IJavaModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+      }
+               }
+               try {
+                       pm.beginTask("", fNumberOfNodes + 10); //$NON-NLS-1$
+                       UndoMemento undo= null;
+                       if (fMode == REDO) {
+                               undo= fRootNode.performDo(fBuffer, pm);
+                               fRootNode.performedDo();
+                       } else {
+                               undo= fRootNode.performUndo(fBuffer, pm);
+                               fRootNode.performedUndo();
+                       }
+                       pm.worked(10);
+                       return undo;
+               } finally {
+                       pm.done();
+                       clear();
+               }
+       }
+       
+       //---- Helper methods ------------------------------------------------------------
+       
+       private RootNode buildTree() {
+               TextEditNode[] nodes= new TextEditNode[fEdits.size()];
+               for (int i= fEdits.size() - 1; i >= 0; i--) {
+                       nodes[i]= TextEditNode.create((TextEdit)fEdits.get(i));
+               }
+               fNumberOfNodes= nodes.length;
+               Arrays.sort(nodes, new TextEditNodeComparator());
+               RootNode root= new RootNode(fBuffer.getLength());
+               for (int i= 0; i < nodes.length; i++) {
+                       root.add(nodes[i]);
+               }
+               return root;
+       }
+       
+       private void internalAdd(TextEdit edit) throws CoreException {
+               edit.index= fEdits.size();
+               edit.isSynthetic= fConnectCount > 0;
+               try {
+                       fConnectCount++;
+                       edit.connect(this);
+               } finally {
+                       fConnectCount--;
+               }
+               fEdits.add(edit);
+       }       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferFactory.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextBufferFactory.java
new file mode 100644 (file)
index 0000000..5d6800b
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * (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.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 net.sourceforge.phpdt.internal.corext.util.IOCloser;
+import net.sourceforge.phpdt.internal.ui.JavaStatusConstants;
+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(), JavaStatusConstants.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(), 
+                       JavaStatusConstants.INTERNAL_ERROR, TextManipulationMessages.getString("TextBufferFactory.bufferNotManaged"), null); //$NON-NLS-1$
+               throw new CoreException(s);
+       }
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEdit.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEdit.java
new file mode 100644 (file)
index 0000000..933aad4
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * A text edit describes an elementary text manipulation operation. Text edits
+ * are executed by adding them to a <code>TextBufferEditor</code> and then
+ * calling <code>perform</code> on the <code>TextBufferEditor</code>.
+ * <p>
+ * After a <code>TextEdit</code> has been added to a <code>TextBufferEditor</code>
+ * the method <code>connect</code> is sent to the text edit. A <code>TextEdit</code>
+ * is allowed to do some adjustments of the text range it is going to manipulate while inside
+ * the hook <code>connect</code>.
+ * 
+ * @see TextBufferEditor
+ */
+public abstract class TextEdit {
+       
+       // index that determines the insertion order into a text buffer
+       /* package */ int index;
+       /* package */ boolean isSynthetic;
+       
+       /**
+        * Connects this text edit to the given <code>TextBufferEditor</code>. A text edit 
+        * must not keep a reference to the passed text buffer editor. It is guaranteed that 
+        * the buffer passed to <code>perform<code> is equal to the buffer managed by
+        * the given text buffer editor. But they don't have to be identical.
+        * <p>
+        * Note that this method <b>should only be called</b> by a <code>
+        * TextBufferEditor</code>.
+        *<p>
+        * This default implementation does nothing. Subclasses may override
+        * if needed.
+        *  
+        * @param editor the text buffer editor this text edit has been added to
+        */
+       public void connect(TextBufferEditor editor) throws CoreException {
+               // does nothing
+       }
+       
+       /**
+        * Returns the <code>TextRange</code> that this text edit is going to
+        * manipulate. If this method is called before the <code>TextEdit</code>
+        * has been added to a <code>TextBufferEditor</code> it may return <code>
+        * null</code> or <code>TextRange.UNDEFINED</code> to indicate this situation.
+        * 
+        * @return the <code>TextRange</code>s this <code>TextEdit is going
+        *      to manipulate
+        */
+       public abstract TextRange getTextRange();
+       
+       /**
+        * Performs the text edit. Note that this method <b>should only be called</b> 
+        * by a <code>TextBufferEditor</code>. 
+        * 
+        * @param buffer the actual buffer to manipulate
+        * @return a text edit that can undo this text edit
+        */
+       public abstract TextEdit perform(TextBuffer buffer) throws CoreException;
+       
+       /**
+        * This method gets called after all <code>TextEdit</code>s added to a text buffer
+        * editor are executed. Implementors of this method can do some clean-up or can 
+        * release allocated resources that are now longer needed.
+        * <p>
+        * This default implementation does nothing.
+        */
+       public void performed() {
+               // do nothing
+       }
+               
+       /**
+     * Creates and returns a copy of this object. The copy method should
+     * be implemented in a way so that the copy can be added to a different 
+     * <code>TextBufferEditor</code> without causing any harm to the object 
+     * from which the copy has been created.
+     * 
+     * @return a copy of this object.
+     */
+       public abstract TextEdit copy() throws CoreException;   
+       
+       /**
+        * Returns the element modified by this text edit. The method
+        * may return <code>null</code> if the modification isn't related to a
+        * element or if the content of the modified text buffer doesn't
+        * follow any syntax.
+        * <p>
+        * This default implementation returns <code>null</code>
+        * 
+        * @return the element modified by this text edit
+        */
+       public Object getModifiedElement() {
+               return null;
+       }       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNode.java
new file mode 100644 (file)
index 0000000..7cfaa70
--- /dev/null
@@ -0,0 +1,493 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocumentListener;
+
+
+/**
+ * A helper class to arrange <code>TextEdit</code>s into a tree to optimize their
+ * execution.
+ */
+/* package */ abstract class TextEditNode {
+
+       /* package */ TextEditNode fParent;
+       /* package */ List fChildren;
+       /* package */ TextEdit fEdit;
+       
+       /* package */ static class DefaultNode extends TextEditNode {
+               public DefaultNode(TextEdit edit) {
+                       super(edit);
+               }
+       }
+       
+       /* package */ static class RootNode extends TextEditNode {
+               private int fUndoIndex;
+               public RootNode(int length) {
+                       super(new NopTextEdit(new TextRange(0, length)));
+                       fEdit.isSynthetic= true;
+               }
+               public boolean covers(TextEditNode node) {
+                       return true;
+               }
+               public UndoMemento performDo(TextBuffer buffer, IProgressMonitor pm) throws CoreException {
+                       DoRangeUpdater updater= new DoRangeUpdater();
+                       UndoMemento undo= new UndoMemento(TextBufferEditor.UNDO);
+                       try {
+                               buffer.registerUpdater(updater);
+                               performDo(buffer, updater, undo, pm);
+                       } finally {
+                               buffer.unregisterUpdater(updater);
+                               updater.setActiveNode(null);
+                       }
+                       return undo;
+               }
+               public UndoMemento performUndo(TextBuffer buffer, IProgressMonitor pm) throws CoreException {
+                       UndoRangeUpdater updater= new UndoRangeUpdater(this);
+                       UndoMemento undo= new UndoMemento(TextBufferEditor.REDO);
+                       try {
+                               buffer.registerUpdater(updater);
+                               performUndo(buffer, updater, undo, pm);
+                       } finally {
+                               buffer.unregisterUpdater(updater);
+                               updater.setActiveNode(null);
+                       }
+                       return undo;
+               }
+               
+               protected void setUndoIndex(int index) {
+                       fUndoIndex= index;
+               }
+               
+               protected int getUndoIndex() {
+                       return fUndoIndex;
+               }
+       }
+       
+       /* package */ abstract static class AbstractMoveNode extends TextEditNode {
+               private int state;              
+               
+               private int fTargetIndex;
+               private int fSourceIndex;
+               
+               private List fAffectedChildren;
+               
+               public AbstractMoveNode(TextEdit edit) {
+                       super(edit);
+                       reset();
+               }
+               protected abstract TextRange getSourceRange();
+               protected abstract TextRange getTargetRange();
+               protected abstract boolean isUpMove();
+               protected boolean isDownMove() {
+                       return !isUpMove();
+               }
+               public boolean isMove() {
+                       return true;
+               }
+               protected void checkRange(DocumentEvent event) {
+                       TextRange range= getChildRange();
+                       int eventOffset= event.getOffset();
+                       int eventLength= event.getLength();
+                       int eventEnd = eventOffset + eventLength - 1;
+                       // "Edit changes text that lies outside its defined range"
+       //              Assert.isTrue(range.fOffset <= eventOffset && eventEnd <= range.getInclusiveEnd());
+               }
+               protected boolean activeNodeChanged(int delta) {
+                       TextRange targetRange= getTargetRange();
+                       TextRange sourceRange= getSourceRange();
+                       switch (state) {
+                               case 0: // the move delete
+                                       init();
+       //                              Assert.isTrue(Math.abs(delta) == sourceRange.fLength);
+                                       if (isUpMove()) {
+                                               updateOffset(fAffectedChildren, delta);
+                                               targetRange.fOffset+= delta;
+                                       }
+                                       sourceRange.fLength= 0;
+                                       state= 1;
+                                       break;
+                               case 1:
+                                       TextEditNode target= (TextEditNode)fParent.fChildren.get(fTargetIndex);
+                                       TextEditNode source= (TextEditNode)fParent.fChildren.get(fSourceIndex);
+                                       updateOffset(source.fChildren, targetRange.fOffset - sourceRange.fOffset);
+                                       target.fChildren= source.fChildren;
+                                       if (target.fChildren != null) {
+                                               for (Iterator iter= target.fChildren.iterator(); iter.hasNext();) {
+                                                       ((TextEditNode)iter.next()).fParent= target;
+                                               }
+                                       }
+                                       source.fChildren= null;                         
+                                       if (isDownMove()) {
+                                               updateOffset(fAffectedChildren, delta);
+                                               sourceRange.fOffset+= delta;
+                                       }
+                                       targetRange.fLength= delta;
+                                       reset();
+                                       break;
+                       }
+                       return true;
+               }
+               private static void updateOffset(List nodes, int delta) {
+                       if (nodes == null)
+                               return;
+                       for (int i= nodes.size() - 1; i >= 0; i--) {
+                               TextEditNode node= (TextEditNode)nodes.get(i);
+                               TextRange range= node.getTextRange();
+                               range.fOffset+= delta;
+                               updateOffset(node.fChildren, delta);
+                       }
+               }
+               private void init() {
+                       TextRange source= getSourceRange();
+                       TextRange target= getTargetRange();
+                       List children= fParent.fChildren;
+                       for (int i= children.size() - 1; i >= 0; i--) {
+                               TextEditNode child= (TextEditNode)children.get(i);
+                               TextRange range= child.fEdit.getTextRange();
+                               if (range == source)
+                                       fSourceIndex= i;
+                               else if (range == target)
+                                       fTargetIndex= i;
+                       }
+                       int start= Math.min(fTargetIndex, fSourceIndex);
+                       int end= Math.max(fTargetIndex, fSourceIndex);
+                       fAffectedChildren= new ArrayList(3);
+                       for (int i= start + 1; i < end; i++) {
+                               fAffectedChildren.add(children.get(i));
+                       }
+               }
+               private void reset() {
+                       state= 0;
+                       fSourceIndex= -1;
+                       fTargetIndex= -1;
+               }
+       }
+       
+       /* package */ static class MoveNode extends AbstractMoveNode {
+               public MoveNode(TextEdit edit) {
+                       super(edit);
+               }
+               protected TextRange getChildRange() {
+                       return ((MoveTextEdit)fEdit).getChildRange();
+               }
+               protected TextRange getSourceRange() {
+                       return ((MoveTextEdit)fEdit).getSourceRange();
+               }
+               protected TextRange getTargetRange() {
+                       return ((MoveTextEdit)fEdit).getTargetRange();
+               }
+               protected boolean isUpMove() {
+                       return ((MoveTextEdit)fEdit).isUpMove();
+               }
+               public boolean isMovePartner(TextEditNode other) {
+                       if (!(other instanceof TargetMarkNode))
+                               return false;
+                       return fEdit == ((MoveTextEdit.TargetMark)other.fEdit).getMoveTextEdit();
+               }
+               public boolean covers(TextEditNode node) {
+                       if (node instanceof TargetMarkNode) {
+                               MoveTextEdit.TargetMark edit= (MoveTextEdit.TargetMark)node.fEdit;
+                               if (edit.getMoveTextEdit() == fEdit)
+                                       return false;
+                       }
+                       return getParentRange().covers(node.getChildRange());
+               }
+       }
+       
+       /* package */ static class TargetMarkNode extends AbstractMoveNode {
+               public TargetMarkNode(TextEdit edit) {
+                       super(edit);
+               }
+               protected TextRange getChildRange() {
+                       return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().getChildRange();
+               }
+               protected TextRange getSourceRange() {
+                       return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().getSourceRange();
+               }
+               protected TextRange getTargetRange() {
+                       return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().getTargetRange();
+               }
+               protected boolean isUpMove() {
+                       return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit().isUpMove();
+               }
+               public boolean isMovePartner(TextEditNode other) {
+                       return ((MoveTextEdit.TargetMark)fEdit).getMoveTextEdit() == other.fEdit;
+               }
+       }
+
+       //---- Range updating ---------------------------------------------------------------------------
+
+       private static abstract class RangeUpdater implements IDocumentListener {
+               protected TextEditNode fActiveNode;
+               public void documentAboutToBeChanged(DocumentEvent event) {
+               }
+               public void setActiveNode(TextEditNode node) {
+                       fActiveNode= node;
+               }
+               public void updateParents(int delta) {
+                       TextEditNode node= fActiveNode.fParent;
+                       while (node != null) {
+                               node.childNodeChanged(delta);
+                               node= node.fParent;
+                       }
+               }
+               public static int getDelta(DocumentEvent event) {
+                       return (event.getText() == null ? 0 : event.getText().length()) - event.getLength();
+               }
+       }
+       private static class DoRangeUpdater extends RangeUpdater {
+               private List fProcessedNodes= new ArrayList(10);
+               public void setActiveNode(TextEditNode node) {
+                       if (fActiveNode != null)
+                               fProcessedNodes.add(fActiveNode);
+                       super.setActiveNode(node);
+               }
+               public void documentChanged(DocumentEvent event) {
+                       fActiveNode.checkRange(event);
+                       int delta= getDelta(event);
+                       if (!fActiveNode.activeNodeChanged(delta)) {
+                               for (Iterator iter= fProcessedNodes.iterator(); iter.hasNext();) {
+                                       ((TextEditNode)iter.next()).previousNodeChanged(delta);
+                               }
+                       }
+                       updateParents(delta);
+               }
+       }
+       private static class UndoRangeUpdater  extends RangeUpdater {
+               private RootNode fRootNode;
+               public UndoRangeUpdater(RootNode root) {
+                       fRootNode= root;
+               }
+               public void setActiveNode(TextEditNode node) {
+                       super.setActiveNode(node);
+               }
+               public void documentChanged(DocumentEvent event) {
+                       fActiveNode.checkRange(event);
+                       int delta= getDelta(event);
+                       if (!fActiveNode.activeNodeChanged(delta)) {
+                               int start= fRootNode.getUndoIndex() + 1;
+                               List children= fRootNode.fChildren;
+                               int size= children != null ? children.size() : 0;
+                               for (int i= start; i < size; i++) {
+                                       updateUndo((TextEditNode)children.get(i), delta);
+                               }
+                       }
+                       updateParents(delta);
+               }
+               private void updateUndo(TextEditNode node, int delta) {
+                       node.previousNodeChanged(delta);
+                       List children= node.fChildren;
+                       int size= children != null ? children.size() : 0;
+                       for (int i= 0; i < size; i++) {
+                               updateUndo((TextEditNode)children.get(i), delta);
+                       }
+               }
+       }
+       
+       //---- Creating instances ---------------------------------------------------------------------------
+       
+       static TextEditNode create(TextEdit edit) {
+               if (edit instanceof MoveTextEdit)
+                       return new MoveNode(edit);
+               if (edit instanceof MoveTextEdit.TargetMark)
+                       return new TargetMarkNode(edit);
+               return new DefaultNode(edit);
+       }
+       
+       static RootNode createRoot(int length) {
+               return new RootNode(length);
+       }
+       
+       private TextEditNode(TextEdit edit) {
+               fEdit= edit;
+       }
+       
+       //---- Adding children ---------------------------------------------------------------------------
+       
+       protected void add(TextEditNode node) {
+               if (fChildren == null) {
+                       fChildren= new ArrayList(1);
+                       node.fParent= this;
+                       fChildren.add(node);
+                       return;
+               }
+               // Optimize using binary search
+               for (Iterator iter= fChildren.iterator(); iter.hasNext();) {
+                       TextEditNode child= (TextEditNode)iter.next();
+                       if (child.covers(node)) {
+                               child.add(node);
+                               return;
+                       }
+               }
+               for (int i= 0; i < fChildren.size(); ) {
+                       TextEditNode child= (TextEditNode)fChildren.get(i);
+                       if (node.covers(child)) {
+                               fChildren.remove(i);
+                               node.add(child);
+                       } else {
+                               i++;
+                       }
+               }
+               node.fParent= this;
+               fChildren.add(node);
+       }
+       
+       public boolean covers(TextEditNode node) {
+               return false; 
+       }
+       
+       //---- Accessing --------------------------------------------------------------------------------------
+       
+       protected RootNode getRoot() {
+               TextEditNode candidate= this;
+               while(candidate.fParent != null)
+                       candidate= candidate.fParent;
+               return (RootNode)candidate;
+       }
+       
+       //---- Query interface --------------------------------------------------------------------------------
+       
+       protected boolean isSynthetic() {
+               return fEdit.isSynthetic;
+       }
+       
+       public boolean isMove() {
+               return false;
+       }
+       
+       //---- Accessing Ranges ------------------------------------------------------------------------------
+       
+       protected void checkRange(DocumentEvent event) {
+               TextRange range= getTextRange();
+               int eventOffset= event.getOffset();
+               int eventLength= event.getLength();
+               int eventEnd = eventOffset + eventLength - 1;
+               // "Edit changes text that lies outside its defined range"
+       //      Assert.isTrue(range.fOffset <= eventOffset && eventEnd <= range.getInclusiveEnd());
+       }
+       
+       protected TextRange getTextRange() {
+               return fEdit.getTextRange();
+       }
+       
+       protected TextRange getChildRange() {
+               return getTextRange();
+       }
+       
+       protected TextRange getParentRange() {
+               return getTextRange();
+       }
+               
+       public boolean validate(int bufferLength) {
+               if (fChildren == null)
+                       return true;
+               // Only Moves and Nops can be parents   
+               if (!(fEdit instanceof MoveTextEdit || fEdit instanceof NopTextEdit))
+                       return false;
+               TextRange lastRange= null;
+               for (Iterator iter= fChildren.iterator(); iter.hasNext(); ) {
+                       TextEditNode node= (TextEditNode)iter.next();
+                       if (!node.validate(bufferLength))
+                               return false;
+                       TextRange range= node.fEdit.getTextRange();
+                       if (!range.isValid() || range.fOffset + range.fLength > bufferLength)
+                               return false;
+                       if (lastRange != null && !(range.isInsertionPointAt(lastRange.fOffset) || range.liesBehind(lastRange)))
+                               return false;
+                       lastRange= range;
+               }
+               return true;
+       }
+
+       //---- Updating ----------------------------------------------------------------------------------------
+       
+       protected boolean activeNodeChanged(int delta) {
+               TextRange range= getTextRange();
+               range.fLength+= delta;
+               // we didn't adjust any processed nodes.
+               return false;
+       }
+       
+       protected void previousNodeChanged(int delta) {
+               TextRange range= getTextRange();
+               range.fOffset+= delta;
+       }
+       
+       protected void childNodeChanged(int delta) {
+               getTextRange().fLength+= delta;
+       }
+
+       //---- Do it ---------------------------------------------------------------------------------------------
+       
+       protected void performDo(TextBuffer buffer, RangeUpdater updater, UndoMemento undo, IProgressMonitor pm) throws CoreException {
+               int size= fChildren != null ? fChildren.size() : 0;
+               for (int i= size - 1; i >= 0; i--) {
+                       TextEditNode child= (TextEditNode)fChildren.get(i);
+                       child.performDo(buffer, updater, undo, pm);
+               }
+               updater.setActiveNode(this);
+               if (isSynthetic())
+                       fEdit.perform(buffer);
+               else
+                       undo.add(fEdit.perform(buffer));
+               pm.worked(1);
+       }
+       
+       public void performedDo()  {
+               int size= fChildren != null ? fChildren.size() : 0;
+               for (int i= size - 1; i >= 0; i--) {
+                       TextEditNode child= (TextEditNode)fChildren.get(i);
+                       child.performedDo();
+               }
+               fEdit.performed();
+       }
+       
+       //---- Undo it -------------------------------------------------------------------------------------------
+       
+       protected void performUndo(TextBuffer buffer, RangeUpdater updater, UndoMemento undo, IProgressMonitor pm) throws CoreException {
+               int size= fChildren != null ? fChildren.size() : 0;
+               for (int i= 0; i < size; i++) {
+                       setUndoIndex(i);
+                       TextEditNode child= (TextEditNode)fChildren.get(i);
+                       child.performUndo(buffer, updater, undo, pm);
+               }
+               updater.setActiveNode(this);
+               if (isSynthetic())
+                       fEdit.perform(buffer);
+               else
+                       undo.add(fEdit.perform(buffer));
+               pm.worked(1);
+       }
+       
+       protected void setUndoIndex(int index) {
+       }
+       
+       public void performedUndo()  {
+               int size= fChildren != null ? fChildren.size() : 0;
+               for (int i= 0; i < size; i++) {
+                       TextEditNode child= (TextEditNode)fChildren.get(i);
+                       child.performedUndo();
+               }
+               fEdit.performed();
+       }
+       
+//     protected void createUndoList(List list) {
+//             int size= fChildren != null ? fChildren.size() : 0;
+//             for (int i= 0; i < size; i++) {
+//                     TextEditNode child= (TextEditNode)fChildren.get(i);
+//                     child.createUndoList(list);
+//             }
+//             list.add(this);
+//     }       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNodeComparator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextEditNodeComparator.java
new file mode 100644 (file)
index 0000000..849078e
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import java.util.Comparator;
+
+
+/**
+ * A special comparator to comapre <code>TextRange</code>s.
+ */
+/* package */ class TextEditNodeComparator  implements Comparator {
+       public int compare(Object o1, Object o2) {
+               TextEditNode node1= (TextEditNode)o1;
+               TextEditNode node2= (TextEditNode)o2;
+               TextRange pos1= node1.getTextRange();
+               TextRange pos2= node2.getTextRange();
+               
+               int offset1= pos1.fOffset;
+               int offset2= pos2.fOffset;
+               if (offset1 < offset2)
+                       return -1;
+               if (offset1 > offset2)
+                       return 1;
+
+               // same offset
+               int length1= pos1.fLength;
+               int length2= pos2.fLength;
+               
+               // insertion points come before anything else at the same position.
+               if (length1 == 0 && length2 != 0)
+                       return -1;
+               if (length1 != 0 && length2 == 0)
+                       return 1;
+               
+               // Longer edits come before shorter edits
+               if (length1 <  length2)
+                       return 1;
+               if (length1 > length2)
+                       return -1;
+               
+               if (node1.fEdit.index < node2.fEdit.index)
+                       return -1;
+               return 1;       
+       }       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextManipulationMessages.java
new file mode 100644 (file)
index 0000000..eb8b44a
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class TextManipulationMessages {
+
+       private static final String BUNDLE_NAME= "org.eclipse.jdt.internal.corext.textmanipulation.Messages"; //$NON-NLS-1$
+
+       private static final ResourceBundle RESOURCE_BUNDLE= ResourceBundle.getBundle(BUNDLE_NAME);
+
+       private TextManipulationMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return RESOURCE_BUNDLE.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+       
+       public static String getFormattedString(String key, Object arg) {
+               return getFormattedString(key, new Object[] { arg });
+       }
+       
+       public static String getFormattedString(String key, Object[] args) {
+               return MessageFormat.format(getString(key), args);      
+       }               
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRange.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRange.java
new file mode 100644 (file)
index 0000000..d92fba2
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+//import org.eclipse.jdt.core.ISourceRange;
+//
+//import org.eclipse.jdt.internal.corext.Assert;
+
+public final class TextRange {
+
+       /* package */ int fOffset;
+       /* package */ int fLength;
+       
+       public static final TextRange UNDEFINED= new TextRange((TextRange)null);
+
+       /**
+        * Creates a insert position with the given offset.
+        *
+        * @param offset the position offset, must be >= 0
+        */
+       public TextRange(int offset) {
+               this(offset, 0);
+       }
+       
+       /**
+        * Creates a new range with the given offset and length.
+        *
+        * @param offset the position offset, must be >= 0
+        * @param length the position length, must be >= 0
+        */
+       public TextRange(int offset, int length) {
+               fOffset= offset;
+//             Assert.isTrue(fOffset >= 0);
+               fLength= length;
+//             Assert.isTrue(fLength >= 0);
+       }
+       
+       /**
+        * Constructor for the undefined text range.
+        */
+       private TextRange(TextRange dummy) {
+               fOffset= -1;
+               fLength= -1;
+       }
+       
+       public static TextRange createFromStartAndLength(int start, int length) {
+               return new TextRange(start, length);
+       }
+       
+       public static TextRange createFromStartAndInclusiveEnd(int start, int end) {
+               return new TextRange(start, end - start + 1);
+       }
+       
+       public static TextRange createFromStartAndExclusiveEnd(int start, int end) {
+               return new TextRange(start, end - start);
+       }
+       
+       /**
+        * Creates a new range from the given source range.
+        * 
+        * @range the source range denoting offset and length
+        */
+//     public TextRange(ISourceRange range) {
+//             this(range.getOffset(), range.getLength());
+//     }
+       
+       /**
+        * Returns the offset of this range.
+        *
+        * @return the length of this range
+        */
+       public int getOffset() {
+               return fOffset;
+       }
+       
+       /**
+        * Returns the length of this range.
+        *
+        * @return the length of this range
+        */
+       public int getLength() {
+               return fLength;
+       }
+       
+       /**
+        * Returns the inclusive end position of this range. That means that the end position
+        * denotes the last character of this range.
+        * 
+        * @return the inclusive end position
+        */
+       public int getInclusiveEnd() {
+               return fOffset + fLength - 1;
+       }
+       
+       /**
+        * Returns the exclusive end position of this range. That means that the end position
+        * denotes the first character after this range.
+        * 
+        * @return the exclusive end position
+        */
+       public int getExclusiveEnd() {
+               return fOffset + fLength;
+       }
+       
+       /**
+        * Creates a copy of this <code>TextRange</code>.
+        * 
+        * @return a copy of this <code>TextRange</code>
+        */
+       public TextRange copy() {
+               if (isUndefined())
+                       return this;
+               return new TextRange(fOffset, fLength);
+       }
+       
+       /**
+        * Returns <code>true</code> if this text range is the <code>UNDEFINED</code>
+        * text range. Otherwise <code>false</code> is returned.
+        */
+       public boolean isUndefined() {
+               return UNDEFINED == this;
+       }
+       
+       /**
+        * Checks if this <code>TextRange</code> is valid. For valid text range the following
+        * expression evaluates to <code>true</code>:
+        * <pre>
+        *      getOffset() >= 0 && getLength() >= 0
+        * </pre>
+        * 
+        * @return <code>true</code> if this text range is a valid range. Otherwise <code>
+        *      false</code>
+        */
+       public boolean isValid() {
+               return fOffset >= 0 && fLength >= 0;
+       }
+       
+       /* package */ boolean isInsertionPoint() {
+               return fLength == 0;
+       }
+       
+       /* package */ boolean equals(TextRange range) {
+               return fOffset == range.fOffset && fLength == range.fLength;
+       }
+
+       /* package */ boolean isEqualInsertionPoint(TextRange range)    {
+               return fLength == 0 && range.fLength == 0 && fOffset == range.fOffset;
+       }
+
+       /* package */ boolean liesBehind(TextRange range) {
+               return fOffset >= range.fOffset + range.fLength;
+       }
+
+       /* package */ boolean isInsertionPointAt(int o) {
+               return fOffset == o && fLength == 0;
+       }
+       
+       /* package */ boolean covers(TextRange other) {
+               if (fLength == 0) {     // an insertion point can't cover anything
+                       return false;
+               } else if (other.fLength == 0) {
+                       int otherOffset= other.fOffset;
+                       return fOffset < otherOffset && otherOffset < fOffset + fLength;
+               } else {
+                       int otherOffset= other.fOffset;
+                       return fOffset <= otherOffset && otherOffset + other.fLength <= fOffset + fLength;
+               }
+       }
+       /* non Java-doc
+        * @see Object#toString()
+        */
+       public String toString() {
+               StringBuffer buffer= new StringBuffer();
+               buffer.append(TextManipulationMessages.getString("TextRange.offset")); //$NON-NLS-1$
+               buffer.append(fOffset);
+               buffer.append(TextManipulationMessages.getString("TextRange.length")); //$NON-NLS-1$
+               buffer.append(fLength);
+               return buffer.toString();
+       }
+
+       public boolean equals(Object obj) {
+               if (! (obj instanceof TextRange))
+                       return false;
+               TextRange other= (TextRange)obj;        
+               return fOffset == other.getOffset() && fLength == other.getLength();
+       }
+
+       public int hashCode() {
+               return fOffset ^ fLength;
+       }
+
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRegion.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/TextRegion.java
new file mode 100644 (file)
index 0000000..69919c6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+
+/**
+ * A text region describes a certain range in an <code>ITextBuffer</code>. A region is defined by 
+ * its offset into the text buffer and its length.
+ * <p>
+ * A region is considered a value object. Its offset or length do not change over time. </p>
+ * <p>
+ * <bf>NOTE:<bf> This class/interface is part of an interim API that is still under development 
+ * and expected to change significantly before reaching stability. It is being made available at 
+ * this early stage to solicit feedback from pioneering adopters on the understanding that any 
+ * code that uses this API will almost certainly be broken (repeatedly) as the API evolves.</p>
+ */
+
+// This class avoids contamination of clients with wrong imports.
+
+public abstract class TextRegion {
+       
+       /**
+        * Returns the offset of the region.
+        *
+        * @return the offset of the region
+        */
+       public abstract int getOffset();
+       /**
+        * Returns the length of the region.
+        *
+        * @return the length of the region
+        */
+       public abstract int getLength();
+       
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/UndoMemento.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/textmanipulation/UndoMemento.java
new file mode 100644 (file)
index 0000000..028b267
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.textmanipulation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * This class encapsulates the reverse change of a number of <code>TextEdit</code>s
+ * executed on a <code>TextBufferEditor</code>
+ */
+public final class UndoMemento {
+
+       /* package */ int fMode;
+       /* package */ List fEdits; 
+
+       /* package */ UndoMemento(int mode) {
+               fMode= mode;
+               fEdits= new ArrayList(10);
+       }
+       
+       /* package */ void add(TextEdit edit) {
+               fEdits.add(edit);
+       }       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/IOCloser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/IOCloser.java
new file mode 100644 (file)
index 0000000..6ed53f7
--- /dev/null
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.internal.corext.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+
+//import org.eclipse.jdt.internal.ui.JavaPlugin;
+
+public class IOCloser {
+       public static void perform(Reader reader, InputStream stream) {
+               try {
+                       rethrows(reader, stream);
+               } catch (IOException e) {
+                       PHPeclipsePlugin.log(e);
+               }
+       }
+       
+       public static void rethrows(Reader reader, InputStream stream) throws IOException {
+               if (reader != null) {
+                       reader.close();
+                       return;
+               }
+               if (stream != null) {
+                       stream.close();
+                       return;
+               }
+       }       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/Strings.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/corext/util/Strings.java
new file mode 100644 (file)
index 0000000..ab80732
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.corext.util;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.IRegion;
+
+//import org.eclipse.jdt.internal.corext.Assert;
+
+/**
+ * Helper class to provide String manipulation functions not available in standard JDK.
+ */
+public class Strings {
+
+       public static String removeNewLine(String message) {
+               StringBuffer result= new StringBuffer();
+               int current= 0;
+               int index= message.indexOf('\n', 0);
+               while (index != -1) {
+                       result.append(message.substring(current, index));
+                       if (current < index && index != 0)
+                               result.append(' ');
+                       current= index + 1;
+                       index= message.indexOf('\n', current);
+               }
+               result.append(message.substring(current));
+               return result.toString();
+       }
+
+       /**
+        * Converts the given string into an array of lines. The lines 
+        * don't contain any line delimiter characters.
+        *
+        * @return the string converted into an array of strings. Returns <code>
+        *      null</code> if the input string can't be converted in an array of lines.
+        */
+       public static String[] convertIntoLines(String input) {
+               try {
+                       ILineTracker tracker= new DefaultLineTracker();
+                       tracker.set(input);
+                       int size= tracker.getNumberOfLines();
+                       String result[]= new String[size];
+                       for (int i= 0; i < size; i++) {
+                               IRegion region= tracker.getLineInformation(i);
+                               int offset= region.getOffset();
+                               result[i]= input.substring(offset, offset + region.getLength());
+                       }
+                       return result;
+               } catch (BadLocationException e) {
+                       return null;
+               }
+       }
+
+       /**
+        * Returns <code>true</code> if the given string only consists of
+        * white spaces according to Java. If the string is empty, <code>true
+        * </code> is returned.
+        * 
+        * @return <code>true</code> if the string only consists of white
+        *      spaces; otherwise <code>false</code> is returned
+        * 
+        * @see java.lang.Character#isWhitespace(char)
+        */
+       public static boolean containsOnlyWhitespaces(String s) {
+               int size= s.length();
+               for (int i= 0; i < size; i++) {
+                       if (!Character.isWhitespace(s.charAt(i)))
+                               return false;
+               }
+               return true;
+       }
+       
+       /**
+        * Removes leading tabs and spaces from the given string. If the string
+        * doesn't contain any leading tabs or spaces then the string itself is 
+        * returned.
+        */
+       public static String trimLeadingTabsAndSpaces(String line) {
+               int size= line.length();
+               int start= size;
+               for (int i= 0; i < size; i++) {
+                       char c= line.charAt(i);
+                       if (c != '\t' && !Character.isSpaceChar(c)) {
+                               start= i;
+                               break;
+                       }
+               }
+               if (start == 0)
+                       return line;
+               else if (start == size)
+                       return ""; //$NON-NLS-1$
+               else
+                       return line.substring(start);
+       }
+       
+       public static String trimTrailingTabsAndSpaces(String line) {
+               int size= line.length();
+               int end= size;
+               for (int i= size - 1; i >= 0; i--) {
+                       char c= line.charAt(i);
+                       if (c == '\t' || Character.isSpaceChar(c)) {
+                               end= i;
+                       } else {
+                               break;
+                       }
+               }
+               if (end == size)
+                       return line;
+               else if (end == 0)
+                       return ""; //$NON-NLS-1$
+               else
+                       return line.substring(0, end);
+       }
+       
+       /**
+        * Returns the indent of the given string.
+        * 
+        * @param line the text line
+        * @param tabWidth the width of the '\t' character.
+        */
+       public static int computeIndent(String line, int tabWidth) {
+               int result= 0;
+               int blanks= 0;
+               int size= line.length();
+               for (int i= 0; i < size; i++) {
+                       char c= line.charAt(i);
+                       if (c == '\t') {
+                               result++;
+                               blanks= 0;
+                       } else if (Character.isSpaceChar(c)) {
+                               blanks++;
+                               if (blanks == tabWidth) {
+                                       result++;
+                                       blanks= 0;
+                               }
+                       } else {
+                               return result;
+                       }
+               }
+               return result;
+       }
+       
+       /**
+        * Removes the given number of idents from the line. Asserts that the given line 
+        * has the requested number of indents. If <code>indentsToRemove <= 0</code>
+        * the line is returned.
+        */
+       public static String trimIndent(String line, int indentsToRemove, int tabWidth) {
+               if (line == null || indentsToRemove <= 0)
+                       return line;
+                       
+               int start= 0;
+               int indents= 0;
+               int blanks= 0;
+               int size= line.length();
+               for (int i= 0; i < size; i++) {
+                       char c= line.charAt(i);
+                       if (c == '\t') {
+                               indents++;
+                               blanks= 0;
+                       } else if (Character.isSpaceChar(c)) {
+                                       blanks++;
+                                       if (blanks == tabWidth) {
+                                               indents++;
+                                               blanks= 0;
+                                       }
+                       } else {
+//                             Assert.isTrue(false, "Line does not have requested number of indents"); //$NON-NLS-1$
+                       }
+                       if (indents == indentsToRemove) {
+                               start= i + 1;
+                               break;
+                       }       
+               }
+               if (start == size)
+                       return ""; //$NON-NLS-1$
+               else
+                       return line.substring(start);
+       }
+       
+       /**
+        * Removes all leading indents from the given line. If the line doesn't contain
+        * any indents the line itself is returned.
+        */
+       public static String trimIndents(String s, int tabWidth) {
+               int indent= computeIndent(s, tabWidth);
+               if (indent == 0)
+                       return s;
+               return trimIndent(s, indent, tabWidth);
+       }
+       
+       /**
+        * Removes the common number of indents from all lines. If a line
+        * only consists out of white space it is ignored.
+        */
+       public static void trimIndentation(String[] lines, int tabWidth) {
+               String[] toDo= new String[lines.length];
+               // find indentation common to all lines
+               int minIndent= Integer.MAX_VALUE; // very large
+               for (int i= 0; i < lines.length; i++) {
+                       String line= lines[i];
+                       if (containsOnlyWhitespaces(line))
+                               continue;
+                       toDo[i]= line;
+                       int indent= computeIndent(line, tabWidth);
+                       if (indent < minIndent) {
+                               minIndent= indent;
+                       }
+               }
+               
+               if (minIndent > 0) {
+                       // remove this indent from all lines
+                       for (int i= 0; i < toDo.length; i++) {
+                               String s= toDo[i];
+                               if (s != null)
+                                       lines[i]= trimIndent(s, minIndent, tabWidth);
+                               else {
+                                       String line= lines[i];
+                                       int indent= computeIndent(line, tabWidth);
+                                       if (indent > minIndent)
+                                               lines[i]= trimIndent(line, minIndent, tabWidth);
+                                       else
+                                               lines[i]= trimLeadingTabsAndSpaces(line);
+                               }
+                       }
+               }
+       }
+       
+       public static String getIndentString(String line, int tabWidth) {
+               int size= line.length();
+               int end= 0;
+               int blanks= 0;
+               for (int i= 0; i < size; i++) {
+                       char c= line.charAt(i);
+                       if (c == '\t') {
+                               end= i;
+                               blanks= 0;
+                       } else if (Character.isSpaceChar(c)) {
+                               blanks++;
+                               if (blanks == tabWidth) {
+                                       end= i;
+                                       blanks= 0;
+                               }
+                       } else {
+                               break;
+                       }
+               }
+               if (end == 0)
+                       return ""; //$NON-NLS-1$
+               else if (end == size)
+                       return line;
+               else
+                       return line.substring(0, end + 1);
+       }
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaStatusConstants.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaStatusConstants.java
new file mode 100644 (file)
index 0000000..338afd6
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui;
+
+/**
+ * Defines status codes relevant to the Java UI plug-in. When a 
+ * Core exception is thrown, it contain a status object describing
+ * the cause of the exception. The status objects originating from the
+ * Java UI plug-in use the codes defined in this interface.
+  */
+public class JavaStatusConstants {
+       
+       // Prevent instantiation
+       private JavaStatusConstants() {
+       }
+
+       /** Status code describing an internal error */
+       public static final int INTERNAL_ERROR= 1;
+       
+       /**
+        * Status constant indicating that an exception occured on
+        * storing or loading templates.
+        */
+       public static final int TEMPLATE_IO_EXCEPTION = 2;
+       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIException.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIException.java
new file mode 100644 (file)
index 0000000..20fc671
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui;
+
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * An exception to wrap a status. This is necessary to use the core's IRunnableWithProgress
+ * support
+ */
+
+public class JavaUIException extends CoreException {
+       
+       public JavaUIException(IStatus status) {
+               super(status);
+       }       
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.java
new file mode 100644 (file)
index 0000000..aee11a9
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class JavaUIMessages {
+
+       private static final String RESOURCE_BUNDLE= "org.eclipse.jdt.internal.ui.JavaUIMessages";//$NON-NLS-1$
+
+       private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+       private JavaUIMessages() {
+       }
+
+       public static String getString(String key) {
+               try {
+                       return fgResourceBundle.getString(key);
+               } catch (MissingResourceException e) {
+                       return '!' + key + '!';
+               }
+       }
+       
+       public static String getFormattedString(String key, String arg) {
+               return getFormattedString(key, new String[] { arg });
+       }
+       
+       public static String getFormattedString(String key, String[] args) {
+               return MessageFormat.format(getString(key), args);      
+       }       
+       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.properties b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIMessages.properties
new file mode 100644 (file)
index 0000000..c6bf376
--- /dev/null
@@ -0,0 +1,542 @@
+#########
+## jdt.internal.ui
+#########
+
+JavaPlugin.internal_error=Internal Error
+JavaElementProperties.name=Name
+
+#########
+## actions
+#########
+AddWatchpointAction.errorTitle=Error Adding Watchpoint
+
+AddGetterSetterAction.label=&Create Getter and Setter
+AddGetterSetterAction.description=Create getter and setter methods for the field
+AddGetterSetterAction.tooltip=Create Getter and Setter Methods for the Field
+
+AddGetterSetterAction.error.title=Generate Getter and Setter
+AddGetterSetterAction.error.actionfailed=Generate Getter and Setter Failed.
+AddGetterSetterAction.error.fieldNotExisting=The field ''{0}'' has been removed in the editor.
+
+AddGetterSetterAction.QueryDialog.title=Generate Getter and Setter
+AddGetterSetterAction.SkipSetterForFinalDialog.message=Field ''{0}'' is final.\nOK to only create getter?
+AddGetterSetterAction.SkipExistingDialog.message=Method ''{0}'' already exists.\nSkip creation?
+AddGetterSetterAction.SkipExistingDialog.skip.label=&Skip
+AddGetterSetterAction.SkipExistingDialog.replace.label=&Replace
+AddGetterSetterAction.SkipExistingDialog.skipAll.label=Skip &All
+
+AddMethodStubAction.label=Create Method
+AddMethodStubAction.detailed.implement=&Implement in ''{0}''
+AddMethodStubAction.detailed.override=&Override in ''{0}''
+AddMethodStubAction.description=Add method stub to type
+AddMethodStubAction.tooltip=Add Method Stub to Type
+
+AddMethodStubAction.error.title=Add Method Stub Failed
+AddMethodStubAction.error.type_removed_in_editor=Input type has been removed in editor
+
+AddMethodStubAction.QueryDialog.title=Create Method Stub
+AddMethodStubAction.OverridesFinalDialog.message=This will override the final method ''{0}'' from ''{1}''\nOK to continue?
+AddMethodStubAction.OverridesPrivateDialog.message=This will override the private method ''{0}'' from ''{1}''\nOK to continue?
+AddMethodStubAction.ReplaceExistingDialog.message=This will replace the existing method ''{0}''.\nOK to continue?
+
+AddJavaDocStubAction.label=Add &Javadoc Comment
+AddJavaDocStubAction.description=Add a Javadoc comment stub to the member element
+AddJavaDocStubAction.tooltip=Add a Javadoc comment stub to the member element
+
+AddJavaDocStubsAction.error.dialogTitle=Add Javadoc Comment
+AddJavaDocStubsAction.error.noWorkingCopy=Could not find working copy.
+AddJavaDocStubsAction.error.memberNotExisting=Member has been removed in editor.
+AddJavaDocStubsAction.error.actionFailed=Error while adding Javadoc comment
+
+AddUnimplementedMethodsAction.label=&Override Methods...
+AddUnimplementedMethodsAction.description=Override Methods from super types.
+AddUnimplementedMethodsAction.tooltip=Override Methods
+
+AddUnimplementedMethodsAction.error.title=Override Methods
+AddUnimplementedMethodsAction.error.nothing_found=No methods to override found for this type.
+AddUnimplementedMethodsAction.error.type_removed_in_editor=Input type has been removed in editor.
+
+AddUnimplementedConstructorsAction.label=Add &Constructors from Superclass
+AddUnimplementedConstructorsAction.description=Evaluate and add constructors from superclass
+AddUnimplementedConstructorsAction.tooltip=Add Constructors from Superclass
+
+AddUnimplementedConstructorsAction.error.title=Add Constructors from Superclass
+AddUnimplementedConstructorsAction.error.nothing_found=No unimplemented constructors found.
+AddUnimplementedConstructorsAction.error.type_removed_in_editor=Input type has been removed in editor.
+
+OpenHierarchyPerspectiveItem.menulabel=Open Type &Hierarchy
+
+OpenImportDeclarationAction.errorMessage=Cannot open resource
+OpenImportDeclarationAction.errorTitle=Error On Open
+OpenImportDeclarationAction.label=&Open
+OpenImportDeclarationAction.description=Open the selected element in the editor\t
+OpenImportDeclarationAction.tooltip=Open the Selected Element in the Editor
+
+OpenJavaElementAction.description=Open the selected element
+OpenJavaElementAction.tooltip=Open the Selected Element
+OpenJavaElementAction.errorMessage=Cannot open element:
+OpenJavaElementAction.errorTitle=Problems while Opening Element
+OpenJavaElementAction.label=&Open
+
+OpenTypeAction.description=Open a type in the editor
+OpenTypeAction.tooltip=Open a Type
+OpenTypeAction.dialogMessage=&Choose a type (? = any character, * = any string):
+OpenTypeAction.dialogTitle=Open Type
+OpenTypeAction.errorMessage=An exception occurred while opening the type.
+OpenTypeAction.errorTitle=Open Type
+OpenTypeAction.label=Open Type...@Ctrl+Shift+T
+
+OpenSuperImplementationAction.label=Open S&uper Implementation
+OpenSuperImplementationAction.description=Open the Implementation in the Super Type
+OpenSuperImplementationAction.tooltip=Open the Implementation in the Super Type
+OpenSuperImplementationAction.error.title=Open Super Implementation
+OpenSuperImplementationAction.error.message=Opening failed. Check log for details.
+
+ShowInPackageViewAction.label=Show in &Package Explorer
+ShowInPackageViewAction.description=Show the selected element in Package Explorer
+ShowInPackageViewAction.tooltip=Show in Package Explorer
+ShowInPackageViewAction.error.title=Show In Package Explorer
+ShowInPackageViewAction.error.message=Internal error. Please see log for details.
+
+ShowTypeHierarchyAction.label=&Show in Type Hierarchy
+ShowTypeHierarchyAction.tooltip=Show in Type Hierarchy
+ShowTypeHierarchyAction.description=Show the type hierarchy of the selected type
+
+ShowTypeHierarchyAction.selectiondialog.title=Show In Type Hierarchy
+ShowTypeHierarchyAction.selectiondialog.message=&Select the type to be shown in the Type Hierarchy view:
+
+ShowTypeHierarchyAction.error.title=Problems Opening Type Hierarchy
+
+
+#######
+## dialogs
+#######
+
+ElementTreeSelectionDialog.nothing_available=No entries available.
+
+CheckedTreeSelectionDialog.nothing_available=No entries available.
+CheckedTreeSelectionDialog.select_all=Select &All
+CheckedTreeSelectionDialog.deselect_all=&Deselect All
+
+MultiElementListSelectionDialog.pageInfoMessage=Page {0} of {1}
+
+MultiTypeSelectionDialog.dialogMessage=Could not uniquely map the type name to a type.
+MultiTypeSelectionDialog.dialogTitle=Select Type
+MultiTypeSelectionDialog.errorMessage=Could not uniquely map the type name to a type.
+MultiTypeSelectionDialog.errorTitle=Select Type
+MultiTypeSelectionDialog.error2Message=Unexpected exception. See log for details.
+MultiTypeSelectionDialog.error2Title=Exception
+
+TypeSelectionDialog.errorMessage=Could not uniquely map the type name to a type.
+TypeSelectionDialog.errorTitle=Select Type
+TypeSelectionDialog.lowerLabel=&Qualifier:
+TypeSelectionDialog.upperLabel=&Matching types:
+TypeSelectionDialog.notypes.title=Type Selection
+TypeSelectionDialog.notypes.message=No types available.
+TypeSelectionDialog.error2Message=Unexpected exception. See log for details.
+TypeSelectionDialog.error2Title=Exception
+TypeSelectionDialog.error3Message=Unexpected exception. See log for details.
+TypeSelectionDialog.error3Title=Exception
+
+ExceptionDialog.seeErrorLogMessage= See error log for more details.
+
+MainTypeSelectionDialog.errorTitle=Error
+MultiMainTypeSelectionDialog.errorTitle=Error
+
+######
+## dnd
+######
+LocalSelectionTransfer.errorMessage=Received wrong transfer data.
+
+###########
+## preferences
+###########
+BuildPathsPropertyPage.error.message=An error occurred while setting the build path
+BuildPathsPropertyPage.error.title=Error Setting Build Path
+BuildPathsPropertyPage.no_java_project.message=Not a Java project.
+BuildPathsPropertyPage.closed_project.message=Java information is not available for a closed project.
+
+ClasspathVariablesPreferencePage.description=A classpath variable can be added to a project's class path. It can be used to define the location of a JAR file that isn't part of the workspace. The reserved class path variables JRE_LIB, JRE_SRC, JRE_SRCROOT are set internally depending on the JRE setting.
+
+ImportOrganizePreferencePage.description=Preferences used by the Organize Imports action:
+
+ImportOrganizePreferencePage.order.label=Define the &sorting order of import statements. A package name prefix (e.g. org.eclipse) is a valid entry.
+
+ImportOrganizePreferencePage.order.add.button=&New..
+ImportOrganizePreferencePage.order.edit.button=&Edit...
+ImportOrganizePreferencePage.order.up.button=&Up
+ImportOrganizePreferencePage.order.down.button=Do&wn
+ImportOrganizePreferencePage.order.remove.button=&Remove
+ImportOrganizePreferencePage.order.load.button=&Load...
+ImportOrganizePreferencePage.order.save.button=Sa&ve...
+ImportOrganizePreferencePage.ignoreLowerCase.label=Do not create imports for &types starting with a lowercase letter
+
+ImportOrganizePreferencePage.threshold.label=Number of &qualified imports before .* is used (e.g. org.eclipse.*):
+ImportOrganizePreferencePage.error.invalidthreshold=Invalid import number.
+
+ImportOrganizePreferencePage.loadDialog.title=Load Import Order from File
+ImportOrganizePreferencePage.loadDialog.error.title=Load Import Order
+ImportOrganizePreferencePage.loadDialog.error.message=Loading failed. Not a valid import order file.
+
+ImportOrganizePreferencePage.saveDialog.title=Save Import Order to File
+ImportOrganizePreferencePage.saveDialog.error.title=Save Import Order
+ImportOrganizePreferencePage.saveDialog.error.message=Writing import order file failed.
+
+
+ImportOrganizeInputDialog.title=Import Order Entry
+ImportOrganizeInputDialog.message=&Package name or package name prefix:
+ImportOrganizeInputDialog.browse.button=&Browse...
+ImportOrganizeInputDialog.ChoosePackageDialog.title=Package Selection
+ImportOrganizeInputDialog.ChoosePackageDialog.description=Choose package name or package prefix:
+ImportOrganizeInputDialog.ChoosePackageDialog.empty=No packages available.
+ImportOrganizeInputDialog.error.enterName=Enter a package name.
+ImportOrganizeInputDialog.error.invalidName=Not a valid package name. {0}
+ImportOrganizeInputDialog.error.entryExists=Package name already exists in list.
+
+JavaBasePreferencePage.description=General settings for Java development:
+
+JavaBasePreferencePage.linkPackageView= L&ink Package Explorer selection to active editor
+JavaBasePreferencePage.dblClick=A&ction on double-clicking in Package Explorer on container is  'Go Into'
+JavaBasePreferencePage.cuChildren=S&how members in Package Explorer
+
+JavaBasePreferencePage.updateJavaViews=Update Java views:
+JavaBasePreferencePage.onSave=On &save only
+JavaBasePreferencePage.whileEditing=While &editing
+JavaBasePreferencePage.notice.outliner=Note: This preference is not applied to already opened views (Outline view is always updated while editing)
+
+JavaBasePreferencePage.typeHierarchySettings=Type Hierarchy settings
+JavaBasePreferencePage.linkTypeHierarchy=Lin&k Type Hierarchy view selection to active editor
+JavaBasePreferencePage.openTypeHierarchy=When opening a Type Hierarchy:
+JavaBasePreferencePage.inPerspective=Open a new Type Hierarchy &Perspective
+JavaBasePreferencePage.inView=Show the &Type Hierarchy View in the current perspective
+JavaBasePreferencePage.doubleclick.action=Action on double click in the Package Explorer:
+JavaBasePreferencePage.doubleclick.gointo=&Go into the selected element
+JavaBasePreferencePage.doubleclick.expand=E&xpand the selected element
+
+JavaBasePreferencePage.linkSettings.text=Link settings:
+JavaBasePreferencePage.linkJavaBrowsingViewsCheckbox.text=&Link Java Browsing views selection to active editor
+
+
+NewJavaProjectPreferencePage.description=Specify the classpath entries used as default by the New Java Project creation wizard:
+
+NewJavaProjectPreferencePage.sourcefolder.label=As source and output location use:
+NewJavaProjectPreferencePage.sourcefolder.project=&Project
+NewJavaProjectPreferencePage.sourcefolder.folder=&Folders
+NewJavaProjectPreferencePage.folders.src=&Source folder name:
+NewJavaProjectPreferencePage.folders.bin=&Output location name:
+
+NewJavaProjectPreferencePage.jrelibrary.label=As &JRE library use:
+NewJavaProjectPreferencePage.jre_variable.description=JRE_LIB variable
+NewJavaProjectPreferencePage.jre_container.description=JRE container
+
+NewJavaProjectPreferencePage.folders.error.namesempty=Enter folder names.
+NewJavaProjectPreferencePage.folders.error.invalidsrcname=Invalid source folder name: {0}
+NewJavaProjectPreferencePage.folders.error.invalidbinname=Invalid output folder name: {0}
+
+NewJavaProjectPreferencePage.error.decode=Error while decoding JRE entry
+
+JavaEditorPreferencePage.updatesOnNextChangeIinEditor.label=Note: Updates on next change in the editor
+JavaEditorPreferencePage.problemIndicationTab.title=Problem Indi&cation
+
+JavaEditorPreferencePage.description=Java Editor settings:
+JavaEditorPreferencePage.font=Text Font:
+JavaEditorPreferencePage.multiLineComment=Multi-line comment
+JavaEditorPreferencePage.singleLineComment=Single-line comment
+JavaEditorPreferencePage.keywords=Keywords
+JavaEditorPreferencePage.strings=Strings
+JavaEditorPreferencePage.others=Others
+JavaEditorPreferencePage.javaDocKeywords=Javadoc keywords
+JavaEditorPreferencePage.javaDocHtmlTags=Javadoc HTML tags
+JavaEditorPreferencePage.javaDocLinks=Javadoc links
+JavaEditorPreferencePage.javaDocOthers=Javadoc others
+JavaEditorPreferencePage.backgroundColor=Background color
+JavaEditorPreferencePage.systemDefault=S&ystem Default
+JavaEditorPreferencePage.custom=C&ustom:
+JavaEditorPreferencePage.foreground=Fo&reground:
+JavaEditorPreferencePage.color=C&olor:
+JavaEditorPreferencePage.bold=&Bold
+JavaEditorPreferencePage.preview=Preview:
+JavaEditorPreferencePage.textFont=Text &font:
+JavaEditorPreferencePage.displayedTabWidth=Displayed &tab width:
+JavaEditorPreferencePage.insertSpaceForTabs=&Insert space for tabs (see Formatting preferences)
+JavaEditorPreferencePage.showProblemsBeforeCompiling=Show problems before c&ompiling
+JavaEditorPreferencePage.showOverviewRuler=Show overview &ruler
+JavaEditorPreferencePage.highlightMatchingBrackets=Highlight &matching brackets
+JavaEditorPreferencePage.matchingBracketsHighlightColor=Matching &brackets highlight color:
+JavaEditorPreferencePage.highlightCurrentLine=Hi&ghlight current line
+JavaEditorPreferencePage.currentLineHighlightColor=Current &line highlight color:
+JavaEditorPreferencePage.highlightProblems=Highlight &problems
+JavaEditorPreferencePage.problemHighlightColor=Prob&lem highlight color:
+JavaEditorPreferencePage.showPrintMargin=Sho&w print margin
+JavaEditorPreferencePage.printMarginColor=Print m&argin color:
+JavaEditorPreferencePage.printMarginColumn=Print margin col&umn:
+JavaEditorPreferencePage.findScopeColor=F&ind Scope Color:
+JavaEditorPreferencePage.linkedPositionColor=Lin&ked Position Color:
+JavaEditorPreferencePage.insertSingleProposalsAutomatically=Insert single &proposals automatically
+JavaEditorPreferencePage.showOnlyProposalsVisibleInTheInvocationContext=Show only proposals &visible in the invocation context
+JavaEditorPreferencePage.presentProposalsInAlphabeticalOrder=Present proposals in a&lphabetical order
+JavaEditorPreferencePage.enableAutoActivation=&Enable auto activation
+JavaEditorPreferencePage.automaticallyAddImportInsteadOfQualifiedName=Automatically add &import instead of qualified name
+JavaEditorPreferencePage.fillArgumentNamesOnMethodCompletion=&Fill argument names on method completion
+JavaEditorPreferencePage.autoActivationDelay=Auto activation dela&y:
+JavaEditorPreferencePage.autoActivationTriggersForJava=Auto activation &triggers for Java:
+JavaEditorPreferencePage.autoActivationTriggersForJavaDoc=Auto activation triggers for &Javadoc:
+JavaEditorPreferencePage.backgroundForCompletionProposals=&Background for completion proposals:
+JavaEditorPreferencePage.foregroundForCompletionProposals=&Foreground for completion proposals:
+JavaEditorPreferencePage.backgroundForMethodParameters=Bac&kground for method parameters:
+JavaEditorPreferencePage.foregroundForMethodParameters=Fo&reground for method parameters:
+JavaEditorPreferencePage.general=Appeara&nce
+JavaEditorPreferencePage.colors=Synta&x
+JavaEditorPreferencePage.codeAssist=Code A&ssist
+JavaEditorPreferencePage.change=C&hange...
+JavaEditorPreferencePage.empty_input=Empty input
+JavaEditorPreferencePage.invalid_input=''{0}'' is not a valid input.
+JavaEditorPreferencePage.showLineNumbers=Show &line numbers
+JavaEditorPreferencePage.lineNumberColor=Line number foreground color:
+JavaEditorPreferencePage.lineNumberForegroundColor=Line number foreground
+JavaEditorPreferencePage.matchingBracketsHighlightColor2=Matching brackets highlight
+JavaEditorPreferencePage.currentLineHighlighColor=Current line highlight
+JavaEditorPreferencePage.problemsHighlightColor=Problems highlight
+JavaEditorPreferencePage.printMarginColor2=Print margin
+JavaEditorPreferencePage.findScopeColor2=Find scope
+JavaEditorPreferencePage.linkedPositionColor2=Linked position
+JavaEditorPreferencePage.showQuickFixables=&Indicate problems solvable with Quick Fix in vertical ruler
+JavaEditorPreferencePage.synchronizeOnCursor=Synchroni&ze outline selection on cursor move (editor must be reopened)
+JavaEditorPreferencePage.appearanceOptions=Appearance co&lor options:
+
+
+JavaElementInfoPage.binary=binary
+JavaElementInfoPage.classpath_entry_kind=Classpath entry kind: 
+JavaElementInfoPage.library=library
+JavaElementInfoPage.nameLabel=Name: 
+JavaElementInfoPage.not_present=not present
+JavaElementInfoPage.package=Package: 
+JavaElementInfoPage.package_contents=Package contents: 
+JavaElementInfoPage.project=project
+JavaElementInfoPage.resource_path=Resource path: 
+JavaElementInfoPage.source=source
+JavaElementInfoPage.variable=variable
+JavaElementInfoPage.variable_path=Variable path:
+JavaElementInfoPage.location=Location:
+
+JavadocConfigurationPropertyPage.IsPackageFragmentRoot.description=Specify the location (URL) of the documentation generated by Javadoc. The Javadoc location will contain a file called 'package-list'. For example: \'http://www.sample-url.org/doc/\'
+JavadocConfigurationPropertyPage.IsIncorrectElement.description=Javadoc location can only be attached to JAR files in projects or Java projects
+JavadocConfigurationPropertyPage.IsJavaProject.description=Specify the location (URL) of the project\'s Javadoc documentation. This location is used by the Javadoc export wizard as default value and by the \'Open External Javadoc\' action. For example: \'file://c:/myworkspace/myproject/doc/\'.
+
+JavadocConfigurationBlock.location.label=Javadoc &Location:
+JavadocConfigurationBlock.location.button=Bro&wse...
+
+JavadocConfigurationBlock.error.invalidurl=Not a valid URL: {0}
+JavadocConfigurationBlock.error.notafolder=Location does not exist.
+JavadocConfigurationBlock.warning.packagelistnotfound=Location does not contain file 'package-list'.
+
+JavadocConfigurationBlock.javadocLocationDialog.label=Javadoc Location Selection
+JavadocConfigurationBlock.javadocLocationDialog.message=&Select Javadoc location:
+
+JavadocConfigurationBlock.MalformedURL.error=Invalid URL
+
+JavadocConfigurationBlock.ValidateButton.label=&Validate...
+JavadocConfigurationBlock.InvalidLocation.message= Location is invalid. Location contains neither the file \'package-list\' nor \'index.html'.
+JavadocConfigurationBlock.ValidLocation.message= Location is valid. Files \'package-list\' and \'index.html\' found. Click OK to open in browser.
+JavadocConfigurationBlock.UnableToValidateLocation.message=Unable to validate location
+JavadocConfigurationBlock.MessageDialog.title=Validating Javadoc Location
+JavadocConfigurationBlock.EmptyJavadocLocation.warning=Enter a javadoc location
+
+JavadocPreferencePage.description=Specify the location of the Javadoc command to be used by the Javadoc export wizard. Location must be an absolute path.
+JavadocPreferencePage.command.label=&Javadoc command:
+JavadocPreferencePage.command.button=Bro&wse...
+
+JavadocPreferencePage.error.notexists=Javadoc command does not exist
+
+JavadocPreferencePage.browsedialog.title=Javadoc Command Selection
+
+SourceAttachmentPropertyPage.error.title=Error Attaching Source
+SourceAttachmentPropertyPage.error.message=An error occurred while associating the source
+
+SourceAttachmentPropertyPage.noarchive.message=Source can only be attached to JAR files in Java projects.
+SourceAttachmentPropertyPage.containerentry.message=JAR belongs to the container ''{0}''.\nTo configure the source attachment, go directly to the corresponding configuration page (For example for JREs go to ''Installed JREs'' page in the preferences).
+
+AppearancePreferencePage.description= Appearance of Java elements in viewers:
+AppearancePreferencePage.methodreturntype.label= Show &method return types
+AppearancePreferencePage.overrideindicator.label= Show &override indicators in outline and hierarchy
+AppearancePreferencePage.pkgNamePatternEnable.label= &Compress package name segments (except for the last one)
+AppearancePreferencePage.pkgNamePattern.label= Com&pression pattern (e.g. given package name 'org.eclipse.jdt' pattern '.' will compress it to '..jdt',  '0' to 'jdt', '1~.' to 'o~.e~.jdt'):
+
+AppearancePreferencePage.showMembersInPackagesView=S&how members in Package Explorer
+AppearancePreferencePage.stackViewsVerticallyInTheJavaBrowsingPerspective=&Stack views vertically in the Java Browsing perspective
+AppearancePreferencePage.preferenceOnlyEffectiveForNewPerspectives=Note: This preference will only take effect on new perspectives
+AppearancePreferencePage.packageNameCompressionPattern.error.isEmpty=Enter a package name compression pattern
+
+CodeFormatterPreferencePage.description=Options for the Java Code Formatter:
+
+CodeFormatterPreferencePage.empty_input=Empty input
+CodeFormatterPreferencePage.invalid_input=''{0}'' is not a valid input.
+
+CodeFormatterPreferencePage.newline_opening_braces.label=I&nsert a new line before an opening brace
+CodeFormatterPreferencePage.newline_control_statement.label=Insert new &lines in control statements
+CodeFormatterPreferencePage.newline_clear_lines=Clear all &blank lines
+CodeFormatterPreferencePage.newline_else_if.label=&Insert new line between 'else if'
+CodeFormatterPreferencePage.newline_empty_block.label=In&sert a new line inside an empty block
+CodeFormatterPreferencePage.split_line.label=Ma&ximum line length:
+CodeFormatterPreferencePage.style_compact_assignement.label=&Compact assignment
+CodeFormatterPreferencePage.tab_char.label=Indentation is represented by a &tab
+CodeFormatterPreferencePage.tab_size.label=&Number of spaces representing a tab:
+
+CodeFormatterPreferencePage.tab.newline.tabtitle=Ne&w Lines
+CodeFormatterPreferencePage.tab.linesplit.tabtitle=Line S&plitting
+CodeFormatterPreferencePage.tab.style.tabtitle=St&yle
+
+CompilerPreferencePage.description=Options for the Java compiler:\nNote that a full rebuild is required to make changes effective.
+CompilerPreferencePage.generation.tabtitle=Classfile &Generation
+CompilerPreferencePage.warnings.tabtitle=&Errors and Warnings
+CompilerPreferencePage.compliance.tabtitle=&JDK Compliance
+CompilerPreferencePage.others.tabtitle=&Other
+
+CompilerPreferencePage.warnings.description=Select the severity level for the following problems:
+
+CompilerPreferencePage.variable_attr.label=Add &variable attributes to generated class files (used by the debugger)
+CompilerPreferencePage.line_number_attr.label=Add &line number attributes to generated class files (used by the debugger)
+CompilerPreferencePage.source_file_attr.label=Add &source file name to generated class file (used by the debugger)
+CompilerPreferencePage.codegen_unused_local.label=Preserve &unused local variables (i.e. never read) 
+
+CompilerPreferencePage.compiler_compliance.label=&Compiler compliance level:
+CompilerPreferencePage.default_settings.label=&Use default compliance settings
+CompilerPreferencePage.source_compatibility.label=&Source compatibility:
+CompilerPreferencePage.codegen_targetplatform.label=Ge&nerated .class files compatibility:
+CompilerPreferencePage.pb_assert_as_identifier.label=&Report 'assert' as identifier:
+
+CompilerPreferencePage.pb_unreachable_code.label=&Unreachable code:
+CompilerPreferencePage.pb_invalid_import.label=Unresol&vable import statements:
+CompilerPreferencePage.pb_overriding_pkg_dflt.label=&Methods overridden but not package visible:
+CompilerPreferencePage.pb_method_naming.label=Me&thods with a constructor name:
+CompilerPreferencePage.pb_deprecation.label=Usage of de&precated API:
+CompilerPreferencePage.pb_hidden_catchblock.label=&Hidden catch blocks:
+CompilerPreferencePage.pb_unused_imports.label=Unu&sed imports:
+CompilerPreferencePage.pb_unused_local.label=Unused &local variables (i.e. never read):
+CompilerPreferencePage.pb_unused_parameter.label=U&nused parameters (i.e. never read):
+CompilerPreferencePage.pb_synth_access_emul.label=A&ccess to a non-accessible member of an enclosing type:
+CompilerPreferencePage.pb_non_externalized_strings.label=Non-e&xternalized strings:
+CompilerPreferencePage.pb_max_per_unit.label=Maximum number of problems &reported per compilation unit:
+
+CompilerPreferencePage.resource_filter.description=Enter resources and resource types that should not be copied to the output folder during a build. List is comma separated (e.g. '*.doc, plugin.xml, scripts/')
+CompilerPreferencePage.resource_filter.label=Filtered &Resources:
+CompilerPreferencePage.build_invalid_classpath.label=Stop &building when an invalid classpath is detected
+
+CompilerPreferencePage.error=Error
+CompilerPreferencePage.warning=Warning
+CompilerPreferencePage.ignore=Ignore
+
+CompilerPreferencePage.jvm11=JVM 1.1
+CompilerPreferencePage.jvm12=JVM 1.2
+CompilerPreferencePage.jvm13=JVM 1.3
+CompilerPreferencePage.jvm14=JVM 1.4
+
+CompilerPreferencePage.version11=1.1
+CompilerPreferencePage.version12=1.2
+CompilerPreferencePage.version13=1.3
+CompilerPreferencePage.version14=1.4
+
+CompilerPreferencePage.needsbuild.title=Compiler Settings Changed
+CompilerPreferencePage.needsbuild.message=The compiler settings have changed. A full rebuild is required to make changes effective. Do the full build now?
+
+CompilerPreferencePage.builderror.title=Compiler Settings
+CompilerPreferencePage.builderror.message=Problem while building. Check log for details.
+
+CompilerPreferencePage.cpl13src14.error=In 1.3 compliance level, source compatibility can not be 1.4
+CompilerPreferencePage.cpl13trg14.error=In 1.3 compliance level, the classfile compatibility can not be 1.4
+CompilerPreferencePage.src14asrterr.error=With 1.4 source compatibility, 'assert' can not be an identifier.
+CompilerPreferencePage.src14tgt14.error=With 1.4 source compatibility, the classfile compatibility must be 1.4
+
+CompilerPreferencePage.empty_input=Number of problems can not be empty.
+CompilerPreferencePage.invalid_input={0} is not a valid number of problems.
+
+CompilerPreferencePage.filter.invalidsegment.error=Filter is invalid: {0}
+
+CodeGenerationPreferencePage.description=Options for Code Generation:
+
+CodeGenerationPreferencePage.gettersetter.label=Getter and Setter Creation:
+CodeGenerationPreferencePage.gettersetter.prefix.checkbox=Remove &prefix from field names
+CodeGenerationPreferencePage.gettersetter.prefix.list=P&refix list (comma separated):
+CodeGenerationPreferencePage.gettersetter.suffix.checkbox=Remove &suffix from field names
+CodeGenerationPreferencePage.gettersetter.suffix.list=S&uffix list (comma separated):
+
+CodeGenerationPreferencePage.comments.label=Comments Creation:
+CodeGenerationPreferencePage.javadoc_comment.label=Create &Javadoc comments for methods and types (template 'typecomment')
+CodeGenerationPreferencePage.see_comment.label=Create &non-Javadoc comments for overridden methods
+CodeGenerationPreferencePage.file_comment.label=Create &file comments for new files (template 'filecomment')
+
+CodeGenerationPreferencePage.gettersetter.error.emptyprefix=Prefix strings can not contain an empty entry.
+CodeGenerationPreferencePage.gettersetter.error.emptysuffix=Suffix strings can not contain an empty entry.
+CodeGenerationPreferencePage.gettersetter.error.invalidprefix={0} is not a valid prefix.
+CodeGenerationPreferencePage.gettersetter.error.invalidsuffix={0} is not a valid suffix.
+
+###########
+## viewsupport
+###########
+JavaImageLabelprovider.assert.wrongImage=no image for this JavaElement Type
+
+JavaTextLabelProvider.default_package=(default package)
+JavaTextLabelProvider.import_declarations=import declarations
+JavaTextLabelProvider.initializer=\{...\}
+
+JavaElementLabels.default_package=(default package)
+JavaElementLabels.import_container=import declarations
+JavaElementLabels.initializer=\{...\}
+JavaElementLabels.concat_string=\ -\ 
+JavaElementLabels.comma_string=,\ 
+JavaElementLabels.declseparator_string=\ :\ 
+
+StatusBarUpdater.num_elements_selected={0} items selected
+StatusBarUpdater.twopart={0} - {1}
+StatusBarUpdater.threepart={0} - {1} - {2}
+
+
+#########
+## jdt.ui
+#########
+JavaElementContentProvider.errorMessage=Child not present
+
+#########
+## util
+#########
+
+OpenTypeHierarchyUtil.error.open_view=Problems opening Type Hierarchy View
+OpenTypeHierarchyUtil.error.open_perspective=Problems opening Type Hierarchy Perspective
+OpenTypeHierarchyUtil.error.open_editor=Problems opening Java Editor
+OpenTypeHierarchyUtil.error.no_perspective=Type Hierarchy perspective not found
+OpenTypeHierarchyUtil.selectionDialog.title=Open In Type Hierarchy
+OpenTypeHierarchyUtil.selectionDialog.message=&Select the type to be shown in the Type Hierarchy:
+
+TypeInfoLabelProvider.default_package=(default package)
+TypeInfoLabelProvider.dash=\ - 
+
+JavaUIHelp.link.label=Javadoc for {0}
+
+#########
+# DnD
+#########
+ResourceTransferDragAdapter.cannot_delete_resource=Cannot delete resources
+ResourceTransferDragAdapter.moving_resource=Moving Resources via DND
+ResourceTransferDragAdapter.cannot_delete_files=Cannot delete the following file(s)
+
+#########
+# misc
+#########
+
+AddImportOnSelectionAction.error.message=AddImportOnSelectionAction: Failed to resolve TypeRef: {0}
+
+CompilationUnitDocumentProvider.problemsCreatingBuffer=Problems creating buffer
+
+_ClassFileDocumentProvider.problemsCreatingBuffer=Problems creating buffer
+
+NewMethodCompletionProposal.method=Method {0}
+
+JavaAnnotationHover.multipleMarkersAtThisLine=Multiple markers at this line
+JavaTextHover.createTextHover=Could not create java text hover
+
+HTMLTextPresenter.ellipsis=
+HTML2TextReader.dash=- 
+
+JavaEditor.codeassist.noCompletions=No completions available.
+
+OptionalMessageDialog.dontShowAgain= Don't show this message again
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIStatus.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/JavaUIStatus.java
new file mode 100644 (file)
index 0000000..e9adab1
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui;
+
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Convenience class for error exceptions thrown inside JavaUI plugin.
+ */
+public class JavaUIStatus extends Status {
+
+       public JavaUIStatus(int code, String message, Throwable throwable) {
+               super(IStatus.ERROR, PHPeclipsePlugin.getPluginId(), code, message, throwable);
+       }
+
+       public JavaUIStatus(int code, String message) {
+               this(code, message, null);
+       }
+
+       public JavaUIStatus(int code) {
+               this(code, ""); //$NON-NLS-1$
+       }
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/IJavaCompletionProposal.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/IJavaCompletionProposal.java
new file mode 100644 (file)
index 0000000..01bcec2
--- /dev/null
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+
+/*
+ * CompletionProposal with a relevance value.
+ * The relevance value is used to sort the completion proposals. Proposals with higher relevance
+ * should be listed before proposals with lower relevance.
+ */
+public interface IJavaCompletionProposal extends ICompletionProposal {
+       
+       /**
+        * Returns the relevance of the proposal.
+        */
+       int getRelevance();
+
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProcessor_NotInUseVersion.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProcessor_NotInUseVersion.java
new file mode 100644 (file)
index 0000000..6d168b5
--- /dev/null
@@ -0,0 +1,378 @@
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationExtension;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+
+import org.eclipse.ui.IEditorPart;
+
+//import org.eclipse.jdt.core.ICompilationUnit;
+//import org.eclipse.jdt.core.JavaCore;
+//import org.eclipse.jdt.core.JavaModelException;
+//
+//import org.eclipse.jdt.ui.IWorkingCopyManager;
+//import org.eclipse.jdt.ui.PreferenceConstants;
+
+import net.sourceforge.phpdt.internal.corext.template.ContextType;
+import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry;
+//import org.eclipse.jdt.internal.ui.JavaPlugin;
+import net.sourceforge.phpdt.internal.ui.JavaUIMessages;
+//import org.eclipse.jdt.internal.ui.text.JavaCodeReader;
+import net.sourceforge.phpdt.internal.ui.text.template.TemplateEngine;
+
+
+/**
+ * Java completion processor.
+ */
+public class JavaCompletionProcessor_NotInUseVersion implements IContentAssistProcessor {
+               
+       private static class ContextInformationWrapper implements IContextInformation, IContextInformationExtension {
+               
+               private final IContextInformation fContextInformation;
+               private int fPosition;
+               
+               public ContextInformationWrapper(IContextInformation contextInformation) {
+                       fContextInformation= contextInformation;
+               }
+               
+               /*
+                * @see IContextInformation#getContextDisplayString()
+                */
+               public String getContextDisplayString() {
+                       return fContextInformation.getContextDisplayString();
+               }
+
+                       /*
+                * @see IContextInformation#getImage()
+                */
+               public Image getImage() {
+                       return fContextInformation.getImage();
+               }
+
+               /*
+                * @see IContextInformation#getInformationDisplayString()
+                */
+               public String getInformationDisplayString() {
+                       return fContextInformation.getInformationDisplayString();
+               }
+
+               /*
+                * @see IContextInformationExtension#getContextInformationPosition()
+                */
+               public int getContextInformationPosition() {
+                       return fPosition;
+               }
+               
+               public void setContextInformationPosition(int position) {
+                       fPosition= position;    
+               }
+       };
+       
+       
+//     private final static String VISIBILITY= JavaCore.CODEASSIST_VISIBILITY_CHECK;
+       private final static String ENABLED= "enabled"; //$NON-NLS-1$
+       private final static String DISABLED= "disabled"; //$NON-NLS-1$
+       
+       
+       
+       private IEditorPart fEditor;
+//     private ResultCollector fCollector;
+//     private IWorkingCopyManager fManager;
+       private IContextInformationValidator fValidator;
+       
+       private char[] fProposalAutoActivationSet;
+       private JavaCompletionProposalComparator fComparator;
+       private boolean fAllowAddImports;
+        
+       private TemplateEngine fTemplateEngine;
+//     private ExperimentalResultCollector fExperimentalCollector;
+       
+       private int fNumberOfComputedResults= 0;
+       
+       
+       public JavaCompletionProcessor_NotInUseVersion(IEditorPart editor) {
+               fEditor= editor;
+//             fCollector= new ResultCollector();
+//             fManager= JavaPlugin.getDefault().getWorkingCopyManager();
+               ContextType contextType= ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
+               if (contextType != null)
+                       fTemplateEngine= new TemplateEngine(contextType);
+//             fExperimentalCollector= new ExperimentalResultCollector();
+               fAllowAddImports= true;
+               
+               fComparator= new JavaCompletionProposalComparator();
+       }
+       
+       /**
+        * Sets this processor's set of characters triggering the activation of the
+        * completion proposal computation.
+        * 
+        * @param activationSet the activation set
+        */
+       public void setCompletionProposalAutoActivationCharacters(char[] activationSet) {
+               fProposalAutoActivationSet= activationSet;
+       }
+       
+       /**
+        * Tells this processor to restrict its proposal to those element
+        * visible in the actual invocation context.
+        * 
+        * @param restrict <code>true</code> if proposals should be restricted
+        */
+       public void restrictProposalsToVisibility(boolean restrict) {
+//             Hashtable options= JavaCore.getOptions();
+//             Object value= options.get(VISIBILITY);
+//             if (value instanceof String) {
+//                     String newValue= restrict ? ENABLED : DISABLED;
+//                     if ( !newValue.equals((String) value)) {
+//                             options.put(VISIBILITY, newValue);
+//                             JavaCore.setOptions(options);
+//                     }
+//             }
+       }
+       
+       /**
+        * Tells this processor to order the proposals alphabetically.
+        * 
+        * @param order <code>true</code> if proposals should be ordered.
+        */
+       public void orderProposalsAlphabetically(boolean order) {
+               fComparator.setOrderAlphabetically(order);
+       }
+       
+       /**
+        * Tells this processor to restrict is proposals to those
+        * starting with matching cases.
+        * 
+        * @param restrict <code>true</code> if proposals should be restricted
+        */
+       public void restrictProposalsToMatchingCases(boolean restrict) {
+               // not yet supported
+       }
+       
+       /**
+        * Tells this processor to add import statement for proposals that have
+        * a fully qualified type name
+        * 
+        * @param restrict <code>true</code> if import can be added
+        */
+       public void allowAddingImports(boolean allowAddingImports) {
+               fAllowAddImports= allowAddingImports;
+       }       
+               
+       /**
+        * @see IContentAssistProcessor#getErrorMessage()
+        */  
+       public String getErrorMessage() {
+       //      if (fNumberOfComputedResults == 0)
+                       return JavaUIMessages.getString("JavaEditor.codeassist.noCompletions"); //$NON-NLS-1$
+//             return fCollector.getErrorMessage();
+       }
+
+       /**
+        * @see IContentAssistProcessor#getContextInformationValidator()
+        */
+       public IContextInformationValidator getContextInformationValidator() {
+//             if (fValidator == null)
+//                     fValidator= new JavaParameterListValidator();
+               return fValidator;
+       }
+
+       /**
+        * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+        */
+       public char[] getContextInformationAutoActivationCharacters() {
+               return null;
+       }
+
+       /**
+        * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+        */
+       public char[] getCompletionProposalAutoActivationCharacters() {
+               return fProposalAutoActivationSet;
+       }
+       
+//     private boolean looksLikeMethod(JavaCodeReader reader) throws IOException {
+//             int curr= reader.read();
+//             while (curr != JavaCodeReader.EOF && Character.isWhitespace((char) curr))
+//                     curr= reader.read();
+//                     
+//             if (curr == JavaCodeReader.EOF)
+//                     return false;
+//
+//             return Character.isJavaIdentifierPart((char) curr) || Character.isJavaIdentifierStart((char) curr);
+//     }
+       
+       private int guessContextInformationPosition(ITextViewer viewer, int offset) {
+               int contextPosition= offset;
+                       
+               IDocument document= viewer.getDocument();
+               
+//             try {
+//
+//                     JavaCodeReader reader= new JavaCodeReader();
+//                     reader.configureBackwardReader(document, offset, true, true);
+//     
+//                     int nestingLevel= 0;
+//
+//                     int curr= reader.read();                
+//                     while (curr != JavaCodeReader.EOF) {
+//
+//                             if (')' == (char) curr)
+//                                     ++ nestingLevel;
+//
+//                             else if ('(' == (char) curr) {
+//                                     -- nestingLevel;
+//                             
+//                                     if (nestingLevel < 0) {
+//                                             int start= reader.getOffset();
+//                                             if (looksLikeMethod(reader))
+//                                                     return start + 1;
+//                                     }       
+//                             }
+//
+//                             curr= reader.read();                                    
+//                     }
+//             } catch (IOException e) {
+//             }
+               
+               return contextPosition;
+       }               
+       
+       private List addContextInformations(ITextViewer viewer, int offset) {
+               ICompletionProposal[] proposals= internalComputeCompletionProposals(viewer, offset, -1);
+
+               List result= new ArrayList();
+               for (int i= 0; i < proposals.length; i++) {
+                       IContextInformation contextInformation= proposals[i].getContextInformation();
+                       if (contextInformation != null) {
+                               ContextInformationWrapper wrapper= new ContextInformationWrapper(contextInformation);
+                               wrapper.setContextInformationPosition(offset);
+                               result.add(wrapper);                            
+                       }
+               }
+               return result;
+       }
+       
+       /**
+        * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+        */
+       public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+               int contextInformationPosition= guessContextInformationPosition(viewer, offset);
+               List result= addContextInformations(viewer, contextInformationPosition);
+               return (IContextInformation[]) result.toArray(new IContextInformation[result.size()]);
+       }
+       
+       /**
+        * Order the given proposals.
+        */
+       private ICompletionProposal[] order(ICompletionProposal[] proposals) {
+               Arrays.sort(proposals, fComparator);
+               return proposals;       
+       }
+       
+       /**
+        * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)
+        */
+       public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+               int contextInformationPosition= guessContextInformationPosition(viewer, offset);
+               return internalComputeCompletionProposals(viewer, offset, contextInformationPosition);
+       }
+       
+       private ICompletionProposal[] internalComputeCompletionProposals(ITextViewer viewer, int offset, int contextOffset) {
+               
+//             ICompilationUnit unit= fManager.getWorkingCopy(fEditor.getEditorInput());
+//             IJavaCompletionProposal[] results;
+//
+//             if (JavaPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES)) {
+//                             
+//                     try {
+//                             if (unit != null) {
+//     
+//                                     fExperimentalCollector.reset(offset, contextOffset, unit.getJavaProject(), fAllowAddImports ? unit : null);
+//                                     fExperimentalCollector.setViewer(viewer);
+//                                     
+//                                     Point selection= viewer.getSelectedRange();
+//                                     if (selection.y > 0)
+//                                             fExperimentalCollector.setReplacementLength(selection.y);
+//                                     
+//                                     unit.codeComplete(offset, fExperimentalCollector);
+//                             }
+//                     } catch (JavaModelException x) {
+//                             Shell shell= viewer.getTextWidget().getShell();
+//                             ErrorDialog.openError(shell, JavaTextMessages.getString("CompletionProcessor.error.accessing.title"), JavaTextMessages.getString("CompletionProcessor.error.accessing.message"), x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$
+//                     }                               
+//
+//                     results= fExperimentalCollector.getResults();
+//
+//             } else {
+//
+//                     try {
+//                             if (unit != null) {
+//     
+//                                     fCollector.reset(offset, contextOffset, unit.getJavaProject(), fAllowAddImports ? unit : null);
+//                                     Point selection= viewer.getSelectedRange();
+//                                     if (selection.y > 0)
+//                                             fCollector.setReplacementLength(selection.y);
+//                                     
+//                                     unit.codeComplete(offset, fCollector);
+//                             }
+//                     } catch (JavaModelException x) {
+//                             Shell shell= viewer.getTextWidget().getShell();
+//                             ErrorDialog.openError(shell, JavaTextMessages.getString("CompletionProcessor.error.accessing.title"), JavaTextMessages.getString("CompletionProcessor.error.accessing.message"), x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$
+//                     }
+//                     
+//                     results= fCollector.getResults();
+//             }
+
+               if (fTemplateEngine != null) {
+          IJavaCompletionProposal[] results;
+//                     try {
+                               fTemplateEngine.reset();
+                               fTemplateEngine.complete(viewer, offset); //, unit);
+//                     } catch (JavaModelException x) {
+//                             Shell shell= viewer.getTextWidget().getShell();
+//                             ErrorDialog.openError(shell, JavaTextMessages.getString("CompletionProcessor.error.accessing.title"), JavaTextMessages.getString("CompletionProcessor.error.accessing.message"), x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$
+//                     }                               
+                        
+                       IJavaCompletionProposal[] templateResults= fTemplateEngine.getResults();
+       
+                       // concatenate arrays
+                       IJavaCompletionProposal[] total= new IJavaCompletionProposal[templateResults.length]; // +results.length ];
+                       System.arraycopy(templateResults, 0, total, 0, templateResults.length);
+//                     System.arraycopy(results, 0, total, templateResults.length, results.length);
+                       results= total;
+//             }
+               
+               fNumberOfComputedResults= (results == null ? 0 : results.length);
+               
+               /*
+                * Order here and not in result collector to make sure that the order
+                * applies to all proposals and not just those of the compilation unit. 
+                */
+               return order(results);
+    }
+    return new IJavaCompletionProposal[0];
+       }
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProposalComparator.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/java/JavaCompletionProposalComparator.java
new file mode 100644 (file)
index 0000000..8b43bb3
--- /dev/null
@@ -0,0 +1,35 @@
+package net.sourceforge.phpdt.internal.ui.text.java;
+
+import java.util.Comparator;
+
+public class JavaCompletionProposalComparator implements Comparator {
+
+       private boolean fOrderAlphabetically;
+
+       /**
+        * Constructor for CompletionProposalComparator.
+        */
+       public JavaCompletionProposalComparator() {
+               fOrderAlphabetically= false;
+       }
+       
+       public void setOrderAlphabetically(boolean orderAlphabetically) {
+               fOrderAlphabetically= orderAlphabetically;
+       }
+       
+       /* (non-Javadoc)
+        * @see Comparator#compare(Object, Object)
+        */
+       public int compare(Object o1, Object o2) {
+               IJavaCompletionProposal c1= (IJavaCompletionProposal) o1;
+               IJavaCompletionProposal c2= (IJavaCompletionProposal) o2;
+               if (!fOrderAlphabetically) {
+                       int relevanceDif= c2.getRelevance() - c1.getRelevance();
+                       if (relevanceDif != 0) {
+                               return relevanceDif;
+                       }
+               }
+               return c1.getDisplayString().compareToIgnoreCase(c2.getDisplayString());
+       }       
+       
+}
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateContentProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateContentProvider.java
new file mode 100644 (file)
index 0000000..a675702
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+import net.sourceforge.phpdt.internal.corext.template.TemplateSet;
+
+public class TemplateContentProvider implements IStructuredContentProvider {
+
+       private TemplateSet fTemplateSet;       
+
+       /*
+        * @see IStructuredContentProvider#getElements(Object)
+        */     
+       public Object[] getElements(Object input) {
+               return fTemplateSet.getTemplates();
+       }
+
+       /*
+        * @see IContentProvider#inputChanged(Viewer, Object, Object)
+        */
+       public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+               fTemplateSet= (TemplateSet) newInput;
+       }
+
+       /*
+        * @see IContentProvider#dispose()
+        */
+       public void dispose() {
+               fTemplateSet= null;
+       }
+       
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateEngine.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateEngine.java
new file mode 100644 (file)
index 0000000..d14b31e
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import java.util.ArrayList;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+
+//import org.eclipse.jdt.core.ICompilationUnit;
+//import org.eclipse.jdt.core.JavaModelException;
+
+//import org.eclipse.jdt.internal.corext.Assert;
+import net.sourceforge.phpdt.internal.corext.template.ContextType;
+import net.sourceforge.phpdt.internal.corext.template.Template;
+import net.sourceforge.phpdt.internal.corext.template.Templates;
+import net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContext;
+import net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContextType;
+//import org.eclipse.jdt.internal.ui.JavaPluginImages;
+import net.sourceforge.phpdt.internal.ui.text.java.IJavaCompletionProposal;
+//import org.eclipse.jdt.internal.ui.text.link.LinkedPositionManager;
+
+public class TemplateEngine {
+
+       /** The context type. */
+       private ContextType fContextType;
+       /** The result proposals. */
+       private ArrayList fProposals= new ArrayList();
+
+       /**
+        * Creates the template engine for a particular context type.
+        * See <code>TemplateContext</code> for supported context types.
+        */
+       public TemplateEngine(ContextType contextType) {
+       //      Assert.isNotNull(contextType);
+               fContextType= contextType;
+       }
+
+       /**
+        * Empties the collector.
+        * 
+        * @param viewer the text viewer  
+        * @param unit   the compilation unit (may be <code>null</code>)
+        */
+       public void reset() {
+               fProposals.clear();
+       }
+
+       /**
+        * Returns the array of matching templates.
+        */
+       public IJavaCompletionProposal[] getResults() {
+               return (IJavaCompletionProposal[]) fProposals.toArray(new IJavaCompletionProposal[fProposals.size()]);
+       }
+
+       /**
+        * Inspects the context of the compilation unit around <code>completionPosition</code>
+        * and feeds the collector with proposals.
+        * @param viewer the text viewer
+        * @param completionPosition the context position in the document of the text viewer
+        * @param compilationUnit the compilation unit (may be <code>null</code>)
+        */
+       public void complete(ITextViewer viewer, int completionPosition)
+  //,ICompilationUnit compilationUnit)
+       //hrows JavaModelException
+       {
+           IDocument document= viewer.getDocument();
+           
+               // prohibit recursion
+//             if (LinkedPositionManager.hasActiveManager(document))
+//                     return;
+
+               if (!(fContextType instanceof CompilationUnitContextType))
+                       return;
+               
+               ((CompilationUnitContextType) fContextType).setContextParameters(document, completionPosition);//mpilationUnit);
+               CompilationUnitContext context= (CompilationUnitContext) fContextType.createContext();
+               int start= context.getStart();
+               int end= context.getEnd();
+               IRegion region= new Region(start, end - start);
+
+               Template[] templates= Templates.getInstance().getTemplates();
+               for (int i= 0; i != templates.length; i++)
+                       if (context.canEvaluate(templates[i]))
+                               fProposals.add(new TemplateProposal(templates[i], context, region, viewer)); //luginImages.get(JavaPluginImages.IMG_OBJS_TEMPLATE)));
+       }
+
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateLabelProvider.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateLabelProvider.java
new file mode 100644 (file)
index 0000000..69765ad
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+
+import net.sourceforge.phpdt.internal.corext.template.Template;
+
+public class TemplateLabelProvider implements ITableLabelProvider {
+
+       /*
+        * @see ITableLabelProvider#getColumnImage(Object, int)
+        */
+       public Image getColumnImage(Object element, int columnIndex) {
+               return null;
+       }
+
+       /*
+        * @see ITableLabelProvider#getColumnText(Object, int)
+        */
+       public String getColumnText(Object element, int columnIndex) {
+               Template template = (Template) element;
+               
+               switch (columnIndex) {
+                       case 0:
+                               return template.getName();
+                       case 1:
+                               return template.getContextTypeName();
+                       case 2:
+                               return template.getDescription();
+                       default:
+                               return null;
+               }
+       }
+
+       /*
+        * @see IBaseLabelProvider#addListener(ILabelProviderListener)
+        */
+       public void addListener(ILabelProviderListener listener) {
+       }
+
+       /*
+        * @see IBaseLabelProvider#dispose()
+        */
+       public void dispose() {
+       }
+
+       /*
+        * @see IBaseLabelProvider#isLabelProperty(Object, String)
+        */
+       public boolean isLabelProperty(Object element, String property) {
+               return false;
+       }
+
+       /*
+        * @see IBaseLabelProvider#removeListener(ILabelProviderListener)
+        */
+       public void removeListener(ILabelProviderListener listener) {
+       }
+
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateProposal.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateProposal.java
new file mode 100644 (file)
index 0000000..5178caa
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import net.sourceforge.phpdt.internal.corext.template.Template;
+import net.sourceforge.phpdt.internal.corext.template.TemplateBuffer;
+import net.sourceforge.phpdt.internal.corext.template.TemplateContext;
+import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
+import net.sourceforge.phpdt.internal.corext.template.TemplatePosition;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.eclipse.core.runtime.CoreException;
+import net.sourceforge.phpdt.internal.corext.template.java.CompilationUnitContext;
+import net.sourceforge.phpdt.internal.corext.template.java.JavaTemplateMessages;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+//import org.eclipse.jdt.internal.ui.JavaPlugin;
+import net.sourceforge.phpdt.internal.ui.text.java.IJavaCompletionProposal;
+//import org.eclipse.jdt.internal.ui.text.link.LinkedPositionManager;
+//import org.eclipse.jdt.internal.ui.text.link.LinkedPositionUI;
+//import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
+
+/**
+ * A template proposal.
+ */
+public class TemplateProposal implements IJavaCompletionProposal {
+
+       private final Template fTemplate;
+       private final TemplateContext fContext;
+       private final ITextViewer fViewer;
+//     private final Image fImage;
+       private final IRegion fRegion;
+
+       private TemplateBuffer fTemplateBuffer;
+       private String fOldText;
+//     private IRegion fSelectedRegion; // initialized by apply()
+               
+       /**
+        * Creates a template proposal with a template and its context.
+        * @param template  the template
+        * @param context   the context in which the template was requested.
+        * @param image     the icon of the proposal.
+        */     
+       public TemplateProposal(Template template, TemplateContext context, IRegion region, ITextViewer viewer){ //, Image image) {
+//             Assert.isNotNull(template);
+//             Assert.isNotNull(context);
+//             Assert.isNotNull(region);
+//             Assert.isNotNull(viewer);
+               
+               fTemplate= template;
+               fContext= context;
+               fViewer= viewer;
+//             fImage= image;
+               fRegion= region;
+       }
+
+       /*
+        * @see ICompletionProposal#apply(IDocument)
+        */
+       public void apply(IDocument document) {
+           try {               
+                   if (fTemplateBuffer == null)
+                               fTemplateBuffer= fContext.evaluate(fTemplate);
+
+                       int start= fRegion.getOffset();
+                       int end= fRegion.getOffset() + fRegion.getLength();
+                       
+                       // insert template string
+                       String templateString= fTemplateBuffer.getString();     
+                       document.replace(start, end - start, templateString);   
+
+                       // translate positions
+       //              LinkedPositionManager manager= new LinkedPositionManager(document);
+                       TemplatePosition[] variables= fTemplateBuffer.getVariables();
+                       for (int i= 0; i != variables.length; i++) {
+                               TemplatePosition variable= variables[i];
+
+                               if (variable.isResolved())
+                                       continue;
+                               
+                               int[] offsets= variable.getOffsets();
+                               int length= variable.getLength();
+                               
+//                             for (int j= 0; j != offsets.length; j++)
+//                                     manager.addPosition(offsets[j] + start, length);
+                       }
+                       
+//                     LinkedPositionUI editor= new LinkedPositionUI(fViewer, manager);
+//                     editor.setFinalCaretOffset(getCaretOffset(fTemplateBuffer) + start);
+//                     editor.enter();
+
+//                     fSelectedRegion= editor.getSelectedRegion();
+                       
+               } catch (BadLocationException e) {
+                       PHPeclipsePlugin.log(e);        
+                       openErrorDialog(e);                         
+
+           } catch (CoreException e) {
+                       handleException(e);
+           }       
+       }
+       
+       private static int getCaretOffset(TemplateBuffer buffer) {
+           TemplatePosition[] variables= buffer.getVariables();
+               for (int i= 0; i != variables.length; i++) {
+                       TemplatePosition variable= variables[i];
+                       
+                       if (variable.getName().equals(JavaTemplateMessages.getString("GlobalVariables.variable.name.cursor"))) //$NON-NLS-1$
+                               return variable.getOffsets()[0];
+               }
+
+               return buffer.getString().length();
+       }
+       
+       /*
+        * @see ICompletionProposal#getSelection(IDocument)
+        */
+       public Point getSelection(IDocument document) {
+//             return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength());
+         return null;
+  }
+
+       /*
+        * @see ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+           try {
+                       if (fTemplateBuffer == null)
+                               fTemplateBuffer= fContext.evaluate(fTemplate);
+
+                       return textToHTML(fTemplateBuffer.getString());
+
+           } catch (CoreException e) {
+                       handleException(e);                 
+                       return null;
+           }
+       }
+
+       /*
+        * @see ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               return fTemplate.getName() + TemplateMessages.getString("TemplateProposal.delimiter") + fTemplate.getDescription(); // $NON-NLS-1$ //$NON-NLS-1$
+       }
+
+       /*
+        * @see ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+//             return fImage;
+     return null;
+       }
+
+       /*
+        * @see ICompletionProposal#getContextInformation()
+        */
+       public IContextInformation getContextInformation() {
+               return null;
+       }
+
+       private static String textToHTML(String string) {
+               StringBuffer buffer= new StringBuffer(string.length());
+               buffer.append("<pre>"); //$NON-NLS-1$
+       
+               for (int i= 0; i != string.length(); i++) {
+                       char ch= string.charAt(i);
+                       
+                       switch (ch) {
+                               case '&':
+                                       buffer.append("&amp;"); //$NON-NLS-1$
+                                       break;
+                                       
+                               case '<':
+                                       buffer.append("&lt;"); //$NON-NLS-1$
+                                       break;
+
+                               case '>':
+                                       buffer.append("&gt;"); //$NON-NLS-1$
+                                       break;
+
+                               case '\t':
+                                       buffer.append("    "); //$NON-NLS-1$
+                                       break;
+
+                               case '\n':
+                                       buffer.append("<br>"); //$NON-NLS-1$
+                                       break;
+
+                               default:
+                                       buffer.append(ch);
+                                       break;
+                       }
+               }
+
+               buffer.append("</pre>"); //$NON-NLS-1$
+               return buffer.toString();
+       }
+
+       private void openErrorDialog(BadLocationException e) {
+               Shell shell= fViewer.getTextWidget().getShell();
+               MessageDialog.openError(shell, TemplateMessages.getString("TemplateEvaluator.error.title"), e.getMessage()); //$NON-NLS-1$
+       }
+
+       private void handleException(CoreException e) {
+               Shell shell= fViewer.getTextWidget().getShell();
+    PHPeclipsePlugin.log(e);
+//             ExceptionHandler.handle(e, shell, TemplateMessages.getString("TemplateEvaluator.error.title"), null); //$NON-NLS-1$
+       }
+
+       /*
+        * @see IJavaCompletionProposal#getRelevance()
+        */
+       public int getRelevance() {
+
+               if (fContext instanceof CompilationUnitContext) {
+                       CompilationUnitContext context= (CompilationUnitContext) fContext;
+                       switch (context.getCharacterBeforeStart()) { 
+                       // high relevance after whitespace
+                       case ' ':
+                       case '\r':
+                       case '\n':
+                       case '\t':
+                               return 90;
+
+                       default:
+                               return 0;
+                       }
+               } else {
+                       return 90;                      
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProcessor.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProcessor.java
new file mode 100644 (file)
index 0000000..ec60207
--- /dev/null
@@ -0,0 +1,129 @@
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+
+import net.sourceforge.phpdt.internal.corext.template.ContextType;
+import net.sourceforge.phpdt.internal.corext.template.TemplateVariable;
+
+public class TemplateVariableProcessor implements IContentAssistProcessor {    
+
+       private static Comparator fgTemplateVariableProposalComparator= new Comparator() {
+               public int compare(Object arg0, Object arg1) {
+                       TemplateVariableProposal proposal0= (TemplateVariableProposal) arg0;
+                       TemplateVariableProposal proposal1= (TemplateVariableProposal) arg1;
+                       
+                       return proposal0.getDisplayString().compareTo(proposal1.getDisplayString());
+               }
+
+               public boolean equals(Object arg0) {
+                       return false;
+               }
+       };
+
+       
+       /** the context type */
+       private ContextType fContextType;
+       
+       /**
+        * Sets the context type.
+        */
+       public void setContextType(ContextType contextType) {
+               fContextType= contextType;      
+       }
+       
+       /*
+        * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)
+        */
+       public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,     int documentOffset) {
+
+               if (fContextType == null)
+                       return null;
+
+               List proposals= new ArrayList();                
+               
+               String text= viewer.getDocument().get();
+               int start= getStart(text, documentOffset);
+               int end= documentOffset;
+
+               String string= text.substring(start, end);
+               String prefix= (string.length() >= 2)
+                       ? string.substring(2)
+                       : null;
+
+               int offset= start;
+               int length= end - start;
+
+               for (Iterator iterator= fContextType.variableIterator(); iterator.hasNext(); ) {
+                       TemplateVariable variable= (TemplateVariable) iterator.next();
+
+                       if (prefix == null || variable.getName().startsWith(prefix))
+                               proposals.add(new TemplateVariableProposal(variable, offset, length, viewer));
+               }
+
+               Collections.sort(proposals, fgTemplateVariableProposalComparator);
+               return (ICompletionProposal[]) proposals.toArray(new ICompletionProposal[proposals.size()]);
+       }
+
+       /* Guesses the start position of the completion */
+       private int getStart(String string, int end) {
+               int start= end;
+
+               if (start >= 1 && string.charAt(start - 1) == '$')
+                       return start - 1;
+                               
+               while ((start != 0) && Character.isUnicodeIdentifierPart(string.charAt(start - 1)))
+                       start--;
+
+               if (start >= 2 && string.charAt(start - 1) == '{' && string.charAt(start - 2) == '$')
+                       return start - 2;
+                       
+               return end;
+       }
+
+       /*
+        * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+        */
+       public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
+               return null;
+       }
+
+       /*
+        * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+        */
+       public char[] getCompletionProposalAutoActivationCharacters() {
+               return new char[] {'$'};
+       }
+
+       /*
+        * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+        */
+       public char[] getContextInformationAutoActivationCharacters() {
+               return null;
+       }
+
+       /*
+        * @see IContentAssistProcessor#getErrorMessage()
+        */
+       public String getErrorMessage() {
+               return null;
+       }
+
+       /*
+        * @see IContentAssistProcessor#getContextInformationValidator()
+        */
+       public IContextInformationValidator getContextInformationValidator() {
+               return null;
+       }
+
+}
+
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProposal.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/ui/text/template/TemplateVariableProposal.java
new file mode 100644 (file)
index 0000000..794209d
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * (c) Copyright IBM Corp. 2000, 2001.
+ * All Rights Reserved.
+ */
+package net.sourceforge.phpdt.internal.ui.text.template;
+
+import net.sourceforge.phpdt.internal.corext.template.TemplateMessages;
+import net.sourceforge.phpdt.internal.corext.template.TemplateVariable;
+import net.sourceforge.phpeclipse.PHPeclipsePlugin;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+//import org.eclipse.jdt.internal.ui.JavaPlugin;
+
+/**
+ * A proposal for insertion of template variables.
+ */
+public class TemplateVariableProposal implements ICompletionProposal {
+
+       private TemplateVariable fVariable;
+       private int fOffset;
+       private int fLength;    
+       private ITextViewer fViewer;
+       
+       private Point fSelection;
+
+       /**
+        * Creates a template variable proposal.
+        * 
+        * @param variable the template variable
+        * @param offset the offset to replace
+        * @param length the length to replace
+        * @param viewer the viewer
+        */
+       public TemplateVariableProposal(TemplateVariable variable, int offset, int length, ITextViewer viewer) {
+               fVariable= variable;
+               fOffset= offset;
+               fLength= length;
+               fViewer= viewer;
+       }
+       
+       /*
+        * @see ICompletionProposal#apply(IDocument)
+        */
+       public void apply(IDocument document) {
+
+               try {
+                       String variable= fVariable.getName().equals("dollar") ? "$$" : "${" + fVariable.getName() + '}'; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                       document.replace(fOffset, fLength, variable);
+                       fSelection= new Point(fOffset + variable.length(), 0);
+
+               } catch (BadLocationException e) {
+                       PHPeclipsePlugin.log(e);
+
+                       Shell shell= fViewer.getTextWidget().getShell();
+                       MessageDialog.openError(shell, TemplateMessages.getString("TemplateVariableProposal.error.title"), e.getMessage()); //$NON-NLS-1$
+               }
+       }
+
+       /*
+        * @see ICompletionProposal#getSelection(IDocument)
+        */
+       public Point getSelection(IDocument document) {
+               return fSelection;
+       }
+
+       /*
+        * @see ICompletionProposal#getAdditionalProposalInfo()
+        */
+       public String getAdditionalProposalInfo() {
+               return null;
+       }
+
+       /*
+        * @see ICompletionProposal#getDisplayString()
+        */
+       public String getDisplayString() {
+               return fVariable.getName() + " - " + fVariable.getDescription(); //$NON-NLS-1$
+       }
+
+       /*
+        * @see ICompletionProposal#getImage()
+        */
+       public Image getImage() {
+               return null;
+       }
+
+       /*
+        * @see ICompletionProposal#getContextInformation()
+        */
+       public IContextInformation getContextInformation() {
+               return null;
+       }
+}
\ No newline at end of file
index 6fd4ce7..c7ad06a 100644 (file)
@@ -13,7 +13,14 @@ package net.sourceforge.phpeclipse.phpeditor.php;
 
 import java.text.MessageFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
+import net.sourceforge.phpdt.internal.corext.template.ContextType;
+import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry;
+import net.sourceforge.phpdt.internal.ui.text.java.IJavaCompletionProposal;
+import net.sourceforge.phpdt.internal.ui.text.java.JavaCompletionProposalComparator;
+import net.sourceforge.phpdt.internal.ui.text.template.TemplateEngine;
 import org.eclipse.jface.text.BadLocationException;
 import org.eclipse.jface.text.IDocument;
 import org.eclipse.jface.text.ITextViewer;
@@ -23,9 +30,10 @@ import org.eclipse.jface.text.contentassist.ContextInformation;
 import org.eclipse.jface.text.contentassist.ICompletionProposal;
 import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
 import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationExtension;
 import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
 import org.eclipse.jface.text.contentassist.IContextInformationValidator;
-import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Image;
 
 /**
  * Example PHP completion processor.
@@ -62,6 +70,48 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
     }
   };
 
+  private static class ContextInformationWrapper implements IContextInformation, IContextInformationExtension {
+
+    private final IContextInformation fContextInformation;
+    private int fPosition;
+
+    public ContextInformationWrapper(IContextInformation contextInformation) {
+      fContextInformation = contextInformation;
+    }
+
+    /*
+     * @see IContextInformation#getContextDisplayString()
+     */
+    public String getContextDisplayString() {
+      return fContextInformation.getContextDisplayString();
+    }
+
+    /*
+    * @see IContextInformation#getImage()
+    */
+    public Image getImage() {
+      return fContextInformation.getImage();
+    }
+
+    /*
+     * @see IContextInformation#getInformationDisplayString()
+     */
+    public String getInformationDisplayString() {
+      return fContextInformation.getInformationDisplayString();
+    }
+
+    /*
+     * @see IContextInformationExtension#getContextInformationPosition()
+     */
+    public int getContextInformationPosition() {
+      return fPosition;
+    }
+
+    public void setContextInformationPosition(int position) {
+      fPosition = position;
+    }
+  };
+
   protected final static String[] fgProposals = PHPFunctionNames.FUNCTION_NAMES;
   //    {
   //      "array",
@@ -101,51 +151,64 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
   //      "var" };
 
   protected IContextInformationValidator fValidator = new Validator();
+  private TemplateEngine fTemplateEngine;
+  private JavaCompletionProposalComparator fComparator;
+  private int fNumberOfComputedResults = 0;
+
+  public PHPCompletionProcessor() {
 
+    ContextType contextType = ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
+    if (contextType != null)
+      fTemplateEngine = new TemplateEngine(contextType);
+
+    fComparator = new JavaCompletionProposalComparator();
+  }
   /* (non-Javadoc)
    * Method declared on IContentAssistProcessor
    */
   public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
-
-    //    ArrayList arrList = new ArrayList(5);
     //    IDocument document = viewer.getDocument();
     //    if (documentOffset > 0) {
     //      try {
+    //        ICompletionProposal[] result;
     //        char character = document.getChar(documentOffset - 1);
-    //        Point point = PHPWordExtractor.findWord(document, documentOffset);
-    //        if (point != null) {
-    //          String word = document.get(point.x, point.y);
+    //        if (character == '$') {
+    ////viewer.  .getActivePage().getActiveEditor();
+    //          result = new ICompletionProposal[fgProposals.length];
     //          for (int i = 0; i < fgProposals.length; i++) {
-    //            if ((fgProposals[i].length() >= point.y) && fgProposals[i].substring(0, point.y).equals(word)) {
-    //              IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
-    //              arrList.add(new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] }))); //$NON-NLS-1$
-    //            }
-    //          }
-    //          if (arrList.size() > 0) {
-    //            ICompletionProposal[] result = new ICompletionProposal[arrList.size()];
-    //            for (int i=0;i<arrList.size();i++) {
-    //              result[i] = (CompletionProposal) arrList.get(i);
-    //            }
-    //            return result;
+    //            IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
+    //            result[i] = new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
     //          }
+    //          return result;
     //        }
     //      } catch (BadLocationException e) {
+    //        return new ICompletionProposal[0];
     //      }
+    //    }
     //
+    //    ICompletionProposal[] result = new ICompletionProposal[fgProposals.length];
+    //    for (int i = 0; i < fgProposals.length; i++) {
+    //      IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
+    //      result[i] = new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
     //    }
+    //    return result;
+    int contextInformationPosition = guessContextInformationPosition(viewer, documentOffset);
+    return internalComputeCompletionProposals(viewer, documentOffset, contextInformationPosition);
+
+  }
 
-    ArrayList arrList = new ArrayList(5);
+  private ICompletionProposal[] internalComputeCompletionProposals(ITextViewer viewer, int offset, int contextOffset) {
     IDocument document = viewer.getDocument();
-    if (documentOffset > 0) {
+    if (offset > 0) {
       try {
         ICompletionProposal[] result;
-        char character = document.getChar(documentOffset - 1);
+        char character = document.getChar(offset - 1);
         if (character == '$') {
-//viewer.  .getActivePage().getActiveEditor();
+          //viewer.  .getActivePage().getActiveEditor();
           result = new ICompletionProposal[fgProposals.length];
           for (int i = 0; i < fgProposals.length; i++) {
             IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
-            result[i] = new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
+            result[i] = new CompletionProposal(fgProposals[i], offset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
           }
           return result;
         }
@@ -154,26 +217,114 @@ public class PHPCompletionProcessor implements IContentAssistProcessor {
       }
     }
 
-    ICompletionProposal[] result = new ICompletionProposal[fgProposals.length];
-    for (int i = 0; i < fgProposals.length; i++) {
-      IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
-      result[i] = new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
+    if (fTemplateEngine != null) {
+      IJavaCompletionProposal[] results;
+      //      try {
+      fTemplateEngine.reset();
+      fTemplateEngine.complete(viewer, offset); //, unit);
+      //      } catch (JavaModelException x) {
+      //        Shell shell= viewer.getTextWidget().getShell();
+      //        ErrorDialog.openError(shell, JavaTextMessages.getString("CompletionProcessor.error.accessing.title"), JavaTextMessages.getString("CompletionProcessor.error.accessing.message"), x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$
+      //      }       
+
+      IJavaCompletionProposal[] templateResults = fTemplateEngine.getResults();
+
+      // concatenate arrays
+      IJavaCompletionProposal[] total = new IJavaCompletionProposal[templateResults.length]; // +results.length ];
+      System.arraycopy(templateResults, 0, total, 0, templateResults.length);
+      //      System.arraycopy(results, 0, total, templateResults.length, results.length);
+      results = total;
+      //    }
+
+      fNumberOfComputedResults = (results == null ? 0 : results.length);
+
+      /*
+       * Order here and not in result collector to make sure that the order
+       * applies to all proposals and not just those of the compilation unit. 
+       */
+      return order(results);
     }
+    return new IJavaCompletionProposal[0];
+  }
 
-    return result;
+  private int guessContextInformationPosition(ITextViewer viewer, int offset) {
+    int contextPosition = offset;
+
+    IDocument document = viewer.getDocument();
+
+    //    try {
+    //
+    //      JavaCodeReader reader= new JavaCodeReader();
+    //      reader.configureBackwardReader(document, offset, true, true);
+    //  
+    //      int nestingLevel= 0;
+    //
+    //      int curr= reader.read();    
+    //      while (curr != JavaCodeReader.EOF) {
+    //
+    //        if (')' == (char) curr)
+    //          ++ nestingLevel;
+    //
+    //        else if ('(' == (char) curr) {
+    //          -- nestingLevel;
+    //        
+    //          if (nestingLevel < 0) {
+    //            int start= reader.getOffset();
+    //            if (looksLikeMethod(reader))
+    //              return start + 1;
+    //          } 
+    //        }
+    //
+    //        curr= reader.read();          
+    //      }
+    //    } catch (IOException e) {
+    //    }
+
+    return contextPosition;
   }
 
   /* (non-Javadoc)
    * Method declared on IContentAssistProcessor
    */
-  public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
-    IContextInformation[] result = new IContextInformation[5];
-    for (int i = 0; i < result.length; i++)
-      result[i] = new ContextInformation(MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.display.pattern"), new Object[] { new Integer(i), new Integer(documentOffset)}), //$NON-NLS-1$
-      MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.value.pattern"), new Object[] { new Integer(i), new Integer(documentOffset - 5), new Integer(documentOffset + 5)})); //$NON-NLS-1$
+  //  public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
+  //    IContextInformation[] result = new IContextInformation[5];
+  //    for (int i = 0; i < result.length; i++)
+  //      result[i] = new ContextInformation(MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.display.pattern"), new Object[] { new Integer(i), new Integer(documentOffset)}), //$NON-NLS-1$
+  //      MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.value.pattern"), new Object[] { new Integer(i), new Integer(documentOffset - 5), new Integer(documentOffset + 5)})); //$NON-NLS-1$
+  //    return result;
+  //  }
+  /**
+   * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+   */
+  public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+    int contextInformationPosition = guessContextInformationPosition(viewer, offset);
+    List result = addContextInformations(viewer, contextInformationPosition);
+    return (IContextInformation[]) result.toArray(new IContextInformation[result.size()]);
+  }
+
+  private List addContextInformations(ITextViewer viewer, int offset) {
+    ICompletionProposal[] proposals = internalComputeCompletionProposals(viewer, offset, -1);
+
+    List result = new ArrayList();
+    for (int i = 0; i < proposals.length; i++) {
+      IContextInformation contextInformation = proposals[i].getContextInformation();
+      if (contextInformation != null) {
+        ContextInformationWrapper wrapper = new ContextInformationWrapper(contextInformation);
+        wrapper.setContextInformationPosition(offset);
+        result.add(wrapper);
+      }
+    }
     return result;
   }
 
+  /**
+   * Order the given proposals.
+   */
+  private ICompletionProposal[] order(ICompletionProposal[] proposals) {
+    Arrays.sort(proposals, fComparator);
+    return proposals;
+  }
+
   /* (non-Javadoc)
    * Method declared on IContentAssistProcessor
    */