Search in sources :

Example 1 with TagLibTagAttr

use of lucee.transformer.library.tag.TagLibTagAttr in project Lucee by lucee.

the class CFTag method validateAttributes.

private static void validateAttributes(Component cfc, StructImpl attributesScope, String tagName) throws ApplicationException, ExpressionException {
    TagLibTag tag = getAttributeRequirments(cfc, false);
    if (tag == null)
        return;
    if (tag.getAttributeType() == TagLibTag.ATTRIBUTE_TYPE_FIXED || tag.getAttributeType() == TagLibTag.ATTRIBUTE_TYPE_MIXED) {
        Iterator<Entry<String, TagLibTagAttr>> it = tag.getAttributes().entrySet().iterator();
        int count = 0;
        Collection.Key key;
        TagLibTagAttr attr;
        Object value;
        Entry<String, TagLibTagAttr> entry;
        // check existing attributes
        while (it.hasNext()) {
            entry = it.next();
            count++;
            key = KeyImpl.toKey(entry.getKey(), null);
            attr = entry.getValue();
            value = attributesScope.get(key, null);
            // check alias
            if (value == null) {
                String[] alias = attr.getAlias();
                if (!ArrayUtil.isEmpty(alias))
                    for (int i = 0; i < alias.length; i++) {
                        value = attributesScope.get(KeyImpl.toKey(alias[i], null), null);
                        if (value != null)
                            break;
                    }
            }
            if (value == null) {
                if (attr.getDefaultValue() != null) {
                    value = attr.getDefaultValue();
                    attributesScope.setEL(key, value);
                } else if (attr.isRequired())
                    throw new ApplicationException("attribute [" + key.getString() + "] is required for tag [" + tagName + "]");
            }
            if (value != null) {
                if (!Decision.isCastableTo(attr.getType(), value, true, true, -1))
                    throw new CasterException(createMessage(attr.getType(), value));
            }
        }
        // check if there are attributes not supported
        if (tag.getAttributeType() == TagLibTag.ATTRIBUTE_TYPE_FIXED && count < attributesScope.size()) {
            Collection.Key[] keys = attributesScope.keys();
            for (int i = 0; i < keys.length; i++) {
                if (tag.getAttribute(keys[i].getLowerString(), true) == null)
                    throw new ApplicationException("attribute [" + keys[i].getString() + "] is not supported for tag [" + tagName + "]");
            }
        // Attribute susi is not allowed for tag cfmail
        }
    }
}
Also used : TagLibTagAttr(lucee.transformer.library.tag.TagLibTagAttr) TagLibTag(lucee.transformer.library.tag.TagLibTag) CasterException(lucee.runtime.exp.CasterException) Key(lucee.runtime.type.Collection.Key) Entry(java.util.Map.Entry) ApplicationException(lucee.runtime.exp.ApplicationException) Collection(lucee.runtime.type.Collection) Key(lucee.runtime.type.Collection.Key)

Example 2 with TagLibTagAttr

use of lucee.transformer.library.tag.TagLibTagAttr in project Lucee by lucee.

the class TagHelper method writeOut.

/**
 * writes out the tag
 * @param tag
 * @param bc
 * @param doReuse
 * @throws TransformerException
 * @throws BundleException
 * @throws ClassException
 */
