0001: /*
0002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
0003: * Distributed under the terms of either:
0004: * - the common development and distribution license (CDDL), v1.0; or
0005: * - the GNU Lesser General Public License, v2.1 or later
0006: * $Id: Parsed.java 3782 2007-06-11 11:01:53Z gbevin $
0007: */
0008: package com.uwyn.rife.template;
0009:
0010: import java.util.*;
0011:
0012: import com.uwyn.rife.asm.ClassWriter;
0013: import com.uwyn.rife.asm.Label;
0014: import com.uwyn.rife.asm.MethodVisitor;
0015: import com.uwyn.rife.asm.Opcodes;
0016: import com.uwyn.rife.pcj.map.IntKeyOpenHashMap;
0017: import com.uwyn.rife.template.exceptions.TemplateException;
0018: import java.net.URL;
0019:
0020: final class Parsed implements Opcodes {
0021: private Parser mParser = null;
0022: private String mTemplateName = null;
0023: private String mPackage = null;
0024: private String mClassName = null;
0025: private URL mResource = null;
0026: private long mModificationTime = -1;
0027:
0028: private Map<String, ParsedBlockData> mBlocks = new LinkedHashMap<String, ParsedBlockData>();
0029: private Set<String> mValueIds = new LinkedHashSet<String>();
0030: private Map<String, String> mDefaultValues = new HashMap<String, String>();
0031: private List<String> mBlockvalues = new ArrayList<String>();
0032: private Map<URL, Long> mDependencies = new HashMap<URL, Long>();
0033: private String mModificationState = null;
0034: private FilteredTagsMap mFilteredValuesMap = null;
0035: private FilteredTagsMap mFilteredBlocksMap = null;
0036:
0037: Parsed(Parser parser) {
0038: assert parser != null;
0039:
0040: mParser = parser;
0041: }
0042:
0043: private IntKeyOpenHashMap<ArrayList<String>> getHashcodeKeysMapping(
0044: Collection<String> stringCollection) {
0045: // create a mapping of all string hashcodes to their possible real values
0046: // hashcodes will be used in a switch for quick lookup of blocks
0047: IntKeyOpenHashMap<ArrayList<String>> hashcode_keys_mapping = new IntKeyOpenHashMap<ArrayList<String>>();
0048: int hashcode;
0049: ArrayList<String> keys = null;
0050: for (String key : stringCollection) {
0051: hashcode = key.hashCode();
0052: keys = hashcode_keys_mapping.get(hashcode);
0053: if (null == keys) {
0054: keys = new ArrayList<String>();
0055: hashcode_keys_mapping.put(hashcode, keys);
0056: }
0057: keys.add(key);
0058: }
0059:
0060: return hashcode_keys_mapping;
0061: }
0062:
0063: // store an integer on the stack
0064: private void addIntegerConst(MethodVisitor method, int value) {
0065: switch (value) {
0066: case -1:
0067: method.visitInsn(ICONST_M1);
0068: break;
0069: case 0:
0070: method.visitInsn(ICONST_0);
0071: break;
0072: case 1:
0073: method.visitInsn(ICONST_1);
0074: break;
0075: case 2:
0076: method.visitInsn(ICONST_2);
0077: break;
0078: case 3:
0079: method.visitInsn(ICONST_3);
0080: break;
0081: case 4:
0082: method.visitInsn(ICONST_4);
0083: break;
0084: case 5:
0085: method.visitInsn(ICONST_5);
0086: break;
0087: default:
0088: method.visitLdcInsn(value);
0089: break;
0090: }
0091: }
0092:
0093: byte[] getByteCode() {
0094: ClassWriter class_writer = new ClassWriter(true);
0095: MethodVisitor method = null;
0096:
0097: String full_classname = (getPackage() + "." + getClassName())
0098: .replace('.', '/');
0099:
0100: // define the template class
0101: class_writer.visit(V1_4, ACC_PUBLIC | ACC_SYNCHRONIZED,
0102: full_classname, null,
0103: "com/uwyn/rife/template/AbstractTemplate", null);
0104:
0105: // generate the template constructor
0106: method = class_writer.visitMethod(ACC_PUBLIC, "<init>", "()V",
0107: null, null);
0108: method.visitVarInsn(ALOAD, 0);
0109: method.visitMethodInsn(INVOKESPECIAL,
0110: "com/uwyn/rife/template/AbstractTemplate", "<init>",
0111: "()V");
0112: method.visitInsn(RETURN);
0113: method.visitMaxs(0, 0);
0114:
0115: // define the method that will return the template name
0116: method = class_writer.visitMethod(ACC_PUBLIC, "getName",
0117: "()Ljava/lang/String;", null, null);
0118: method.visitLdcInsn(mClassName);
0119: method.visitInsn(ARETURN);
0120: method.visitMaxs(0, 0);
0121:
0122: // define the method that will return the full template name
0123: method = class_writer.visitMethod(ACC_PUBLIC, "getFullName",
0124: "()Ljava/lang/String;", null, null);
0125: method.visitLdcInsn(mTemplateName);
0126: method.visitInsn(ARETURN);
0127: method.visitMaxs(0, 0);
0128:
0129: // define the methods that will return the modification time
0130: method = class_writer.visitMethod(ACC_STATIC,
0131: "getModificationTimeReal", "()J", null, null);
0132: method.visitLdcInsn(getModificationTime());
0133: method.visitInsn(LRETURN);
0134: method.visitMaxs(0, 0);
0135:
0136: method = class_writer.visitMethod(ACC_PUBLIC,
0137: "getModificationTime", "()J", null, null);
0138: method.visitMethodInsn(INVOKESTATIC, full_classname,
0139: "getModificationTimeReal", "()J");
0140: method.visitInsn(LRETURN);
0141: method.visitMaxs(0, 0);
0142:
0143: // define the method that will return the modification state
0144: method = class_writer.visitMethod(ACC_STATIC,
0145: "getModificationState", "()Ljava/lang/String;", null,
0146: null);
0147: if (null == mModificationState) {
0148: method.visitInsn(ACONST_NULL);
0149: } else {
0150: method.visitLdcInsn(mModificationState);
0151: }
0152: method.visitInsn(ARETURN);
0153: method.visitMaxs(0, 0);
0154:
0155: // prepare the blocks for lookup switches
0156: ParsedBlockData block_data = null;
0157: ArrayList<String> keys = null;
0158:
0159: IntKeyOpenHashMap<ArrayList<String>> hashcode_keys_mapping = null;
0160: LinkedHashMap<String, ParsedBlockPart> blockparts_order = null;
0161: int[] hashcodes = null;
0162:
0163: hashcode_keys_mapping = getHashcodeKeysMapping(mBlocks.keySet());
0164: blockparts_order = new LinkedHashMap<String, ParsedBlockPart>();
0165: hashcodes = hashcode_keys_mapping.keySet().toArray();
0166: Arrays.sort(hashcodes);
0167: keys = null;
0168:
0169: // generate the method that will append the block parts according to the current set of values
0170: // for external usage
0171: {
0172: method = class_writer
0173: .visitMethod(
0174: ACC_PROTECTED,
0175: "appendBlockExternalForm",
0176: "(Ljava/lang/String;Lcom/uwyn/rife/template/ExternalValue;)Z",
0177: null, null);
0178: method.visitVarInsn(ALOAD, 1);
0179: method.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String",
0180: "hashCode", "()I");
0181: Label external_default = new Label();
0182: Label external_found = new Label();
0183: Label[] external_labels = new Label[hashcodes.length];
0184: for (int i = 0; i < external_labels.length; i++) {
0185: external_labels[i] = new Label();
0186: }
0187:
0188: method.visitLookupSwitchInsn(external_default, hashcodes,
0189: external_labels);
0190: String blockdata_static_prefix = "sBlockPart";
0191: long blockdata_static_counter = 0L;
0192: String static_identifier = null;
0193: for (int i = 0; i < hashcodes.length; i++) {
0194: method.visitLabel(external_labels[i]);
0195:
0196: keys = hashcode_keys_mapping.get(hashcodes[i]);
0197: if (1 == keys.size()) {
0198: block_data = mBlocks.get(keys.get(0));
0199:
0200: Iterator<ParsedBlockPart> block_data_it = block_data
0201: .iterator();
0202: ParsedBlockPart block_part = null;
0203: while (block_data_it.hasNext()) {
0204: block_part = block_data_it.next();
0205:
0206: static_identifier = blockdata_static_prefix
0207: + (blockdata_static_counter++);
0208:
0209: blockparts_order.put(static_identifier,
0210: block_part);
0211: block_part.visitByteCodeExternalForm(method,
0212: full_classname, static_identifier);
0213: }
0214: } else {
0215: for (String key : keys) {
0216: Label after_key_label = new Label();
0217: method.visitVarInsn(ALOAD, 1);
0218: method.visitLdcInsn(key);
0219: method.visitMethodInsn(INVOKEVIRTUAL,
0220: "java/lang/String", "equals",
0221: "(Ljava/lang/Object;)Z");
0222: method.visitJumpInsn(IFEQ, after_key_label);
0223:
0224: block_data = mBlocks.get(key);
0225:
0226: for (ParsedBlockPart block_part : block_data) {
0227: static_identifier = blockdata_static_prefix
0228: + (blockdata_static_counter++);
0229:
0230: blockparts_order.put(static_identifier,
0231: block_part);
0232: block_part.visitByteCodeExternalForm(
0233: method, full_classname,
0234: static_identifier);
0235: }
0236: method.visitJumpInsn(GOTO, external_found);
0237: method.visitLabel(after_key_label);
0238: }
0239: method.visitInsn(ICONST_0);
0240: method.visitInsn(IRETURN);
0241: }
0242: method.visitJumpInsn(GOTO, external_found);
0243: }
0244: method.visitLabel(external_default);
0245: method.visitInsn(ICONST_0);
0246: method.visitInsn(IRETURN);
0247: method.visitLabel(external_found);
0248: method.visitInsn(ICONST_1);
0249: method.visitInsn(IRETURN);
0250: method.visitMaxs(0, 0);
0251: }
0252:
0253: // generate the method that will append the block parts according to the current set of values
0254: // for internal usage
0255: {
0256: method = class_writer
0257: .visitMethod(
0258: ACC_PROTECTED,
0259: "appendBlockInternalForm",
0260: "(Ljava/lang/String;Lcom/uwyn/rife/template/InternalValue;)Z",
0261: null, null);
0262: method.visitVarInsn(ALOAD, 1);
0263: method.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String",
0264: "hashCode", "()I");
0265: Label internal_default = new Label();
0266: Label internal_found = new Label();
0267: Label[] internal_labels = new Label[hashcodes.length];
0268: for (int i = 0; i < internal_labels.length; i++) {
0269: internal_labels[i] = new Label();
0270: }
0271:
0272: method.visitLookupSwitchInsn(internal_default, hashcodes,
0273: internal_labels);
0274: String static_identifier = null;
0275: Iterator<String> static_identifiers_it = blockparts_order
0276: .keySet().iterator();
0277: for (int i = 0; i < hashcodes.length; i++) {
0278: method.visitLabel(internal_labels[i]);
0279:
0280: int text_count = 0;
0281: int value_count = 0;
0282:
0283: keys = hashcode_keys_mapping.get(hashcodes[i]);
0284: if (1 == keys.size()) {
0285: block_data = mBlocks.get(keys.get(0));
0286:
0287: Iterator<ParsedBlockPart> block_data_it = null;
0288: ParsedBlockPart block_part = null;
0289:
0290: block_data_it = block_data.iterator();
0291: while (block_data_it.hasNext()) {
0292: block_part = block_data_it.next();
0293:
0294: if (ParsedBlockPart.TEXT == block_part
0295: .getType()) {
0296: text_count++;
0297: } else if (ParsedBlockPart.VALUE == block_part
0298: .getType()) {
0299: value_count++;
0300: }
0301: }
0302:
0303: if (text_count + value_count > 0) {
0304: method.visitVarInsn(ALOAD, 0);
0305: method.visitVarInsn(ALOAD, 2);
0306: addIntegerConst(method, text_count
0307: + value_count);
0308: method
0309: .visitMethodInsn(
0310: INVOKEVIRTUAL,
0311: full_classname,
0312: "increasePartsCapacityInternal",
0313: "(Lcom/uwyn/rife/template/InternalValue;I)V");
0314: }
0315:
0316: if (value_count > 0) {
0317: method.visitVarInsn(ALOAD, 0);
0318: method.visitVarInsn(ALOAD, 2);
0319: addIntegerConst(method, value_count);
0320: method
0321: .visitMethodInsn(
0322: INVOKEVIRTUAL,
0323: full_classname,
0324: "increaseValuesCapacityInternal",
0325: "(Lcom/uwyn/rife/template/InternalValue;I)V");
0326: }
0327:
0328: block_data_it = block_data.iterator();
0329: while (block_data_it.hasNext()) {
0330: block_part = block_data_it.next();
0331:
0332: static_identifier = static_identifiers_it
0333: .next();
0334:
0335: block_part.visitByteCodeInternalForm(method,
0336: full_classname, static_identifier);
0337: }
0338: method.visitJumpInsn(GOTO, internal_found);
0339: } else {
0340: for (String key : keys) {
0341: Label after_key_label = new Label();
0342: method.visitVarInsn(ALOAD, 1);
0343: method.visitLdcInsn(key);
0344: method.visitMethodInsn(INVOKEVIRTUAL,
0345: "java/lang/String", "equals",
0346: "(Ljava/lang/Object;)Z");
0347: method.visitJumpInsn(IFEQ, after_key_label);
0348:
0349: block_data = mBlocks.get(key);
0350:
0351: Iterator<ParsedBlockPart> block_data_it = null;
0352: ParsedBlockPart block_part = null;
0353:
0354: block_data_it = block_data.iterator();
0355: while (block_data_it.hasNext()) {
0356: block_part = block_data_it.next();
0357:
0358: if (ParsedBlockPart.TEXT == block_part
0359: .getType()) {
0360: text_count++;
0361: } else if (ParsedBlockPart.VALUE == block_part
0362: .getType()) {
0363: value_count++;
0364: }
0365: }
0366:
0367: method.visitVarInsn(ALOAD, 0);
0368: method.visitVarInsn(ALOAD, 2);
0369: addIntegerConst(method, text_count
0370: + value_count);
0371: method
0372: .visitMethodInsn(
0373: INVOKEVIRTUAL,
0374: full_classname,
0375: "increasePartsCapacityInternal",
0376: "(Lcom/uwyn/rife/template/InternalValue;I)V");
0377:
0378: method.visitVarInsn(ALOAD, 0);
0379: method.visitVarInsn(ALOAD, 2);
0380: addIntegerConst(method, value_count);
0381: method
0382: .visitMethodInsn(
0383: INVOKEVIRTUAL,
0384: full_classname,
0385: "increaseValuesCapacityInternal",
0386: "(Lcom/uwyn/rife/template/InternalValue;I)V");
0387:
0388: block_data_it = block_data.iterator();
0389: while (block_data_it.hasNext()) {
0390: block_part = block_data_it.next();
0391:
0392: static_identifier = static_identifiers_it
0393: .next();
0394:
0395: block_part.visitByteCodeInternalForm(
0396: method, full_classname,
0397: static_identifier);
0398: }
0399:
0400: method.visitJumpInsn(GOTO, internal_found);
0401: method.visitLabel(after_key_label);
0402: }
0403: method.visitInsn(ICONST_0);
0404: method.visitInsn(IRETURN);
0405: }
0406: }
0407:
0408: method.visitLabel(internal_default);
0409: method.visitInsn(ICONST_0);
0410: method.visitInsn(IRETURN);
0411: method.visitLabel(internal_found);
0412: method.visitInsn(ICONST_1);
0413: method.visitInsn(IRETURN);
0414: method.visitMaxs(0, 0);
0415: }
0416:
0417: // generate the method that will return the defined default values
0418: method = class_writer.visitMethod(ACC_PUBLIC,
0419: "getDefaultValue",
0420: "(Ljava/lang/String;)Ljava/lang/String;", null, null);
0421: {
0422: Label after_null_check = new Label();
0423: method.visitInsn(ACONST_NULL);
0424: method.visitVarInsn(ALOAD, 1);
0425: method.visitJumpInsn(IF_ACMPNE, after_null_check);
0426: method.visitTypeInsn(NEW,
0427: "java/lang/IllegalArgumentException");
0428: method.visitInsn(DUP);
0429: method.visitLdcInsn("id can't be null.");
0430: method.visitMethodInsn(INVOKESPECIAL,
0431: "java/lang/IllegalArgumentException", "<init>",
0432: "(Ljava/lang/String;)V");
0433: method.visitInsn(ATHROW);
0434: method.visitLabel(after_null_check);
0435:
0436: Label after_empty_check = new Label();
0437: method.visitInsn(ICONST_0);
0438: method.visitVarInsn(ALOAD, 1);
0439: method.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String",
0440: "length", "()I");
0441: method.visitJumpInsn(IF_ICMPNE, after_empty_check);
0442: method.visitTypeInsn(NEW,
0443: "java/lang/IllegalArgumentException");
0444: method.visitInsn(DUP);
0445: method.visitLdcInsn("id can't be empty.");
0446: method.visitMethodInsn(INVOKESPECIAL,
0447: "java/lang/IllegalArgumentException", "<init>",
0448: "(Ljava/lang/String;)V");
0449: method.visitInsn(ATHROW);
0450: method.visitLabel(after_empty_check);
0451:
0452: method.visitInsn(ACONST_NULL);
0453: method.visitVarInsn(ASTORE, 2);
0454:
0455: if (mBlockvalues.size() > 0) {
0456: Label blockvalue_doesntexist_label = new Label();
0457: method.visitFieldInsn(GETSTATIC, full_classname,
0458: "sBlockvalues", "Ljava/util/ArrayList;");
0459: method.visitVarInsn(ALOAD, 1);
0460: method.visitMethodInsn(INVOKEVIRTUAL,
0461: "java/util/ArrayList", "contains",
0462: "(Ljava/lang/Object;)Z");
0463: method
0464: .visitJumpInsn(IFEQ,
0465: blockvalue_doesntexist_label);
0466: method.visitTypeInsn(NEW,
0467: "com/uwyn/rife/template/ExternalValue");
0468: method.visitInsn(DUP);
0469: method.visitMethodInsn(INVOKESPECIAL,
0470: "com/uwyn/rife/template/ExternalValue",
0471: "<init>", "()V");
0472: method.visitVarInsn(ASTORE, 3);
0473: method.visitVarInsn(ALOAD, 0);
0474: method.visitVarInsn(ALOAD, 1);
0475: method.visitVarInsn(ALOAD, 3);
0476: method
0477: .visitMethodInsn(INVOKEVIRTUAL, full_classname,
0478: "appendBlockExternalForm",
0479: "(Ljava/lang/String;Lcom/uwyn/rife/template/ExternalValue;)Z");
0480: method.visitInsn(POP);
0481: method.visitVarInsn(ALOAD, 3);
0482: method.visitMethodInsn(INVOKEVIRTUAL,
0483: "com/uwyn/rife/template/ExternalValue",
0484: "toString", "()Ljava/lang/String;");
0485: method.visitVarInsn(ASTORE, 2);
0486: method.visitLabel(blockvalue_doesntexist_label);
0487: }
0488: if (mDefaultValues.size() > 0) {
0489: Label defaultvalues_alreadyexist_label = new Label();
0490: method.visitInsn(ACONST_NULL);
0491: method.visitVarInsn(ALOAD, 2);
0492: method.visitJumpInsn(IF_ACMPNE,
0493: defaultvalues_alreadyexist_label);
0494: method.visitFieldInsn(GETSTATIC, full_classname,
0495: "sDefaultValues", "Ljava/util/HashMap;");
0496: method.visitVarInsn(ALOAD, 1);
0497: method.visitMethodInsn(INVOKEVIRTUAL,
0498: "java/util/HashMap", "get",
0499: "(Ljava/lang/Object;)Ljava/lang/Object;");
0500: method.visitTypeInsn(CHECKCAST, "java/lang/String");
0501: method.visitVarInsn(ASTORE, 2);
0502: method.visitLabel(defaultvalues_alreadyexist_label);
0503: }
0504:
0505: method.visitVarInsn(ALOAD, 2);
0506: method.visitInsn(ARETURN);
0507: method.visitMaxs(0, 0);
0508: }
0509:
0510: // generate the method that will append defined default values
0511: // for external usage
0512: method = class_writer
0513: .visitMethod(
0514: ACC_PROTECTED,
0515: "appendDefaultValueExternalForm",
0516: "(Ljava/lang/String;Lcom/uwyn/rife/template/ExternalValue;)Z",
0517: null, null);
0518: {
0519: method.visitInsn(ICONST_0);
0520: method.visitVarInsn(ISTORE, 3);
0521: if (mBlockvalues.size() > 0) {
0522: Label blockvalue_doesntexist_label = new Label();
0523: method.visitFieldInsn(GETSTATIC, full_classname,
0524: "sBlockvalues", "Ljava/util/ArrayList;");
0525: method.visitVarInsn(ALOAD, 1);
0526: method.visitMethodInsn(INVOKEVIRTUAL,
0527: "java/util/ArrayList", "contains",
0528: "(Ljava/lang/Object;)Z");
0529: method
0530: .visitJumpInsn(IFEQ,
0531: blockvalue_doesntexist_label);
0532: method.visitVarInsn(ALOAD, 0);
0533: method.visitVarInsn(ALOAD, 1);
0534: method.visitVarInsn(ALOAD, 2);
0535: method
0536: .visitMethodInsn(INVOKEVIRTUAL, full_classname,
0537: "appendBlockExternalForm",
0538: "(Ljava/lang/String;Lcom/uwyn/rife/template/ExternalValue;)Z");
0539: method.visitInsn(POP);
0540: method.visitInsn(ICONST_1);
0541: method.visitVarInsn(ISTORE, 3);
0542: method.visitLabel(blockvalue_doesntexist_label);
0543: }
0544: if (mDefaultValues.size() > 0) {
0545: Label alreadyfound_defaultvalue_label = new Label();
0546: method.visitVarInsn(ILOAD, 3);
0547: method.visitJumpInsn(IFNE,
0548: alreadyfound_defaultvalue_label);
0549: method.visitFieldInsn(GETSTATIC, full_classname,
0550: "sDefaultValues", "Ljava/util/HashMap;");
0551: method.visitVarInsn(ALOAD, 1);
0552: method.visitMethodInsn(INVOKEVIRTUAL,
0553: "java/util/HashMap", "containsKey",
0554: "(Ljava/lang/Object;)Z");
0555: method.visitJumpInsn(IFEQ,
0556: alreadyfound_defaultvalue_label);
0557: method.visitVarInsn(ALOAD, 2);
0558: method.visitFieldInsn(GETSTATIC, full_classname,
0559: "sDefaultValues", "Ljava/util/HashMap;");
0560: method.visitVarInsn(ALOAD, 1);
0561: method.visitMethodInsn(INVOKEVIRTUAL,
0562: "java/util/HashMap", "get",
0563: "(Ljava/lang/Object;)Ljava/lang/Object;");
0564: method.visitTypeInsn(CHECKCAST, "java/lang/String");
0565: method.visitMethodInsn(INVOKEVIRTUAL,
0566: "com/uwyn/rife/template/ExternalValue",
0567: "append", "(Ljava/lang/CharSequence;)V");
0568: method.visitInsn(ICONST_1);
0569: method.visitVarInsn(ISTORE, 3);
0570: method.visitLabel(alreadyfound_defaultvalue_label);
0571: }
0572: method.visitVarInsn(ILOAD, 3);
0573: method.visitInsn(IRETURN);
0574: method.visitMaxs(0, 0);
0575: }
0576:
0577: // generate the method that will append defined default values
0578: // for internal usage
0579: method = class_writer
0580: .visitMethod(
0581: ACC_PROTECTED,
0582: "appendDefaultValueInternalForm",
0583: "(Ljava/lang/String;Lcom/uwyn/rife/template/InternalValue;)Z",
0584: null, null);
0585: {
0586: if (mBlockvalues.size() > 0) {
0587: Label blockvalue_doesntexist_label = new Label();
0588: method.visitFieldInsn(GETSTATIC, full_classname,
0589: "sBlockvalues", "Ljava/util/ArrayList;");
0590: method.visitVarInsn(ALOAD, 1);
0591: method.visitMethodInsn(INVOKEVIRTUAL,
0592: "java/util/ArrayList", "contains",
0593: "(Ljava/lang/Object;)Z");
0594: method
0595: .visitJumpInsn(IFEQ,
0596: blockvalue_doesntexist_label);
0597: method.visitVarInsn(ALOAD, 0);
0598: method.visitVarInsn(ALOAD, 1);
0599: method.visitVarInsn(ALOAD, 2);
0600: method
0601: .visitMethodInsn(INVOKEVIRTUAL, full_classname,
0602: "appendBlockInternalForm",
0603: "(Ljava/lang/String;Lcom/uwyn/rife/template/InternalValue;)Z");
0604: method.visitInsn(POP);
0605: method.visitInsn(ICONST_1);
0606: method.visitInsn(IRETURN);
0607: method.visitLabel(blockvalue_doesntexist_label);
0608: }
0609: method.visitInsn(ICONST_0);
0610: method.visitInsn(IRETURN);
0611: method.visitMaxs(0, 0);
0612: }
0613:
0614: // generate the method that checks the modification status of this particular template class
0615: method = class_writer
0616: .visitMethod(
0617: ACC_PUBLIC | ACC_STATIC,
0618: "isModified",
0619: "(Lcom/uwyn/rife/resources/ResourceFinder;Ljava/lang/String;)Z",
0620: null, null);
0621: method.visitFieldInsn(GETSTATIC, full_classname, "sResource",
0622: "Ljava/net/URL;");
0623: method.visitMethodInsn(INVOKESTATIC, full_classname,
0624: "getModificationTimeReal", "()J");
0625: method.visitFieldInsn(GETSTATIC, full_classname,
0626: "sDependencies", "Ljava/util/HashMap;");
0627: method.visitMethodInsn(INVOKESTATIC, full_classname,
0628: "getModificationState", "()Ljava/lang/String;");
0629: method.visitVarInsn(ALOAD, 0);
0630: method.visitVarInsn(ALOAD, 1);
0631: method
0632: .visitMethodInsn(
0633: INVOKESTATIC,
0634: full_classname,
0635: "isTemplateClassModified",
0636: "(Ljava/net/URL;JLjava/util/Map;Ljava/lang/String;Lcom/uwyn/rife/resources/ResourceFinder;Ljava/lang/String;)Z");
0637: method.visitInsn(IRETURN);
0638: method.visitMaxs(0, 0);
0639:
0640: // generate the method that checks if a value is present in a template
0641: method = class_writer.visitMethod(ACC_PUBLIC, "hasValueId",
0642: "(Ljava/lang/String;)Z", null, null);
0643: if (mValueIds.size() > 0) {
0644: method.visitFieldInsn(GETSTATIC, full_classname,
0645: "sValueIds", "Ljava/util/HashSet;");
0646: method.visitVarInsn(ALOAD, 1);
0647: method.visitMethodInsn(INVOKEVIRTUAL, "java/util/HashSet",
0648: "contains", "(Ljava/lang/Object;)Z");
0649: } else {
0650: method.visitInsn(ICONST_0);
0651: }
0652: method.visitInsn(IRETURN);
0653: method.visitMaxs(0, 0);
0654:
0655: // generate the method that returns all values that are available
0656: method = class_writer.visitMethod(ACC_PUBLIC,
0657: "getAvailableValueIds", "()[Ljava/lang/String;", null,
0658: null);
0659: if (mValueIds.size() > 0) {
0660: method.visitFieldInsn(GETSTATIC, full_classname,
0661: "sValueIdsArray", "[Ljava/lang/String;");
0662: } else {
0663: method.visitInsn(ICONST_0);
0664: method.visitTypeInsn(ANEWARRAY, "java/lang/String");
0665: }
0666: method.visitInsn(ARETURN);
0667: method.visitMaxs(0, 0);
0668:
0669: // generate the method that returns all values that aren't set yet
0670: method = class_writer.visitMethod(ACC_PUBLIC,
0671: "getUnsetValueIds", "()Ljava/util/Collection;", null,
0672: null);
0673: method.visitTypeInsn(NEW, "java/util/ArrayList");
0674: method.visitInsn(DUP);
0675: method.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList",
0676: "<init>", "()V");
0677: method.visitVarInsn(ASTORE, 1);
0678: if (mValueIds.size() > 0) {
0679: Label while_start_label = new Label();
0680: Label while_end_label = new Label();
0681: method.visitFieldInsn(GETSTATIC, full_classname,
0682: "sValueIds", "Ljava/util/HashSet;");
0683: method.visitMethodInsn(INVOKEVIRTUAL, "java/util/HashSet",
0684: "iterator", "()Ljava/util/Iterator;");
0685: method.visitVarInsn(ASTORE, 2);
0686: method.visitInsn(ACONST_NULL);
0687: method.visitVarInsn(ASTORE, 3);
0688: method.visitLabel(while_start_label);
0689: method.visitVarInsn(ALOAD, 2);
0690: method.visitMethodInsn(INVOKEINTERFACE,
0691: "java/util/Iterator", "hasNext", "()Z");
0692: method.visitJumpInsn(IFEQ, while_end_label);
0693: method.visitVarInsn(ALOAD, 2);
0694: method.visitMethodInsn(INVOKEINTERFACE,
0695: "java/util/Iterator", "next",
0696: "()Ljava/lang/Object;");
0697: method.visitTypeInsn(CHECKCAST, "java/lang/String");
0698: method.visitVarInsn(ASTORE, 3);
0699: method.visitVarInsn(ALOAD, 0);
0700: method.visitVarInsn(ALOAD, 3);
0701: method.visitMethodInsn(INVOKEVIRTUAL, full_classname,
0702: "isValueSet", "(Ljava/lang/String;)Z");
0703: method.visitJumpInsn(IFNE, while_start_label);
0704: method.visitVarInsn(ALOAD, 0);
0705: method.visitVarInsn(ALOAD, 3);
0706: method.visitMethodInsn(INVOKEVIRTUAL, full_classname,
0707: "hasDefaultValue", "(Ljava/lang/String;)Z");
0708: method.visitJumpInsn(IFNE, while_start_label);
0709: method.visitVarInsn(ALOAD, 1);
0710: method.visitVarInsn(ALOAD, 3);
0711: method.visitMethodInsn(INVOKEVIRTUAL,
0712: "java/util/ArrayList", "add",
0713: "(Ljava/lang/Object;)Z");
0714: method.visitInsn(POP);
0715: method.visitJumpInsn(GOTO, while_start_label);
0716: method.visitLabel(while_end_label);
0717: }
0718: method.visitVarInsn(ALOAD, 1);
0719: method.visitInsn(ARETURN);
0720: method.visitMaxs(0, 0);
0721:
0722: // generate the method that returns the list of blocks according to a filter
0723: method = class_writer.visitMethod(ACC_PUBLIC,
0724: "getFilteredBlocks",
0725: "(Ljava/lang/String;)Ljava/util/List;", null, null);
0726: {
0727: Label after_null_check = new Label();
0728: method.visitInsn(ACONST_NULL);
0729: method.visitVarInsn(ALOAD, 1);
0730: method.visitJumpInsn(IF_ACMPNE, after_null_check);
0731: method.visitTypeInsn(NEW,
0732: "java/lang/IllegalArgumentException");
0733: method.visitInsn(DUP);
0734: method.visitLdcInsn("filter can't be null.");
0735: method.visitMethodInsn(INVOKESPECIAL,
0736: "java/lang/IllegalArgumentException", "<init>",
0737: "(Ljava/lang/String;)V");
0738: method.visitInsn(ATHROW);
0739: method.visitLabel(after_null_check);
0740:
0741: Label after_empty_check = new Label();
0742: method.visitInsn(ICONST_0);
0743: method.visitVarInsn(ALOAD, 1);
0744: method.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String",
0745: "length", "()I");
0746: method.visitJumpInsn(IF_ICMPNE, after_empty_check);
0747: method.visitTypeInsn(NEW,
0748: "java/lang/IllegalArgumentException");
0749: method.visitInsn(DUP);
0750: method.visitLdcInsn("filter can't be empty.");
0751: method.visitMethodInsn(INVOKESPECIAL,
0752: "java/lang/IllegalArgumentException", "<init>",
0753: "(Ljava/lang/String;)V");
0754: method.visitInsn(ATHROW);
0755: method.visitLabel(after_empty_check);
0756:
0757: if (mFilteredBlocksMap != null) {
0758: method.visitFieldInsn(GETSTATIC, full_classname,
0759: "sFilteredBlocksMap", "Ljava/util/HashMap;");
0760: method.visitVarInsn(ALOAD, 1);
0761: method.visitMethodInsn(INVOKEVIRTUAL,
0762: "java/util/HashMap", "get",
0763: "(Ljava/lang/Object;)Ljava/lang/Object;");
0764: method.visitTypeInsn(CHECKCAST, "java/util/List");
0765: method.visitVarInsn(ASTORE, 2);
0766: method.visitInsn(ACONST_NULL);
0767: method.visitVarInsn(ALOAD, 2);
0768: Label list_null_check = new Label();
0769: method.visitJumpInsn(IF_ACMPNE, list_null_check);
0770: method.visitFieldInsn(GETSTATIC,
0771: "java/util/Collections", "EMPTY_LIST",
0772: "Ljava/util/List;");
0773: method.visitVarInsn(ASTORE, 2);
0774: method.visitLabel(list_null_check);
0775: method.visitVarInsn(ALOAD, 2);
0776: method.visitInsn(ARETURN);
0777: } else {
0778: method.visitFieldInsn(GETSTATIC,
0779: "java/util/Collections", "EMPTY_LIST",
0780: "Ljava/util/List;");
0781: method.visitInsn(ARETURN);
0782: }
0783: method.visitMaxs(0, 0);
0784: }
0785:
0786: // generate the method that verifies if blocks are present that match a certain filter
0787: method = class_writer.visitMethod(ACC_PUBLIC,
0788: "hasFilteredBlocks", "(Ljava/lang/String;)Z", null,
0789: null);
0790: {
0791: Label after_null_check = new Label();
0792: method.visitInsn(ACONST_NULL);
0793: method.visitVarInsn(ALOAD, 1);
0794: method.visitJumpInsn(IF_ACMPNE, after_null_check);
0795: method.visitTypeInsn(NEW,
0796: "java/lang/IllegalArgumentException");
0797: method.visitInsn(DUP);
0798: method.visitLdcInsn("filter can't be null.");
0799: method.visitMethodInsn(INVOKESPECIAL,
0800: "java/lang/IllegalArgumentException", "<init>",
0801: "(Ljava/lang/String;)V");
0802: method.visitInsn(ATHROW);
0803: method.visitLabel(after_null_check);
0804:
0805: Label after_empty_check = new Label();
0806: method.visitInsn(ICONST_0);
0807: method.visitVarInsn(ALOAD, 1);
0808: method.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String",
0809: "length", "()I");
0810: method.visitJumpInsn(IF_ICMPNE, after_empty_check);
0811: method.visitTypeInsn(NEW,
0812: "java/lang/IllegalArgumentException");
0813: method.visitInsn(DUP);
0814: method.visitLdcInsn("filter can't be empty.");
0815: method.visitMethodInsn(INVOKESPECIAL,
0816: "java/lang/IllegalArgumentException", "<init>",
0817: "(Ljava/lang/String;)V");
0818: method.visitInsn(ATHROW);
0819: method.visitLabel(after_empty_check);
0820:
0821: if (mFilteredBlocksMap != null) {
0822: method.visitFieldInsn(GETSTATIC, full_classname,
0823: "sFilteredBlocksMap", "Ljava/util/HashMap;");
0824: method.visitVarInsn(ALOAD, 1);
0825: method.visitMethodInsn(INVOKEVIRTUAL,
0826: "java/util/HashMap", "containsKey",
0827: "(Ljava/lang/Object;)Z");
0828: method.visitInsn(IRETURN);
0829: } else {
0830: method.visitInsn(ICONST_0);
0831: method.visitInsn(IRETURN);
0832: }
0833: method.visitMaxs(0, 0);
0834: }
0835:
0836: // generate the method that returns the list of values according to a filter
0837: method = class_writer.visitMethod(ACC_PUBLIC,
0838: "getFilteredValues",
0839: "(Ljava/lang/String;)Ljava/util/List;", null, null);
0840: {
0841: Label after_null_check = new Label();
0842: method.visitInsn(ACONST_NULL);
0843: method.visitVarInsn(ALOAD, 1);
0844: method.visitJumpInsn(IF_ACMPNE, after_null_check);
0845: method.visitTypeInsn(NEW,
0846: "java/lang/IllegalArgumentException");
0847: method.visitInsn(DUP);
0848: method.visitLdcInsn("filter can't be null.");
0849: method.visitMethodInsn(INVOKESPECIAL,
0850: "java/lang/IllegalArgumentException", "<init>",
0851: "(Ljava/lang/String;)V");
0852: method.visitInsn(ATHROW);
0853: method.visitLabel(after_null_check);
0854:
0855: Label after_empty_check = new Label();
0856: method.visitInsn(ICONST_0);
0857: method.visitVarInsn(ALOAD, 1);
0858: method.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String",
0859: "length", "()I");
0860: method.visitJumpInsn(IF_ICMPNE, after_empty_check);
0861: method.visitTypeInsn(NEW,
0862: "java/lang/IllegalArgumentException");
0863: method.visitInsn(DUP);
0864: method.visitLdcInsn("filter can't be empty.");
0865: method.visitMethodInsn(INVOKESPECIAL,
0866: "java/lang/IllegalArgumentException", "<init>",
0867: "(Ljava/lang/String;)V");
0868: method.visitInsn(ATHROW);
0869: method.visitLabel(after_empty_check);
0870:
0871: if (mFilteredValuesMap != null) {
0872: method.visitFieldInsn(GETSTATIC, full_classname,
0873: "sFilteredValuesMap", "Ljava/util/HashMap;");
0874: method.visitVarInsn(ALOAD, 1);
0875: method.visitMethodInsn(INVOKEVIRTUAL,
0876: "java/util/HashMap", "get",
0877: "(Ljava/lang/Object;)Ljava/lang/Object;");
0878: method.visitTypeInsn(CHECKCAST, "java/util/List");
0879: method.visitVarInsn(ASTORE, 2);
0880: method.visitInsn(ACONST_NULL);
0881: method.visitVarInsn(ALOAD, 2);
0882: Label list_null_check = new Label();
0883: method.visitJumpInsn(IF_ACMPNE, list_null_check);
0884: method.visitFieldInsn(GETSTATIC,
0885: "java/util/Collections", "EMPTY_LIST",
0886: "Ljava/util/List;");
0887: method.visitVarInsn(ASTORE, 2);
0888: method.visitLabel(list_null_check);
0889: method.visitVarInsn(ALOAD, 2);
0890: method.visitInsn(ARETURN);
0891: } else {
0892: method.visitFieldInsn(GETSTATIC,
0893: "java/util/Collections", "EMPTY_LIST",
0894: "Ljava/util/List;");
0895: method.visitInsn(ARETURN);
0896: }
0897: method.visitMaxs(0, 0);
0898: }
0899:
0900: // generate the method that verifies if values are present that match a certain filter
0901: method = class_writer.visitMethod(ACC_PUBLIC,
0902: "hasFilteredValues", "(Ljava/lang/String;)Z", null,
0903: null);
0904: {
0905: Label after_null_check = new Label();
0906: method.visitInsn(ACONST_NULL);
0907: method.visitVarInsn(ALOAD, 1);
0908: method.visitJumpInsn(IF_ACMPNE, after_null_check);
0909: method.visitTypeInsn(NEW,
0910: "java/lang/IllegalArgumentException");
0911: method.visitInsn(DUP);
0912: method.visitLdcInsn("filter can't be null.");
0913: method.visitMethodInsn(INVOKESPECIAL,
0914: "java/lang/IllegalArgumentException", "<init>",
0915: "(Ljava/lang/String;)V");
0916: method.visitInsn(ATHROW);
0917: method.visitLabel(after_null_check);
0918:
0919: Label after_empty_check = new Label();
0920: method.visitInsn(ICONST_0);
0921: method.visitVarInsn(ALOAD, 1);
0922: method.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String",
0923: "length", "()I");
0924: method.visitJumpInsn(IF_ICMPNE, after_empty_check);
0925: method.visitTypeInsn(NEW,
0926: "java/lang/IllegalArgumentException");
0927: method.visitInsn(DUP);
0928: method.visitLdcInsn("filter can't be empty.");
0929: method.visitMethodInsn(INVOKESPECIAL,
0930: "java/lang/IllegalArgumentException", "<init>",
0931: "(Ljava/lang/String;)V");
0932: method.visitInsn(ATHROW);
0933: method.visitLabel(after_empty_check);
0934:
0935: if (mFilteredValuesMap != null) {
0936: method.visitFieldInsn(GETSTATIC, full_classname,
0937: "sFilteredValuesMap", "Ljava/util/HashMap;");
0938: method.visitVarInsn(ALOAD, 1);
0939: method.visitMethodInsn(INVOKEVIRTUAL,
0940: "java/util/HashMap", "containsKey",
0941: "(Ljava/lang/Object;)Z");
0942: method.visitInsn(IRETURN);
0943: } else {
0944: method.visitInsn(ICONST_0);
0945: method.visitInsn(IRETURN);
0946: }
0947: method.visitMaxs(0, 0);
0948: }
0949:
0950: // generate the method that returns the dependencies
0951: method = class_writer.visitMethod(1, "getDependencies",
0952: "()Ljava/util/Map;", null, null);
0953: method.visitFieldInsn(GETSTATIC, full_classname,
0954: "sDependencies", "Ljava/util/HashMap;");
0955: method.visitInsn(ARETURN);
0956: method.visitMaxs(0, 0);
0957:
0958: // performs all the static initialization
0959: class_writer.visitField(ACC_PRIVATE | ACC_STATIC, "sResource",
0960: "Ljava/net/URL;", null, null);
0961: class_writer.visitField(ACC_PRIVATE | ACC_STATIC,
0962: "sDependencies", "Ljava/util/HashMap;", null, null);
0963: for (Map.Entry<String, ParsedBlockPart> entry : blockparts_order
0964: .entrySet()) {
0965: entry.getValue().visitByteCodeStaticDeclaration(
0966: class_writer, entry.getKey());
0967: }
0968: if (mDefaultValues.size() > 0) {
0969: class_writer
0970: .visitField(ACC_PRIVATE | ACC_STATIC,
0971: "sDefaultValues", "Ljava/util/HashMap;",
0972: null, null);
0973: }
0974: if (mBlockvalues.size() > 0) {
0975: class_writer
0976: .visitField(ACC_PRIVATE | ACC_STATIC,
0977: "sBlockvalues", "Ljava/util/ArrayList;",
0978: null, null);
0979: }
0980: if (mValueIds.size() > 0) {
0981: class_writer.visitField(ACC_PRIVATE | ACC_STATIC,
0982: "sValueIds", "Ljava/util/HashSet;", null, null);
0983: class_writer
0984: .visitField(ACC_PRIVATE | ACC_STATIC,
0985: "sValueIdsArray", "[Ljava/lang/String;",
0986: null, null);
0987: }
0988: if (mFilteredBlocksMap != null) {
0989: class_writer.visitField(ACC_PRIVATE | ACC_STATIC,
0990: "sFilteredBlocksMap", "Ljava/util/HashMap;", null,
0991: null);
0992: }
0993: if (mFilteredValuesMap != null) {
0994: class_writer.visitField(ACC_PRIVATE | ACC_STATIC,
0995: "sFilteredValuesMap", "Ljava/util/HashMap;", null,
0996: null);
0997: }
0998:
0999: // static initialization
1000: method = class_writer.visitMethod(ACC_STATIC, "<clinit>",
1001: "()V", null, null);
1002:
1003: // set the resource
1004: Label resource_start_label = new Label();
1005: Label resource_end_label = new Label();
1006: Label resource_handler_label = new Label();
1007: Label after_resource_label = new Label();
1008: method.visitLabel(resource_start_label);
1009: method.visitTypeInsn(NEW, "java/net/URL");
1010: method.visitInsn(DUP);
1011: method.visitLdcInsn(mResource.getProtocol());
1012: method.visitLdcInsn(mResource.getHost());
1013: addIntegerConst(method, mResource.getPort());
1014: method.visitLdcInsn(mResource.getFile());
1015: method
1016: .visitMethodInsn(INVOKESPECIAL, "java/net/URL",
1017: "<init>",
1018: "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)V");
1019: method.visitFieldInsn(PUTSTATIC, full_classname, "sResource",
1020: "Ljava/net/URL;");
1021: method.visitLabel(resource_end_label);
1022: method.visitJumpInsn(GOTO, after_resource_label);
1023: method.visitLabel(resource_handler_label);
1024: method.visitVarInsn(ASTORE, 0);
1025: method.visitInsn(ACONST_NULL);
1026: method.visitFieldInsn(PUTSTATIC, full_classname, "sResource",
1027: "Ljava/net/URL;");
1028: method.visitTryCatchBlock(resource_start_label,
1029: resource_end_label, resource_handler_label,
1030: "java/net/MalformedURLException");
1031: method.visitLabel(after_resource_label);
1032:
1033: // set the file dependencies
1034: method.visitTypeInsn(NEW, "java/util/HashMap");
1035: method.visitInsn(DUP);
1036: method.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap",
1037: "<init>", "()V");
1038: method.visitFieldInsn(PUTSTATIC, full_classname,
1039: "sDependencies", "Ljava/util/HashMap;");
1040: if (mDependencies.size() > 0) {
1041: for (URL url : mDependencies.keySet()) {
1042: Label url_start_label = new Label();
1043: Label url_end_label = new Label();
1044: Label url_handler_label = new Label();
1045: Label after_url_label = new Label();
1046: method.visitLabel(url_start_label);
1047: method.visitFieldInsn(GETSTATIC, full_classname,
1048: "sDependencies", "Ljava/util/HashMap;");
1049: method.visitTypeInsn(NEW, "java/net/URL");
1050: method.visitInsn(DUP);
1051: method.visitLdcInsn(url.getProtocol());
1052: method.visitLdcInsn(url.getHost());
1053: addIntegerConst(method, url.getPort());
1054: method.visitLdcInsn(url.getFile());
1055: method
1056: .visitMethodInsn(INVOKESPECIAL, "java/net/URL",
1057: "<init>",
1058: "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)V");
1059: method.visitTypeInsn(NEW, "java/lang/Long");
1060: method.visitInsn(DUP);
1061: method.visitLdcInsn(mDependencies.get(url).longValue());
1062: method.visitMethodInsn(INVOKESPECIAL, "java/lang/Long",
1063: "<init>", "(J)V");
1064: method
1065: .visitMethodInsn(INVOKEVIRTUAL,
1066: "java/util/HashMap", "put",
1067: "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
1068: method.visitInsn(POP);
1069: method.visitLabel(url_end_label);
1070: method.visitJumpInsn(GOTO, after_url_label);
1071: method.visitLabel(url_handler_label);
1072: method.visitVarInsn(ASTORE, 0);
1073: method.visitTryCatchBlock(url_start_label,
1074: url_end_label, url_handler_label,
1075: "java/net/MalformedURLException");
1076: method.visitLabel(after_url_label);
1077: }
1078: }
1079:
1080: // generate the static initialization for the block data
1081: for (Map.Entry<String, ParsedBlockPart> entry : blockparts_order
1082: .entrySet()) {
1083: entry.getValue().visitByteCodeStaticDefinition(method,
1084: full_classname, entry.getKey());
1085: }
1086:
1087: // set the default values if they're present
1088: if (mDefaultValues.size() > 0) {
1089: method.visitTypeInsn(NEW, "java/util/HashMap");
1090: method.visitInsn(DUP);
1091: method.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap",
1092: "<init>", "()V");
1093: method.visitFieldInsn(PUTSTATIC, full_classname,
1094: "sDefaultValues", "Ljava/util/HashMap;");
1095: for (String key : mDefaultValues.keySet()) {
1096: method.visitFieldInsn(GETSTATIC, full_classname,
1097: "sDefaultValues", "Ljava/util/HashMap;");
1098: method.visitLdcInsn(key);
1099: method.visitLdcInsn(mDefaultValues.get(key));
1100: method
1101: .visitMethodInsn(INVOKEVIRTUAL,
1102: "java/util/HashMap", "put",
1103: "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
1104: method.visitInsn(POP);
1105: }
1106: }
1107:
1108: // set the blockvalues if they're present
1109: if (mBlockvalues.size() > 0) {
1110: method.visitTypeInsn(NEW, "java/util/ArrayList");
1111: method.visitInsn(DUP);
1112: method.visitMethodInsn(INVOKESPECIAL,
1113: "java/util/ArrayList", "<init>", "()V");
1114: method.visitFieldInsn(PUTSTATIC, full_classname,
1115: "sBlockvalues", "Ljava/util/ArrayList;");
1116: for (String key : mBlockvalues) {
1117: method.visitFieldInsn(GETSTATIC, full_classname,
1118: "sBlockvalues", "Ljava/util/ArrayList;");
1119: method.visitLdcInsn(key);
1120: method.visitMethodInsn(INVOKEVIRTUAL,
1121: "java/util/ArrayList", "add",
1122: "(Ljava/lang/Object;)Z");
1123: method.visitInsn(POP);
1124: }
1125: }
1126:
1127: // set the values ids if they're present
1128: if (mValueIds.size() > 0) {
1129: method.visitTypeInsn(NEW, "java/util/HashSet");
1130: method.visitInsn(DUP);
1131: method.visitMethodInsn(INVOKESPECIAL, "java/util/HashSet",
1132: "<init>", "()V");
1133: method.visitFieldInsn(PUTSTATIC, full_classname,
1134: "sValueIds", "Ljava/util/HashSet;");
1135: for (String id : mValueIds) {
1136: method.visitFieldInsn(GETSTATIC, full_classname,
1137: "sValueIds", "Ljava/util/HashSet;");
1138: method.visitLdcInsn(id);
1139: method.visitMethodInsn(INVOKEVIRTUAL,
1140: "java/util/HashSet", "add",
1141: "(Ljava/lang/Object;)Z");
1142: method.visitInsn(POP);
1143: }
1144: method.visitFieldInsn(GETSTATIC, full_classname,
1145: "sValueIds", "Ljava/util/HashSet;");
1146: method.visitMethodInsn(INVOKEVIRTUAL, "java/util/HashSet",
1147: "size", "()I");
1148: method.visitTypeInsn(ANEWARRAY, "java/lang/String");
1149: method.visitFieldInsn(PUTSTATIC, full_classname,
1150: "sValueIdsArray", "[Ljava/lang/String;");
1151: method.visitFieldInsn(GETSTATIC, full_classname,
1152: "sValueIds", "Ljava/util/HashSet;");
1153: method.visitFieldInsn(GETSTATIC, full_classname,
1154: "sValueIdsArray", "[Ljava/lang/String;");
1155: method.visitMethodInsn(INVOKEVIRTUAL, "java/util/HashSet",
1156: "toArray",
1157: "([Ljava/lang/Object;)[Ljava/lang/Object;");
1158: method.visitInsn(POP);
1159: }
1160:
1161: // write the filtered blocks if they're present
1162: if (mFilteredBlocksMap != null) {
1163: method.visitTypeInsn(NEW, "java/util/HashMap");
1164: method.visitInsn(DUP);
1165: method.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap",
1166: "<init>", "()V");
1167: method.visitFieldInsn(PUTSTATIC, full_classname,
1168: "sFilteredBlocksMap", "Ljava/util/HashMap;");
1169:
1170: method.visitInsn(ACONST_NULL);
1171: method.visitVarInsn(ASTORE, 0);
1172: FilteredTags filtered_blocks = null;
1173:
1174: for (String key : mFilteredBlocksMap.keySet()) {
1175: filtered_blocks = mFilteredBlocksMap
1176: .getFilteredTag(key);
1177: method.visitTypeInsn(NEW, "java/util/ArrayList");
1178: method.visitInsn(DUP);
1179: method.visitMethodInsn(INVOKESPECIAL,
1180: "java/util/ArrayList", "<init>", "()V");
1181: method.visitVarInsn(ASTORE, 1);
1182:
1183: for (String[] captured_groups : filtered_blocks) {
1184: method.visitVarInsn(ALOAD, 1);
1185: addIntegerConst(method, captured_groups.length);
1186: method.visitTypeInsn(ANEWARRAY, "java/lang/String");
1187: for (int i = 0; i < captured_groups.length; i++) {
1188: method.visitInsn(DUP);
1189: addIntegerConst(method, i);
1190: method.visitLdcInsn(captured_groups[i]);
1191: method.visitInsn(AASTORE);
1192: }
1193: method.visitMethodInsn(INVOKEVIRTUAL,
1194: "java/util/ArrayList", "add",
1195: "(Ljava/lang/Object;)Z");
1196: method.visitInsn(POP);
1197: }
1198: method.visitFieldInsn(GETSTATIC, full_classname,
1199: "sFilteredBlocksMap", "Ljava/util/HashMap;");
1200: method.visitLdcInsn(key);
1201: method.visitVarInsn(ALOAD, 1);
1202: method.visitMethodInsn(INVOKESTATIC,
1203: "java/util/Collections", "unmodifiableList",
1204: "(Ljava/util/List;)Ljava/util/List;");
1205: method
1206: .visitMethodInsn(INVOKEVIRTUAL,
1207: "java/util/HashMap", "put",
1208: "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
1209: method.visitInsn(POP);
1210: }
1211: }
1212:
1213: // write the filtered values if they're present
1214: if (mFilteredValuesMap != null) {
1215: method.visitTypeInsn(NEW, "java/util/HashMap");
1216: method.visitInsn(DUP);
1217: method.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap",
1218: "<init>", "()V");
1219: method.visitFieldInsn(PUTSTATIC, full_classname,
1220: "sFilteredValuesMap", "Ljava/util/HashMap;");
1221:
1222: method.visitInsn(ACONST_NULL);
1223: method.visitVarInsn(ASTORE, 1);
1224: FilteredTags filtered_values = null;
1225:
1226: for (String key : mFilteredValuesMap.keySet()) {
1227: filtered_values = mFilteredValuesMap
1228: .getFilteredTag(key);
1229: method.visitTypeInsn(NEW, "java/util/ArrayList");
1230: method.visitInsn(DUP);
1231: method.visitMethodInsn(INVOKESPECIAL,
1232: "java/util/ArrayList", "<init>", "()V");
1233: method.visitVarInsn(ASTORE, 1);
1234:
1235: for (String[] captured_groups : filtered_values) {
1236: method.visitVarInsn(ALOAD, 1);
1237: addIntegerConst(method, captured_groups.length);
1238: method.visitTypeInsn(ANEWARRAY, "java/lang/String");
1239: for (int i = 0; i < captured_groups.length; i++) {
1240: method.visitInsn(DUP);
1241: addIntegerConst(method, i);
1242: if (null == captured_groups[i]) {
1243: method.visitInsn(ACONST_NULL);
1244: } else {
1245: method.visitLdcInsn(captured_groups[i]);
1246: }
1247: method.visitInsn(AASTORE);
1248: }
1249: method.visitMethodInsn(INVOKEVIRTUAL,
1250: "java/util/ArrayList", "add",
1251: "(Ljava/lang/Object;)Z");
1252: method.visitInsn(POP);
1253: }
1254: method.visitFieldInsn(GETSTATIC, full_classname,
1255: "sFilteredValuesMap", "Ljava/util/HashMap;");
1256: method.visitLdcInsn(key);
1257: method.visitVarInsn(ALOAD, 1);
1258: method.visitMethodInsn(INVOKESTATIC,
1259: "java/util/Collections", "unmodifiableList",
1260: "(Ljava/util/List;)Ljava/util/List;");
1261: method
1262: .visitMethodInsn(INVOKEVIRTUAL,
1263: "java/util/HashMap", "put",
1264: "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
1265: method.visitInsn(POP);
1266: }
1267: }
1268: method.visitInsn(RETURN);
1269: method.visitMaxs(0, 0);
1270:
1271: class_writer.visitEnd();
1272:
1273: return class_writer.toByteArray();
1274: }
1275:
1276: void setTemplateName(String templateName) {
1277: assert templateName != null;
1278:
1279: mTemplateName = templateName;
1280: }
1281:
1282: String getTemplateName() {
1283: return mTemplateName;
1284: }
1285:
1286: void setClassName(String className) {
1287: assert className != null;
1288:
1289: mClassName = className;
1290: }
1291:
1292: String getClassName() {
1293: return mClassName;
1294: }
1295:
1296: String getFullClassName() {
1297: if (null != mClassName) {
1298: return mPackage + "." + mClassName;
1299: } else {
1300: return null;
1301: }
1302: }
1303:
1304: void setResource(URL resource) {
1305: assert resource != null;
1306:
1307: mResource = resource;
1308: }
1309:
1310: URL getResource() {
1311: return mResource;
1312: }
1313:
1314: private long getModificationTime() throws TemplateException {
1315: if (-1 == mModificationTime) {
1316: mModificationTime = Parser.getModificationTime(mParser
1317: .getTemplateFactory().getResourceFinder(),
1318: getResource());
1319: }
1320:
1321: assert mModificationTime > 0;
1322:
1323: return mModificationTime;
1324: }
1325:
1326: void setBlock(String id, ParsedBlockData blockData) {
1327: assert id != null;
1328: assert blockData != null;
1329:
1330: mBlocks.put(id, blockData);
1331: }
1332:
1333: ParsedBlockData getContent() {
1334: return getBlock("");
1335: }
1336:
1337: ParsedBlockData getBlock(String id) {
1338: assert id != null;
1339:
1340: return mBlocks.get(id);
1341: }
1342:
1343: Collection<String> getBlockIds() {
1344: return mBlocks.keySet();
1345: }
1346:
1347: Map<String, ParsedBlockData> getBlocks() {
1348: return mBlocks;
1349: }
1350:
1351: void addValue(String id) {
1352: assert id != null;
1353: assert id.length() > 0;
1354:
1355: mValueIds.add(id);
1356: }
1357:
1358: Collection<String> getValueIds() {
1359: return mValueIds;
1360: }
1361:
1362: void setDefaultValue(String id, String value) {
1363: assert id != null;
1364: assert id.length() > 0;
1365: assert value != null;
1366:
1367: mDefaultValues.put(id, value);
1368: }
1369:
1370: void setBlockvalue(String id) {
1371: assert id != null;
1372: assert id.length() > 0;
1373:
1374: mBlockvalues.add(id);
1375: }
1376:
1377: String getDefaultValue(String id) {
1378: assert id != null;
1379: assert id.length() > 0;
1380:
1381: return mDefaultValues.get(id);
1382: }
1383:
1384: boolean hasDefaultValue(String id) {
1385: assert id != null;
1386: assert id.length() > 0;
1387:
1388: return mDefaultValues.containsKey(id);
1389: }
1390:
1391: boolean hasBlockvalue(String id) {
1392: assert id != null;
1393: assert id.length() > 0;
1394:
1395: return mBlockvalues.contains(id);
1396: }
1397:
1398: Map<String, String> getDefaultValues() {
1399: return mDefaultValues;
1400: }
1401:
1402: List<String> getBlockvalues() {
1403: return mBlockvalues;
1404: }
1405:
1406: void addDependency(Parsed parsed) throws TemplateException {
1407: assert parsed != null;
1408:
1409: long modification_time = -1;
1410:
1411: // store the filename in the array of dependent files
1412: try {
1413: modification_time = parsed.getModificationTime();
1414: } catch (TemplateException e) {
1415: // set the modification time to -1, this means that the dependent file will be considered
1416: // as outdated at the next verification
1417: modification_time = -1;
1418: }
1419: mDependencies.put(parsed.getResource(), new Long(
1420: modification_time));
1421: }
1422:
1423: void addDependency(URL resource, Long modificationTime) {
1424: mDependencies.put(resource, modificationTime);
1425: }
1426:
1427: Map<URL, Long> getDependencies() {
1428: return mDependencies;
1429: }
1430:
1431: void setModificationState(String state) {
1432: mModificationState = state;
1433: }
1434:
1435: String getPackage() {
1436: return mPackage;
1437: }
1438:
1439: void setPackage(String thePackage) {
1440: assert thePackage != null;
1441:
1442: mPackage = thePackage;
1443: }
1444:
1445: void setFilteredValues(FilteredTagsMap filteredValues) {
1446: mFilteredValuesMap = filteredValues;
1447: }
1448:
1449: FilteredTagsMap getFilteredValuesMap() {
1450: return mFilteredValuesMap;
1451: }
1452:
1453: void setFilteredBlocks(FilteredTagsMap filteredBlocks) {
1454: mFilteredBlocksMap = filteredBlocks;
1455: }
1456:
1457: FilteredTagsMap getFilteredBlocksMap() {
1458: return mFilteredBlocksMap;
1459: }
1460: }
|