import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.jcr.Item;
+import javax.jcr.LoginException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.PropertyType;
+import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
import org.argeo.ArgeoException;
+import org.argeo.eclipse.ui.TreeParent;
+import org.argeo.jcr.RepositoryRegister;
import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TreeNode;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
private TreeViewer nodesViewer;
private TableViewer propertiesViewer;
- private Session jcrSession;
+ // private Session jcrSession;
+ private RepositoryRegister repositoryRegister;
private Comparator<Item> itemComparator = new Comparator<Item>() {
public int compare(Item o1, Item o2) {
}
}
});
- try {
- nodesViewer.setInput(jcrSession.getRootNode());
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot initialize view", e);
- }
+ nodesViewer.addDoubleClickListener(new IDoubleClickListener() {
+ public void doubleClick(DoubleClickEvent event) {
+ Object obj = ((IStructuredSelection) event.getSelection())
+ .getFirstElement();
+ if (obj instanceof RepositoryNode) {
+ ((RepositoryNode) obj).login();
+ } else if (obj instanceof WorkspaceNode) {
+ ((WorkspaceNode) obj).login();
+ }
+
+ }
+ });
+ nodesViewer.setInput(repositoryRegister);
Composite bottom = new Composite(sashForm, SWT.NONE);
bottom.setLayout(new GridLayout(1, false));
return new int[] { 70, 30 };
}
- public void setJcrSession(Session jcrSession) {
- this.jcrSession = jcrSession;
+ public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
+ this.repositoryRegister = repositoryRegister;
}
/*
* NODES
*/
+ protected Object[] childrenNodes(Node parentNode) {
+ try {
+ List<Node> children = new ArrayList<Node>();
+ NodeIterator nit = parentNode.getNodes();
+ while (nit.hasNext()) {
+ Node node = nit.nextNode();
+ children.add(node);
+ }
+ Node[] arr = children.toArray(new Node[children.size()]);
+ Arrays.sort(arr, itemComparator);
+ return arr;
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot list children of " + parentNode, e);
+ }
+ }
+
private class NodeContentProvider implements ITreeContentProvider {
public Object[] getElements(Object inputElement) {
}
public Object[] getChildren(Object parentElement) {
- try {
- if (parentElement instanceof Node) {
- List<Node> children = new ArrayList<Node>();
- NodeIterator nit = ((Node) parentElement).getNodes();
- while (nit.hasNext()) {
- Node node = nit.nextNode();
- children.add(node);
- }
- Node[] arr = children.toArray(new Node[children.size()]);
- Arrays.sort(arr, itemComparator);
- return arr;
- } else {
- return null;
+ if (parentElement instanceof Node) {
+ return childrenNodes((Node) parentElement);
+ } else if (parentElement instanceof RepositoryNode) {
+ return ((RepositoryNode) parentElement).getChildren();
+ } else if (parentElement instanceof WorkspaceNode) {
+ Session session = ((WorkspaceNode) parentElement).getSession();
+ if (session == null)
+ return new Object[0];
+
+ try {
+ return childrenNodes(session.getRootNode());
+ } catch (RepositoryException e) {
+ throw new ArgeoException("Cannot retrieve root node of "
+ + session, e);
}
- } catch (RepositoryException e) {
- throw new ArgeoException("Cannot retrieve children for "
- + parentElement, e);
+ } else if (parentElement instanceof RepositoryRegister) {
+ RepositoryRegister repositoryRegister = (RepositoryRegister) parentElement;
+ List<RepositoryNode> nodes = new ArrayList<RepositoryNode>();
+ Map<String, Repository> repositories = repositoryRegister
+ .getRepositories();
+ for (String name : repositories.keySet()) {
+ nodes.add(new RepositoryNode(name, repositories.get(name)));
+ }
+ return nodes.toArray();
+ } else {
+ return new Object[0];
}
}
try {
if (element instanceof Node) {
return ((Node) element).hasNodes();
+ } else if (element instanceof RepositoryNode) {
+ return ((RepositoryNode) element).hasChildren();
+ } else if (element instanceof WorkspaceNode) {
+ return ((WorkspaceNode) element).getSession() != null;
}
return false;
} catch (RepositoryException e) {
}
}
+
+ private class RepositoryNode extends TreeParent {
+ private final String name;
+ private final Repository repository;
+ private Session defaultSession = null;
+
+ public RepositoryNode(String name, Repository repository) {
+ super(name);
+ this.name = name;
+ this.repository = repository;
+ }
+
+ public Repository getRepository() {
+ return repository;
+ }
+
+ public Session getDefaultSession() {
+ return defaultSession;
+ }
+
+ public void login() {
+ try {
+ defaultSession = repository.login();
+ String[] wkpNames = defaultSession.getWorkspace()
+ .getAccessibleWorkspaceNames();
+ for (String wkpName : wkpNames) {
+ if (wkpName.equals(defaultSession.getWorkspace().getName()))
+ addChild(new WorkspaceNode(repository, wkpName,
+ defaultSession));
+ else
+ addChild(new WorkspaceNode(repository, wkpName));
+ }
+ nodesViewer.refresh(this);
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Cannot connect to repository " + name, e);
+ }
+ }
+ }
+
+ private class WorkspaceNode extends TreeParent {
+ private final String name;
+ private final Repository repository;
+ private Session session = null;
+
+ public WorkspaceNode(Repository repository, String name) {
+ this(repository, name, null);
+ }
+
+ public WorkspaceNode(Repository repository, String name, Session session) {
+ super(name);
+ this.name = name;
+ this.repository = repository;
+ this.session = session;
+ }
+
+ public Session getSession() {
+ return session;
+ }
+
+ public void login() {
+ try {
+ if (session != null)
+ session.logout();
+
+ session = repository.login(name);
+ nodesViewer.refresh(this);
+ } catch (RepositoryException e) {
+ throw new ArgeoException(
+ "Cannot connect to repository " + name, e);
+ }
+ }
+
+ }
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.argeo.server.jackrabbit.webapp</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+#Tue Feb 22 17:15:24 CET 2011
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Webapp
+Bundle-SymbolicName: org.argeo.server.jackrabbit.webapp
+Bundle-Version: 1.0.0.qualifier
+Web-ContextPath: jcr
+Bundle-Vendor: Argeo
+Import-Package: javax.jcr,
+ javax.servlet,
+ javax.servlet.http,
+ javax.servlet.resources,
+ org.argeo.jcr,
+ org.argeo.server.jackrabbit.webdav,
+ org.springframework.osgi.web.context.support;version="1.2.1",
+ org.springframework.security;version="2.0.6.RELEASE",
+ org.springframework.security.ui.webapp;version="2.0.6.RELEASE",
+ org.springframework.web.context;version="2.5.6.SEC01",
+ org.springframework.web.filter;version="2.5.6.SEC01",
+ org.springframework.web.servlet.handler;version="2.5.6.SEC01"
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
+ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+ <import resource="osgi.xml" />
+ <import resource="security.xml" />
+
+ <bean id="repositoryRegister" class="org.argeo.jcr.DefaultRepositoryRegister" />
+
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<beans:beans xmlns="http://www.springframework.org/schema/osgi"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"\r
+ xmlns:security="http://www.springframework.org/schema/security"\r
+ xsi:schemaLocation="http://www.springframework.org/schema/osgi \r
+ http://www.springframework.org/schema/osgi/spring-osgi-1.1.xsd\r
+ http://www.springframework.org/schema/beans \r
+ http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
+ http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">\r
+\r
+ <set id="repositories" interface="javax.jcr.Repository" cardinality="0..N">\r
+ <listener ref="repositoryRegister" bind-method="register"\r
+ unbind-method="unregister" />\r
+ </set>\r
+\r
+ <reference id="_authenticationManager"\r
+ interface="org.springframework.security.AuthenticationManager" />\r
+</beans:beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
+ xmlns:tx="http://www.springframework.org/schema/tx"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
+ http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+ <bean
+ class="org.springframework.web.servlet.handler.SimpleServletPostProcessor" />
+
+ <bean id="servletHandler"
+ class="org.springframework.web.servlet.handler.SimpleServletHandlerAdapter" />
+
+ <bean id="urlMapping"
+ class="org.argeo.server.jackrabbit.webdav.MultipleRepositoryHandlerMapping">
+ <property name="repositoryRegister" ref="repositoryRegister" />
+ </bean>
+
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:security="http://www.springframework.org/schema/security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
+
+ <security:http>
+ <security:http-basic />
+ <security:intercept-url pattern="/**"
+ access="ROLE_USER,ROLE_ADMIN,ROLE_ANONYMOUS" />
+ </security:http>
+</beans>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ version="2.5">
+
+ <display-name>Argeo Jackrabbit Webapp</display-name>
+
+ <!-- General -->
+ <context-param>
+ <param-name>contextConfigLocation</param-name>
+ <param-value>/WEB-INF/applicationContext.xml</param-value>
+ </context-param>
+
+ <listener>
+ <display-name>Spring Context</display-name>
+ <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+ </listener>
+ <context-param>
+ <param-name>contextClass</param-name>
+ <param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
+ </context-param>
+
+ <!-- Remoting -->
+ <servlet>
+ <servlet-name>remoting</servlet-name>
+ <servlet-class>org.argeo.server.jackrabbit.webdav.ExtendedDispatcherServlet</servlet-class>
+ <init-param>
+ <param-name>contextClass</param-name>
+ <param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value>
+ </init-param>
+ <init-param>
+ <param-name>dispatchOptionsRequest</param-name>
+ <param-value>true</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>remoting</servlet-name>
+ <url-pattern>/remoting/*</url-pattern>
+ </servlet-mapping>
+
+ <!-- Security -->
+ <filter>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+ </filter>
+
+ <filter-mapping>
+ <filter-name>springSecurityFilterChain</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+</web-app>
--- /dev/null
+bin.includes = META-INF/
/** Namespaces to register: key is prefix, value namespace */
private Map<String, String> namespaces = new HashMap<String, String>();
+ private Boolean autocreateWorkspaces = false;
+
public void afterPropertiesSet() throws Exception {
// Load cnds as resources
for (String resUrl : cndFiles) {
try {
session = repository.login(credentials, workspaceName);
} catch (NoSuchWorkspaceException e) {
- session = createWorkspaceAndLogsIn(credentials, workspaceName);
+ if (autocreateWorkspaces)
+ session = createWorkspaceAndLogsIn(credentials, workspaceName);
+ else
+ throw e;
}
processNewSession(session);
return session;
try {
session = repository.login(workspaceName);
} catch (NoSuchWorkspaceException e) {
- session = createWorkspaceAndLogsIn(null, workspaceName);
+ if (autocreateWorkspaces)
+ session = createWorkspaceAndLogsIn(null, workspaceName);
+ else
+ throw e;
}
processNewSession(session);
return session;
--- /dev/null
+package org.argeo.server.jackrabbit.webdav;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.jcr.LoginException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.server.SessionProvider;
+
+public class CachingSessionProvider implements SessionProvider {
+ private static final String JCR_SESSIONS_ATTRIBUTE = "jcrSessions";
+
+ private final static Log log = LogFactory
+ .getLog(CachingSessionProvider.class);
+
+ @SuppressWarnings("unchecked")
+ public Session getSession(HttpServletRequest request, Repository rep,
+ String workspace) throws LoginException, ServletException,
+ RepositoryException {
+ HttpSession httpSession = request.getSession();
+
+ if (httpSession.getAttribute(JCR_SESSIONS_ATTRIBUTE) == null) {
+ httpSession
+ .setAttribute(JCR_SESSIONS_ATTRIBUTE, Collections
+ .synchronizedMap(new HashMap<String, Session>()));
+ }
+ Map<String, Session> sessions = (Map<String, Session>) httpSession
+ .getAttribute(JCR_SESSIONS_ATTRIBUTE);
+ if (!sessions.containsKey(workspace)) {
+ Session session = rep.login(workspace);
+ sessions.put(workspace, session);
+ return session;
+ } else {
+ Session session = sessions.get(workspace);
+ if (!session.isLive()) {
+ session = rep.login(workspace);
+ }
+ return session;
+ }
+ }
+
+ public void releaseSession(Session session) {
+ if (log.isDebugEnabled())
+ log.debug("Releasing JCR session " + session);
+ session.logout();
+ }
+
+}
import org.springframework.web.servlet.DispatcherServlet;
public class ExtendedDispatcherServlet extends DispatcherServlet {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = -5584673209855752009L;
private final static Log log = LogFactory
.getLog(ExtendedDispatcherServlet.class);
--- /dev/null
+package org.argeo.server.jackrabbit.webdav;
+
+import java.util.Enumeration;
+
+import javax.jcr.Repository;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+import org.apache.jackrabbit.server.SessionProvider;
+import org.springframework.web.servlet.mvc.ServletWrappingController;
+
+public class JcrRemotingServlet extends
+ org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet {
+
+ private static final long serialVersionUID = 3131835511468341309L;
+
+ private final Repository repository;
+
+ public JcrRemotingServlet(Repository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ protected Repository getRepository() {
+ return repository;
+ }
+
+ @Override
+ protected SessionProvider getSessionProvider() {
+ return new CachingSessionProvider();
+ }
+
+}
--- /dev/null
+package org.argeo.server.jackrabbit.webdav;
+
+import java.util.Enumeration;
+import java.util.Properties;
+
+import javax.jcr.Repository;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.webdav.jcr.JCRWebdavServerServlet;
+import org.argeo.jcr.RepositoryRegister;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.web.context.ServletContextAware;
+import org.springframework.web.servlet.HandlerExecutionChain;
+import org.springframework.web.servlet.HandlerMapping;
+import org.springframework.web.servlet.mvc.ServletWrappingController;
+
+public class MultipleRepositoryHandlerMapping implements HandlerMapping,
+ ApplicationContextAware, ServletContextAware {
+ private final static Log log = LogFactory
+ .getLog(MultipleRepositoryHandlerMapping.class);
+
+ private ConfigurableApplicationContext applicationContext;
+ private ServletContext servletContext;
+
+ private RepositoryRegister repositoryRegister;
+
+ public HandlerExecutionChain getHandler(HttpServletRequest request)
+ throws Exception {
+ log.debug(request);
+ log.debug("getContextPath=" + request.getContextPath());
+ log.debug("getServletPath=" + request.getServletPath());
+ log.debug("getPathInfo=" + request.getPathInfo());
+
+ String repositoryName = "repo";
+ String pathPrefix = "/remoting/repo";
+ String beanName = "remoting_" + repositoryName;
+
+ if (!applicationContext.containsBean(beanName)) {
+ Repository repository = repositoryRegister.getRepositories().get(
+ repositoryName);
+ JcrRemotingServlet jcrRemotingServlet = new JcrRemotingServlet(
+ repository);
+ Properties initParameters = new Properties();
+ initParameters.setProperty(
+ JCRWebdavServerServlet.INIT_PARAM_RESOURCE_PATH_PREFIX,
+ pathPrefix);
+ jcrRemotingServlet.init(new DelegatingServletConfig(beanName,
+ initParameters));
+ applicationContext.getBeanFactory().registerSingleton(beanName,
+ jcrRemotingServlet);
+ }
+ HttpServlet remotingServlet = (HttpServlet) applicationContext
+ .getBean(beanName);
+ return new HandlerExecutionChain(remotingServlet);
+ }
+
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ this.applicationContext = (ConfigurableApplicationContext) applicationContext;
+ }
+
+ public void setServletContext(ServletContext servletContext) {
+ this.servletContext = servletContext;
+ }
+
+ public void setRepositoryRegister(RepositoryRegister repositoryRegister) {
+ this.repositoryRegister = repositoryRegister;
+ }
+
+ private class DelegatingServletConfig implements ServletConfig {
+ private String name;
+ private Properties initParameters;
+
+ public DelegatingServletConfig(String name, Properties initParameters) {
+ super();
+ this.name = name;
+ this.initParameters = initParameters;
+ }
+
+ public String getServletName() {
+ return name;
+ }
+
+ public ServletContext getServletContext() {
+ return servletContext;
+ }
+
+ public String getInitParameter(String paramName) {
+ return initParameters.getProperty(paramName);
+ }
+
+ public Enumeration getInitParameterNames() {
+ return initParameters.keys();
+ }
+ }
+
+}
output.. = target/classes/
bin.includes = META-INF/,\
.
-additional.bundles = org.argeo.server.jackrabbit,\
- com.springsource.slf4j.api,\
+additional.bundles = com.springsource.slf4j.api,\
com.springsource.slf4j.log4j,\
com.springsource.org.apache.log4j,\
com.springsource.org.apache.commons.collections,\
<groupId>org.springframework.ws</groupId>
<artifactId>org.springframework.xml</artifactId>
</dependency>
+
+ <!-- OSGi -->
+ <dependency>
+ <groupId>org.eclipse.osgi</groupId>
+ <artifactId>org.eclipse.osgi</artifactId>
+ <scope>provided</scope>
+ </dependency>
<!-- Logging -->
<dependency>
--- /dev/null
+package org.argeo.jcr;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Observable;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class DefaultRepositoryRegister extends Observable implements
+ RepositoryRegister {
+ private final static Log log = LogFactory
+ .getLog(DefaultRepositoryRegister.class);
+
+ private SortedMap<String, Repository> repositories = Collections
+ .synchronizedSortedMap(new TreeMap<String, Repository>());
+
+ @SuppressWarnings("rawtypes")
+ public synchronized Repository getRepository(Map parameters)
+ throws RepositoryException {
+ if (!parameters.containsKey(JCR_REPOSITORY_NAME))
+ throw new RepositoryException("Parameter " + JCR_REPOSITORY_NAME
+ + " has to be defined.");
+ String name = parameters.get(JCR_REPOSITORY_NAME).toString();
+ if (!repositories.containsKey(name))
+ throw new RepositoryException("No repository registered with name "
+ + name);
+
+ return repositories.get(name);
+ }
+
+ public Map<String, Repository> getRepositories() {
+ return new TreeMap<String, Repository>(repositories);
+ }
+
+ /** Registers a service, typically called when OSGi services are bound. */
+ @SuppressWarnings("rawtypes")
+ public synchronized void register(Repository repository, Map properties) {
+ // TODO: also check bean name?
+ if (properties == null || !properties.containsKey(JCR_REPOSITORY_NAME)) {
+ log.warn("Cannot register a repository without property "
+ + JCR_REPOSITORY_NAME);
+ return;
+ }
+
+ String name = properties.get(JCR_REPOSITORY_NAME).toString();
+ repositories.put(name, repository);
+ setChanged();
+ notifyObservers(repository);
+ }
+
+ /** Unregisters a service, typically called when OSGi services are unbound. */
+ @SuppressWarnings("rawtypes")
+ public synchronized void unregister(Repository repository, Map properties) {
+ // TODO: also check bean name?
+ if (properties == null || !properties.containsKey(JCR_REPOSITORY_NAME)) {
+ log.warn("Cannot unregister a repository without property "
+ + JCR_REPOSITORY_NAME);
+ return;
+ }
+
+ String name = properties.get(JCR_REPOSITORY_NAME).toString();
+ repositories.remove(name);
+ setChanged();
+ notifyObservers(repository);
+ }
+}
--- /dev/null
+package org.argeo.jcr;
+
+import java.util.Map;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryFactory;
+
+/** Allows to register repositories by name. */
+public interface RepositoryRegister extends RepositoryFactory{
+ public final static String JCR_REPOSITORY_NAME = "argeo.jcr.repository.name";
+
+ public Map<String,Repository> getRepositories();
+}