1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.plus.annotation;
20
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.concurrent.TimeUnit;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31
32 import javax.servlet.ServletContainerInitializer;
33
34 import org.eclipse.jetty.util.ConcurrentHashSet;
35 import org.eclipse.jetty.util.Loader;
36 import org.eclipse.jetty.util.StringUtil;
37 import org.eclipse.jetty.util.log.Log;
38 import org.eclipse.jetty.util.log.Logger;
39 import org.eclipse.jetty.webapp.WebAppContext;
40
41 public class ContainerInitializer
42 {
43 private static final Logger LOG = Log.getLogger(ContainerInitializer.class);
44
45 final protected ServletContainerInitializer _target;
46 final protected Class<?>[] _interestedTypes;
47 final protected Set<String> _applicableTypeNames = new ConcurrentHashSet<String>();
48 final protected Set<String> _annotatedTypeNames = new ConcurrentHashSet<String>();
49
50
51 public ContainerInitializer (ServletContainerInitializer target, Class<?>[] classes)
52 {
53 _target = target;
54 _interestedTypes = classes;
55 }
56
57 public ContainerInitializer (ClassLoader loader, String toString)
58 {
59 Matcher m = Pattern.compile("ContainerInitializer\\{(.*),interested=(.*),applicable=(.*),annotated=(.*)\\}").matcher(toString);
60 if (!m.matches())
61 throw new IllegalArgumentException(toString);
62
63 try
64 {
65 _target = (ServletContainerInitializer)loader.loadClass(m.group(1)).newInstance();
66 String[] interested = StringUtil.arrayFromString(m.group(2));
67 _interestedTypes = new Class<?>[interested.length];
68 for (int i=0;i<interested.length;i++)
69 _interestedTypes[i]=loader.loadClass(interested[i]);
70 for (String s:StringUtil.arrayFromString(m.group(3)))
71 _applicableTypeNames.add(s);
72 for (String s:StringUtil.arrayFromString(m.group(4)))
73 _annotatedTypeNames.add(s);
74 }
75 catch(Exception e)
76 {
77 throw new IllegalArgumentException(toString, e);
78 }
79 }
80
81 public ServletContainerInitializer getTarget ()
82 {
83 return _target;
84 }
85
86 public Class[] getInterestedTypes ()
87 {
88 return _interestedTypes;
89 }
90
91
92
93
94
95
96
97 public void addAnnotatedTypeName (String className)
98 {
99 _annotatedTypeNames.add(className);
100 }
101
102 public Set<String> getAnnotatedTypeNames ()
103 {
104 return Collections.unmodifiableSet(_annotatedTypeNames);
105 }
106
107 public void addApplicableTypeName (String className)
108 {
109 _applicableTypeNames.add(className);
110 }
111
112 public Set<String> getApplicableTypeNames ()
113 {
114 return Collections.unmodifiableSet(_applicableTypeNames);
115 }
116
117
118 public void callStartup(WebAppContext context)
119 throws Exception
120 {
121 if (_target != null)
122 {
123 Set<Class<?>> classes = new HashSet<Class<?>>();
124
125 ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
126 Thread.currentThread().setContextClassLoader(context.getClassLoader());
127
128 try
129 {
130 for (String s : _applicableTypeNames)
131 classes.add(Loader.loadClass(context.getClass(), s));
132
133 context.getServletContext().setExtendedListenerTypes(true);
134 if (LOG.isDebugEnabled())
135 {
136 long start = System.nanoTime();
137 _target.onStartup(classes, context.getServletContext());
138 LOG.debug("ContainerInitializer {} called in {}ms", _target.getClass().getName(), TimeUnit.MILLISECONDS.convert(System.nanoTime()-start, TimeUnit.NANOSECONDS));
139 }
140 else
141 _target.onStartup(classes, context.getServletContext());
142 }
143 finally
144 {
145 context.getServletContext().setExtendedListenerTypes(false);
146 Thread.currentThread().setContextClassLoader(oldLoader);
147 }
148 }
149 }
150
151 public String toString()
152 {
153 List<String> interested = Collections.emptyList();
154 if (_interestedTypes != null)
155 {
156 interested = new ArrayList<>(_interestedTypes.length);
157 for (Class<?> c : _interestedTypes)
158 interested.add(c.getName());
159 }
160
161 return String.format("ContainerInitializer{%s,interested=%s,applicable=%s,annotated=%s}",_target.getClass().getName(),interested,_applicableTypeNames,_annotatedTypeNames);
162 }
163
164 public void resolveClasses(WebAppContext context, Map<String, Set<String>> classMap)
165 {
166
167
168
169 Set<String> annotatedClassNames = getAnnotatedTypeNames();
170 if (annotatedClassNames != null && !annotatedClassNames.isEmpty())
171 {
172 for (String name : annotatedClassNames)
173 {
174
175 addApplicableTypeName(name);
176
177
178 addInheritedTypes(classMap, (Set<String>)classMap.get(name));
179 }
180 }
181
182
183
184
185 if (getInterestedTypes() != null)
186 {
187 for (Class<?> c : getInterestedTypes())
188 {
189 if (!c.isAnnotation())
190 {
191
192
193 addInheritedTypes(classMap, (Set<String>)classMap.get(c.getName()));
194 }
195 }
196 }
197 }
198
199 private void addInheritedTypes(Map<String, Set<String>> classMap,Set<String> names)
200 {
201 if (names == null || names.isEmpty())
202 return;
203
204 for (String s : names)
205 {
206
207 addApplicableTypeName(s);
208
209
210 addInheritedTypes(classMap, (Set<String>)classMap.get(s));
211 }
212 }
213 }