1 8 9 package mx4j.loading; 10 11 import java.lang.reflect.Constructor ; 12 import java.util.ArrayList ; 13 import java.util.List ; 14 15 import javax.management.MalformedObjectNameException ; 16 import javax.management.ObjectName ; 17 import javax.management.loading.MLet ; 18 19 27 public class MLetParser 28 { 29 public static final String OPEN_COMMENT = "<!--"; 30 public static final String CLOSE_COMMENT = "-->"; 31 32 public static final String OPEN_BRACKET = "<"; 33 public static final String CLOSE_BRACKET = ">"; 34 35 public static final String MLET_TAG = "MLET"; 36 public static final String CODE_ATTR = "CODE"; 37 public static final String OBJECT_ATTR = "OBJECT"; 38 public static final String ARCHIVE_ATTR = "ARCHIVE"; 39 public static final String CODEBASE_ATTR = "CODEBASE"; 40 public static final String NAME_ATTR = "NAME"; 41 public static final String VERSION_ATTR = "VERSION"; 42 43 public static final String ARG_TAG = "ARG"; 44 public static final String TYPE_ATTR = "TYPE"; 45 public static final String VALUE_ATTR = "VALUE"; 46 47 private MLet mlet; 48 49 52 public MLetParser() 53 { 54 } 55 56 60 public MLetParser(MLet mlet) 61 { 62 this.mlet = mlet; 63 } 64 65 72 public List parse(String content) throws MLetParseException 73 { 74 if (content == null) throw new MLetParseException("MLet file content cannot be null"); 75 76 content = stripComments(content.trim()); 78 content = convertToUpperCase(content); 79 80 ArrayList mlets = parseMLets(content); 81 if (mlets.size() < 1) throw new MLetParseException("MLet file is empty"); 82 83 ArrayList mletTags = new ArrayList (); 84 for (int i = 0; i < mlets.size(); ++i) 85 { 86 String mletTag = (String )mlets.get(i); 87 88 MLetTag tag = parseMLet(mletTag); 89 mletTags.add(tag); 90 } 91 92 return mletTags; 93 } 94 95 private MLetTag parseMLet(String content) throws MLetParseException 96 { 97 MLetTag tag = new MLetTag(); 98 parseMLetAttributes(tag, content); 99 parseMLetArguments(tag, content); 100 return tag; 101 } 102 103 private ArrayList parseMLets(String content) throws MLetParseException 104 { 105 ArrayList list = new ArrayList (); 106 int start = 0; 107 int current = -1; 108 while ((current = findOpenTag(content, start, MLET_TAG)) >= 0) 109 { 110 int end = findCloseTag(content, current + 1, MLET_TAG, true); 111 if (end < 0) throw new MLetParseException("MLET tag not closed at index: " + current); 112 113 String mlet = content.substring(current, end); 114 list.add(mlet); 115 116 start = end + 1; 117 } 118 return list; 119 } 120 121 private void parseMLetArguments(MLetTag tag, String content) throws MLetParseException 122 { 123 int start = 0; 124 int current = -1; 125 while ((current = findOpenTag(content, start, ARG_TAG)) >= 0) 126 { 127 int end = findCloseTag(content, current + 1, ARG_TAG, false); 128 if (end < 0) throw new MLetParseException("ARG tag not closed"); 129 130 String arg = content.substring(current, end); 131 132 int type = arg.indexOf(TYPE_ATTR); 133 if (type < 0) throw new MLetParseException("Missing TYPE attribute"); 134 135 int value = arg.indexOf(VALUE_ATTR); 136 if (value < 0) throw new MLetParseException("Missing VALUE attribute"); 137 138 String className = findAttributeValue(arg, type, TYPE_ATTR); 139 tag.addArg(className, convertToObject(className, findAttributeValue(arg, value, VALUE_ATTR))); 140 141 start = end + 1; 142 } 143 } 144 145 private void parseMLetAttributes(MLetTag tag, String content) throws MLetParseException 146 { 147 int end = content.indexOf(CLOSE_BRACKET); 148 String attributes = content.substring(0, end); 149 150 int archive = -1; 152 int object = -1; 153 int code = -1; 154 155 archive = attributes.indexOf(ARCHIVE_ATTR); 156 if (archive < 0) throw new MLetParseException("Missing ARCHIVE attribute"); 157 158 code = attributes.indexOf(CODE_ATTR); 159 object = attributes.indexOf(OBJECT_ATTR); 160 if (code < 0 && object < 0) throw new MLetParseException("Missing CODE or OBJECT attribute"); 161 if (code > 0 && object > 0) throw new MLetParseException("CODE and OBJECT attributes cannot be both present"); 162 163 if (code >= 0) 164 tag.setCode(findAttributeValue(attributes, code, CODE_ATTR)); 165 else 166 tag.setObject(findAttributeValue(attributes, object, OBJECT_ATTR)); 167 168 tag.setArchive(findAttributeValue(attributes, archive, ARCHIVE_ATTR)); 169 170 int codebase = attributes.indexOf(CODEBASE_ATTR); 172 if (codebase >= 0) tag.setCodeBase(findAttributeValue(attributes, codebase, CODEBASE_ATTR)); 173 174 int name = attributes.indexOf(NAME_ATTR); 175 if (name >= 0) 176 { 177 String objectName = findAttributeValue(attributes, name, NAME_ATTR); 178 try 179 { 180 tag.setName(new ObjectName (objectName)); 181 } 182 catch (MalformedObjectNameException x) 183 { 184 throw new MLetParseException("Invalid ObjectName: " + objectName); 185 } 186 } 187 188 int version = attributes.indexOf(VERSION_ATTR); 189 if (version >= 0) tag.setVersion(findAttributeValue(attributes, version, VERSION_ATTR)); 190 } 191 192 private String findAttributeValue(String content, int start, String attribute) throws MLetParseException 193 { 194 int equal = content.indexOf('=', start); 195 if (equal < 0) throw new MLetParseException("Missing '=' for attribute"); 196 197 if (!attribute.equals(content.substring(start, equal).trim())) throw new MLetParseException("Invalid attribute"); 199 200 int begin = content.indexOf('"', equal + 1); 201 if (begin < 0) throw new MLetParseException("Missing quotes for attribute value"); 202 203 if (content.substring(equal + 1, begin).trim().length() != 0) throw new MLetParseException("Invalid attribute value"); 205 206 int end = content.indexOf('"', begin + 1); 207 if (end < 0) throw new MLetParseException("Missing quote for attribute value"); 208 209 return content.substring(begin + 1, end).trim(); 210 } 211 212 private int findOpenTag(String content, int start, String tag) 213 { 214 String opening = new StringBuffer (OPEN_BRACKET).append(tag).toString(); 215 return content.indexOf(opening, start); 216 } 217 218 private int findCloseTag(String content, int start, String tag, boolean strictSyntax) 219 { 220 int count = 1; 221 222 do 223 { 224 int close = content.indexOf(CLOSE_BRACKET, start); 225 if (close < 0) 226 { 227 return -1; 228 } 229 int open = content.indexOf(OPEN_BRACKET, start); 230 if (open >= 0 && close > open) 231 { 232 ++count; 233 } 234 else 235 { 236 --count; 237 if (count == 0) 238 { 239 if (!strictSyntax || (strictSyntax && content.charAt(close - 1) == '/')) 242 { 243 return close + 1; 245 } 246 else 247 { 248 String closing = new StringBuffer (OPEN_BRACKET).append("/").append(tag).append(CLOSE_BRACKET).toString(); 250 close = content.indexOf(closing, start); 251 if (close < 0) 252 return -1; 253 else 254 return close + closing.length(); 255 } 256 } 257 } 258 259 start = close + 1; 260 } 261 while (true); 262 } 263 264 private String stripComments(String content) throws MLetParseException 265 { 266 StringBuffer buffer = new StringBuffer (); 267 int start = 0; 268 int current = -1; 269 while ((current = content.indexOf(OPEN_COMMENT, start)) >= 0) 270 { 271 int end = content.indexOf(CLOSE_COMMENT, current + 1); 272 273 if (end < 0) throw new MLetParseException("Missing close comment tag at index: " + current); 274 275 String stripped = content.substring(start, current); 276 buffer.append(stripped); 277 start = end + CLOSE_COMMENT.length(); 278 } 279 String stripped = content.substring(start, content.length()); 280 buffer.append(stripped); 281 return buffer.toString(); 282 } 283 284 private String convertToUpperCase(String content) throws MLetParseException 285 { 286 StringBuffer buffer = new StringBuffer (); 287 int start = 0; 288 int current = -1; 289 while ((current = content.indexOf("\"", start)) >= 0) 290 { 291 int end = content.indexOf("\"", current + 1); 292 293 if (end < 0) throw new MLetParseException("Missing closing quote at index: " + current); 294 295 String converted = content.substring(start, current).toUpperCase(); 296 buffer.append(converted); 297 String quoted = content.substring(current, end + 1); 298 buffer.append(quoted); 299 start = end + 1; 300 } 301 String converted = content.substring(start, content.length()).toUpperCase(); 302 buffer.append(converted); 303 return buffer.toString(); 304 } 305 306 private Object convertToObject(String clsName, String value) throws MLetParseException 307 { 308 try 309 { 310 if (clsName.equals("boolean") || clsName.equals("java.lang.Boolean")) 311 return Boolean.valueOf(value); 312 else if (clsName.equals("byte") || clsName.equals("java.lang.Byte")) 313 return Byte.valueOf(value); 314 else if (clsName.equals("char") || clsName.equals("java.lang.Character")) 315 { 316 char ch = 0; 317 if (value.length() > 0) ch = value.charAt(0); 318 return new Character (ch); 319 } 320 else if (clsName.equals("short") || clsName.equals("java.lang.Short")) 321 return Short.valueOf(value); 322 else if (clsName.equals("int") || clsName.equals("java.lang.Integer")) 323 return Integer.valueOf(value); 324 else if (clsName.equals("long") || clsName.equals("java.lang.Long")) 325 return Long.valueOf(value); 326 else if (clsName.equals("float") || clsName.equals("java.lang.Float")) 327 return Float.valueOf(value); 328 else if (clsName.equals("double") || clsName.equals("java.lang.Double")) 329 return Double.valueOf(value); 330 else if (clsName.equals("java.lang.String")) 331 return value; 332 else if (mlet != null) 333 { 334 try 335 { 336 Class cls = mlet.loadClass(clsName); 337 Constructor ctor = cls.getConstructor(new Class []{String .class}); 338 return ctor.newInstance(new Object []{value}); 339 } 340 catch (Exception ignored) 341 { 342 } 343 } 344 } 345 catch (NumberFormatException x) 346 { 347 throw new MLetParseException("Invalid value: " + value); 348 } 349 return null; 350 } 351 } 352 | Popular Tags |