public static void writeOut(Tag tag, BytecodeContext bc, boolean doReuse, final FlowControlFinal fcf) throws TransformerException {
    final GeneratorAdapter adapter = bc.getAdapter();
    final TagLibTag tlt = tag.getTagLibTag();
    final ClassDefinition cd = tlt.getTagClassDefinition();
    final boolean fromBundle = cd.getName() != null;
    final Type currType;
    if (fromBundle) {
        try {
            if (Reflector.isInstaneOf(cd.getClazz(), BodyTag.class))
                currType = BODY_TAG;
            else
                currType = TAG;
        } catch (Exception e) {
            if (e instanceof TransformerException)
                throw (TransformerException) e;
            throw new TransformerException(e, tag.getStart());
        }
    } else
        currType = getTagType(tag);
    final int currLocal = adapter.newLocal(currType);
    Label tagBegin = new Label();
    Label tagEnd = new Label();
    ExpressionUtil.visitLine(bc, tag.getStart());
    // TODO adapter.visitLocalVariable("tag", "L"+currType.getInternalName()+";", null, tagBegin, tagEnd, currLocal);
    adapter.visitLabel(tagBegin);
    // tag=pc.use(String tagClassName,String tagBundleName, String tagBundleVersion, String fullname,int attrType) throws PageException {
    adapter.loadArg(0);
    adapter.checkCast(Types.PAGE_CONTEXT_IMPL);
    adapter.push(cd.getClassName());
    // has bundle info/version
    if (fromBundle) {
        // name
        adapter.push(cd.getName());
        // version
        if (cd.getVersion() != null)
            adapter.push(cd.getVersionAsString());
        else
            ASMConstants.NULL(adapter);
    }
    adapter.push(tlt.getFullName());
    adapter.push(tlt.getAttributeType());
    adapter.invokeVirtual(Types.PAGE_CONTEXT_IMPL, fromBundle ? USE5 : USE3);
    if (currType != TAG)
        adapter.checkCast(currType);
    adapter.storeLocal(currLocal);
    TryFinallyVisitor outerTcfv = new TryFinallyVisitor(new OnFinally() {

        @Override
        public void _writeOut(BytecodeContext bc) {
            adapter.loadArg(0);
            adapter.checkCast(Types.PAGE_CONTEXT_IMPL);
            adapter.loadLocal(currLocal);
            if (cd.getName() != null) {
                adapter.push(cd.getName());
                if (cd.getVersion() != null)
                    adapter.push(cd.getVersionAsString());
                else
                    ASMConstants.NULL(adapter);
            }
            adapter.invokeVirtual(Types.PAGE_CONTEXT_IMPL, fromBundle ? RE_USE3 : RE_USE1);
        }
    }, null);
    if (doReuse)
        outerTcfv.visitTryBegin(bc);
    // appendix
    if (tlt.hasAppendix()) {
        adapter.loadLocal(currLocal);
        adapter.push(tag.getAppendix());
        if (// PageContextUtil.setAppendix(tag,appendix)
        fromBundle)
            ASMUtil.invoke(ASMUtil.STATIC, adapter, Types.TAG_UTIL, SET_APPENDIX2);
        else
            // tag.setAppendix(appendix)
            ASMUtil.invoke(ASMUtil.VIRTUAL, adapter, currType, SET_APPENDIX1);
    }
    // hasBody
    boolean hasBody = tag.getBody() != null;
    if (tlt.isBodyFree() && tlt.hasBodyMethodExists()) {
        adapter.loadLocal(currLocal);
        adapter.push(hasBody);
        if (// PageContextUtil.setAppendix(tag,appendix)
        fromBundle)
            ASMUtil.invoke(ASMUtil.STATIC, adapter, Types.TAG_UTIL, HAS_BODY2);
        else
            // tag.setAppendix(appendix)
            ASMUtil.invoke(ASMUtil.VIRTUAL, adapter, currType, HAS_BODY1);
    }
    // default attributes (get overwritten by attributeCollection because of that set before)
    setAttributes(bc, tag, currLocal, currType, true, fromBundle);
    // attributeCollection
    Attribute attrColl = tag.getAttribute("attributecollection");
    if (attrColl != null) {
        int attrType = tag.getTagLibTag().getAttributeType();
        if (TagLibTag.ATTRIBUTE_TYPE_NONAME != attrType) {
            tag.removeAttribute("attributecollection");
            // TagUtil.setAttributeCollection(Tag, Struct)
            adapter.loadArg(0);
            adapter.loadLocal(currLocal);
            if (currType != TAG)
                adapter.cast(currType, TAG);
            // /
            TagLibTagAttr[] missings = tag.getMissingAttributes();
            if (!ArrayUtil.isEmpty(missings)) {
                ArrayVisitor av = new ArrayVisitor();
                av.visitBegin(adapter, MISSING_ATTRIBUTE, missings.length);
                int count = 0;
                TagLibTagAttr miss;
                for (int i = 0; i < missings.length; i++) {
                    miss = missings[i];
                    av.visitBeginItem(adapter, count++);
                    bc.getFactory().registerKey(bc, bc.getFactory().createLitString(miss.getName()), false);
                    adapter.push(miss.getType());
                    if (ArrayUtil.isEmpty(miss.getAlias()))
                        adapter.invokeStatic(MISSING_ATTRIBUTE, NEW_INSTANCE_MAX2);
                    else {
                        new LiteralStringArray(bc.getFactory(), miss.getAlias()).writeOut(bc, Expression.MODE_REF);
                        adapter.invokeStatic(MISSING_ATTRIBUTE, NEW_INSTANCE_MAX3);
                    }
                    av.visitEndItem(bc.getAdapter());
                }
                av.visitEnd();
            } else {
                ASMConstants.NULL(adapter);
            }
            // /
            attrColl.getValue().writeOut(bc, Expression.MODE_REF);
            adapter.push(attrType);
            adapter.invokeStatic(TAG_UTIL, SET_ATTRIBUTE_COLLECTION);
        }
    }
    // metadata
    Attribute attr;
    Map<String, Attribute> metadata = tag.getMetaData();
    if (metadata != null) {
        Iterator<Attribute> it = metadata.values().iterator();
        while (it.hasNext()) {
            attr = it.next();
            adapter.loadLocal(currLocal);
            adapter.push(attr.getName());
            attr.getValue().writeOut(bc, Expression.MODE_REF);
            if (fromBundle)
                ASMUtil.invoke(ASMUtil.STATIC, adapter, Types.TAG_UTIL, SET_META_DATA3);
            else
                ASMUtil.invoke(ASMUtil.VIRTUAL, adapter, currType, SET_META_DATA2);
        }
    }
    // set attributes
    setAttributes(bc, tag, currLocal, currType, false, fromBundle);
    // Body
    if (hasBody) {
        final int state = adapter.newLocal(Types.INT_VALUE);
        // int state=tag.doStartTag();
        adapter.loadLocal(currLocal);
        ASMUtil.invoke(fromBundle ? ASMUtil.INTERFACE : ASMUtil.VIRTUAL, adapter, currType, DO_START_TAG);
        // adapter.invokeVirtual(currType, DO_START_TAG);
        adapter.storeLocal(state);
        // if (state!=Tag.SKIP_BODY)
        Label endBody = new Label();
        adapter.loadLocal(state);
        adapter.push(javax.servlet.jsp.tagext.Tag.SKIP_BODY);
        adapter.visitJumpInsn(Opcodes.IF_ICMPEQ, endBody);
        // pc.initBody(tag, state);
        adapter.loadArg(0);
        adapter.loadLocal(currLocal);
        adapter.loadLocal(state);
        adapter.invokeVirtual(Types.PAGE_CONTEXT, INIT_BODY);
        OnFinally onFinally = new OnFinally() {

            @Override
            public void _writeOut(BytecodeContext bc) {
                Label endIf = new Label();
                /*if(tlt.handleException() && fcf!=null && fcf.getAfterFinalGOTOLabel()!=null){
							ASMUtil.visitLabel(adapter, fcf.getFinalEntryLabel());
						}*/
                adapter.loadLocal(state);
                adapter.push(javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE);
                adapter.visitJumpInsn(Opcodes.IF_ICMPEQ, endIf);
                // ... pc.popBody();
                adapter.loadArg(0);
                adapter.invokeVirtual(Types.PAGE_CONTEXT, POP_BODY);
                adapter.pop();
                adapter.visitLabel(endIf);
                // tag.doFinally();
                if (tlt.handleException()) {
                    adapter.loadLocal(currLocal);
                    ASMUtil.invoke(fromBundle ? ASMUtil.INTERFACE : ASMUtil.VIRTUAL, adapter, currType, DO_FINALLY);
                // adapter.invokeVirtual(currType, DO_FINALLY);
                }
            // GOTO after execution body, used when a continue/break was called before
            /*if(fcf!=null) {
							Label l = fcf.getAfterFinalGOTOLabel();
							if(l!=null)adapter.visitJumpInsn(Opcodes.GOTO, l);
						}*/
            }
        };
        if (tlt.handleException()) {
            TryCatchFinallyVisitor tcfv = new TryCatchFinallyVisitor(onFinally, fcf);
            tcfv.visitTryBegin(bc);
            doTry(bc, adapter, tag, currLocal, currType, fromBundle);
            int t = tcfv.visitTryEndCatchBeging(bc);
            // tag.doCatch(t);
            adapter.loadLocal(currLocal);
            adapter.loadLocal(t);
            // adapter.visitVarInsn(Opcodes.ALOAD,t);
            ASMUtil.invoke(fromBundle ? ASMUtil.INTERFACE : ASMUtil.VIRTUAL, adapter, currType, DO_CATCH);
            // adapter.invokeVirtual(currType, DO_CATCH);
            tcfv.visitCatchEnd(bc);
        } else {
            TryFinallyVisitor tfv = new TryFinallyVisitor(onFinally, fcf);
            tfv.visitTryBegin(bc);
            doTry(bc, adapter, tag, currLocal, currType, fromBundle);
            tfv.visitTryEnd(bc);
        }
        adapter.visitLabel(endBody);
    } else {
        // tag.doStartTag();
        adapter.loadLocal(currLocal);
        ASMUtil.invoke(fromBundle ? ASMUtil.INTERFACE : ASMUtil.VIRTUAL, adapter, currType, DO_START_TAG);
        // adapter.invokeVirtual(currType, DO_START_TAG);
        adapter.pop();
    }
    // if (tag.doEndTag()==Tag.SKIP_PAGE) throw new Abort(0<!-- SCOPE_PAGE -->);
    Label endDoEndTag = new Label();
    adapter.loadLocal(currLocal);
    ASMUtil.invoke(fromBundle ? ASMUtil.INTERFACE : ASMUtil.VIRTUAL, adapter, currType, DO_END_TAG);
    // adapter.invokeVirtual(currType, DO_END_TAG);
    adapter.push(javax.servlet.jsp.tagext.Tag.SKIP_PAGE);
    adapter.visitJumpInsn(Opcodes.IF_ICMPNE, endDoEndTag);
    adapter.push(Abort.SCOPE_PAGE);
    adapter.invokeStatic(ABORT, NEW_INSTANCE);
    adapter.throwException();
    adapter.visitLabel(endDoEndTag);
    if (doReuse) {
        // } finally{pc.reuse(tag);}
        outerTcfv.visitTryEnd(bc);
    }
    adapter.visitLabel(tagEnd);
    ExpressionUtil.visitLine(bc, tag.getEnd());
}
Also used : TagLibTagAttr(lucee.transformer.library.tag.TagLibTagAttr) TagLibTag(lucee.transformer.library.tag.TagLibTag) LiteralStringArray(lucee.transformer.bytecode.expression.type.LiteralStringArray) MissingAttribute(lucee.runtime.tag.MissingAttribute) Label(org.objectweb.asm.Label) ClassDefinition(lucee.runtime.db.ClassDefinition) ClassException(lucee.commons.lang.ClassException) TransformerException(lucee.transformer.TransformerException) BundleException(org.osgi.framework.BundleException) Type(org.objectweb.asm.Type) OnFinally(lucee.transformer.bytecode.visitor.OnFinally) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) TryCatchFinallyVisitor(lucee.transformer.bytecode.visitor.TryCatchFinallyVisitor) ArrayVisitor(lucee.transformer.bytecode.visitor.ArrayVisitor) TryFinallyVisitor(lucee.transformer.bytecode.visitor.TryFinallyVisitor) TransformerException(lucee.transformer.TransformerException) BytecodeContext(lucee.transformer.bytecode.BytecodeContext)

