KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > text > templates > TemplateContextType


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jface.text.templates;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collections JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19
20 import org.eclipse.core.runtime.Assert;
21
22 import org.eclipse.text.edits.MalformedTreeException;
23 import org.eclipse.text.edits.MultiTextEdit;
24 import org.eclipse.text.edits.RangeMarker;
25 import org.eclipse.text.edits.ReplaceEdit;
26 import org.eclipse.text.edits.TextEdit;
27
28 import org.eclipse.jface.text.BadLocationException;
29 import org.eclipse.jface.text.Document;
30 import org.eclipse.jface.text.IDocument;
31
32
33 /**
34  * A context type defines a context within which templates are resolved. It
35  * stores a number of <code>TemplateVariableResolver</code>s. A
36  * <code>TemplateBuffer</code> can be resolved in a
37  * <code>TemplateContext</code> using the
38  * {@link #resolve(TemplateBuffer, TemplateContext)} method.
39  * <p>
40  * Clients may extend this class.
41  * </p>
42  *
43  * @since 3.0
44  */

45 public class TemplateContextType {
46
47     /** Name of the context type. */
48     private /* final */ String JavaDoc fId= null;
49
50     /** Variable resolvers used by this content type. */
51     private final Map JavaDoc fResolvers= new HashMap JavaDoc();
52
53     /** The name of the context type. */
54     private String JavaDoc fName= null;
55
56     /**
57      * Creates a context type with an identifier. The identifier must be unique,
58      * a qualified name is suggested. The id is also used as name.
59      *
60      * @param id the unique identifier of the context type
61      */

62     public TemplateContextType(String JavaDoc id) {
63         this(id, id);
64     }
65
66     /**
67      * Creates a context type with an identifier. The identifier must be unique, a qualified name is suggested.
68      *
69      * @param id the unique identifier of the context type
70      * @param name the name of the context type
71      */

72     public TemplateContextType(String JavaDoc id, String JavaDoc name) {
73         Assert.isNotNull(id);
74         Assert.isNotNull(name);
75         fId= id;
76         fName= name;
77     }
78
79     /**
80      * Returns the name of the context type.
81      *
82      * @return the name of the receiver
83      */

84     public String JavaDoc getId() {
85         return fId;
86     }
87
88
89     /**
90      * Returns the name of the context type.
91      *
92      * @return the name of the context type
93      */

94     public String JavaDoc getName() {
95         return fName;
96     }
97
98     /**
99      * Creates a context type with a <code>null</code> identifier.
100      * <p>
101      * This is a framework-only constructor that exists only so that context
102      * types can be contributed via an extension point and that should not be
103      * called in client code except for subclass constructors; use
104      * {@link #TemplateContextType(String)} instead.
105      * </p>
106      */

107     public TemplateContextType() {
108     }
109
110     /**
111      * Sets the id of this context.
112      * <p>
113      * This is a framework-only method that exists solely so that context types
114      * can be contributed via an extension point and that should not be called
115      * in client code; use {@link #TemplateContextType(String)} instead.
116      * </p>
117      *
118      * @param id the identifier of this context
119      * @throws RuntimeException an unspecified exception if the id has already
120      * been set on this context type
121      */

122     public final void setId(String JavaDoc id) throws RuntimeException JavaDoc {
123         Assert.isNotNull(id);
124         Assert.isTrue(fId == null); // may only be called once when the context is instantiated
125
fId= id;
126     }
127
128     /**
129      * Sets the name of the context type.
130      *
131      * <p>
132      * This is a framework-only method that exists solely so that context types
133      * can be contributed via an extension point and that should not be called
134      * in client code; use {@link #TemplateContextType(String, String)} instead.
135      * </p>
136      *
137      * @param name the name of the context type
138      */

139     public final void setName(String JavaDoc name) {
140         Assert.isTrue(fName == null); // only initialized by extension code
141
fName= name;
142     }
143
144     /**
145      * Adds a variable resolver to the context type. If there already is a resolver
146      * for the same type, the previous one gets replaced by <code>resolver</code>.
147      *
148      * @param resolver the resolver to be added under its name
149      */

150     public void addResolver(TemplateVariableResolver resolver) {
151         Assert.isNotNull(resolver);
152         fResolvers.put(resolver.getType(), resolver);
153     }
154
155     /**
156      * Removes a template variable from the context type.
157      *
158      * @param resolver the variable to be removed
159      */

160     public void removeResolver(TemplateVariableResolver resolver) {
161         Assert.isNotNull(resolver);
162         fResolvers.remove(resolver.getType());
163     }
164
165     /**
166      * Removes all template variables from the context type.
167      */

168     public void removeAllResolvers() {
169         fResolvers.clear();
170     }
171
172     /**
173      * Returns an iterator for the variables known to the context type.
174      *
175      * @return an iterator over the variables in this context type
176      */

177     public Iterator JavaDoc resolvers() {
178         return Collections.unmodifiableMap(fResolvers).values().iterator();
179     }
180
181     /**
182      * Returns the resolver for the given type.
183      *
184      * @param type the type for which a resolver is needed
185      * @return a resolver for the given type, or <code>null</code> if none is registered
186      */

187     protected TemplateVariableResolver getResolver(String JavaDoc type) {
188         return (TemplateVariableResolver) fResolvers.get(type);
189     }
190
191     /**
192      * Validates a pattern, a <code>TemplateException</code> is thrown if
193      * validation fails.
194      *
195      * @param pattern the template pattern to validate
196      * @throws TemplateException if the pattern is invalid
197      */

198     public void validate(String JavaDoc pattern) throws TemplateException {
199         TemplateTranslator translator= new TemplateTranslator();
200         TemplateBuffer buffer= translator.translate(pattern);
201         validateVariables(buffer.getVariables());
202     }
203
204     /**
205      * Validates the variables in this context type. If a variable is not valid,
206      * e.g. if its type is not known in this context type, a
207      * <code>TemplateException</code> is thrown.
208      * <p>
209      * The default implementation does nothing.
210      * </p>
211      *
212      * @param variables the variables to validate
213      * @throws TemplateException if one of the variables is not valid in this
214      * context type
215      */

216     protected void validateVariables(TemplateVariable[] variables) throws TemplateException {
217     }
218
219     /**
220      * Resolves the variables in <code>buffer</code> within <code>context</code>
221      * and edits the template buffer to reflect the resolved variables.
222      *
223      * @param buffer the template buffer
224      * @param context the template context
225      * @throws MalformedTreeException if the positions in the buffer overlap
226      * @throws BadLocationException if the buffer cannot be successfully modified
227      */

228     public void resolve(TemplateBuffer buffer, TemplateContext context) throws MalformedTreeException, BadLocationException {
229         Assert.isNotNull(context);
230         TemplateVariable[] variables= buffer.getVariables();
231
232         List JavaDoc positions= variablesToPositions(variables);
233         List JavaDoc edits= new ArrayList JavaDoc(5);
234
235         // iterate over all variables and try to resolve them
236
for (int i= 0; i != variables.length; i++) {
237             TemplateVariable variable= variables[i];
238
239             if (!variable.isResolved())
240                 resolve(variable, context);
241
242             String JavaDoc value= variable.getDefaultValue();
243             int[] offsets= variable.getOffsets();
244             // update buffer to reflect new value
245
for (int k= 0; k != offsets.length; k++)
246                 edits.add(new ReplaceEdit(offsets[k], variable.getInitialLength(), value));
247
248         }
249
250         IDocument document= new Document(buffer.getString());
251         MultiTextEdit edit= new MultiTextEdit(0, document.getLength());
252         edit.addChildren((TextEdit[]) positions.toArray(new TextEdit[positions.size()]));
253         edit.addChildren((TextEdit[]) edits.toArray(new TextEdit[edits.size()]));
254         edit.apply(document, TextEdit.UPDATE_REGIONS);
255
256         positionsToVariables(positions, variables);
257
258         buffer.setContent(document.get(), variables);
259     }
260
261     /**
262      * Resolves a single variable in a context. Resolving is delegated to the registered resolver.
263      *
264      * @param variable the variable to resolve
265      * @param context the context in which to resolve the variable
266      * @since 3.3
267      */

268     public void resolve(TemplateVariable variable, TemplateContext context) {
269         String JavaDoc type= variable.getType();
270         TemplateVariableResolver resolver= (TemplateVariableResolver) fResolvers.get(type);
271         if (resolver == null)
272             resolver= new TemplateVariableResolver(type, ""); //$NON-NLS-1$
273
resolver.resolve(variable, context);
274     }
275
276     private static List JavaDoc variablesToPositions(TemplateVariable[] variables) {
277         List JavaDoc positions= new ArrayList JavaDoc(5);
278         for (int i= 0; i != variables.length; i++) {
279             int[] offsets= variables[i].getOffsets();
280             for (int j= 0; j != offsets.length; j++)
281                 positions.add(new RangeMarker(offsets[j], 0));
282         }
283
284         return positions;
285     }
286
287     private static void positionsToVariables(List JavaDoc positions, TemplateVariable[] variables) {
288         Iterator JavaDoc iterator= positions.iterator();
289
290         for (int i= 0; i != variables.length; i++) {
291             TemplateVariable variable= variables[i];
292
293             int[] offsets= new int[variable.getOffsets().length];
294             for (int j= 0; j != offsets.length; j++)
295                 offsets[j]= ((TextEdit) iterator.next()).getOffset();
296
297             variable.setOffsets(offsets);
298         }
299     }
300 }
301
Popular Tags