package org.openntf.domino.rest.service; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.openntf.domino.AutoMime; import org.openntf.domino.ext.Session.Fixes; import org.openntf.domino.graph2.impl.DFramedTransactionalGraph; import org.openntf.domino.rest.resources.command.CommandResource; import org.openntf.domino.rest.resources.frames.FramedCollectionResource; import org.openntf.domino.rest.resources.frames.FramedResource; import org.openntf.domino.utils.Factory; import org.openntf.domino.utils.Factory.SessionType; import org.openntf.domino.utils.Factory.ThreadConfig; import org.openntf.domino.xsp.ODAPlatform; import org.openntf.domino.xsp.session.DasCurrentSessionFactory; import com.ibm.domino.das.service.IRestServiceExt; import com.ibm.domino.das.service.RestService; import com.tinkerpop.frames.FramedGraph; public class ODAGraphService extends RestService implements IRestServiceExt { private Map<String, FramedGraph<?>> graphMap_; private Map<String, IGraphFactory> factoryMap_; public ODAGraphService() { init(); } protected void initDynamicGraphs() { // Get a list of all registered extensions IExtension extensions[] = null; final IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry(); if (extensionRegistry != null) { final IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint("org.openntf.domino.rest.graph"); // $NON-NLS-1$ if (extensionPoint != null) { extensions = extensionPoint.getExtensions(); } } if (extensions == null) { return; } // Walk through each extension in the list for (final IExtension extension : extensions) { final IConfigurationElement configElements[] = extension.getConfigurationElements(); if (configElements == null) { continue; } for (final IConfigurationElement configElement : configElements) { try { beforeDoService(null); // We only handle serviceResources elements for now if (!("serviceResources".equalsIgnoreCase(configElement.getName()))) { // $NON-NLS-1$ continue; } final Object object = configElement.createExecutableExtension("class"); // $NON-NLS-1$ if (!(object instanceof IGraphFactory)) { // Class was constructed but it is the wrong type continue; } // System.out.println("Found an extension point instance: " // + object.getClass().getName()); IGraphFactory factory = (IGraphFactory) object; Map<String, FramedGraph<?>> registry = factory.getRegisteredGraphs(); for (String key : registry.keySet()) { FramedGraph<?> graph = registry.get(key); // System.out.println("Adding graph called " + key); addGraph(key, graph); addFactory(key, factory); } } catch (final CoreException e) { e.printStackTrace(); } finally { afterDoService(null); } } } } @Override public Set<Class<?>> getClasses() { Set<Class<?>> supers = super.getClasses(); Set<Class<?>> result = new HashSet<Class<?>>(supers); return result; } @Override public Set<Object> getSingletons() { Set<Object> supers = super.getSingletons(); Set<Object> result = new HashSet<Object>(supers); // TODO NTF commented out resources are ones that aren't yet // implemented. // existing classes are just stubs to be filled out later. // result.add(new DataResource(this)); // result.add(new DataCollectionResource(this)); // result.add(new ViewResource(this)); // result.add(new ViewCollectionResource(this)); // result.add(new DocumentResource(this)); // result.add(new DocumentCollectionResource(this)); result.add(new FramedResource(this)); result.add(new FramedCollectionResource(this)); // result.add(new VertexFrameResource(this)); // result.add(new VertexFrameCollectionResource(this)); // result.add(new EdgeFrameResource(this)); // result.add(new EdgeFrameCollectionResource(this)); // result.add(new GraphResource(this)); // result.add(new GraphCollectionResource(this)); // result.add(new EdgeResource(this)); // result.add(new EdgeCollectionResource(this)); // result.add(new VertexResource(this)); // result.add(new VertexCollectionResource(this)); result.add(new CommandResource(this)); return result; } protected Map<String, FramedGraph<?>> getGraphMap() { if (graphMap_ == null) { graphMap_ = new HashMap<String, FramedGraph<?>>(); } return graphMap_; } protected Map<String, IGraphFactory> getFactoryMap() { if (factoryMap_ == null) { factoryMap_ = new HashMap<String, IGraphFactory>(); } return factoryMap_; } public void addFactory(final String name, final IGraphFactory factory) { getFactoryMap().put(name, factory); } public IGraphFactory getFactory(final String name) { return getFactoryMap().get(name); } @SuppressWarnings("rawtypes") public DFramedTransactionalGraph getGraph(final String name) { return (DFramedTransactionalGraph) getGraphMap().get(name); } public void addGraph(final String name, final FramedGraph<?> graph) { getGraphMap().put(name, graph); } public FramedGraph<?> removeGraph(final String name) { return getGraphMap().remove(name); } public void init() { try { ODAPlatform.start(); initDynamicGraphs(); } catch (Throwable t) { t.printStackTrace(); } } @Override public void destroy() { ODAPlatform.stop(); } protected ThreadConfig getDataServiceConfig() { Fixes[] fixes = Fixes.values(); AutoMime autoMime = AutoMime.WRAP_32K; boolean bubbleExceptions = false; return new ThreadConfig(fixes, autoMime, bubbleExceptions); } @Override public boolean beforeDoService(final HttpServletRequest request) { Factory.initThread(getDataServiceConfig()); Factory.setSessionFactory(new DasCurrentSessionFactory(request), SessionType.CURRENT); return true; } @Override public void afterDoService(final HttpServletRequest request) { Factory.termThread(); } @Override public void onUnknownError(final HttpServletRequest request, final Throwable t) { Factory.termThread(); t.printStackTrace(); } }