Example 3 with TagLibTagAttr

use of lucee.transformer.library.tag.TagLibTagAttr in project Lucee by lucee.

the class CFMLTransformer method attributes.

/**
 * Liest die Attribute eines Tags ein, dies Abhaengig von der Definition innerhalb der Tag-Lib.
 * Hierbei unterscheiden wir vier verschiedene Arten von Attributen:<br>
 * <ul>
 * <li>FIX: Definierte Attribute Fix, fuer jedes Attribut ist definiert ob es required ist oder nicht (gleich wie JSP). </li>
 * <li>DYNAMIC: Die Attribute des Tag sind frei, keine Namen sind vorgegeben.
 * Es kann aber definiert sein wieviele Attribute maximal und minimal verwendetet werden duerfen.</li>
 * <li>FULLDYNAMIC: Gleich wie DYNAMIC, jedoch kann der Name des Attribut auch ein dynamischer Wert sein (wie bei cfset).</li>
 * <li>NONAME: Ein Tag welches nur ein Attribut besitzt ohne Name, sondern einfach nur mit einem Attribut Wert</li>
 * </ul>
 * <br />
 * EBNF:<br />
 * <code>({spaces attribute} "/>" | {spaces attribute} ">") | attribute-value;(* Welcher Teil der "oder" Bedingung ausgefuehrt wird, ist abhaengig von der Tag Attribute Definition in der Tag Lib. *)</code>
 * @param tag
 * @param parent
 * @throws TemplateException
 */
