001 package com.mockrunner.tag; 002 003 import java.util.List; 004 import java.util.Map; 005 006 import javax.servlet.jsp.JspException; 007 import javax.servlet.jsp.tagext.JspTag; 008 import javax.servlet.jsp.tagext.TagSupport; 009 010 /** 011 * <code>NestedTag</code> is used to simulate tags with static body 012 * content and child tags. It can be used to test the interaction 013 * of different tags. A <code>NestedTag</code> always wraps a real tag 014 * class (the actual testee). 015 * {@link TagTestModule} works with <code>NestedTag</code> instances 016 * internally. If you only want to test the ouptput of one single tag 017 * without interaction with other tags, you do not have to care about 018 * <code>NestedTag</code>. Use it, if you want to write sophisticated 019 * tests of body tags. <code>NestedTag</code> instances are created with 020 * the help of {@link TagTestModule#createNestedTag}. You do not need to 021 * create them on your own in the tests. 022 */ 023 public interface NestedTag 024 { 025 /** 026 * Specify if the <code>release</code> method should be called 027 * before populating a tag. Defaults to <code>false</code>. It's 028 * the container behaviour to call <code>release</code> when the tag 029 * goes back to the pool. It's usually not necessary in the tests, 030 * because the tag instances are not pooled and reused during a test run. 031 * Only sets the <code>doRelease</code> flag for this tag and 032 * leaves the flag for child tags. 033 * @param doRelease should release be called, default is <code>false</code> 034 */ 035 public void setDoRelease(boolean doRelease); 036 037 /** 038 * Specify if the <code>release</code> method should be called 039 * before populating a tag. Defaults to <code>false</code>. It's 040 * the container behaviour to call <code>release</code> when the tag 041 * goes back to the pool. It's usually not necessary in the tests, 042 * because the tag instances are not pooled and reused during a test run. 043 * Recursively sets the <code>doRelease</code> flag for this 044 * tag and all childs. 045 * @param doRelease should release be called, default is <code>false</code> 046 */ 047 public void setDoReleaseRecursive(boolean doRelease); 048 049 /** 050 * Populates the attributes of the underlying tag. The setters 051 * of the tag are called. Please note that child tags are not 052 * populated. 053 */ 054 public void populateAttributes(); 055 056 /** 057 * Performs the tags lifecycle. All <code>doBody</code> and <code>doTag</code> 058 * methods are called as in the real web container. The evaluation of the body 059 * is simulated by performing the lifecycle recursively for all childs of the 060 * <code>NestedTag</code>. 061 * @return the result of the final <code>doEndTag</code> call 062 */ 063 public int doLifecycle() throws JspException; 064 065 /** 066 * Returns the wrapped tag (the testee). 067 * @return the wrapped tag 068 */ 069 public TagSupport getTag(); 070 071 /** 072 * Returns the wrapped tag (the testee). 073 * @return the wrapped tag 074 */ 075 public JspTag getWrappedTag(); 076 077 /** 078 * Removes all childs. 079 */ 080 public void removeChilds(); 081 082 /** 083 * Returns the <code>List</code> of childs. 084 * @return the <code>List</code> of childs 085 */ 086 public List getChilds(); 087 088 /** 089 * Returns a child specified by its index. 090 * @param index the index 091 * @return the child 092 */ 093 public Object getChild(int index); 094 095 /** 096 * Adds a text child simulating static body content. 097 * @param text the static text 098 */ 099 public void addTextChild(String text); 100 101 /** 102 * Adds a dynamic child simulating scriptlets and 103 * EL expressions. Check out 104 * {@link com.mockrunner.tag.TagUtil#evalBody(List, Object)} 105 * for details about child handling. 106 * @param child the dynamic child instance 107 */ 108 public void addDynamicChild(DynamicChild child); 109 110 /** 111 * Adds a tag child simulating nested tags. 112 * The corresponding <code>NestedTag</code> will be created 113 * automatically wrapping the specified tag. An empty attribute 114 * <code>Map</code> will be used for the tag. 115 * @param tag the tag class 116 */ 117 public NestedTag addTagChild(Class tag); 118 119 /** 120 * Adds a tag child simulating nested tags. 121 * The corresponding <code>NestedTag</code> will be created 122 * automatically wrapping the specified tag. The attributes 123 * <code>Map</code> contains the attributes of this tag 124 * (<i>propertyname</i> maps to <i>propertyvalue</i>). 125 * @param tag the tag class 126 * @param attributeMap the attribute map 127 */ 128 public NestedTag addTagChild(Class tag, Map attributeMap); 129 130 /** 131 * Adds a tag child simulating nested tags. 132 * <code>NestedTag</code> will be created automatically 133 * wrapping the specified tag. An empty attribute <code>Map</code> 134 * will be used for the tag. 135 * @param tag the tag 136 */ 137 public NestedTag addTagChild(TagSupport tag); 138 139 /** 140 * Adds a tag child simulating nested tags. 141 * The corresponding <code>NestedTag</code> will be created 142 * automatically wrapping the specified tag. The attributes 143 * <code>Map</code> contains the attributes of this tag 144 * (<i>propertyname</i> maps to <i>propertyvalue</i>). 145 * @param tag the tag 146 * @param attributeMap the attribute map 147 */ 148 public NestedTag addTagChild(TagSupport tag, Map attributeMap); 149 150 /** 151 * Adds a tag child simulating nested tags. 152 * <code>NestedTag</code> will be created automatically 153 * wrapping the specified tag. An empty attribute <code>Map</code> 154 * will be used for the tag. 155 * @param tag the tag 156 */ 157 public NestedTag addTagChild(JspTag tag); 158 159 /** 160 * Adds a tag child simulating nested tags. 161 * The corresponding <code>NestedTag</code> will be created 162 * automatically wrapping the specified tag. The attributes 163 * <code>Map</code> contains the attributes of this tag 164 * (<i>propertyname</i> maps to <i>propertyvalue</i>). 165 * @param tag the tag 166 * @param attributeMap the attribute map 167 */ 168 public NestedTag addTagChild(JspTag tag, Map attributeMap); 169 }