|
|||||||||||||||||||
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover | |||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
ShowTemplate.java | 0% | 0% | 0% | 0% |
|
1 |
// Copyright 2004, 2005 The Apache Software Foundation
|
|
2 |
//
|
|
3 |
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4 |
// you may not use this file except in compliance with the License.
|
|
5 |
// You may obtain a copy of the License at
|
|
6 |
//
|
|
7 |
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8 |
//
|
|
9 |
// Unless required by applicable law or agreed to in writing, software
|
|
10 |
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11 |
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12 |
// See the License for the specific language governing permissions and
|
|
13 |
// limitations under the License.
|
|
14 |
|
|
15 |
package org.apache.tapestry.contrib.inspector;
|
|
16 |
|
|
17 |
import java.util.Iterator;
|
|
18 |
import java.util.Map;
|
|
19 |
|
|
20 |
import org.apache.tapestry.BaseComponent;
|
|
21 |
import org.apache.tapestry.IComponent;
|
|
22 |
import org.apache.tapestry.IDirect;
|
|
23 |
import org.apache.tapestry.IMarkupWriter;
|
|
24 |
import org.apache.tapestry.IRender;
|
|
25 |
import org.apache.tapestry.IRequestCycle;
|
|
26 |
import org.apache.tapestry.Tapestry;
|
|
27 |
import org.apache.tapestry.engine.DirectServiceParameter;
|
|
28 |
import org.apache.tapestry.engine.IEngineService;
|
|
29 |
import org.apache.tapestry.engine.ILink;
|
|
30 |
import org.apache.tapestry.link.DirectLink;
|
|
31 |
import org.apache.tapestry.parse.CloseToken;
|
|
32 |
import org.apache.tapestry.parse.ComponentTemplate;
|
|
33 |
import org.apache.tapestry.parse.LocalizationToken;
|
|
34 |
import org.apache.tapestry.parse.OpenToken;
|
|
35 |
import org.apache.tapestry.parse.TemplateToken;
|
|
36 |
import org.apache.tapestry.parse.TextToken;
|
|
37 |
import org.apache.tapestry.parse.TokenType;
|
|
38 |
import org.apache.tapestry.services.TemplateSource;
|
|
39 |
|
|
40 |
/**
|
|
41 |
* Component of the {@link Inspector}page used to display the ids and types of all embedded
|
|
42 |
* components.
|
|
43 |
*
|
|
44 |
* @author Howard Lewis Ship
|
|
45 |
*/
|
|
46 |
|
|
47 |
public abstract class ShowTemplate extends BaseComponent implements IDirect |
|
48 |
{ |
|
49 |
/** @since 4.0 */
|
|
50 |
public abstract TemplateSource getTemplateSource();
|
|
51 |
|
|
52 | 0 |
public boolean getHasTemplate() |
53 |
{ |
|
54 | 0 |
Inspector inspector; |
55 |
|
|
56 | 0 |
inspector = (Inspector) getPage(); |
57 |
|
|
58 |
// Components that inherit from BaseComponent have templates,
|
|
59 |
// others do not.
|
|
60 |
|
|
61 | 0 |
return inspector.getInspectedComponent() instanceof BaseComponent; |
62 |
} |
|
63 |
|
|
64 | 0 |
public IRender getTemplateDelegate()
|
65 |
{ |
|
66 | 0 |
return new IRender() |
67 |
{ |
|
68 | 0 |
public void render(IMarkupWriter writer, IRequestCycle cycle) |
69 |
{ |
|
70 | 0 |
writeTemplate(writer, cycle); |
71 |
} |
|
72 |
}; |
|
73 |
} |
|
74 |
|
|
75 |
/**
|
|
76 |
* Writes the HTML template for the component. When <jwc> tags are written, the id is made
|
|
77 |
* a link (that selects the named component). We use some magic to accomplish this, creating
|
|
78 |
* links as if we were a {@link DirectLink}component, and attributing those links to the
|
|
79 |
* captive {@link DirectLink}component embedded here.
|
|
80 |
*/
|
|
81 |
|
|
82 | 0 |
private void writeTemplate(IMarkupWriter writer, IRequestCycle cycle) |
83 |
{ |
|
84 | 0 |
IComponent inspectedComponent = getInspectedComponent(); |
85 | 0 |
ComponentTemplate template = null;
|
86 |
|
|
87 | 0 |
try
|
88 |
{ |
|
89 | 0 |
template = getTemplateSource().getTemplate(cycle, inspectedComponent); |
90 |
} |
|
91 |
catch (Exception ex)
|
|
92 |
{ |
|
93 | 0 |
return;
|
94 |
} |
|
95 |
|
|
96 | 0 |
writer.begin("pre");
|
97 |
|
|
98 | 0 |
int count = template.getTokenCount();
|
99 |
|
|
100 | 0 |
for (int i = 0; i < count; i++) |
101 |
{ |
|
102 | 0 |
TemplateToken token = template.getToken(i); |
103 | 0 |
TokenType type = token.getType(); |
104 |
|
|
105 | 0 |
if (type == TokenType.TEXT)
|
106 |
{ |
|
107 | 0 |
write(writer, (TextToken) token); |
108 | 0 |
continue;
|
109 |
} |
|
110 |
|
|
111 | 0 |
if (type == TokenType.CLOSE)
|
112 |
{ |
|
113 | 0 |
write(writer, (CloseToken) token); |
114 |
|
|
115 | 0 |
continue;
|
116 |
} |
|
117 |
|
|
118 | 0 |
if (token.getType() == TokenType.LOCALIZATION)
|
119 |
{ |
|
120 |
|
|
121 | 0 |
write(writer, (LocalizationToken) token); |
122 | 0 |
continue;
|
123 |
} |
|
124 |
|
|
125 | 0 |
if (token.getType() == TokenType.OPEN)
|
126 |
{ |
|
127 | 0 |
boolean nextIsClose = (i + 1 < count)
|
128 |
&& (template.getToken(i + 1).getType() == TokenType.CLOSE); |
|
129 |
|
|
130 | 0 |
write(writer, nextIsClose, (OpenToken) token); |
131 |
|
|
132 | 0 |
if (nextIsClose)
|
133 | 0 |
i++; |
134 |
|
|
135 | 0 |
continue;
|
136 |
} |
|
137 |
|
|
138 |
// That's all the types known at this time.
|
|
139 |
} |
|
140 |
|
|
141 | 0 |
writer.end(); // <pre>
|
142 |
} |
|
143 |
|
|
144 |
/** @since 3.0 * */
|
|
145 |
|
|
146 | 0 |
private IComponent getInspectedComponent()
|
147 |
{ |
|
148 | 0 |
Inspector page = (Inspector) getPage(); |
149 |
|
|
150 | 0 |
return page.getInspectedComponent();
|
151 |
} |
|
152 |
|
|
153 |
/** @since 3.0 * */
|
|
154 |
|
|
155 | 0 |
private void write(IMarkupWriter writer, TextToken token) |
156 |
{ |
|
157 |
// Print the section of the template ... print() will
|
|
158 |
// escape and invalid characters as HTML entities. Also,
|
|
159 |
// we show the full stretch of text, not the trimmed version.
|
|
160 |
|
|
161 | 0 |
writer.print(token.getTemplateDataAsString()); |
162 |
} |
|
163 |
|
|
164 |
/** @since 3.0 * */
|
|
165 |
|
|
166 | 0 |
private void write(IMarkupWriter writer, CloseToken token) |
167 |
{ |
|
168 | 0 |
writer.begin("span");
|
169 | 0 |
writer.attribute("class", "jwc-tag"); |
170 |
|
|
171 | 0 |
writer.print("</");
|
172 | 0 |
writer.print(token.getTag()); |
173 | 0 |
writer.print(">");
|
174 |
|
|
175 | 0 |
writer.end(); // <span>
|
176 |
} |
|
177 |
|
|
178 |
/** @since 3.0 * */
|
|
179 |
|
|
180 | 0 |
private void write(IMarkupWriter writer, LocalizationToken token) |
181 |
{ |
|
182 | 0 |
IComponent component = getInspectedComponent(); |
183 |
|
|
184 | 0 |
writer.begin("span");
|
185 | 0 |
writer.attribute("class", "jwc-tag"); |
186 |
|
|
187 | 0 |
writer.print("<span key=\"");
|
188 | 0 |
writer.print(token.getKey()); |
189 | 0 |
writer.print('"');
|
190 |
|
|
191 | 0 |
Map attributes = token.getAttributes(); |
192 | 0 |
if (attributes != null && !attributes.isEmpty()) |
193 |
{ |
|
194 | 0 |
Iterator it = attributes.entrySet().iterator(); |
195 | 0 |
while (it.hasNext())
|
196 |
{ |
|
197 | 0 |
Map.Entry entry = (Map.Entry) it.next(); |
198 | 0 |
String attributeName = (String) entry.getKey(); |
199 | 0 |
String attributeValue = (String) entry.getValue(); |
200 |
|
|
201 | 0 |
writer.print(' '); |
202 | 0 |
writer.print(attributeName); |
203 | 0 |
writer.print("=\"");
|
204 | 0 |
writer.print(attributeValue); |
205 | 0 |
writer.print('"');
|
206 |
|
|
207 |
} |
|
208 |
} |
|
209 |
|
|
210 | 0 |
writer.print('>'); |
211 | 0 |
writer.begin("span");
|
212 | 0 |
writer.attribute("class", "localized-string"); |
213 |
|
|
214 | 0 |
writer.print(component.getMessages().getMessage(token.getKey())); |
215 | 0 |
writer.end(); // <span>
|
216 |
|
|
217 | 0 |
writer.print("</span>");
|
218 |
|
|
219 | 0 |
writer.end(); // <span>
|
220 |
} |
|
221 |
|
|
222 |
/** @since 3.0 * */
|
|
223 |
|
|
224 | 0 |
private void write(IMarkupWriter writer, boolean nextIsClose, OpenToken token) |
225 |
{ |
|
226 | 0 |
IComponent component = getInspectedComponent(); |
227 | 0 |
IEngineService service = getPage().getEngine().getService(Tapestry.DIRECT_SERVICE); |
228 |
|
|
229 |
// Each id references a component embedded in the inspected component.
|
|
230 |
// Get that component.
|
|
231 |
|
|
232 | 0 |
String id = token.getId(); |
233 | 0 |
IComponent embedded = component.getComponent(id); |
234 | 0 |
Object[] serviceParameters = new Object[]
|
235 |
{ embedded.getIdPath() }; |
|
236 |
|
|
237 |
// Build a URL to select that component, as if by the captive
|
|
238 |
// component itself (it's a Direct).
|
|
239 |
|
|
240 | 0 |
DirectServiceParameter dsp = new DirectServiceParameter(this, serviceParameters); |
241 | 0 |
ILink link = service.getLink(getPage().getRequestCycle(), dsp); |
242 |
|
|
243 | 0 |
writer.begin("span");
|
244 | 0 |
writer.attribute("class", "jwc-tag"); |
245 |
|
|
246 | 0 |
writer.print("<");
|
247 | 0 |
writer.print(token.getTag()); |
248 |
|
|
249 | 0 |
writer.print(" jwcid=\"");
|
250 |
|
|
251 | 0 |
writer.begin("span");
|
252 | 0 |
writer.attribute("class", "jwc-id"); |
253 |
|
|
254 | 0 |
writer.begin("a");
|
255 | 0 |
writer.attribute("href", link.getURL());
|
256 | 0 |
writer.print(id); |
257 |
|
|
258 | 0 |
writer.end(); // <a>
|
259 | 0 |
writer.end(); // <span>
|
260 | 0 |
writer.print('"');
|
261 |
|
|
262 | 0 |
Map attributes = token.getAttributesMap(); |
263 |
|
|
264 | 0 |
if (attributes != null) |
265 |
{ |
|
266 | 0 |
Iterator ii = attributes.entrySet().iterator(); |
267 |
|
|
268 | 0 |
while (ii.hasNext())
|
269 |
{ |
|
270 | 0 |
Map.Entry e = (Map.Entry) ii.next(); |
271 |
|
|
272 | 0 |
String value = (String) e.getValue(); |
273 |
|
|
274 | 0 |
writer.print(' '); |
275 | 0 |
writer.print(e.getKey().toString()); |
276 | 0 |
writer.print("=\"");
|
277 | 0 |
writer.print(value); |
278 | 0 |
writer.print('"');
|
279 |
} |
|
280 |
} |
|
281 |
|
|
282 |
// Collapse an open & close down to a single tag.
|
|
283 |
|
|
284 | 0 |
if (nextIsClose)
|
285 | 0 |
writer.print('/'); |
286 |
|
|
287 | 0 |
writer.print('>'); |
288 | 0 |
writer.end(); // <span>
|
289 |
} |
|
290 |
|
|
291 |
/**
|
|
292 |
* Invoked when a component id is clicked.
|
|
293 |
*/
|
|
294 |
|
|
295 | 0 |
public void trigger(IRequestCycle cycle, String componentId) |
296 |
{ |
|
297 | 0 |
Inspector inspector = (Inspector) getPage(); |
298 |
|
|
299 | 0 |
inspector.selectComponent(componentId); |
300 |
|
|
301 | 0 |
IComponent newComponent = inspector.getInspectedComponent(); |
302 |
|
|
303 |
// If the component is not a BaseComponent then it won't have
|
|
304 |
// a template, so switch to the specification view.
|
|
305 |
|
|
306 | 0 |
if (!(newComponent instanceof BaseComponent)) |
307 | 0 |
inspector.setView(View.SPECIFICATION); |
308 |
} |
|
309 |
|
|
310 |
/**
|
|
311 |
* Always returns true.
|
|
312 |
*
|
|
313 |
* @since 2.3
|
|
314 |
*/
|
|
315 |
|
|
316 | 0 |
public boolean isStateful() |
317 |
{ |
|
318 | 0 |
return true; |
319 |
} |
|
320 |
} |
|