KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > logicalcobwebs > cglib > util > StringSwitcher


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 2002 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution,
20  * if any, must include the following acknowledgment:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowledgment may appear in the software itself,
24  * if and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Apache" and "Apache Software Foundation" must
27  * not be used to endorse or promote products derived from this
28  * software without prior written permission. For written
29  * permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache",
32  * nor may "Apache" appear in their name, without prior written
33  * permission of the Apache Software Foundation.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation. For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  */

54 package org.logicalcobwebs.cglib.util;
55
56 import java.util.*;
57 import org.logicalcobwebs.cglib.core.*;
58 import org.logicalcobwebs.asm.ClassVisitor;
59 import org.logicalcobwebs.asm.Label;
60 import org.logicalcobwebs.asm.Type;
61
62 /**
63  * This class implements a simple String->int mapping for a fixed set of keys.
64  */

65 abstract public class StringSwitcher {
66     private static final Type STRING_SWITCHER =
67       TypeUtils.parseType("org.logicalcobwebs.cglib.util.StringSwitcher");
68     private static final Signature INT_VALUE =
69       TypeUtils.parseSignature("int intValue(String)");
70     private static final StringSwitcherKey KEY_FACTORY =
71       (StringSwitcherKey)KeyFactory.create(StringSwitcherKey.class);
72
73     interface StringSwitcherKey {
74         public Object JavaDoc newInstance(String JavaDoc[] strings, int[] ints, boolean fixedInput);
75     }
76
77     /**
78      * Helper method to create a StringSwitcher.
79      * For finer control over the generated instance, use a new instance of StringSwitcher.Generator
80      * instead of this static method.
81      * @param strings the array of String keys; must be the same length as the value array
82      * @param ints the array of integer results; must be the same length as the key array
83      * @param fixedInput if false, an unknown key will be returned from {@link #intValue} as <code>-1</code>; if true,
84      * the result will be undefined, and the resulting code will be faster
85      */

86     public static StringSwitcher create(String JavaDoc[] strings, int[] ints, boolean fixedInput) {
87         Generator gen = new Generator();
88         gen.setStrings(strings);
89         gen.setInts(ints);
90         gen.setFixedInput(fixedInput);
91         return gen.create();
92     }
93
94     protected StringSwitcher() {
95     }
96
97     /**
98      * Return the integer associated with the given key.
99      * @param s the key
100      * @return the associated integer value, or <code>-1</code> if the key is unknown (unless
101      * <code>fixedInput</code> was specified when this <code>StringSwitcher</code> was created,
102      * in which case the return value for an unknown key is undefined)
103      */

104     abstract public int intValue(String JavaDoc s);
105
106     public static class Generator extends AbstractClassGenerator {
107         private static final Source SOURCE = new Source(StringSwitcher.class.getName());
108
109         private String JavaDoc[] strings;
110         private int[] ints;
111         private boolean fixedInput;
112         
113         public Generator() {
114             super(SOURCE);
115         }
116
117         /**
118          * Set the array of recognized Strings.
119          * @param strings the array of String keys; must be the same length as the value array
120          * @see #setInts
121          */

122         public void setStrings(String JavaDoc[] strings) {
123             this.strings = strings;
124         }
125
126         /**
127          * Set the array of integer results.
128          * @param ints the array of integer results; must be the same length as the key array
129          * @see #setStrings
130          */

131         public void setInts(int[] ints) {
132             this.ints = ints;
133         }
134
135         /**
136          * Configure how unknown String keys will be handled.
137          * @param fixedInput if false, an unknown key will be returned from {@link #intValue} as <code>-1</code>; if true,
138          * the result will be undefined, and the resulting code will be faster
139          */

140         public void setFixedInput(boolean fixedInput) {
141             this.fixedInput = fixedInput;
142         }
143
144         protected ClassLoader JavaDoc getDefaultClassLoader() {
145             return getClass().getClassLoader();
146         }
147
148         /**
149          * Generate the <code>StringSwitcher</code>.
150          */

151         public StringSwitcher create() {
152             setNamePrefix(StringSwitcher.class.getName());
153             Object JavaDoc key = KEY_FACTORY.newInstance(strings, ints, fixedInput);
154             return (StringSwitcher)super.create(key);
155         }
156
157         public void generateClass(ClassVisitor v) throws Exception JavaDoc {
158             ClassEmitter ce = new ClassEmitter(v);
159             ce.begin_class(Constants.ACC_PUBLIC,
160                            getClassName(),
161                            STRING_SWITCHER,
162                            null,
163                            Constants.SOURCE_FILE);
164             EmitUtils.null_constructor(ce);
165             final CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, INT_VALUE, null, null);
166             e.load_arg(0);
167             final List stringList = Arrays.asList(strings);
168             int style = fixedInput ? Constants.SWITCH_STYLE_HASHONLY : Constants.SWITCH_STYLE_HASH;
169             EmitUtils.string_switch(e, strings, style, new ObjectSwitchCallback() {
170                 public void processCase(Object JavaDoc key, Label end) {
171                     e.push(ints[stringList.indexOf(key)]);
172                     e.return_value();
173                 }
174                 public void processDefault() {
175                     e.push(-1);
176                     e.return_value();
177                 }
178             });
179             e.end_method();
180             ce.end_class();
181         }
182
183         protected Object JavaDoc firstInstance(Class JavaDoc type) {
184             return (StringSwitcher)ReflectUtils.newInstance(type);
185         }
186
187         protected Object JavaDoc nextInstance(Object JavaDoc instance) {
188             return instance;
189         }
190     }
191 }
192
Popular Tags