1 package net.sourceforge.jparam;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.PrintStream;
7 import java.io.StringBufferInputStream;
8 import java.util.Iterator;
9 import java.util.LinkedList;
10 import java.util.List;
11
12 import net.sourceforge.jparam.conversion.ConverterRegistry;
13 import net.sourceforge.jparam.conversion.creators.CreatorRegistry;
14 import net.sourceforge.jparam.output.ISerializer;
15 import net.sourceforge.jparam.output.SerializerRegistry;
16 import net.sourceforge.jparam.parser.AssignmentListener;
17 import net.sourceforge.jparam.parser.TreeNode;
18 import net.sourceforge.jparam.parser.ValueSetItem;
19 import net.sourceforge.jparam.parser.xParamLexer;
20 import net.sourceforge.jparam.parser.xParamParser;
21 import net.sourceforge.jparam.typename.TypeNameRegistry;
22
23 /***
24 * This is the main JParam class, in order to use JParam, use the static methods
25 * of this class
26 *
27 * @author ron_sidi
28 *
29 */
30 public class JParam {
31 /***
32 * Initializes all the registries of JParam, this must be called before
33 * JParam can be used
34 *
35 * @todo: Make initialization clearer, currently running init twice should
36 * be avoided unless all registreies were "reset" before
37 */
38 public static void init() {
39 try {
40 BasicRegistration.doRegistration();
41 } catch (Exception ex) {
42 ByteArrayOutputStream baos = new ByteArrayOutputStream();
43 PrintStream out = new PrintStream(baos);
44 ex.printStackTrace(out);
45 throw new RuntimeException(
46 "Error in JParam initialization, original error: "
47 + out.toString());
48 }
49 }
50
51 /***
52 * This method should give help about certain parameters and status of
53 * JParam
54 *
55 * @todo: implement JParam help
56 *
57 * @param topic
58 * @return
59 */
60 public static String help(String topic) {
61 return "Help not implemented yet. (Asked for help for " + topic + ")";
62 }
63
64 /***
65 * Parse the given string into the Java object it represents
66 *
67 * @param str
68 * A string representation in JParam format
69 * @return Object
70 * @throws JParamException
71 * if the parse failed
72 */
73 public static Object parse(String str) throws JParamException {
74 InputStream in = new StringBufferInputStream(str);
75 return readObject(in);
76 }
77
78 /***
79 * Parse an Object from the given input stream
80 *
81 * @param in
82 * InputStream from which a JParam formatted string can be read
83 * @return @throws
84 * JParamException
85 */
86 public static Object readObject(InputStream in) throws JParamException {
87 try {
88 xParamLexer lexer = new xParamLexer(in);
89 xParamParser parser = new xParamParser(lexer);
90 TreeNode tree = parser.value();
91 return tree.getConstructedValue(Object.class);
92 } catch (JParamException e) {
93 throw e;
94 } catch (Exception ex) {
95 throw new JParamException(ex.getMessage(), ex);
96 }
97 }
98
99 /***
100 * Read a set of values from the given stream, the
101 * <code>notifyAssignemnt</code> will be called for each assignment in the
102 * input stream, this shouldn't be a public interface, but since Java lacks
103 * the friend funcionality this has to be public for the
104 * <code>ParamSet</code> class to reference
105 *
106 * @param in
107 * @param listener
108 * @throws JParamException
109 */
110 public static void readValueSet(InputStream in, AssignmentListener listener)
111 throws JParamException {
112 try {
113 xParamLexer lexer = new xParamLexer(in);
114 xParamParser parser = new xParamParser(lexer);
115 List valueSet = new LinkedList();
116 parser.value_set(valueSet);
117
118 Iterator i = valueSet.iterator();
119 while (i.hasNext()) {
120 ValueSetItem item = (ValueSetItem) i.next();
121 try {
122 listener.notifyAssignment(item.getName(), item.getValue());
123 } catch (Exception e) {
124 throw new JParamException(
125 "while parsing assignment to parameter '"
126 + item.getName() + "':\n" + e.getMessage(),
127 e);
128 }
129 }
130 } catch (JParamException ex) {
131 throw ex;
132 } catch (Exception ex) {
133 throw new JParamException(ex.getMessage(), ex);
134 }
135 }
136
137 /***
138 * Output the given object to the given PrintStream, the object's class and
139 * all of its internal members must be registered in JParam for this to work
140 *
141 * @param obj
142 * @param out
143 * @throws JParamException
144 */
145 public static void writeObject(Object obj, PrintStream out)
146 throws JParamException {
147 try {
148 SerializerRegistry registry = SerializerRegistry.getInstance();
149 ISerializer serializer = registry.getSerializer(obj);
150 serializer.serialize(obj, out);
151 } catch (JParamException ex) {
152 throw ex;
153 } catch (Exception ex) {
154 throw new JParamException(ex.getMessage(), ex);
155 }
156 }
157
158 /***
159 * Get the JParam string representation of the given Object, same
160 * restrictions like in <code>writeObject</code>
161 *
162 * @param obj
163 * @return @throws
164 * JParamException
165 */
166 public static String toString(Object obj) throws JParamException {
167 ByteArrayOutputStream baos = new ByteArrayOutputStream();
168 PrintStream out = new PrintStream(baos);
169 writeObject(obj, out);
170 return baos.toString();
171 }
172
173 /***
174 * Register the given <code>Class</code> as the given JParam type
175 *
176 * @param typeName
177 * the type name in JParam syntax that will represent this class
178 * @param type
179 */
180 public static void registerClass(String typeName, Class type) {
181 registerClass(typeName, type, null);
182 }
183
184 /***
185 * Register the class as well as the gien helper class All methods from the
186 * helper class will be defined regardless of whether or not they are
187 * related to the given class
188 *
189 * @param typeName
190 * @param type
191 * @param helperClass
192 */
193 public static void registerClass(String typeName, Class type,
194 Class helperClass) {
195 TypeNameRegistry.getInstance().registerJParamAndJava(type, typeName);
196 if (helperClass != null) {
197 registerHelperClass(helperClass);
198 }
199 }
200
201 /***
202 * Register all available creators/converters/serializers/constants from the
203 * given helper class
204 *
205 * @see CreatorRegistry
206 * @see SerializerRegistry
207 * @see ConverterRegistry
208 * @see ConstantRegistry
209 *
210 * @param helperClass
211 */
212 public static void registerHelperClass(Class helperClass) {
213 CreatorRegistry.getInstance().registerHelperClass(helperClass);
214 SerializerRegistry.getInstance().registerHelperClass(helperClass);
215 ConverterRegistry.getInstance().registerHelperClass(helperClass);
216 ConstantRegistry.getInstance().registerHelperClass(helperClass);
217 }
218
219 /***
220 * A helper method for registering constants, when the string literal
221 * <code>name</code> will be detected in the JParam input, it will be
222 * switched with the given value
223 *
224 * @param name
225 * @param value
226 */
227 public static void registerConstant(String name, Object value) {
228 ConstantRegistry.getInstance().registerConstant(name, value);
229 }
230 }