source: AnnotationManagerN4J/src/main/java/de/mpiwg/itgroup/annotations/restlet/BaseRestlet.java @ 50:64aa756c60cc

Last change on this file since 50:64aa756c60cc was 50:64aa756c60cc, checked in by casties, 12 years ago

annotations ui can show and delete annotations now.

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