1 /*
2 * $Id: DefinitionModel.java 1305937 2012-03-27 18:15:15Z nlebas $
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 package org.apache.tiles.template;
23
24 import java.io.IOException;
25 import java.util.Deque;
26
27 import org.apache.tiles.Attribute;
28 import org.apache.tiles.Definition;
29 import org.apache.tiles.access.TilesAccess;
30 import org.apache.tiles.autotag.core.runtime.ModelBody;
31 import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
32 import org.apache.tiles.mgmt.MutableTilesContainer;
33 import org.apache.tiles.request.Request;
34
35 /**
36 * <p>
37 * <strong>Create a definition at runtime. </strong>
38 * </p>
39 * <p>
40 * Create a new definition at runtime. Newly created definition will be
41 * available across the entire request.
42 * </p>
43 *
44 * @version $Rev: 1305937 $ $Date: 2012-03-28 05:15:15 +1100 (Wed, 28 Mar 2012) $
45 * @since 2.2.0
46 */
47 public class DefinitionModel {
48
49 /**
50 * Executes the operation.
51 *
52 * @param name The name of the definition to create. If not specified, an
53 * anonymous definition will be created.
54 * @param template The template of this definition.
55 * @param role A comma-separated list of roles. If present, the definition
56 * will be rendered only if the current user belongs to one of the roles.
57 * @param extendsParam The definition name that this definition extends.
58 * @param preparer The preparer to use to invoke before the definition is
59 * rendered.
60 * @param request The request.
61 * @param modelBody The body.
62 * @throws IOException If something goes wrong.
63 * @since 2.2.0
64 */
65 public void execute(String name, String template, String role,
66 @Parameter(name = "extends") String extendsParam, String preparer,
67 Request request, ModelBody modelBody) throws IOException {
68 Deque<Object> composeStack = ComposeStackUtil
69 .getComposeStack(request);
70 Definition definition = createDefinition(name, template, role,
71 extendsParam, preparer);
72 composeStack.push(definition);
73 modelBody.evaluateWithoutWriting();
74 MutableTilesContainer container = (MutableTilesContainer) TilesAccess
75 .getCurrentContainer(request);
76 definition = (Definition) composeStack.pop();
77 registerDefinition(definition, container, composeStack, request);
78 }
79
80 /**
81 * Creates the definition to store.
82 *
83 * @param name The name of the definition to create. If not specified, an
84 * anonymous definition will be created.
85 * @param template The template of this definition.
86 * @param role A comma-separated list of roles. If present, the definition
87 * will be rendered only if the current user belongs to one of the roles.
88 * @param extendsParam The definition name that this definition extends.
89 * @param preparer The preparer to use to invoke before the definition is
90 * rendered.
91 * @return The created definition.
92 */
93 private Definition createDefinition(String name, String template,
94 String role, String extendsParam, String preparer) {
95 Definition definition = new Definition();
96 definition.setName(name);
97 Attribute templateAttribute = Attribute
98 .createTemplateAttribute(template);
99 templateAttribute.setRole(role);
100 definition.setTemplateAttribute(templateAttribute);
101 definition.setExtends(extendsParam);
102 definition.setPreparer(preparer);
103 return definition;
104 }
105
106 /**
107 * Registers a definition in the container.
108 *
109 * @param definition The definition to register.
110 * @param container The container into which the definition will be
111 * registered.
112 * @param composeStack The compose stack,
113 * @param request The request.
114 */
115 private void registerDefinition(Definition definition,
116 MutableTilesContainer container, Deque<Object> composeStack,
117 Request request) {
118 container.register(definition, request);
119
120 if (composeStack.isEmpty()) {
121 return;
122 }
123
124 Object obj = composeStack.peek();
125 if (obj instanceof Attribute) {
126 Attribute attribute = (Attribute) obj;
127 attribute.setValue(definition.getName());
128 if (attribute.getRenderer() == null) {
129 attribute.setRenderer("definition");
130 }
131 }
132 }
133 }