1 /*
2 * $Id$
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.struts.tiles;
23
24 import java.io.Serializable;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.Map;
29
30 import jakarta.servlet.ServletRequest;
31 import jakarta.servlet.jsp.PageContext;
32
33 import org.apache.struts.tiles.taglib.ComponentConstants;
34
35 /**
36 * Component context.
37 */
38 public class ComponentContext implements Serializable {
39 private static final long serialVersionUID = 5887062776582589341L;
40
41 /**
42 * Component attributes.
43 */
44 private HashMap<String, Object> attributes = null;
45
46 /**
47 * Constructor.
48 */
49 public ComponentContext() {
50 super();
51 }
52
53 /**
54 * Constructor.
55 * Create a context and set specified attributes.
56 * @param attributes Attributes to initialize context.
57 */
58 public ComponentContext(Map<String, Object> attributes) {
59 if (attributes != null) {
60 this.attributes = new HashMap<>(attributes);
61 }
62 }
63
64 /**
65 * Add all attributes to this context.
66 * Copies all of the mappings from the specified attribute map to this context.
67 * New attribute mappings will replace any mappings that this context had for any of the keys
68 * currently in the specified attribute map.
69 * @param newAttributes Attributes to add.
70 */
71 public void addAll(Map<String, Object> newAttributes) {
72 if (attributes == null) {
73 attributes = new HashMap<>(newAttributes);
74 return;
75 }
76
77 attributes.putAll(newAttributes);
78 }
79
80 /**
81 * Add all missing attributes to this context.
82 * Copies all of the mappings from the specified attributes map to this context.
83 * New attribute mappings will be added only if they don't already exist in
84 * this context.
85 * @param defaultAttributes Attributes to add.
86 */
87 public void addMissing(Map<String, Object> defaultAttributes) {
88 if (defaultAttributes == null) {
89 return;
90 }
91
92 if (attributes == null) {
93 attributes = new HashMap<>(defaultAttributes);
94 return;
95 }
96
97 for (Map.Entry<String, Object> entry : defaultAttributes.entrySet()) {
98 if (!attributes.containsKey(entry.getKey())) {
99 attributes.put(entry.getKey(), entry.getValue());
100 }
101 }
102 }
103
104 /**
105 * Get an attribute from context.
106 * @param name Name of the attribute.
107 * @return the value of the attribute
108 */
109 public Object getAttribute(String name) {
110 if (attributes == null){
111 return null;
112 }
113
114 return attributes.get(name);
115 }
116
117 /**
118 * Get names of all attributes.
119 * @return iterator with all attribute-names
120 */
121 public Iterator<String> getAttributeNames() {
122 if (attributes == null) {
123 return Collections.emptyListIterator();
124 }
125
126 return attributes.keySet().iterator();
127 }
128
129 /**
130 * Put a new attribute to context.
131 * @param name Name of the attribute.
132 * @param value Value of the attribute.
133 */
134 public void putAttribute(String name, Object value) {
135 if (attributes == null) {
136 attributes = new HashMap<>();
137 }
138
139 attributes.put(name, value);
140 }
141
142 /**
143 * Find object in one of the contexts.
144 * Order : component then pageContext.findAttribute()
145 * @param beanName Name of the bean to find.
146 * @param pageContext Page context.
147 * @return Requested bean or <code>null</code> if not found.
148 */
149 public Object findAttribute(String beanName, PageContext pageContext) {
150 Object attribute = getAttribute(beanName);
151 if (attribute == null) {
152 attribute = pageContext.findAttribute(beanName);
153 }
154
155 return attribute;
156 }
157
158 /**
159 * Get object from requested context.
160 * Context can be 'component'.
161 * @param beanName Name of the bean to find.
162 * @param scope Search scope (see {@link PageContext}).
163 * @param pageContext Page context.
164 * @return requested bean or <code>null</code> if not found.
165 */
166 public Object getAttribute(
167 String beanName,
168 int scope,
169 PageContext pageContext) {
170
171 if (scope == ComponentConstants.COMPONENT_SCOPE){
172 return getAttribute(beanName);
173 }
174
175 return pageContext.getAttribute(beanName, scope);
176 }
177
178 /**
179 * Get component context from request.
180 * @param request ServletRequest.
181 * @return ComponentContext or null if context is not found or an
182 * jspException is present in the request.
183 */
184 static public ComponentContext getContext(ServletRequest request) {
185 if (request.getAttribute("jakarta.servlet.jsp.jspException") != null) {
186 return null;
187 } return (ComponentContext) request.getAttribute(
188 ComponentConstants.COMPONENT_CONTEXT);
189 }
190
191 /**
192 * Store component context into request.
193 * @param context ComponentContext to store.
194 * @param request Request to store ComponentContext.
195 */
196 static public void setContext(
197 ComponentContext context,
198 ServletRequest request) {
199
200 request.setAttribute(ComponentConstants.COMPONENT_CONTEXT, context);
201 }
202 }