c6c96e359b7343d5bbeff6190f360e32dddf6d72
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / corext / template / ContextType.java
1 /*
2  * (c) Copyright IBM Corp. 2000, 2001.
3  * All Rights Reserved.
4  */
5 package net.sourceforge.phpdt.internal.corext.template;
6
7 import java.util.HashMap;
8 import java.util.Iterator;
9 import java.util.Map;
10 import java.util.Vector;
11
12 import net.sourceforge.phpdt.internal.corext.textmanipulation.MultiTextEdit;
13 import net.sourceforge.phpdt.internal.corext.textmanipulation.NopTextEdit;
14 import net.sourceforge.phpdt.internal.corext.textmanipulation.SimpleTextEdit;
15 import net.sourceforge.phpdt.internal.corext.textmanipulation.TextBuffer;
16 import net.sourceforge.phpdt.internal.corext.textmanipulation.TextBufferEditor;
17 import net.sourceforge.phpdt.internal.corext.textmanipulation.TextEdit;
18 import org.eclipse.core.runtime.CoreException;
19
20 /**
21  * A context type is a context factory.
22  */
23 public abstract class ContextType implements ITemplateEditor {
24
25   /** name of the context type */
26   private final String fName;
27
28   /** variables used by this content type */
29   private final Map fVariables = new HashMap();
30
31   /**
32    * Creates a context type with a name.
33    * 
34    * @param name the name of the context. It has to be unique wrt to other context names.
35    */
36   public ContextType(String name) {
37     fName = name;
38   }
39
40   /**
41    * Returns the name of the context type.
42    */
43   public String getName() {
44     return fName;
45   }
46
47   /**
48    * Adds a template variable to the context type.
49    */
50   public void addVariable(TemplateVariable variable) {
51     fVariables.put(variable.getName(), variable);
52   }
53
54   /**
55    * Removes a template variable from the context type.
56    */
57   public void removeVariable(TemplateVariable variable) {
58     fVariables.remove(variable.getName());
59   }
60
61   /**
62    * Removes all template variables from the context type.
63    */
64   public void removeAllVariables() {
65     fVariables.clear();
66   }
67
68   /**
69    * Returns an iterator for the variables known to the context type.
70    */
71   public Iterator variableIterator() {
72     return fVariables.values().iterator();
73   }
74
75   /**
76    * Creates a template context.
77    */
78   public abstract TemplateContext createContext();
79
80   /*
81    * @see ITemplateEditor#edit(TemplateBuffer)
82    */
83   public void edit(TemplateBuffer templateBuffer, TemplateContext context) throws CoreException {
84     TextBuffer textBuffer = TextBuffer.create(templateBuffer.getString());
85     TemplatePosition[] variables = templateBuffer.getVariables();
86
87     MultiTextEdit positions = variablesToPositions(variables);
88     MultiTextEdit multiEdit = new MultiTextEdit();
89
90     // iterate over all variables and try to resolve them
91     for (int i = 0; i != variables.length; i++) {
92       TemplatePosition variable = variables[i];
93
94       if (variable.isResolved())
95         continue;
96
97       String name = variable.getName();
98       int[] offsets = variable.getOffsets();
99       int length = variable.getLength();
100
101       TemplateVariable evaluator = (TemplateVariable) fVariables.get(name);
102       String value = (evaluator == null) ? null : evaluator.evaluate(context);
103
104       if (value == null)
105         continue;
106
107       variable.setLength(value.length());
108       variable.setResolved(evaluator.isResolved(context));
109
110       for (int k = 0; k != offsets.length; k++)
111         multiEdit.add(SimpleTextEdit.createReplace(offsets[k], length, value));
112     }
113
114     TextBufferEditor editor = new TextBufferEditor(textBuffer);
115     editor.add(positions);
116     editor.add(multiEdit);
117     editor.performEdits(null);
118
119     positionsToVariables(positions, variables);
120
121     templateBuffer.setContent(textBuffer.getContent(), variables);
122   }
123
124   private static MultiTextEdit variablesToPositions(TemplatePosition[] variables) {
125     MultiTextEdit positions = new MultiTextEdit();
126     for (int i = 0; i != variables.length; i++) {
127       int[] offsets = variables[i].getOffsets();
128       for (int j = 0; j != offsets.length; j++)
129         positions.add(new NopTextEdit(offsets[j], 0));
130     }
131
132     return positions;
133   }
134
135   private static void positionsToVariables(MultiTextEdit positions, TemplatePosition[] variables) {
136     Iterator iterator = positions.iterator();
137
138     for (int i = 0; i != variables.length; i++) {
139       TemplatePosition variable = variables[i];
140
141       int[] offsets = new int[variable.getOffsets().length];
142       for (int j = 0; j != offsets.length; j++)
143         offsets[j] = ((TextEdit) iterator.next()).getTextRange().getOffset();
144
145       variable.setOffsets(offsets);
146     }
147   }
148
149   /**
150    * Returns the templates associated with this context type.
151    */
152   public Template[] getTemplates() {
153     Template[] templates = Templates.getInstance().getTemplates();
154
155     Vector vector = new Vector();
156     for (int i = 0; i != templates.length; i++)
157       if (templates[i].getContextTypeName().equals(fName))
158         vector.add(templates[i]);
159
160     return (Template[]) vector.toArray(new Template[vector.size()]);
161   }
162
163 }