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 }