001 package railo.runtime.tag; 002 003 import javax.servlet.jsp.tagext.Tag; 004 005 import railo.runtime.exp.ApplicationException; 006 import railo.runtime.exp.PageException; 007 import railo.runtime.ext.tag.TagImpl; 008 import railo.runtime.functions.other.GetBaseTagData; 009 import railo.runtime.op.Caster; 010 import railo.runtime.op.Decision; 011 import railo.runtime.type.Array; 012 import railo.runtime.type.ArrayImpl; 013 import railo.runtime.type.Collection; 014 import railo.runtime.type.Collection.Key; 015 import railo.runtime.type.KeyImpl; 016 import railo.runtime.type.Struct; 017 018 /** 019 * Allows subtag data to be saved with the base tag. Applies only to custom tags. 020 * 021 * 022 * 023 **/ 024 public final class Associate extends TagImpl { 025 026 private static final Key ASSOC_ATTRS = KeyImpl.intern("AssocAttribs"); 027 028 029 /** The name of the structure in which the base tag stores subtag data. */ 030 private Collection.Key datacollection=ASSOC_ATTRS; 031 032 /** The name of the base tag. */ 033 private String basetag; 034 035 @Override 036 public void release() { 037 super.release(); 038 datacollection=ASSOC_ATTRS; 039 } 040 041 /** set the value datacollection 042 * The name of the structure in which the base tag stores subtag data. 043 * @param datacollection value to set 044 **/ 045 public void setDatacollection(String datacollection) { 046 this.datacollection=KeyImpl.init(datacollection); 047 } 048 049 /** set the value basetag 050 * The name of the base tag. 051 * @param basetag value to set 052 **/ 053 public void setBasetag(String basetag) { 054 this.basetag=basetag; 055 } 056 057 058 @Override 059 public int doStartTag() throws PageException { 060 061 // current 062 CFTag current=getCFTag(); 063 Struct value; 064 if(current==null || (value=current.getAttributesScope())==null) 065 throw new ApplicationException("invalid context, tag is no inside a custom tag"); 066 067 // parent 068 CFTag parent=GetBaseTagData.getParentCFTag(current.getParent(), basetag, -1); 069 if(parent==null) throw new ApplicationException("there is no parent tag with name ["+basetag+"]"); 070 071 Struct thisTag=parent.getThis(); 072 Object obj=thisTag.get(datacollection,null); 073 074 Array array; 075 076 if(obj==null) { 077 array=new ArrayImpl(new Object[]{value}); 078 thisTag.set(datacollection,array); 079 } 080 else if(Decision.isArray(obj) && (array=Caster.toArray(obj)).getDimension()==1) { 081 array.append(value); 082 } 083 else { 084 array=new ArrayImpl(new Object[]{obj,value}); 085 thisTag.set(datacollection,array); 086 } 087 return SKIP_BODY; 088 } 089 090 /*private static CFTag getParentCFTag(Tag srcTag,String trgTagName) { 091 String pureName=trgTagName; 092 CFTag cfTag; 093 if(StringUtil.startsWithIgnoreCase(pureName,"cf_")) { 094 pureName=pureName.substring(3); 095 } 096 if(StringUtil.startsWithIgnoreCase(pureName,"cf")) { 097 pureName=pureName.substring(2); 098 } 099 int count=0; 100 while((srcTag=srcTag.getParent())!=null) { 101 if(srcTag instanceof CFTag) { 102 if(count++==0)continue; 103 cfTag=(CFTag)srcTag; 104 if(cfTag instanceof CFTagCore){ 105 CFTagCore tc=(CFTagCore) cfTag; 106 if(tc.getName().equalsIgnoreCase(pureName)) 107 return cfTag; 108 continue; 109 } 110 if(cfTag.getAppendix().equalsIgnoreCase(pureName)) { 111 return cfTag; 112 } 113 } 114 } 115 return null; 116 }*/ 117 118 private CFTag getCFTag() { 119 Tag tag=this; 120 while((tag=tag.getParent())!=null) { 121 if(tag instanceof CFTag) { 122 return (CFTag)tag; 123 } 124 } 125 return null; 126 } 127 128 @Override 129 public int doEndTag() { 130 return EVAL_PAGE; 131 } 132 133 }