comparison src/main/java/de/mpiwg/itgroup/annotations/restlet/BaseRestlet.java @ 18:aafa3884b2c4

new AnnotationStore restlet for HTML-UI. reorganisation of classes.
author casties
date Wed, 05 Sep 2012 18:05:54 +0200
parents
children f0f55ab768c9
comparison
equal deleted inserted replaced
17:e9dfac5b0566 18:aafa3884b2c4
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 /**
36 * Properties holding consumer keys and secrets
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
42 protected Properties serverConfig;
43 public String CONFIG_PROPS_PATH = "WEB-INF/serverconfig.property";
44 public static final String SERVERCONFIG_KEY = "annotationmanager.serverconfig";
45
46 protected GraphDatabaseService graphDb;
47 public static final String GRAPHDB_KEY = "annotationmanager.graphdb";
48 public static final String GRAPHDB_PATH_KEY = "annotationmanager.graphdb.path";
49 public String graphdbPath = "WEB-INF/neo4j-annotation-db";
50
51 protected WrappingNeoServerBootstrapper srv;
52 public static final String GRAPHDBSRV_KEY = "annotationmanager.graphdb.srv";
53
54 protected AnnotationStore store;
55 public static final String ANNSTORE_KEY = "annotationmanager.store";
56
57 protected String ldapServerUrl;
58 public static final String LDAP_SERVER_KEY = "annotationmanager.ldapserver.url";
59
60 /**
61 * constructor
62 *
63 * @param context
64 */
65 public BaseRestlet(Context context) {
66 super(context);
67 configure();
68 }
69
70 /**
71 * Configures the restlet.
72 * Reads serverConfig, consumerKeys and graphDb config from config files and starts graphDb.
73 * Uses config from webapp context if already initialized.
74 */
75 protected void configure() {
76 ServletContext sc = (ServletContext) getContext().getServerDispatcher().getContext().getAttributes()
77 .get("org.restlet.ext.servlet.ServletContext");
78 if (sc != null) {
79 if (sc.getAttribute("annotationserver.log4j.configured") == null) {
80 // TODO: is this the right place to run the log4j configurator?
81 BasicConfigurator.configure();
82 sc.setAttribute("annotationserver.log4j.configured", "done");
83 }
84 logger.info(getVersion() + " starting...");
85
86 /*
87 * read config from webapp
88 */
89 serverConfig = (Properties) sc.getAttribute(SERVERCONFIG_KEY);
90 if (serverConfig == null) {
91 serverConfig = new Properties();
92 InputStream ps = getResourceAsStream(sc, CONFIG_PROPS_PATH);
93 if (ps != null) {
94 logger.debug("loading config from " + CONFIG_PROPS_PATH);
95 try {
96 serverConfig.load(ps);
97 /*
98 * read serverconfig options
99 */
100 graphdbPath = serverConfig.getProperty(GRAPHDB_PATH_KEY, graphdbPath);
101 ldapServerUrl = serverConfig.getProperty(LDAP_SERVER_KEY, null);
102 } catch (IOException e) {
103 logger.warn("Error loading server config: ", e);
104 }
105 logger.debug("config: " + serverConfig);
106 } else {
107 logger.error("Unable to get resource " + CONFIG_PROPS_PATH);
108 }
109 // store config
110 sc.setAttribute(SERVERCONFIG_KEY, serverConfig);
111 }
112 // look for database service in context
113 graphDb = (GraphDatabaseService) sc.getAttribute(GRAPHDB_KEY);
114 if (graphDb == null) {
115 /*
116 * open database
117 */
118 String dbFn = getResourcePath(sc, graphdbPath);
119 if (dbFn != null) {
120 logger.debug("opening DB " + dbFn);
121 graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(dbFn);
122 registerShutdownHook(graphDb);
123 // store in context
124 sc.setAttribute(GRAPHDB_KEY, graphDb);
125 // AnnotationStore
126 store = new AnnotationStore(graphDb);
127 sc.setAttribute(ANNSTORE_KEY, store);
128 // admin server
129 srv = new WrappingNeoServerBootstrapper((AbstractGraphDatabase) graphDb);
130 logger.debug("Starting DB admin server...");
131 // store in context
132 sc.setAttribute(GRAPHDBSRV_KEY, srv);
133 srv.start();
134 } else {
135 logger.error("Unable to get resource " + dbFn);
136 }
137 }
138 /*
139 * read consumerKeys from webapp
140 */
141 consumerKeys = (Properties) sc.getAttribute(CONSUMERKEYS_KEY);
142 if (consumerKeys == null) {
143 consumerKeys = new Properties();
144 InputStream ps = getResourceAsStream(sc, CONSUMER_KEYS_PATH);
145 if (ps != null) {
146 logger.debug("loading consumer keys from " + CONSUMER_KEYS_PATH);
147 try {
148 consumerKeys.load(ps);
149 } catch (IOException e) {
150 // TODO Auto-generated catch block
151 e.printStackTrace();
152 }
153 logger.debug("consumer keys: " + consumerKeys);
154 } else {
155 logger.error("Unable to get resource " + CONSUMER_KEYS_PATH);
156 }
157 // store config
158 sc.setAttribute(CONSUMERKEYS_KEY, consumerKeys);
159 }
160 } else {
161 logger.error("Unable to get ServletContext!");
162 }
163 }
164
165 public abstract String getVersion();
166
167 /**
168 * returns consumer secret for consumer key. returns null if consumer key
169 * doesn't exist.
170 *
171 * @param consumerKey
172 * @return
173 */
174 public String getConsumerSecret(String consumerKey) {
175 return consumerKeys.getProperty(consumerKey);
176 }
177
178 /**
179 * Hole den vollen Benutzernamen aus dem LDAP
180 *
181 * @param creator
182 * @return
183 */
184 public String getFullNameFromLdap(String creator) {
185 String retString = creator; // falls nichts gefunden wird einfach den
186 // creator zurueckgeben
187 if (ldapServerUrl == null) {
188 return retString;
189 }
190 Hashtable<String, String> env = new Hashtable<String, String>();
191 String sp = "com.sun.jndi.ldap.LdapCtxFactory";
192 env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, sp);
193 env.put(javax.naming.Context.PROVIDER_URL, ldapServerUrl);
194
195 DirContext dctx;
196 try {
197 dctx = new InitialDirContext(env);
198 } catch (NamingException e) {
199 logger.error("Error in getFullNameFromLDAP!", e);
200 return retString;
201 }
202
203 String base = "ou=people";
204
205 SearchControls sc = new SearchControls();
206 String[] attributeFilter = { "cn", "mail" };
207 sc.setReturningAttributes(attributeFilter);
208 sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
209
210 String filter = "(uid=" + creator + ")";
211
212 try {
213 NamingEnumeration<SearchResult> results = dctx.search(base, filter, sc);
214 while (results.hasMore()) {
215 SearchResult sr = (SearchResult) results.next();
216 javax.naming.directory.Attributes attrs = sr.getAttributes();
217
218 Attribute attr = attrs.get("cn");
219 retString = (String) attr.get();
220 }
221 } catch (NamingException e) {
222 logger.error("Error in getFullNameFromLDAP!", e);
223 }
224
225 try {
226 dctx.close();
227 } catch (NamingException e) {
228 logger.error("Error in getFullNameFromLDAP!", e);
229 }
230 return retString;
231 }
232
233 /**
234 * returns resource from path (in webapp) as InputStream.
235 *
236 * @param sc
237 * @param path
238 * @return
239 */
240 protected InputStream getResourceAsStream(ServletContext sc, String path) {
241 InputStream ps = sc.getResourceAsStream(path);
242 if (ps == null) {
243 // try as file
244 File pf = new File(sc.getRealPath(path));
245 if (pf != null) {
246 logger.debug("trying file for: " + pf);
247 try {
248 ps = new FileInputStream(pf);
249 } catch (FileNotFoundException e) {
250 logger.error(e);
251 }
252 }
253 }
254 return ps;
255 }
256
257 /**
258 * get a real file name for a web app file pathname.
259 *
260 * If filename starts with "/" its treated as absolute else the path is
261 * appended to the base directory of the web-app.
262 *
263 * @param filename
264 * @param sc
265 * @return
266 */
267 public static String getResourcePath(ServletContext sc, String filename) {
268 File f = new File(filename);
269 // is the filename absolute?
270 if (!f.isAbsolute()) {
271 // relative path -> use getRealPath to resolve in webapp
272 filename = sc.getRealPath(filename);
273 }
274 return filename;
275 }
276
277 /*
278 * (non-Javadoc)
279 *
280 * @see org.restlet.Application#stop()
281 */
282 @Override
283 public synchronized void stop() throws Exception {
284 /*
285 * trying to clean up databases, not sure if this is the right way...
286 */
287 if (srv != null) {
288 logger.debug("Stopping DB admin server...");
289 srv.stop();
290 srv = null;
291 }
292 if (graphDb != null) {
293 logger.debug("Stopping DB...");
294 graphDb.shutdown();
295 graphDb = null;
296 }
297 super.stop();
298 }
299
300 private static void registerShutdownHook(final GraphDatabaseService graphDb) {
301 // Registers a shutdown hook for the Neo4j instance so that it
302 // shuts down nicely when the VM exits (even if you "Ctrl-C" the
303 // running example before it's completed)
304 Runtime.getRuntime().addShutdownHook(new Thread() {
305 @Override
306 public void run() {
307 graphDb.shutdown();
308 }
309 });
310 }
311
312 }