1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package javax.servlet.jsp.tagext;
19
20 import javax.servlet.jsp;
21
22
23 /**
24 * Wraps any SimpleTag and exposes it using a Tag interface. This is used
25 * to allow collaboration between classic Tag handlers and SimpleTag
26 * handlers.
27 * <p>
28 * Because SimpleTag does not extend Tag, and because Tag.setParent()
29 * only accepts a Tag instance, a classic tag handler (one
30 * that implements Tag) cannot have a SimpleTag as its parent. To remedy
31 * this, a TagAdapter is created to wrap the SimpleTag parent, and the
32 * adapter is passed to setParent() instead. A classic Tag Handler can
33 * call getAdaptee() to retrieve the encapsulated SimpleTag instance.
34 *
35 * @since 2.0
36 */
37 public class TagAdapter
38 implements Tag
39 {
40 /** The simple tag that's being adapted. */
41 private SimpleTag simpleTagAdaptee;
42
43 /** The parent, of this tag, converted (if necessary) to be of type Tag. */
44 private Tag parent;
45
46 // Flag indicating whether we have already determined the parent
47 private boolean parentDetermined;
48
49 /**
50 * Creates a new TagAdapter that wraps the given SimpleTag and
51 * returns the parent tag when getParent() is called.
52 *
53 * @param adaptee The SimpleTag being adapted as a Tag.
54 */
55 public TagAdapter( SimpleTag adaptee ) {
56 if( adaptee == null ) {
57 // Cannot wrap a null adaptee.
58 throw new IllegalArgumentException();
59 }
60 this.simpleTagAdaptee = adaptee;
61 }
62
63 /**
64 * Must not be called.
65 *
66 * @param pc ignored.
67 * @throws UnsupportedOperationException Must not be called
68 */
69 public void setPageContext(PageContext pc) {
70 throw new UnsupportedOperationException(
71 "Illegal to invoke setPageContext() on TagAdapter wrapper" );
72 }
73
74
75 /**
76 * Must not be called. The parent of this tag is always
77 * getAdaptee().getParent().
78 *
79 * @param parentTag ignored.
80 * @throws UnsupportedOperationException Must not be called.
81 */
82 public void setParent( Tag parentTag ) {
83 throw new UnsupportedOperationException(
84 "Illegal to invoke setParent() on TagAdapter wrapper" );
85 }
86
87
88 /**
89 * Returns the parent of this tag, which is always
90 * getAdaptee().getParent().
91 *
92 * This will either be the enclosing Tag (if getAdaptee().getParent()
93 * implements Tag), or an adapter to the enclosing Tag (if
94 * getAdaptee().getParent() does not implement Tag).
95 *
96 * @return The parent of the tag being adapted.
97 */
98 public Tag getParent() {
99 if (!parentDetermined) {
100 JspTag adapteeParent = simpleTagAdaptee.getParent();
101 if (adapteeParent != null) {
102 if (adapteeParent instanceof Tag) {
103 this.parent = (Tag) adapteeParent;
104 } else {
105 // Must be SimpleTag - no other types defined.
106 this.parent = new TagAdapter((SimpleTag) adapteeParent);
107 }
108 }
109 parentDetermined = true;
110 }
111
112 return this.parent;
113 }
114
115 /**
116 * Gets the tag that is being adapted to the Tag interface.
117 * This should be an instance of SimpleTag in JSP 2.0, but room
118 * is left for other kinds of tags in future spec versions.
119 *
120 * @return the tag that is being adapted
121 */
122 public JspTag getAdaptee() {
123 return this.simpleTagAdaptee;
124 }
125
126 /**
127 * Must not be called.
128 *
129 * @return always throws UnsupportedOperationException
130 * @throws UnsupportedOperationException Must not be called
131 * @throws JspException never thrown
132 */
133 public int doStartTag() throws JspException {
134 throw new UnsupportedOperationException(
135 "Illegal to invoke doStartTag() on TagAdapter wrapper" );
136 }
137
138 /**
139 * Must not be called.
140 *
141 * @return always throws UnsupportedOperationException
142 * @throws UnsupportedOperationException Must not be called
143 * @throws JspException never thrown
144 */
145 public int doEndTag() throws JspException {
146 throw new UnsupportedOperationException(
147 "Illegal to invoke doEndTag() on TagAdapter wrapper" );
148 }
149
150 /**
151 * Must not be called.
152 *
153 * @throws UnsupportedOperationException Must not be called
154 */
155 public void release() {
156 throw new UnsupportedOperationException(
157 "Illegal to invoke release() on TagAdapter wrapper" );
158 }
159 }