1
18
19 package io.undertow.servlet.api;
20
21 import java.lang.reflect.Constructor;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.concurrent.Executor;
29
30 import javax.servlet.MultipartConfigElement;
31 import javax.servlet.Servlet;
32
33 import io.undertow.server.HandlerWrapper;
34 import io.undertow.servlet.UndertowServletMessages;
35 import io.undertow.servlet.util.ConstructorInstanceFactory;
36
37
40 public class ServletInfo implements Cloneable {
41
42 private final Class<? extends Servlet> servletClass;
43 private final String name;
44
45 private final List<String> mappings = new ArrayList<>();
46 private final Map<String, String> initParams = new HashMap<>();
47 private final List<SecurityRoleRef> securityRoleRefs = new ArrayList<>();
48 private final List<HandlerWrapper> handlerChainWrappers = new ArrayList<>();
49
50 private InstanceFactory<? extends Servlet> instanceFactory;
51 private String jspFile;
52 private Integer loadOnStartup;
53 private boolean enabled;
54 private boolean asyncSupported;
55 private String runAs;
56 private MultipartConfigElement multipartConfig;
57 private ServletSecurityInfo servletSecurityInfo;
58 private Executor executor;
59
66 private boolean requireWelcomeFileMapping;
67
68 public ServletInfo(final String name, final Class<? extends Servlet> servletClass) {
69 if (name == null) {
70 throw UndertowServletMessages.MESSAGES.paramCannotBeNull("name");
71 }
72 if (servletClass == null) {
73 throw UndertowServletMessages.MESSAGES.paramCannotBeNull("servletClass", "Servlet", name);
74 }
75 if (!Servlet.class.isAssignableFrom(servletClass)) {
76 throw UndertowServletMessages.MESSAGES.servletMustImplementServlet(name, servletClass);
77 }
78 try {
79 final Constructor<? extends Servlet> ctor = servletClass.getDeclaredConstructor();
80 ctor.setAccessible(true);
81 this.instanceFactory = new ConstructorInstanceFactory(ctor);
82 this.name = name;
83 this.servletClass = servletClass;
84 } catch (NoSuchMethodException e) {
85 throw UndertowServletMessages.MESSAGES.componentMustHaveDefaultConstructor("Servlet", servletClass);
86 }
87 }
88
89
90 public ServletInfo(final String name, final Class<? extends Servlet> servletClass, final InstanceFactory<? extends Servlet> instanceFactory) {
91 if (name == null) {
92 throw UndertowServletMessages.MESSAGES.paramCannotBeNull("name");
93 }
94 if (servletClass == null) {
95 throw UndertowServletMessages.MESSAGES.paramCannotBeNull("servletClass", "Servlet", name);
96 }
97 if (!Servlet.class.isAssignableFrom(servletClass)) {
98 throw UndertowServletMessages.MESSAGES.servletMustImplementServlet(name, servletClass);
99 }
100 this.instanceFactory = instanceFactory;
101 this.name = name;
102 this.servletClass = servletClass;
103 }
104
105 public void validate() {
106
107 }
108
109 @Override
110 public ServletInfo clone() {
111 ServletInfo info = new ServletInfo(name, servletClass, instanceFactory)
112 .setJspFile(jspFile)
113 .setLoadOnStartup(loadOnStartup)
114 .setEnabled(enabled)
115 .setAsyncSupported(asyncSupported)
116 .setRunAs(runAs)
117 .setMultipartConfig(multipartConfig)
118 .setExecutor(executor)
119 .setRequireWelcomeFileMapping(requireWelcomeFileMapping);
120 info.mappings.addAll(mappings);
121 info.initParams.putAll(initParams);
122 info.securityRoleRefs.addAll(securityRoleRefs);
123 info.handlerChainWrappers.addAll(handlerChainWrappers);
124 if (servletSecurityInfo != null) {
125 info.servletSecurityInfo = servletSecurityInfo.clone();
126 }
127 return info;
128 }
129
130 public Class<? extends Servlet> getServletClass() {
131 return servletClass;
132 }
133
134 public String getName() {
135 return name;
136 }
137
138 public void setInstanceFactory(final InstanceFactory<? extends Servlet> instanceFactory) {
139 if (instanceFactory == null) {
140 throw UndertowServletMessages.MESSAGES.paramCannotBeNull("instanceFactory");
141 }
142 this.instanceFactory = instanceFactory;
143 }
144
145 public InstanceFactory<? extends Servlet> getInstanceFactory() {
146 return instanceFactory;
147 }
148
149 public List<String> getMappings() {
150 return Collections.unmodifiableList(mappings);
151 }
152
153 public ServletInfo addMapping(final String mapping) {
154 if(!mapping.startsWith("/") && !mapping.startsWith("*") && !mapping.isEmpty()) {
155
156 mappings.add("/" + mapping);
157 } else {
158 mappings.add(mapping);
159 }
160 return this;
161 }
162
163
164 public ServletInfo addMappings(final Collection<String> mappings) {
165 for(String m : mappings) {
166 addMapping(m);
167 }
168 return this;
169 }
170
171
172 public ServletInfo addMappings(final String... mappings) {
173 for(String m : mappings) {
174 addMapping(m);
175 }
176 return this;
177 }
178
179 public ServletInfo addInitParam(final String name, final String value) {
180 initParams.put(name, value);
181 return this;
182 }
183
184
185 public Map<String, String> getInitParams() {
186 return Collections.unmodifiableMap(initParams);
187 }
188
189 public String getJspFile() {
190 return jspFile;
191 }
192
193 public ServletInfo setJspFile(final String jspFile) {
194 this.jspFile = jspFile;
195 return this;
196 }
197
198 public Integer getLoadOnStartup() {
199 return loadOnStartup;
200 }
201
202 public ServletInfo setLoadOnStartup(final Integer loadOnStartup) {
203 this.loadOnStartup = loadOnStartup;
204 return this;
205 }
206
207 public boolean isAsyncSupported() {
208 return asyncSupported;
209 }
210
211 public ServletInfo setAsyncSupported(final boolean asyncSupported) {
212 this.asyncSupported = asyncSupported;
213 return this;
214 }
215
216 public boolean isEnabled() {
217 return enabled;
218 }
219
220 public ServletInfo setEnabled(final boolean enabled) {
221 this.enabled = enabled;
222 return this;
223 }
224
225 public String getRunAs() {
226 return runAs;
227 }
228
229 public ServletInfo setRunAs(final String runAs) {
230 this.runAs = runAs;
231 return this;
232 }
233
234 public MultipartConfigElement getMultipartConfig() {
235 return multipartConfig;
236 }
237
238 public ServletInfo setMultipartConfig(final MultipartConfigElement multipartConfig) {
239 this.multipartConfig = multipartConfig;
240 return this;
241 }
242
243 public void addSecurityRoleRef(final String role, final String linkedRole) {
244 this.securityRoleRefs.add(new SecurityRoleRef(role, linkedRole));
245 }
246
247 public List<SecurityRoleRef> getSecurityRoleRefs() {
248 return Collections.unmodifiableList(securityRoleRefs);
249 }
250
251 public ServletInfo addHandlerChainWrapper(final HandlerWrapper wrapper) {
252 this.handlerChainWrappers.add(wrapper);
253 return this;
254 }
255
256 public List<HandlerWrapper> getHandlerChainWrappers() {
257 return Collections.unmodifiableList(handlerChainWrappers);
258 }
259
260 public ServletSecurityInfo getServletSecurityInfo() {
261 return servletSecurityInfo;
262 }
263
264 public ServletInfo setServletSecurityInfo(final ServletSecurityInfo servletSecurityInfo) {
265 this.servletSecurityInfo = servletSecurityInfo;
266 return this;
267 }
268
269 public Executor getExecutor() {
270 return executor;
271 }
272
273 public ServletInfo setExecutor(final Executor executor) {
274 this.executor = executor;
275 return this;
276 }
277
278
282 public boolean isRequireWelcomeFileMapping() {
283 return requireWelcomeFileMapping;
284 }
285
286 public ServletInfo setRequireWelcomeFileMapping(boolean requireWelcomeFileMapping) {
287 this.requireWelcomeFileMapping = requireWelcomeFileMapping;
288 return this;
289 }
290
291 @Override
292 public String toString() {
293 return "ServletInfo{" +
294 "mappings=" + mappings +
295 ", servletClass=" + servletClass +
296 ", name='" + name + '\'' +
297 '}';
298 }
299 }
300