001: // ============================================================================
002: // $Id: GenericParser.java,v 1.15 2006/09/02 02:25:09 davidahall Exp $
003: // Copyright (c) 2004-2005 David A. Hall
004: // ============================================================================
005: // The contents of this file are subject to the Common Development and
006: // Distribution License (CDDL), Version 1.0 (the License); you may not use this
007: // file except in compliance with the License. You should have received a copy
008: // of the the License along with this file: if not, a copy of the License is
009: // available from Sun Microsystems, Inc.
010: //
011: // http://www.sun.com/cddl/cddl.html
012: //
013: // From time to time, the license steward (initially Sun Microsystems, Inc.) may
014: // publish revised and/or new versions of the License. You may not use,
015: // distribute, or otherwise make this file available under subsequent versions
016: // of the License.
017: //
018: // Alternatively, the contents of this file may be used under the terms of the
019: // GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which
020: // case the provisions of the LGPL are applicable instead of those above. If you
021: // wish to allow use of your version of this file only under the terms of the
022: // LGPL, and not to allow others to use your version of this file under the
023: // terms of the CDDL, indicate your decision by deleting the provisions above
024: // and replace them with the notice and other provisions required by the LGPL.
025: // If you do not delete the provisions above, a recipient may use your version
026: // of this file under the terms of either the CDDL or the LGPL.
027: //
028: // This library is distributed in the hope that it will be useful,
029: // but WITHOUT ANY WARRANTY; without even the implied warranty of
030: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
031: // ============================================================================
032:
033: package net.sf.jga.parser;
034:
035: import java.text.MessageFormat;
036: import net.sf.jga.fn.BinaryFunctor;
037: import net.sf.jga.fn.Generator;
038: import net.sf.jga.fn.UnaryFunctor;
039:
040: /**
041: * FunctorParser wrapper that adds runtime type-safe entry points to the non-generified
042: * base parser. This class maps between the inherently type<b>un</b>safe
043: * baseclass and the generic functors that are returned: if the returned functor
044: * does not return the correct type, then a ClassCastException will be thrown by
045: * the entry point.
046: * <p>
047: * Copyright © 2004-2005 David A. Hall
048: * @author <a href="mailto:davidahall@users.sf.net">David A. Hall</a>
049: */
050:
051: public class GenericParser implements IParser {
052:
053: // global instance
054: static private GenericParser _instance;
055:
056: /**
057: * Returns a globally accessible default instance of a GenericParser.
058: */
059: static public synchronized GenericParser getInstance() {
060: if (_instance == null) {
061: _instance = new GenericParser(FunctorParser.getInstance());
062: }
063:
064: return _instance;
065: }
066:
067: private IParser _delegate;
068:
069: public GenericParser() {
070: _delegate = new JFXGParser();
071: }
072:
073: public GenericParser(IParser delegate) {
074: _delegate = delegate;
075: }
076:
077: //======================
078: // Parser Entry Points
079: //======================
080:
081: /**
082: * Parses the string to create a Generator.
083: */
084: public <R> Generator<R> parseGenerator(String str,
085: Class<R> returnType) throws ClassCastException,
086: ParseException {
087: Generator gen = parseGenerator(str);
088: if (returnType.isAssignableFrom(getReturnType()))
089: return (Generator<R>) gen;
090:
091: String err = "Expected Generator<{0}>, but expression returns {1}";
092: String msg = MessageFormat.format(err, new Object[] {
093: returnType.getName(), getReturnType().getName() });
094: throw new ClassCastException(msg);
095: }
096:
097: /**
098: * Parses the string to create a UnaryFunctor that takes an argument of the
099: * given type.
100: */
101: public <T, R> UnaryFunctor<T, R> parseUnary(String str,
102: Class<T> argType, Class<R> returnType)
103: throws ClassCastException, ParseException {
104: UnaryFunctor uf = parseUnary(str, argType);
105: if (returnType.isAssignableFrom(getReturnType()))
106: return (UnaryFunctor<T, R>) uf;
107:
108: String err = "Expected UnaryFunctor<{0},{1}>, but expression returns {2}";
109: String msg = MessageFormat.format(err, new Object[] {
110: argType.getName(), returnType.getName(),
111: getReturnType().getName() });
112: throw new ClassCastException(msg);
113: }
114:
115: /**
116: * Parses the string to create a BinaryFunctor that takes arguments of the
117: * given types.
118: */
119: public <T1, T2, R> BinaryFunctor<T1, T2, R> parseBinary(String str,
120: Class<T1> arg1Type, Class<T2> arg2Type, Class<R> returnType)
121: throws ClassCastException, ParseException {
122: BinaryFunctor bf = parseBinary(str, arg1Type, arg2Type);
123: if (returnType.isAssignableFrom(getReturnType()))
124: return (BinaryFunctor<T1, T2, R>) bf;
125:
126: String err = "Expected BinaryFunctor<{0},{1},{2}>, but expression returns {3}";
127: String msg = MessageFormat.format(err, new Object[] {
128: arg1Type.getName(), arg2Type.getName(),
129: returnType.getName(), getReturnType().getName() });
130: throw new ClassCastException(msg);
131: }
132:
133: //=======================
134: // IParser implementation
135: //=======================
136:
137: /**
138: * Parses the string to create a Generator.
139: */
140: public Generator parseGenerator(String str) throws ParseException {
141: return _delegate.parseGenerator(str);
142: }
143:
144: /**
145: * Parses the string to create a UnaryFunctor that takes an argument of the
146: * given type.
147: */
148: public UnaryFunctor parseUnary(String str, Class argType)
149: throws ParseException {
150: return _delegate.parseUnary(str, argType);
151: }
152:
153: /**
154: * Parses the string to create a BinaryFunctor that takes arguments of the
155: * given types.
156: */
157: public BinaryFunctor parseBinary(String str, Class arg1Type,
158: Class arg2Type) throws ParseException {
159: return _delegate.parseBinary(str, arg1Type, arg2Type);
160: }
161:
162: /**
163: * Returns the type of object returned by the last functor parsed.
164: * @throws IllegalStateException if the parser has not been used or if
165: * parsing the last functor resulted in an exception being thrown.
166: */
167: public Class getReturnType() {
168: return _delegate.getReturnType();
169: }
170:
171: //======================
172: // Static entry points
173: //======================
174:
175: /**
176: * Parses the string to create a Generator.
177: */
178: static public <R> Generator<R> parse(String str, Class<R> returnType)
179: throws UncheckedParseException, ClassCastException {
180: try {
181: return getInstance().parseGenerator(str);
182: } catch (ParseException x) {
183: throw new UncheckedParseException(x);
184: }
185: }
186:
187: /**
188: * Parses the string to create a UnaryFunctor that takes an argument of the
189: * given type.
190: */
191: static public <T, R> UnaryFunctor<T, R> parse(String str,
192: Class<T> argType, Class<R> returnType)
193: throws UncheckedParseException, ClassCastException {
194: try {
195: return getInstance().parseUnary(str, argType, returnType);
196: } catch (ParseException x) {
197: throw new UncheckedParseException(x);
198: }
199: }
200:
201: /**
202: * Parses the string to create a BinaryFunctor that takes arguments of the
203: * given types.
204: */
205: static public <T1, T2, R> BinaryFunctor<T1, T2, R> parse(
206: String str, Class<T1> arg1Type, Class<T2> arg2Type,
207: Class<R> returnType) throws UncheckedParseException,
208: ClassCastException {
209: try {
210: return getInstance().parseBinary(str, arg1Type, arg2Type,
211: returnType);
212: } catch (ParseException x) {
213: throw new UncheckedParseException(x);
214: }
215: }
216:
217: //======================
218: // Deprecated methods
219: //======================
220:
221: // All of these methods are deprecated, and will be removed in a future release.
222: // These were all part of the public interface of the base class, and had been
223: // available before this class was refactored to be a wrapper rather than a
224: // derived class. For one more release, we'll support them.
225:
226: // The supported use for these methods is to build and configure the actual parser,
227: // then wrap it in a Generic wrapper.
228:
229: /**
230: * @deprecated Configure the delegate parser prior to wrapping it
231: */
232: public void importClass(Class clasz) {
233: ((JFXGParser) _delegate).importClass(clasz);
234: }
235:
236: /**
237: * @deprecated Configure the delegate parser prior to wrapping it
238: */
239: public void importClass(String alias, Class clasz) {
240: ((JFXGParser) _delegate).importClass(alias, clasz);
241: }
242:
243: /**
244: * @deprecated Configure the delegate parser prior to wrapping it
245: */
246: public void deportClass(String alias) {
247: ((JFXGParser) _delegate).deportClass(alias);
248: }
249:
250: /**
251: * @deprecated Configure the delegate parser prior to wrapping it
252: */
253: public void importStatics(Class clasz) {
254: ((JFXGParser) _delegate).importStatics(clasz);
255: }
256:
257: /**
258: * @deprecated Configure the delegate parser prior to wrapping it
259: */
260: public void importField(Class clasz, String name)
261: throws NoSuchFieldException {
262: ((JFXGParser) _delegate).importField(clasz, name);
263: }
264:
265: /**
266: * @deprecated Configure the delegate parser prior to wrapping it
267: */
268: public void importField(java.lang.reflect.Field field)
269: throws IllegalArgumentException {
270: ((JFXGParser) _delegate).importField(field);
271: }
272:
273: /**
274: * @deprecated Configure the delegate parser prior to wrapping it
275: */
276: public java.lang.reflect.Field getImportedField(String name) {
277: return ((JFXGParser) _delegate).getImportedField(name);
278: }
279:
280: /**
281: * @deprecated Configure the delegate parser prior to wrapping it
282: */
283: public void importMethod(Class clasz, String name)
284: throws NoSuchMethodException {
285: ((JFXGParser) _delegate).importMethod(clasz, name);
286: }
287:
288: /**
289: * @deprecated Configure the delegate parser prior to wrapping it
290: */
291: public void importMethod(java.lang.reflect.Method meth) {
292: ((JFXGParser) _delegate).importMethod(meth);
293: }
294:
295: /**
296: * @deprecated Configure the delegate parser prior to wrapping it
297: */
298: public void importMethod(String name, java.lang.reflect.Method meth) {
299: ((JFXGParser) _delegate).importMethod(name, meth);
300: }
301:
302: /**
303: * @deprecated Configure the delegate parser prior to wrapping it
304: */
305: public java.lang.reflect.Method[] getImportedMethods(String name) {
306: return ((JFXGParser) _delegate).getImportedMethods(name);
307: }
308:
309: /**
310: * @deprecated Configure the delegate parser prior to wrapping it
311: */
312: public void bindThis(Object this Binding) {
313: ((JFXGParser) _delegate).bindThis(this Binding);
314: }
315:
316: /**
317: * @deprecated Configure the delegate parser prior to wrapping it
318: */
319: protected Object getBoundObject() {
320: return ((JFXGParser) _delegate).getBoundObject();
321: }
322:
323: /**
324: * @deprecated Configure the delegate parser prior to wrapping it
325: */
326: public void setUndecoratedDecimal(boolean flag) {
327: ((JFXGParser) _delegate).setUndecoratedDecimal(flag);
328: }
329:
330: /**
331: * @deprecated Configure the delegate parser prior to wrapping it
332: */
333: public boolean isUndecoratedDecimal() {
334: return ((JFXGParser) _delegate).isUndecoratedDecimal();
335: }
336:
337: }
|