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