public static void attributes(TagData data, TagLibTag tag, Tag parent) throws TemplateException {
    int type = tag.getAttributeType();
    int start = data.srcCode.getPos();
    // Tag with attribute names
    if (type != TagLibTag.ATTRIBUTE_TYPE_NONAME) {
        try {
            int min = tag.getMin();
            int max = tag.getMax();
            int count = 0;
            ArrayList<String> args = new ArrayList<String>();
            RefBoolean allowDefaultValue = new RefBooleanImpl(tag.getDefaultAttribute() != null);
            while (data.srcCode.isValidIndex()) {
                data.srcCode.removeSpace();
                // if no more attributes break
                if (data.srcCode.isCurrent('/') || data.srcCode.isCurrent('>'))
                    break;
                parent.addAttribute(attribute(data, tag, args, allowDefaultValue));
                count++;
            }
            // set default values
            if (tag.hasDefaultValue()) {
                Map<String, TagLibTagAttr> hash = tag.getAttributes();
                Iterator<Entry<String, TagLibTagAttr>> it = hash.entrySet().iterator();
                Entry<String, TagLibTagAttr> e;
                TagLibTagAttr att;
                while (it.hasNext()) {
                    e = it.next();
                    att = e.getValue();
                    if (!parent.containsAttribute(att.getName()) && att.hasDefaultValue()) {
                        Attribute attr = new Attribute(tag.getAttributeType() == TagLibTag.ATTRIBUTE_TYPE_DYNAMIC, att.getName(), CastOther.toExpression(data.factory.createLitString(Caster.toString(att.getDefaultValue(), null)), att.getType()), att.getType());
                        attr.setDefaultAttribute(true);
                        parent.addAttribute(attr);
                    }
                }
            }
            boolean hasAttributeCollection = args.contains("attributecollection");
            // to less attributes
            if (!hasAttributeCollection && min > count)
                throw createTemplateException(data.srcCode, "the tag " + tag.getFullName() + " must have at least " + min + " attributes", tag);
            // too much attributes
            if (!hasAttributeCollection && max > 0 && max < count)
                throw createTemplateException(data.srcCode, "the tag " + tag.getFullName() + " can have a maximum of " + max + " attributes", tag);
            // not defined attributes
            if (type == TagLibTag.ATTRIBUTE_TYPE_FIXED || type == TagLibTag.ATTRIBUTE_TYPE_MIXED) {
                // Map<String, TagLibTagAttr> hash = tag.getAttributes();
                Iterator<TagLibTagAttr> it = tag.getAttributes().values().iterator();
                while (it.hasNext()) {
                    TagLibTagAttr att = it.next();
                    if (att.isRequired() && !contains(args, att) && att.getDefaultValue() == null) {
                        if (!hasAttributeCollection)
                            throw createTemplateException(data.srcCode, "attribute " + att.getName() + " is required for tag " + tag.getFullName(), tag);
                        parent.addMissingAttribute(att);
                    }
                }
            }
        } catch (TemplateException te) {
            data.srcCode.setPos(start);
            // if the tag supports a non name attribute try this
            TagLibTagAttr sa = tag.getSingleAttr();
            if (sa != null)
                attrNoName(parent, tag, data, sa);
            else
                throw te;
        }
    } else // tag without attributes name
    {
        attrNoName(parent, tag, data, null);
    }
}
Also used : TagLibTagAttr(lucee.transformer.library.tag.TagLibTagAttr) RefBoolean(lucee.commons.lang.types.RefBoolean) Attribute(lucee.transformer.bytecode.statement.tag.Attribute) ComponentTemplateException(lucee.transformer.cfml.script.AbstrCFMLScriptTransformer.ComponentTemplateException) TemplateException(lucee.runtime.exp.TemplateException) ArrayList(java.util.ArrayList) LitString(lucee.transformer.expression.literal.LitString) Entry(java.util.Map.Entry) RefBooleanImpl(lucee.commons.lang.types.RefBooleanImpl)

