Mercurial > hg > AnnotationManagerN4J
annotate src/main/java/de/mpiwg/itgroup/annotations/restlet/BaseRestlet.java @ 61:b8ef15c8c4a5
implemented new shape format for image annotations.
minor cleanups.
author | casties |
---|---|
date | Thu, 22 Nov 2012 17:38:53 +0100 |
parents | 99d9afcfd04d |
children | 5b568de5ee0d |
rev | line source |
---|---|
18 | 1 package de.mpiwg.itgroup.annotations.restlet; |
2 | |
3 import java.io.File; | |
4 import java.io.FileInputStream; | |
5 import java.io.FileNotFoundException; | |
6 import java.io.IOException; | |
7 import java.io.InputStream; | |
8 import java.util.Hashtable; | |
9 import java.util.Properties; | |
10 | |
11 import javax.naming.NamingEnumeration; | |
12 import javax.naming.NamingException; | |
13 import javax.naming.directory.Attribute; | |
14 import javax.naming.directory.DirContext; | |
15 import javax.naming.directory.InitialDirContext; | |
16 import javax.naming.directory.SearchControls; | |
17 import javax.naming.directory.SearchResult; | |
18 import javax.servlet.ServletContext; | |
19 | |
20 import org.apache.log4j.BasicConfigurator; | |
21 import org.apache.log4j.Logger; | |
22 import org.neo4j.graphdb.GraphDatabaseService; | |
23 import org.neo4j.graphdb.factory.GraphDatabaseFactory; | |
24 import org.neo4j.kernel.AbstractGraphDatabase; | |
25 import org.neo4j.server.WrappingNeoServerBootstrapper; | |
26 import org.restlet.Application; | |
27 import org.restlet.Context; | |
28 | |
29 import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore; | |
30 | |
31 public abstract class BaseRestlet extends Application { | |
32 | |
33 public static Logger logger = Logger.getLogger(BaseRestlet.class); | |
34 | |
35 /** | |
57
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
36 * Properties holding consumer keys and secrets. |
18 | 37 */ |
38 protected Properties consumerKeys; | |
39 public String CONSUMER_KEYS_PATH = "WEB-INF/consumerkeys.property"; | |
40 public static final String CONSUMERKEYS_KEY = "annotationmanager.consumerkeys"; | |
41 | |
57
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
42 /** |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
43 * Properties holding server config. |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
44 */ |
18 | 45 protected Properties serverConfig; |
46 public String CONFIG_PROPS_PATH = "WEB-INF/serverconfig.property"; | |
47 public static final String SERVERCONFIG_KEY = "annotationmanager.serverconfig"; | |
48 | |
57
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
49 /** |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
50 * database instance; |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
51 */ |
18 | 52 protected GraphDatabaseService graphDb; |
53 public static final String GRAPHDB_KEY = "annotationmanager.graphdb"; | |
54 public static final String GRAPHDB_PATH_KEY = "annotationmanager.graphdb.path"; | |
55 public String graphdbPath = "WEB-INF/neo4j-annotation-db"; | |
56 | |
57
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
57 /** |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
58 * database interface server instance. |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
59 */ |
18 | 60 protected WrappingNeoServerBootstrapper srv; |
61 public static final String GRAPHDBSRV_KEY = "annotationmanager.graphdb.srv"; | |
62 | |
57
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
63 /** |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
64 * annotation store instance. |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
65 */ |
18 | 66 protected AnnotationStore store; |
67 public static final String ANNSTORE_KEY = "annotationmanager.store"; | |
68 | |
57
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
69 /** |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
70 * LDAP server URI (for looking up full user names). |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
71 */ |
18 | 72 protected String ldapServerUrl; |
73 public static final String LDAP_SERVER_KEY = "annotationmanager.ldapserver.url"; | |
74 | |
50 | 75 public static final String ADMIN_USER_KEY = "annotationmanager.admin.user"; |
76 public static final String ADMIN_PASSWORD_KEY = "annotationmanager.admin.password"; | |
77 | |
18 | 78 /** |
57
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
79 * run in authorization mode i.e. with tokens. |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
80 */ |
58 | 81 protected boolean authorizationMode = false; |
57
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
82 public static final String AUTHORIZATION_MODE_KEY = "annotationmanager.authorization"; |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
83 |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
84 /** |
58 | 85 * prefix to create uris for tags in store. |
86 */ | |
87 public static String TAGS_URI_PREFIX = ""; | |
88 public static final String TAGS_URI_KEY = "annotationmanager.uris.tags"; | |
89 | |
90 /** | |
91 * prefix to create uris for persons in store. | |
92 */ | |
93 public static String PERSONS_URI_PREFIX = ""; | |
94 public static final String PERSONS_URI_KEY = "annotationmanager.uris.persons"; | |
95 | |
96 /** | |
97 * prefix to create uris for groups in store. | |
98 */ | |
99 public static String GROUPS_URI_PREFIX = ""; | |
100 public static final String GROUPS_URI_KEY = "annotationmanager.uris.groups"; | |
101 | |
59
e2f86ef9b871
make annotation uri in store configurable. fix npe with no tags.
casties
parents:
58
diff
changeset
|
102 public static final String ANNOTATIONS_URI_KEY = "annotationmanager.uris.annotations"; |
e2f86ef9b871
make annotation uri in store configurable. fix npe with no tags.
casties
parents:
58
diff
changeset
|
103 |
58 | 104 /** |
18 | 105 * constructor |
106 * | |
107 * @param context | |
108 */ | |
109 public BaseRestlet(Context context) { | |
110 super(context); | |
111 configure(); | |
112 } | |
113 | |
114 /** | |
115 * Configures the restlet. | |
116 * Reads serverConfig, consumerKeys and graphDb config from config files and starts graphDb. | |
117 * Uses config from webapp context if already initialized. | |
118 */ | |
119 protected void configure() { | |
120 ServletContext sc = (ServletContext) getContext().getServerDispatcher().getContext().getAttributes() | |
121 .get("org.restlet.ext.servlet.ServletContext"); | |
122 if (sc != null) { | |
123 if (sc.getAttribute("annotationserver.log4j.configured") == null) { | |
124 // TODO: is this the right place to run the log4j configurator? | |
125 BasicConfigurator.configure(); | |
126 sc.setAttribute("annotationserver.log4j.configured", "done"); | |
127 } | |
128 logger.info(getVersion() + " starting..."); | |
129 | |
130 /* | |
131 * read config from webapp | |
132 */ | |
133 serverConfig = (Properties) sc.getAttribute(SERVERCONFIG_KEY); | |
134 if (serverConfig == null) { | |
135 serverConfig = new Properties(); | |
136 InputStream ps = getResourceAsStream(sc, CONFIG_PROPS_PATH); | |
137 if (ps != null) { | |
138 logger.debug("loading config from " + CONFIG_PROPS_PATH); | |
139 try { | |
140 serverConfig.load(ps); | |
141 /* | |
142 * read serverconfig options | |
143 */ | |
144 graphdbPath = serverConfig.getProperty(GRAPHDB_PATH_KEY, graphdbPath); | |
145 ldapServerUrl = serverConfig.getProperty(LDAP_SERVER_KEY, null); | |
60
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
146 /* |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
147 * uri prefixes |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
148 */ |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
149 if (serverConfig.containsKey(PERSONS_URI_KEY)) { |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
150 BaseRestlet.PERSONS_URI_PREFIX = serverConfig.getProperty(PERSONS_URI_KEY); |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
151 } |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
152 if (serverConfig.containsKey(GROUPS_URI_KEY)) { |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
153 BaseRestlet.GROUPS_URI_PREFIX = serverConfig.getProperty(GROUPS_URI_KEY); |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
154 } |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
155 if (serverConfig.containsKey(TAGS_URI_KEY)) { |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
156 BaseRestlet.TAGS_URI_PREFIX = serverConfig.getProperty(TAGS_URI_KEY); |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
157 } |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
158 if (serverConfig.containsKey(ANNOTATIONS_URI_KEY)) { |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
159 AnnotationStore.ANNOTATION_URI_PREFIX = serverConfig.getProperty(ANNOTATIONS_URI_KEY); |
99d9afcfd04d
configuration of uri prefixes was completely broken.
casties
parents:
59
diff
changeset
|
160 } |
18 | 161 } catch (IOException e) { |
162 logger.warn("Error loading server config: ", e); | |
163 } | |
164 logger.debug("config: " + serverConfig); | |
165 } else { | |
166 logger.error("Unable to get resource " + CONFIG_PROPS_PATH); | |
167 } | |
168 // store config | |
169 sc.setAttribute(SERVERCONFIG_KEY, serverConfig); | |
170 } | |
171 // look for database service in context | |
172 graphDb = (GraphDatabaseService) sc.getAttribute(GRAPHDB_KEY); | |
173 if (graphDb == null) { | |
174 /* | |
175 * open database | |
176 */ | |
177 String dbFn = getResourcePath(sc, graphdbPath); | |
178 if (dbFn != null) { | |
179 logger.debug("opening DB " + dbFn); | |
180 graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(dbFn); | |
181 registerShutdownHook(graphDb); | |
182 // store in context | |
183 sc.setAttribute(GRAPHDB_KEY, graphDb); | |
184 // AnnotationStore | |
185 store = new AnnotationStore(graphDb); | |
186 sc.setAttribute(ANNSTORE_KEY, store); | |
187 // admin server | |
188 srv = new WrappingNeoServerBootstrapper((AbstractGraphDatabase) graphDb); | |
189 logger.debug("Starting DB admin server..."); | |
190 // store in context | |
191 sc.setAttribute(GRAPHDBSRV_KEY, srv); | |
192 srv.start(); | |
193 } else { | |
194 logger.error("Unable to get resource " + dbFn); | |
195 } | |
22 | 196 } else { |
197 // get existing AnnotationStore | |
198 store = (AnnotationStore) sc.getAttribute(ANNSTORE_KEY); | |
18 | 199 } |
200 /* | |
201 * read consumerKeys from webapp | |
202 */ | |
203 consumerKeys = (Properties) sc.getAttribute(CONSUMERKEYS_KEY); | |
204 if (consumerKeys == null) { | |
205 consumerKeys = new Properties(); | |
206 InputStream ps = getResourceAsStream(sc, CONSUMER_KEYS_PATH); | |
207 if (ps != null) { | |
208 logger.debug("loading consumer keys from " + CONSUMER_KEYS_PATH); | |
209 try { | |
210 consumerKeys.load(ps); | |
211 } catch (IOException e) { | |
212 // TODO Auto-generated catch block | |
213 e.printStackTrace(); | |
214 } | |
215 logger.debug("consumer keys: " + consumerKeys); | |
216 } else { | |
217 logger.error("Unable to get resource " + CONSUMER_KEYS_PATH); | |
218 } | |
219 // store config | |
220 sc.setAttribute(CONSUMERKEYS_KEY, consumerKeys); | |
221 } | |
222 } else { | |
223 logger.error("Unable to get ServletContext!"); | |
224 } | |
225 } | |
226 | |
227 public abstract String getVersion(); | |
228 | |
229 /** | |
57
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
230 * @return the authorizationMode |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
231 */ |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
232 public boolean isAuthorizationMode() { |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
233 return authorizationMode; |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
234 } |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
235 |
4efb21cf0ce0
new non-authorized mode without tokens. enabled by default. configured with annotationmanager.authorization=false property.
casties
parents:
50
diff
changeset
|
236 /** |
19 | 237 * @return the store |
238 */ | |
239 public AnnotationStore getAnnotationStore() { | |
240 return store; | |
241 } | |
242 | |
243 /** | |
18 | 244 * returns consumer secret for consumer key. returns null if consumer key |
245 * doesn't exist. | |
246 * | |
247 * @param consumerKey | |
248 * @return | |
249 */ | |
250 public String getConsumerSecret(String consumerKey) { | |
251 return consumerKeys.getProperty(consumerKey); | |
252 } | |
253 | |
254 /** | |
255 * Hole den vollen Benutzernamen aus dem LDAP | |
256 * | |
257 * @param creator | |
258 * @return | |
259 */ | |
260 public String getFullNameFromLdap(String creator) { | |
261 String retString = creator; // falls nichts gefunden wird einfach den | |
262 // creator zurueckgeben | |
263 if (ldapServerUrl == null) { | |
264 return retString; | |
265 } | |
266 Hashtable<String, String> env = new Hashtable<String, String>(); | |
267 String sp = "com.sun.jndi.ldap.LdapCtxFactory"; | |
268 env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, sp); | |
269 env.put(javax.naming.Context.PROVIDER_URL, ldapServerUrl); | |
270 | |
271 DirContext dctx; | |
272 try { | |
273 dctx = new InitialDirContext(env); | |
274 } catch (NamingException e) { | |
275 logger.error("Error in getFullNameFromLDAP!", e); | |
276 return retString; | |
277 } | |
278 | |
279 String base = "ou=people"; | |
280 | |
281 SearchControls sc = new SearchControls(); | |
282 String[] attributeFilter = { "cn", "mail" }; | |
283 sc.setReturningAttributes(attributeFilter); | |
284 sc.setSearchScope(SearchControls.SUBTREE_SCOPE); | |
285 | |
286 String filter = "(uid=" + creator + ")"; | |
287 | |
288 try { | |
289 NamingEnumeration<SearchResult> results = dctx.search(base, filter, sc); | |
290 while (results.hasMore()) { | |
291 SearchResult sr = (SearchResult) results.next(); | |
292 javax.naming.directory.Attributes attrs = sr.getAttributes(); | |
293 | |
294 Attribute attr = attrs.get("cn"); | |
295 retString = (String) attr.get(); | |
296 } | |
297 } catch (NamingException e) { | |
298 logger.error("Error in getFullNameFromLDAP!", e); | |
299 } | |
300 | |
301 try { | |
302 dctx.close(); | |
303 } catch (NamingException e) { | |
304 logger.error("Error in getFullNameFromLDAP!", e); | |
305 } | |
306 return retString; | |
307 } | |
308 | |
309 /** | |
310 * returns resource from path (in webapp) as InputStream. | |
311 * | |
312 * @param sc | |
313 * @param path | |
314 * @return | |
315 */ | |
316 protected InputStream getResourceAsStream(ServletContext sc, String path) { | |
317 InputStream ps = sc.getResourceAsStream(path); | |
318 if (ps == null) { | |
319 // try as file | |
320 File pf = new File(sc.getRealPath(path)); | |
321 if (pf != null) { | |
322 logger.debug("trying file for: " + pf); | |
323 try { | |
324 ps = new FileInputStream(pf); | |
325 } catch (FileNotFoundException e) { | |
326 logger.error(e); | |
327 } | |
328 } | |
329 } | |
330 return ps; | |
331 } | |
332 | |
333 /** | |
334 * get a real file name for a web app file pathname. | |
335 * | |
336 * If filename starts with "/" its treated as absolute else the path is | |
337 * appended to the base directory of the web-app. | |
338 * | |
339 * @param filename | |
340 * @param sc | |
341 * @return | |
342 */ | |
343 public static String getResourcePath(ServletContext sc, String filename) { | |
344 File f = new File(filename); | |
345 // is the filename absolute? | |
346 if (!f.isAbsolute()) { | |
347 // relative path -> use getRealPath to resolve in webapp | |
348 filename = sc.getRealPath(filename); | |
349 } | |
350 return filename; | |
351 } | |
352 | |
353 /* | |
354 * (non-Javadoc) | |
355 * | |
356 * @see org.restlet.Application#stop() | |
357 */ | |
358 @Override | |
359 public synchronized void stop() throws Exception { | |
360 /* | |
361 * trying to clean up databases, not sure if this is the right way... | |
362 */ | |
363 if (srv != null) { | |
364 logger.debug("Stopping DB admin server..."); | |
365 srv.stop(); | |
366 srv = null; | |
367 } | |
368 if (graphDb != null) { | |
369 logger.debug("Stopping DB..."); | |
370 graphDb.shutdown(); | |
371 graphDb = null; | |
372 } | |
373 super.stop(); | |
374 } | |
375 | |
376 private static void registerShutdownHook(final GraphDatabaseService graphDb) { | |
377 // Registers a shutdown hook for the Neo4j instance so that it | |
378 // shuts down nicely when the VM exits (even if you "Ctrl-C" the | |
379 // running example before it's completed) | |
380 Runtime.getRuntime().addShutdownHook(new Thread() { | |
381 @Override | |
382 public void run() { | |
383 graphDb.shutdown(); | |
384 } | |
385 }); | |
386 } | |
387 | |
388 } |