Mercurial > hg > AnnotationManagerN4J
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/mpiwg/itgroup/annotations/restlet/BaseRestlet.java Wed Sep 05 18:05:54 2012 +0200 @@ -0,0 +1,312 @@ +package de.mpiwg.itgroup.annotations.restlet; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Hashtable; +import java.util.Properties; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import javax.servlet.ServletContext; + +import org.apache.log4j.BasicConfigurator; +import org.apache.log4j.Logger; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.factory.GraphDatabaseFactory; +import org.neo4j.kernel.AbstractGraphDatabase; +import org.neo4j.server.WrappingNeoServerBootstrapper; +import org.restlet.Application; +import org.restlet.Context; + +import de.mpiwg.itgroup.annotations.neo4j.AnnotationStore; + +public abstract class BaseRestlet extends Application { + + public static Logger logger = Logger.getLogger(BaseRestlet.class); + + /** + * Properties holding consumer keys and secrets + */ + protected Properties consumerKeys; + public String CONSUMER_KEYS_PATH = "WEB-INF/consumerkeys.property"; + public static final String CONSUMERKEYS_KEY = "annotationmanager.consumerkeys"; + + protected Properties serverConfig; + public String CONFIG_PROPS_PATH = "WEB-INF/serverconfig.property"; + public static final String SERVERCONFIG_KEY = "annotationmanager.serverconfig"; + + protected GraphDatabaseService graphDb; + public static final String GRAPHDB_KEY = "annotationmanager.graphdb"; + public static final String GRAPHDB_PATH_KEY = "annotationmanager.graphdb.path"; + public String graphdbPath = "WEB-INF/neo4j-annotation-db"; + + protected WrappingNeoServerBootstrapper srv; + public static final String GRAPHDBSRV_KEY = "annotationmanager.graphdb.srv"; + + protected AnnotationStore store; + public static final String ANNSTORE_KEY = "annotationmanager.store"; + + protected String ldapServerUrl; + public static final String LDAP_SERVER_KEY = "annotationmanager.ldapserver.url"; + + /** + * constructor + * + * @param context + */ + public BaseRestlet(Context context) { + super(context); + configure(); + } + + /** + * Configures the restlet. + * Reads serverConfig, consumerKeys and graphDb config from config files and starts graphDb. + * Uses config from webapp context if already initialized. + */ + protected void configure() { + ServletContext sc = (ServletContext) getContext().getServerDispatcher().getContext().getAttributes() + .get("org.restlet.ext.servlet.ServletContext"); + if (sc != null) { + if (sc.getAttribute("annotationserver.log4j.configured") == null) { + // TODO: is this the right place to run the log4j configurator? + BasicConfigurator.configure(); + sc.setAttribute("annotationserver.log4j.configured", "done"); + } + logger.info(getVersion() + " starting..."); + + /* + * read config from webapp + */ + serverConfig = (Properties) sc.getAttribute(SERVERCONFIG_KEY); + if (serverConfig == null) { + serverConfig = new Properties(); + InputStream ps = getResourceAsStream(sc, CONFIG_PROPS_PATH); + if (ps != null) { + logger.debug("loading config from " + CONFIG_PROPS_PATH); + try { + serverConfig.load(ps); + /* + * read serverconfig options + */ + graphdbPath = serverConfig.getProperty(GRAPHDB_PATH_KEY, graphdbPath); + ldapServerUrl = serverConfig.getProperty(LDAP_SERVER_KEY, null); + } catch (IOException e) { + logger.warn("Error loading server config: ", e); + } + logger.debug("config: " + serverConfig); + } else { + logger.error("Unable to get resource " + CONFIG_PROPS_PATH); + } + // store config + sc.setAttribute(SERVERCONFIG_KEY, serverConfig); + } + // look for database service in context + graphDb = (GraphDatabaseService) sc.getAttribute(GRAPHDB_KEY); + if (graphDb == null) { + /* + * open database + */ + String dbFn = getResourcePath(sc, graphdbPath); + if (dbFn != null) { + logger.debug("opening DB " + dbFn); + graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(dbFn); + registerShutdownHook(graphDb); + // store in context + sc.setAttribute(GRAPHDB_KEY, graphDb); + // AnnotationStore + store = new AnnotationStore(graphDb); + sc.setAttribute(ANNSTORE_KEY, store); + // admin server + srv = new WrappingNeoServerBootstrapper((AbstractGraphDatabase) graphDb); + logger.debug("Starting DB admin server..."); + // store in context + sc.setAttribute(GRAPHDBSRV_KEY, srv); + srv.start(); + } else { + logger.error("Unable to get resource " + dbFn); + } + } + /* + * read consumerKeys from webapp + */ + consumerKeys = (Properties) sc.getAttribute(CONSUMERKEYS_KEY); + if (consumerKeys == null) { + consumerKeys = new Properties(); + InputStream ps = getResourceAsStream(sc, CONSUMER_KEYS_PATH); + if (ps != null) { + logger.debug("loading consumer keys from " + CONSUMER_KEYS_PATH); + try { + consumerKeys.load(ps); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + logger.debug("consumer keys: " + consumerKeys); + } else { + logger.error("Unable to get resource " + CONSUMER_KEYS_PATH); + } + // store config + sc.setAttribute(CONSUMERKEYS_KEY, consumerKeys); + } + } else { + logger.error("Unable to get ServletContext!"); + } + } + + public abstract String getVersion(); + + /** + * returns consumer secret for consumer key. returns null if consumer key + * doesn't exist. + * + * @param consumerKey + * @return + */ + public String getConsumerSecret(String consumerKey) { + return consumerKeys.getProperty(consumerKey); + } + + /** + * Hole den vollen Benutzernamen aus dem LDAP + * + * @param creator + * @return + */ + public String getFullNameFromLdap(String creator) { + String retString = creator; // falls nichts gefunden wird einfach den + // creator zurueckgeben + if (ldapServerUrl == null) { + return retString; + } + Hashtable<String, String> env = new Hashtable<String, String>(); + String sp = "com.sun.jndi.ldap.LdapCtxFactory"; + env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, sp); + env.put(javax.naming.Context.PROVIDER_URL, ldapServerUrl); + + DirContext dctx; + try { + dctx = new InitialDirContext(env); + } catch (NamingException e) { + logger.error("Error in getFullNameFromLDAP!", e); + return retString; + } + + String base = "ou=people"; + + SearchControls sc = new SearchControls(); + String[] attributeFilter = { "cn", "mail" }; + sc.setReturningAttributes(attributeFilter); + sc.setSearchScope(SearchControls.SUBTREE_SCOPE); + + String filter = "(uid=" + creator + ")"; + + try { + NamingEnumeration<SearchResult> results = dctx.search(base, filter, sc); + while (results.hasMore()) { + SearchResult sr = (SearchResult) results.next(); + javax.naming.directory.Attributes attrs = sr.getAttributes(); + + Attribute attr = attrs.get("cn"); + retString = (String) attr.get(); + } + } catch (NamingException e) { + logger.error("Error in getFullNameFromLDAP!", e); + } + + try { + dctx.close(); + } catch (NamingException e) { + logger.error("Error in getFullNameFromLDAP!", e); + } + return retString; + } + + /** + * returns resource from path (in webapp) as InputStream. + * + * @param sc + * @param path + * @return + */ + protected InputStream getResourceAsStream(ServletContext sc, String path) { + InputStream ps = sc.getResourceAsStream(path); + if (ps == null) { + // try as file + File pf = new File(sc.getRealPath(path)); + if (pf != null) { + logger.debug("trying file for: " + pf); + try { + ps = new FileInputStream(pf); + } catch (FileNotFoundException e) { + logger.error(e); + } + } + } + return ps; + } + + /** + * get a real file name for a web app file pathname. + * + * If filename starts with "/" its treated as absolute else the path is + * appended to the base directory of the web-app. + * + * @param filename + * @param sc + * @return + */ + public static String getResourcePath(ServletContext sc, String filename) { + File f = new File(filename); + // is the filename absolute? + if (!f.isAbsolute()) { + // relative path -> use getRealPath to resolve in webapp + filename = sc.getRealPath(filename); + } + return filename; + } + + /* + * (non-Javadoc) + * + * @see org.restlet.Application#stop() + */ + @Override + public synchronized void stop() throws Exception { + /* + * trying to clean up databases, not sure if this is the right way... + */ + if (srv != null) { + logger.debug("Stopping DB admin server..."); + srv.stop(); + srv = null; + } + if (graphDb != null) { + logger.debug("Stopping DB..."); + graphDb.shutdown(); + graphDb = null; + } + super.stop(); + } + + private static void registerShutdownHook(final GraphDatabaseService graphDb) { + // Registers a shutdown hook for the Neo4j instance so that it + // shuts down nicely when the VM exits (even if you "Ctrl-C" the + // running example before it's completed) + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + graphDb.shutdown(); + } + }); + } + +}