001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.transformer.bytecode.statement.tag;
020
021import java.util.HashMap;
022import java.util.HashSet;
023import java.util.LinkedHashMap;
024import java.util.Map;
025
026import lucee.runtime.op.Caster;
027import lucee.transformer.bytecode.Body;
028import lucee.transformer.bytecode.BytecodeContext;
029import lucee.transformer.bytecode.BytecodeException;
030import lucee.transformer.bytecode.Position;
031import lucee.transformer.bytecode.statement.FlowControlFinal;
032import lucee.transformer.bytecode.statement.StatementBase;
033import lucee.transformer.bytecode.visitor.ParseBodyVisitor;
034import lucee.transformer.library.tag.TagLibTag;
035import lucee.transformer.library.tag.TagLibTagAttr;
036
037/**
038 * 
039 */
040public abstract class TagBase extends StatementBase implements Tag {
041
042        private Body body=null;
043        private String appendix;
044        private String fullname;
045        private TagLibTag tagLibTag;
046        Map<String,Attribute> attributes=new LinkedHashMap<String,Attribute>();
047        //Map<String,String> missingAttributes=new HashMap<String,String>();
048        HashSet<TagLibTagAttr> missingAttributes=new HashSet<TagLibTagAttr>();
049        private boolean scriptBase=false;
050        
051        private Map<String, Attribute> metadata;
052        //private Label finallyLabel;
053
054
055        public TagBase(Position start, Position end) {
056        super(start,end);
057        }
058
059    
060        /**
061         * @see lucee.transformer.bytecode.statement.tag.Tag#getAppendix()
062         */
063        public String getAppendix() {
064                return appendix;
065        }
066
067        @Override
068        public Map<String,Attribute> getAttributes() {
069                return attributes;
070        }
071
072        @Override
073        public String getFullname() {
074                return fullname;
075        }
076
077        @Override
078        public TagLibTag getTagLibTag() {
079                return tagLibTag;
080        }
081
082        @Override
083        public void setAppendix(String appendix) {
084                this.appendix=appendix;
085        }
086
087        @Override
088        public void setFullname(String fullname) {
089                this.fullname=fullname;
090        }
091
092        @Override
093        public void setTagLibTag(TagLibTag tagLibTag) {
094                this.tagLibTag=tagLibTag;
095        }
096
097        @Override
098        public void addAttribute(Attribute attribute) {
099                attributes.put(attribute.getName().toLowerCase(), attribute);
100        }
101
102        @Override
103        public boolean containsAttribute(String name) {
104                return attributes.containsKey(name.toLowerCase());
105        }
106
107        @Override
108        public Body getBody() {
109                return body;
110        }
111
112        @Override
113        public void setBody(Body body) {
114                this.body = body;
115                body.setParent(this);
116        }
117
118        @Override
119        public void _writeOut(BytecodeContext bc) throws BytecodeException {
120                _writeOut(bc,true,null);
121        }
122        
123        public void _writeOut(BytecodeContext bc, boolean doReuse) throws BytecodeException {
124                _writeOut(bc,doReuse,null);
125        }
126        
127        protected void _writeOut(BytecodeContext bc, boolean doReuse, final FlowControlFinal fcf) throws BytecodeException {
128                //_writeOut(bc, true);
129                boolean output=tagLibTag.getParseBody() || Caster.toBooleanValue(getAttribute("output"), false);
130                
131                if(output) {
132                        ParseBodyVisitor pbv=new ParseBodyVisitor();
133                        pbv.visitBegin(bc);
134                                TagHelper.writeOut(this,bc, doReuse,fcf);
135                        pbv.visitEnd(bc);
136                }
137                else TagHelper.writeOut(this,bc, doReuse,fcf);
138        }
139        
140        @Override
141        public Attribute getAttribute(String name) {
142                return attributes.get(name.toLowerCase());
143        }
144
145        @Override
146        public Attribute removeAttribute(String name) {
147                return attributes.remove(name);
148        }
149
150        @Override
151        public String toString() {
152                return appendix+":"+fullname+":"+super.toString();
153        }
154        
155        @Override
156        public boolean isScriptBase() {
157                return scriptBase;
158        }
159        
160        @Override
161        public void setScriptBase(boolean scriptBase) {
162                this.scriptBase = scriptBase;
163        }
164        
165        @Override
166        public void addMissingAttribute(TagLibTagAttr attr) {
167                missingAttributes.add(attr);
168        }
169        
170        @Override
171        public TagLibTagAttr[] getMissingAttributes() {
172                
173                return missingAttributes.toArray(new TagLibTagAttr[missingAttributes.size()]);
174        }
175        
176        @Override
177        public void addMetaData(Attribute metadata) {
178                if(this.metadata==null) this.metadata=new HashMap<String, Attribute>();
179                this.metadata.put(metadata.getName(), metadata);
180        }
181        
182        @Override
183        public Map<String, Attribute> getMetaData() {
184                return metadata;
185        }
186        
187        
188}