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 }