KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > celtix > tools > common > toolspec > parser > Option


1 package org.objectweb.celtix.tools.common.toolspec.parser;
2
3 import java.util.StringTokenizer JavaDoc;
4 import java.util.logging.Level JavaDoc;
5 import java.util.logging.Logger JavaDoc;
6
7 import org.w3c.dom.Element JavaDoc;
8 import org.w3c.dom.NodeList JavaDoc;
9
10 import org.objectweb.celtix.common.logging.LogUtils;
11 import org.objectweb.celtix.tools.common.toolspec.Tool;
12
13 public class Option implements TokenConsumer {
14
15     private static final Logger JavaDoc LOG = LogUtils.getL7dLogger(Option.class);
16     private static final String JavaDoc VALUE_ENUM_SEPARATOR = "|";
17     protected Element JavaDoc argument;
18     protected Element JavaDoc annotation;
19     private final Element JavaDoc element;
20     private Element JavaDoc valueType;
21
22     private int numMatches;
23
24     public Option(Element JavaDoc el) {
25         this.element = el;
26
27         NodeList JavaDoc list = element.getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID, "associatedArgument");
28
29         if (list != null && list.getLength() > 0) {
30             argument = (Element JavaDoc)list.item(0);
31         }
32
33         list = element.getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID, "annotation");
34         if (list != null && list.getLength() > 0) {
35             annotation = (Element JavaDoc)list.item(0);
36         }
37
38         if (annotation == null && argument != null) {
39             list = argument.getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID, "annotation");
40             if (list != null && list.getLength() > 0) {
41                 annotation = (Element JavaDoc)list.item(0);
42             }
43         }
44     }
45
46     public boolean hasArgument() {
47         return argument != null;
48     }
49
50     public boolean hasImmediateArgument() {
51         return hasArgument() && "immediate".equals(argument.getAttribute("placement"));
52     }
53
54     /**
55      * @return whether the first token was accepted
56      */

