KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > editor > TokenContext


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.editor;
21
22 import java.lang.reflect.Field JavaDoc;
23 import java.lang.reflect.Modifier JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Arrays JavaDoc;
26 import java.util.ArrayList JavaDoc;
27
28 /**
29 * Token context defines the environment in which only a limited set
30 * of tokens can be used. This set can be retrieved by calling
31 * the <tt>getTokenIDs()</tt> method. The context can contain other
32 * contexts which means that the context can possibly switch
33 * into one of its children contexts during lexing.
34 * The child context can also have other children that can
35 * work in the same way.
36 * In this way context-paths can be created. They describe
37 * the way how was the token lexically recognized.
38 * The context can be retrieved when the syntax-class is known
39 * using the <tt>get</tt> method.
40 *
41 *
42 * @author Miloslav Metelka
43 * @version 1.00
44 */

45
46 public class TokenContext {
47
48     private static final TokenContext[] EMPTY_CHILDREN = new TokenContext[0];
49
50     private final String JavaDoc namePrefix;
51
52     private final TokenContext[] children;
53
54     private final HashMap JavaDoc pathCache = new HashMap JavaDoc(37);
55
56     private final ArrayList JavaDoc tokenIDList = new ArrayList JavaDoc();
57
58     private final ArrayList JavaDoc tokenCategoryList = new ArrayList JavaDoc();
59
60     private TokenID[] tokenIDs;
61
62     private TokenCategory[] tokenCategories;
63
64     private TokenContextPath contextPath;
65
66     private TokenContextPath[] allContextPaths;
67
68     private TokenContextPath[] lastContextPathPair;
69
70     public TokenContext(String JavaDoc namePrefix) {
71         this(namePrefix, EMPTY_CHILDREN);
72     }
73
74     /** Construct new token-context.
75     * @param namePrefix name that will prefix all the token-ids names.
76     * @param children child token contexts.
77     */

78     public TokenContext(String JavaDoc namePrefix, TokenContext[] children) {
79         if (namePrefix == null) {
80             throw new IllegalArgumentException JavaDoc("Name prefix must be non-null."); // NOI18N
81
}
82
83         this.namePrefix = namePrefix.intern();
84         this.children = (children != null) ? children : EMPTY_CHILDREN;
85
86         contextPath = TokenContextPath.get(new TokenContext[] { this });
87     }
88
89     /** Get the prefix that this context adds to the name of its tokens. */
90     public String JavaDoc getNamePrefix() {
91         return namePrefix;
92     }
93
94     /** Get the children contexts of this context. It returns empty-array
95     * if there are no children.
96     */

97     public TokenContext[] getChildren() {
98         return children;
99     }
100
101     /** Add token-id to the set of token-ids that belong to this context. */
102     protected void addTokenID(TokenID tokenID) {
103         synchronized (tokenIDList) {
104             tokenIDList.add(tokenID);
105             tokenIDs = null;
106
107             // Check whether there's a valid and new category for this token-id
108
TokenCategory tcat = tokenID.getCategory();
109             if (tcat != null && tokenCategoryList.indexOf(tcat) < 0) {
110                 tokenCategoryList.add(tcat);
111                 tokenCategories = null;
112             }
113         }
114     }
115
116     /** Add all static-final token-id fields declared
117     * in this token-context using <tt>Class.getDeclaredFields()</tt> call.
118     */

119     protected void addDeclaredTokenIDs() throws IllegalAccessException JavaDoc, SecurityException JavaDoc {
120         Field JavaDoc[] fields = this.getClass().getDeclaredFields();
121         for (int i = 0; i < fields.length; i++) {
122             int flags = Modifier.STATIC | Modifier.FINAL;
123             if ((fields[i].getModifiers() & flags) == flags
124                     && TokenID.class.isAssignableFrom(fields[i].getType())
125                ) {
126                 addTokenID((TokenID)fields[i].get(null));
127             }
128         }
129     }
130
131     /** Get the token-ids that belong to this token-context. It doesn't
132     * return the children's token-ids.
133     */

134     public TokenID[] getTokenIDs() {
135         if (tokenIDs == null) {
136             synchronized (tokenIDList) {
137                 tokenIDs = (TokenID[])tokenIDList.toArray(new TokenID[tokenIDList.size()]);
138             }
139         }
140
141         return tokenIDs;
142     }
143
144     /** Get the token-categories that belong to this token-context. It doesn't
145     * return the children's token-categories.
146     */

147     public TokenCategory[] getTokenCategories() {
148         if (tokenCategories == null) {
149             synchronized (tokenCategoryList) {
150                 tokenCategories = (TokenCategory[])tokenCategoryList.toArray(
151                                       new TokenCategory[tokenCategoryList.size()]);
152             }
153         }
154
155         return tokenCategories;
156     }
157
158     /** Get the context path for this token-context. */
159     public TokenContextPath getContextPath() {
160         return contextPath;
161     }
162
163     /** Get the context path for this token-context that is derived
164     * from the path of one of the children.
165     */

166     public TokenContextPath getContextPath(TokenContextPath childPath) {
167         if (childPath == null) {
168             return contextPath;
169         }
170
171         TokenContextPath[] lastPair = lastContextPathPair;
172         if (lastPair == null || lastPair[0] != childPath) {
173             synchronized (pathCache) {
174                 lastPair = (TokenContextPath[])pathCache.get(childPath);
175                 if (lastPair == null) {
176                     // Build the array of contexts
177
TokenContext[] origContexts = childPath.getContexts();
178                     TokenContext[] contexts = new TokenContext[origContexts.length + 1];
179                     System.arraycopy(origContexts, 0, contexts, 0, origContexts.length);
180                     contexts[origContexts.length] = this;
181
182                     TokenContextPath path = TokenContextPath.get(contexts);
183
184                     lastPair = new TokenContextPath[] { childPath, path };
185                     pathCache.put(childPath, lastPair);
186                 }
187                 lastContextPathPair = lastPair;
188             }
189         }
190
191         return lastPair[1];
192     }
193
194     /** Get all the context paths for this token-context including
195     * itself as the first one and all its children.
196     */

197     public TokenContextPath[] getAllContextPaths() {
198         if (allContextPaths == null) {
199             ArrayList JavaDoc cpList = new ArrayList JavaDoc();
200             cpList.add(getContextPath());
201
202             for (int i = 0; i < children.length; i++) {
203                 TokenContextPath[] childPaths = children[i].getAllContextPaths();
204                 for (int j = 0; j < childPaths.length; j++) {
205                     cpList.add(getContextPath(childPaths[j]));
206                 }
207             }
208
209             allContextPaths = new TokenContextPath[cpList.size()];
210             cpList.toArray(allContextPaths);
211         }
212
213         return allContextPaths;
214     }
215
216 }
217
Popular Tags