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