Example 4 with TagLibTagAttr

use of lucee.transformer.library.tag.TagLibTagAttr in project Lucee by lucee.

the class AbstrCFMLScriptTransformer method _paramStatement.

private Tag _paramStatement(ExprData data, Body parent) throws TemplateException {
    if (!data.srcCode.forwardIfCurrent("param "))
        return null;
    Position line = data.srcCode.getPosition();
    TagLibTag tlt = CFMLTransformer.getTLT(data.srcCode, "param", data.config.getIdentification());
    TagParam param = new TagParam(data.factory, line, null);
    // type
    boolean hasType = false;
    boolean hasName = false;
    int pos = data.srcCode.getPos();
    // first 2 arguments can be type/name directly
    String tmp = variableDec(data, true);
    do {
        if (!StringUtil.isEmpty(tmp)) {
            TagLibTagAttr attr = tlt.getAttribute(tmp.toLowerCase(), true);
            // name is not a defined attribute
            if (attr == null) {
                comments(data);
                // it could be a name followed by default value
                if (data.srcCode.forwardIfCurrent('=')) {
                    comments(data);
                    Expression v = attributeValue(data, true);
                    param.addAttribute(new Attribute(false, "name", data.factory.createLitString(tmp), "string"));
                    param.addAttribute(new Attribute(false, "default", v, "string"));
                    hasName = true;
                    // if we had a value this was already name
                    break;
                }
                // can be type or name
                int pos2 = data.srcCode.getPos();
                // first could be type, followed by name
                comments(data);
                String tmp2 = variableDec(data, true);
                if (!StringUtil.isEmpty(tmp2)) {
                    attr = tlt.getAttribute(tmp2.toLowerCase(), true);
                    if (attr == null) {
                        param.addAttribute(new Attribute(false, "name", data.factory.createLitString(tmp2), "string"));
                        param.addAttribute(new Attribute(false, "type", data.factory.createLitString(tmp), "string"));
                        if (data.srcCode.forwardIfCurrent('=')) {
                            Expression v = attributeValue(data, true);
                            param.addAttribute(new Attribute(false, "default", v, "string"));
                        }
                        hasName = true;
                        hasType = true;
                        break;
                    }
                }
                param.addAttribute(new Attribute(false, "name", data.factory.createLitString(tmp), "string"));
                data.srcCode.setPos(pos2);
                hasName = true;
            } else
                data.srcCode.setPos(pos);
        } else
            data.srcCode.setPos(pos);
    } while (false);
    // folgend wird tlt extra nicht uebergeben, sonst findet pruefung statt
    Attribute[] attrs = attributes(param, tlt, data, SEMI, data.factory.NULL(), Boolean.TRUE, "name", true, ',', false);
    checkSemiColonLineFeed(data, true, true, true);
    param.setTagLibTag(tlt);
    param.setScriptBase(true);
    Attribute attr;
    // first fill all regular attribute -> name="value"
    boolean hasDynamic = false;
    for (int i = attrs.length - 1; i >= 0; i--) {
        attr = attrs[i];
        if (!attr.getValue().equals(data.factory.NULL())) {
            if (attr.getName().equalsIgnoreCase("name")) {
                hasName = true;
                param.addAttribute(attr);
            } else if (attr.getName().equalsIgnoreCase("type")) {
                hasType = true;
                param.addAttribute(attr);
            } else if (attr.isDynamicType()) {
                hasName = true;
                if (hasDynamic)
                    throw attrNotSupported(data.srcCode, tlt, attr.getName());
                hasDynamic = true;
                param.addAttribute(new Attribute(false, "name", data.factory.createLitString(attr.getName()), "string"));
                param.addAttribute(new Attribute(false, "default", attr.getValue(), "any"));
            } else
                param.addAttribute(attr);
        }
    }
    // now fill name named attributes -> attr1 attr2
    String first = null, second = null;
    for (int i = 0; i < attrs.length; i++) {
        attr = attrs[i];
        if (attr.getValue().equals(data.factory.NULL())) {
            // type
            if (first == null && (!hasName || !hasType)) {
                first = attr.getName();
            } else // name
            if (second == null && !hasName && !hasType) {
                second = attr.getName();
            } else // attr with no value
            {
                attr = new Attribute(true, attr.getName(), data.factory.EMPTY(), "string");
                param.addAttribute(attr);
            }
        }
    }
    if (first != null) {
        if (second != null) {
            hasName = true;
            hasType = true;
            if (hasDynamic)
                throw attrNotSupported(data.srcCode, tlt, first);
            hasDynamic = true;
            param.addAttribute(new Attribute(false, "name", data.factory.createLitString(second), "string"));
            param.addAttribute(new Attribute(false, "type", data.factory.createLitString(first), "string"));
        } else {
            param.addAttribute(new Attribute(false, hasName ? "type" : "name", data.factory.createLitString(first), "string"));
            hasName = true;
        }
    }
    if (!hasName)
        throw new TemplateException(data.srcCode, "missing name declaration for param");
    param.setEnd(data.srcCode.getPosition());
    return param;
}
Also used : TagLibTagAttr(lucee.transformer.library.tag.TagLibTagAttr) TagLibTag(lucee.transformer.library.tag.TagLibTag) TagParam(lucee.transformer.bytecode.statement.tag.TagParam) Position(lucee.transformer.Position) FunctionAsExpression(lucee.transformer.bytecode.expression.FunctionAsExpression) Expression(lucee.transformer.expression.Expression) Attribute(lucee.transformer.bytecode.statement.tag.Attribute) TemplateException(lucee.runtime.exp.TemplateException)

