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 }