KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > lexer > gen > TokenTypes


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-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.lexer.gen;
21
22 import java.lang.reflect.Field JavaDoc;
23 import java.lang.SecurityException JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Arrays JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.util.List JavaDoc;
32 import org.netbeans.modules.lexer.gen.util.LexerGenUtilities;
33
34 /**
35  * The lexer generators often generate a class or interface
36  * that contains integer fields of token types
37  * named e.g. xxxConstants or xxxTokenTypes etc.
38  * <BR>The <CODE>TokenConstants</CODE> class encapsulates the information
39  * contained in such token types class.
40  * <P>The reflection is used to collect
41  * the "public static final int" fields in the token types class.
42  * All these fields are collected but subclasses
43  * may wish to hide some of the fields (e.g. some fields
44  * may be related to states of an automaton instead of token types
45  * identification).
46  *
47  * @author Miloslav Metelka
48  * @version 1.00
49  */

50
51 public class TokenTypes {
52     
53     private final Class JavaDoc tokenTypesClass;
54     
55     private boolean inspected;
56
57     /** Map of [tokenTypeName, tokenTypeValue] */
58     protected final Map JavaDoc name2value = new HashMap JavaDoc();
59     
60     /** Map of [tokenTypeValue, tokenTypeName] */
61     protected final Map JavaDoc value2name = new HashMap JavaDoc();
62     
63     public TokenTypes(Class JavaDoc tokenTypesClass) {
64         this.tokenTypesClass = tokenTypesClass;
65     }
66     
67     /**
68      * Called by <CODE>LanguageData.registerTokenTypes()</CODE>
69      * to update the language data into which it's being registered.
70      * By default it adds mutable token ids that correspond
71      * to the constants discovered in token types.
72      * Can be overriden by subclasses to provide some more functionality.
73      */

74     protected void updateData(LanguageData languageData) {
75         inspect();
76
77         for (Iterator JavaDoc it = tokenTypeNamesIterator(); it.hasNext();) {
78             String JavaDoc tokenTypeName = (String JavaDoc)it.next();
79             MutableTokenId id = languageData.findIdByTokenTypeName(tokenTypeName);
80             
81             if (id == null) {
82                 String JavaDoc idName = LexerGenUtilities.idToLowerCase(tokenTypeName);
83                 id = languageData.newId(idName);
84                 id.updateByTokenType(tokenTypeName); // updateId() called automatically
85

86             } else {
87                 updateId(id);
88             }
89         }
90     }
91     
92     /**
93      * Update a newly created or an existing token-id by the information
94      * contained in this token-types.
95      * The passed token-id already has tokenTypeName
96      * filled in.
97      */

98     protected void updateId(MutableTokenId id) {
99         String JavaDoc tokenTypeName = id.getTokenTypeName();
100         if (tokenTypeName != null) { // no associated tokenTypeName
101
Integer JavaDoc value = getTokenTypeValue(tokenTypeName);
102             if (value == null) {
103                 throw new IllegalArgumentException JavaDoc("tokenTypeName=" + tokenTypeName
104                     + " is not declared in " + getTokenTypesClass().getName());
105             }
106
107             // assign intId
108
id.setIntId(value.intValue());
109         }
110     }
111     
112     public Class JavaDoc getTokenTypesClass() {
113         return tokenTypesClass;
114     }
115     
116     /**
117      * @return Integer value of the static field with the given name
118      * or null if the field does not exist.
119      */

120     public Integer JavaDoc getTokenTypeValue(String JavaDoc tokenTypeName) {
121         inspect();
122
123         return (Integer JavaDoc)name2value.get(tokenTypeName);
124     }
125
126     public String JavaDoc getTokenTypeName(int tokenTypeValue) {
127         inspect();
128
129         return (String JavaDoc)value2name.get(new Integer JavaDoc(tokenTypeValue));
130     }
131
132     /**
133      * @return all the field names
134      */

135     public Iterator JavaDoc tokenTypeNamesIterator() {
136         inspect();
137
138         return name2value.keySet().iterator();
139     }
140     
141     
142     public int findMaxTokenTypeValue() {
143         inspect();
144
145         int maxValue = 0;
146         for (Iterator JavaDoc it = value2name.keySet().iterator(); it.hasNext();) {
147             Integer JavaDoc i = (Integer JavaDoc)it.next();
148             maxValue = Math.max(maxValue, i.intValue());
149         }
150         return maxValue;
151     }
152             
153     /** Inspect the token types class.
154      * This method can be overriden by children if necessary.
155      * The method goes through the class
156      * and puts the [field-name, integer-constant-value]
157      * for all the static fields into the info map.
158      * The <CODE>null</CODE> key is mapped to maximum constant value
159      * found in the token types class.
160      * The <CODE>List.class</CODE> key is mapped to the list
161      * of all the field names in the order in which they
162      * were found in the token types class.
163      * @return true if the inspection was really done
164      * or false if the inspection was already done previously.
165      */

166     protected boolean inspect() {
167         if (inspected) {
168             return false;
169         }
170         inspected = true;
171
172         try {
173             Field JavaDoc[] fields = getTokenTypesClass().getDeclaredFields();
174             for (int i = 0; i < fields.length; i++) {
175                 Field JavaDoc f = fields[i];
176                 if (f.getType() == int.class) {
177                     int value = f.getInt(null);
178                     String JavaDoc fieldName = f.getName();
179                     if (isAccepted(fieldName, value)) {
180                         Integer JavaDoc valueInteger = new Integer JavaDoc(value);
181                         name2value.put(fieldName, valueInteger);
182                         value2name.put(valueInteger, fieldName);
183                     }
184                 }
185             }
186             
187         } catch (SecurityException JavaDoc e) {
188             e.printStackTrace();
189             throw new IllegalStateException JavaDoc(e.toString());
190
191         } catch (IllegalAccessException JavaDoc e) {
192             e.printStackTrace();
193             throw new IllegalStateException JavaDoc(e.toString());
194         }
195         
196         return true; // inspection really done
197
}
198
199     /**
200      * Whether it's ok to add the given field name to the list
201      * of the [tokenTypeName, Integer] pairs.
202      * <BR>Subclasses can exclude some field(s) if necessary.
203      */

204     protected boolean isAccepted(String JavaDoc tokenTypeName, int tokenTypeValue) {
205         return true;
206     }
207
208 }
209
210
Popular Tags