Example 5 with TagLibTagAttr

use of lucee.transformer.library.tag.TagLibTagAttr in project Lucee by lucee.

the class AbstrCFMLScriptTransformer method attributes.

private final Attribute[] attributes(Tag tag, TagLibTag tlt, ExprData data, EndCondition endCond, Expression defaultValue, Object oAllowExpression, String ignoreAttrReqFor, boolean allowTwiceAttr, char attributeSeparator, boolean allowColonAsNameValueSeparator) throws TemplateException {
    ArrayList<Attribute> attrs = new ArrayList<Attribute>();
    ArrayList<String> ids = new ArrayList<String>();
    while (data.srcCode.isValidIndex()) {
        data.srcCode.removeSpace();
        // if no more attributes break
        if (endCond.isEnd(data))
            break;
        Attribute attr = attribute(tlt, data, ids, defaultValue, oAllowExpression, allowTwiceAttr, allowColonAsNameValueSeparator);
        attrs.add(attr);
        // seperator
        if (attributeSeparator > 0) {
            data.srcCode.removeSpace();
            data.srcCode.forwardIfCurrent(attributeSeparator);
        }
    }
    // not defined attributes
    if (tlt != null) {
        boolean hasAttributeCollection = false;
        Iterator<Attribute> iii = attrs.iterator();
        while (iii.hasNext()) {
            if ("attributecollection".equalsIgnoreCase(iii.next().getName())) {
                hasAttributeCollection = true;
                break;
            }
        }
        int type = tlt.getAttributeType();
        if (type == TagLibTag.ATTRIBUTE_TYPE_FIXED || type == TagLibTag.ATTRIBUTE_TYPE_MIXED) {
            Map<String, TagLibTagAttr> hash = tlt.getAttributes();
            Iterator<Entry<String, TagLibTagAttr>> it = hash.entrySet().iterator();
            Entry<String, TagLibTagAttr> e;
            while (it.hasNext()) {
                e = it.next();
                TagLibTagAttr att = e.getValue();
                if (att.isRequired() && !contains(attrs, att) && att.getDefaultValue() == null && !att.getName().equals(ignoreAttrReqFor)) {
                    if (!hasAttributeCollection)
                        throw new TemplateException(data.srcCode, "attribute " + att.getName() + " is required for statement " + tlt.getName());
                    if (tag != null)
                        tag.addMissingAttribute(att);
                }
            }
        }
    }
    return attrs.toArray(new Attribute[attrs.size()]);
}
Also used : TagLibTagAttr(lucee.transformer.library.tag.TagLibTagAttr) Attribute(lucee.transformer.bytecode.statement.tag.Attribute) TemplateException(lucee.runtime.exp.TemplateException) ArrayList(java.util.ArrayList) Entry(java.util.Map.Entry)