57     public boolean accept(TokenInputStream args, Element JavaDoc result, ErrorVisitor errors) {
58
59         if (args.available() == 0) {
60             return false;
61         }
62         String JavaDoc arg = args.peek();
63
64         if (arg == null) {
65             LOG.severe("ARGUMENT_IS_NULL_MSG");
66         }
67
68         // go through each switch to see if we can match one to the arg.
69
NodeList JavaDoc switches = element.getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID, "switch");
70
71         boolean accepted = false;
72
73         for (int i = 0; i < switches.getLength(); i++) {
74
75             String JavaDoc switchArg = "-" + switches.item(i).getFirstChild().getNodeValue();
76             if (LOG.isLoggable(Level.FINE)) {
77                 LOG.fine("switchArg is " + switchArg);
78             }
79             if (hasImmediateArgument() ? arg.startsWith(switchArg) : arg.equals(switchArg)) {
80                 LOG.fine("Matches a switch!!!");
81                 // consume the token
82
args.read();
83                 // Add ourselves to the result document
84
Element JavaDoc optionEl = result.getOwnerDocument()
85                     .createElementNS("http://www.xsume.com/Xutil/Command", "option");
86
87                 optionEl.setAttribute("name", getName());
88
89                 // Add argument value to result
90
if (hasArgument()) {
91                     String JavaDoc argValue;
92                     if (hasImmediateArgument()) {
93                         argValue = arg.substring(switchArg.length());
94                     } else {
95                         argValue = readArgumentValue(args, switchArg, errors);
96                     }
97                     if (argValue != null) {
98                         if (LOG.isLoggable(Level.FINE)) {
99                             LOG.fine("Setting argument value of option to " + argValue);
100                         }
101                         optionEl.appendChild(result.getOwnerDocument().createTextNode(argValue));
102
103                     } else {
104                         break;
105                     }
106                 }
107                 result.appendChild(optionEl);
108                 numMatches++;
109                 accepted = true;
110             }
111         }
112         return accepted;
113     }
114
115     private String JavaDoc readArgumentValue(TokenInputStream args, String JavaDoc switchArg, ErrorVisitor errors) {
116         String JavaDoc value = null;
117         if (args.available() > 0) {
118             value = args.read();
119             if (value.startsWith("-")) {
120                 errors.add(new ErrorVisitor.InvalidOption(switchArg));
121                 value = null;
122             } else if (hasInvalidCharacter(value)) {
123                 errors.add(new ErrorVisitor.UserError(switchArg + " has invalid character!"));
124             }
125             if (!isInEnumArgumentValue(value)) {
126                 errors.add(new ErrorVisitor.UserError(switchArg + " "
127                                                       + value + " not in the enumeration value list!"));
128             }
129         } else {
130             errors.add(new ErrorVisitor.InvalidOption(switchArg));
131         }
132         return value;
133     }
134
135     private boolean hasInvalidCharacter(String JavaDoc argValue) {
136         NodeList JavaDoc list = argument.getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID, "valuetype");
137         String JavaDoc valuetypeStr = null;
138
139         if (list != null && list.getLength() > 0) {
140             valueType = (Element JavaDoc)list.item(0);
141             valuetypeStr = valueType.getFirstChild().getNodeValue();
142
143             if ("IdentifyString".equals(valuetypeStr)) {
144                 return !isIdentifyString(argValue);
145             } else if ("NamingSpacePackageString".equals(valuetypeStr)) {
146                 return !isNamingSpacePackageString(argValue);
147             } else if ("Digital".equals(valuetypeStr)) {
148                 for (int i = 0; i < argValue.length(); i++) {
149                     if (!Character.isDigit(argValue.charAt(i))) {
150                         return true;
151                     }
152                 }
153             }
154         }
155         return false;
156     }
157     
158     private boolean isInEnumArgumentValue(String JavaDoc argValue) {
159         boolean result = true;
160         NodeList JavaDoc list = argument.getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID, "valueenum");
161         if (list != null && list.getLength() == 1) {
162             result = false;
163             String JavaDoc enumValue = list.item(0).getTextContent();
164             StringTokenizer JavaDoc stk = new StringTokenizer JavaDoc(enumValue, VALUE_ENUM_SEPARATOR);
165             if (stk.countTokens() <= 0) {
166                 return result;
167             }
168             while (stk.hasMoreTokens()) {
169                 if (argValue.equals(stk.nextToken())) {
170                     result = true;
171                 }
172             }
173         }
174         return result;
175     }
176
177     private boolean isIdentifyString(String JavaDoc value) {
178         for (int i = 0; i < value.length(); i++) {
179             if (value.charAt(i) == '.') {
180                 continue;
181             } else {
182                 if (!Character.isJavaIdentifierPart(value.charAt(i))) {
183                     return false;
184                 }
185             }
186         }
187         return true;
188     }
189
190     private boolean isNamingSpacePackageString(String JavaDoc value) {
191         if (value.indexOf("=") < 0) {
192             return isIdentifyString(value);
193         } else {
194             String JavaDoc packageName = value.substring(value.indexOf("=") + 1, value.length());
195             return isIdentifyString(packageName);
196         }
197     }
198
199     
200     public boolean isSatisfied(ErrorVisitor errors) {
201         if (errors.getErrors().size() > 0) {
202             return false;
203         }
204         if (LOG.isLoggable(Level.FINE)) {
205             LOG.fine("For this option, minOccurs=" + element.getAttribute("minOccurs") + " and maxOccurs="
206                      + element.getAttribute("maxOccurs") + ", numMatches currently " + numMatches);
207         }
208         boolean result = true;
209
210         if (!isAtleastMinimum()) {
211             errors.add(new ErrorVisitor.MissingOption(this));
212             result = false;
213         }
214         if (result && !isNoGreaterThanMaximum()) {
215             errors.add(new ErrorVisitor.DuplicateOption(getName()));
216             result = false;
217         }
218         if (LOG.isLoggable(Level.FINE)) {
219             LOG.fine("isSatisfied() returning " + result);
220         }
221         return result;
222     }
223
224     private boolean isAtleastMinimum() {
225         boolean result = true;
226         int minOccurs = 0;
227
228         if (!"".equals(element.getAttribute("minOccurs"))) {
229             result = numMatches >= Integer.parseInt(element.getAttribute("minOccurs"));
230         } else {
231             result = numMatches >= minOccurs;
232         }
233         return result;
234     }
235
236     private boolean isNoGreaterThanMaximum() {
237         boolean result = true;
238         int maxOccurs = 1;
239
240         if (!"".equals(element.getAttribute("maxOccurs"))) {
241             result = "unbounded".equals(element.getAttribute("maxOccurs"))
242                      || numMatches <= Integer.parseInt(element.getAttribute("maxOccurs"));
243         } else {
244             result = numMatches <= maxOccurs;
245         }
246         return result;
247     }
248
249     public String JavaDoc getName() {
250         return element.getAttribute("id");
251     }
252
253     public String JavaDoc getAnnotation() {
254         return annotation.getFirstChild().getNodeValue();
255     }
256
257     public String JavaDoc getPrimarySwitch() {
258         NodeList JavaDoc switches = element.getElementsByTagNameNS(Tool.TOOL_SPEC_PUBLIC_ID, "switch");
259
260         // options must have atleast one switch, as enforced by schema, so no
261
// need for defensive coding.
262
return switches.item(0).getFirstChild().getNodeValue();
263     }
264
265     public String JavaDoc toString() {
266         return getName();
267     }
268
269 }
270
Popular Tags