1/*2 * $Id: ImportAttributeModel.java 1291847 2012-02-21 15:09:30Z nlebas $3 *4 * Licensed to the Apache Software Foundation (ASF) under one5 * or more contributor license agreements. See the NOTICE file6 * distributed with this work for additional information7 * regarding copyright ownership. The ASF licenses this file8 * to you under the Apache License, Version 2.0 (the9 * "License"); you may not use this file except in compliance10 * with the License. You may obtain a copy of the License at11 *12 * http://www.apache.org/licenses/LICENSE-2.013 *14 * Unless required by applicable law or agreed to in writing,15 * software distributed under the License is distributed on an16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY17 * KIND, either express or implied. See the License for the18 * specific language governing permissions and limitations19 * under the License.20 */2122package org.apache.tiles.template;
2324import java.util.Collection;
25import java.util.HashMap;
26import java.util.Map;
2728import org.apache.tiles.Attribute;
29import org.apache.tiles.AttributeContext;
30import org.apache.tiles.TilesContainer;
31import org.apache.tiles.access.TilesAccess;
32import org.apache.tiles.request.Request;
33import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
3536/**37 * <p>38 * <strong>Import attribute(s) in specified context.</strong>39 * </p>40 * <p>41 * Import attribute(s) to requested scope. Attribute name and scope are42 * optional. If not specified, all attributes are imported in page scope. Once43 * imported, an attribute can be used as any other beans from jsp contexts.44 * </p>45 *46 * @version $Rev: 1291847 $ $Date: 2012-02-22 02:09:30 +1100 (Wed, 22 Feb 2012) $47 * @since 2.2.048 */49publicclassImportAttributeModel {
5051/**52 * The logging object.53 */54private Logger log = LoggerFactory.getLogger(getClass());
5556/**57 * Executes the model.58 *59 * @param name The name of the attribute to import. If it is60 * <code>null</code>, all the attributes will be imported.61 * @param scope The scope into which the attribute(s) will be imported. If62 * <code>null</code>, the import will go in page scope.63 * @param toName The name of the attribute into which the attribute will be64 * imported. To be used in conjunction to <code>name</code>. If65 * <code>null</code>, the value of <code>name</code> will be used.66 * @param ignore If <code>true</code>, if the attribute is not present, the67 * problem will be ignored.68 * @param request The request.69 */70publicvoid execute(String name, String scope, String toName, boolean ignore, Request request) {
71 Map<String, Object> attributes = getImportedAttributes(
72 name, toName, ignore, request);
73if (scope == null) {
74 scope = request.getAvailableScopes().get(0);
75 }
76 request.getContext(scope).putAll(attributes);
77 }
7879/**80 * Retuns a Map that contains the attributes to be imported. The importing81 * code must be done by the caller.82 * @param name The attribute to import. If null, all the attributes will be83 * imported.84 * @param toName The destination name of the attribute to import. Valid only85 * if <code>name</code> is specified.86 * @param ignore If <code>true</code> and the attribute is not found, or an87 * exception happens, the problem will be ignored.88 * @param request The request.89 *90 * @return A Map of the attributes to be imported: the key is the name of an91 * attribute, the value is the value of that attribute.92 * @since 2.2.093 */94private Map<String, Object> getImportedAttributes(String name,
95 String toName, boolean ignore, Request request) {
96TilesContainer container = TilesAccess.getCurrentContainer(request);
97 Map<String, Object> retValue = new HashMap<String, Object>();
98AttributeContext attributeContext = container
99 .getAttributeContext(request);
100// Some tags allow for unspecified attributes. This101// implies that the tag should use all of the attributes.102if (name != null) {
103 importSingleAttribute(container, attributeContext, name, toName,
104 ignore, retValue, request);
105 } else {
106 importAttributes(attributeContext.getCascadedAttributeNames(),
107 container, attributeContext, retValue, ignore, request);
108 importAttributes(attributeContext.getLocalAttributeNames(),
109 container, attributeContext, retValue, ignore, request);
110 }
111return retValue;
112 }
113114/**115 * Imports a single attribute.116 *117 * @param container The Tiles container to use.118 * @param attributeContext The context from which the attributes will be119 * got.120 * @param name The name of the attribute.121 * @param toName The name of the destination attribute. If null,122 * <code>name</code> will be used.123 * @param ignore If <code>true</code> and the attribute is not found, or an124 * exception happens, the problem will be ignored.125 * @param attributes The map of the attributes to fill.126 * @param request The request.127 */128privatevoid importSingleAttribute(TilesContainer container,
129AttributeContext attributeContext, String name, String toName,
130boolean ignore, Map<String, Object> attributes,
131 Request request) {
132Attribute attr = attributeContext.getAttribute(name);
133if (attr != null) {
134try {
135 Object attributeValue = container.evaluate(attr,
136 request);
137if (attributeValue == null) {
138if (!ignore) {
139thrownewNoSuchAttributeException(
140"Error importing attributes. " + "Attribute '"141 + name + "' has a null value ");
142 }
143 } else {
144if (toName != null) {
145 attributes.put(toName, attributeValue);
146 } else {
147 attributes.put(name, attributeValue);
148 }
149 }
150 } catch (RuntimeException e) {
151if (!ignore) {
152throw e;
153 } elseif (log.isDebugEnabled()) {
154 log.debug("Ignoring Tiles Exception", e);
155 }
156 }
157 } elseif (!ignore) {
158thrownewNoSuchAttributeException(
159"Error importing attributes. " + "Attribute '" + name
160 + "' is null");
161 }
162 }
163164/**165 * Imports all the attributes.166 *167 * @param names The names of the attributes to be imported.168 * @param container The Tiles container to use.169 * @param attributeContext The context from which the attributes will be170 * got.171 * @param attributes The map of the attributes to fill.172 * @param ignore If <code>true</code> and the attribute is not found, or an173 * exception happens, the problem will be ignored.174 * @param request The request.175 */176privatevoid importAttributes(Collection<String> names,
177TilesContainer container, AttributeContext attributeContext,
178 Map<String, Object> attributes, boolean ignore,
179 Request request) {
180if (names == null || names.isEmpty()) {
181return;
182 }
183184for (String name : names) {
185if (name == null && !ignore) {
186thrownewNoSuchAttributeException(
187"Error importing attributes. "188 + "Attribute with null key found.");
189 } elseif (name == null) {
190continue;
191 }
192193 importSingleAttribute(container, attributeContext, name, name,
194 ignore, attributes, request);
195 }
196 }
197 }