Aggregations

TagLibTagAttr (lucee.transformer.library.tag.TagLibTagAttr)17 Entry (java.util.Map.Entry)8 TagLibTag (lucee.transformer.library.tag.TagLibTag)8 Attribute (lucee.transformer.bytecode.statement.tag.Attribute)6 TemplateException (lucee.runtime.exp.TemplateException)5 RefBooleanImpl (lucee.commons.lang.types.RefBooleanImpl)4 Key (lucee.runtime.type.Collection.Key)4 Struct (lucee.runtime.type.Struct)4 Expression (lucee.transformer.expression.Expression)4 LitString (lucee.transformer.expression.literal.LitString)4 ArrayList (java.util.ArrayList)3 RefBoolean (lucee.commons.lang.types.RefBoolean)3 FunctionAsExpression (lucee.transformer.bytecode.expression.FunctionAsExpression)3 StructImpl (lucee.runtime.type.StructImpl)2 Position (lucee.transformer.Position)2 ComponentTemplateException (lucee.transformer.cfml.script.AbstrCFMLScriptTransformer.ComponentTemplateException)2 ClassException (lucee.commons.lang.ClassException)1 Component (lucee.runtime.Component)1 ComponentSpecificAccess (lucee.runtime.ComponentSpecificAccess)1 Member (lucee.runtime.component.Member)1