Introduce repo managers
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 11 Mar 2014 14:29:53 +0000 (14:29 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 11 Mar 2014 14:29:53 +0000 (14:29 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@6891 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

16 files changed:
modules/org.argeo.slc.server.repo/META-INF/spring/repo-osgi.xml
modules/org.argeo.slc.server.repo/META-INF/spring/services.xml
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/ArtifactIndexer.java
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/JarFileIndexer.java
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/JavaRepoManager.java [new file with mode: 0644]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoIndexer.java [deleted file]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoNames.java [deleted file]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoTypes.java [deleted file]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RpmIndexer.java
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RpmRepoManager.java [new file with mode: 0644]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/SlcRepoManager.java [new file with mode: 0644]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/AbstractJcrRepoManager.java [new file with mode: 0644]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/JavaRepoManagerImpl.java [new file with mode: 0644]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/RpmRepoManagerImpl.java [new file with mode: 0644]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/SlcRepoManagerImpl.java [new file with mode: 0644]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/WorkspaceIndexer.java [new file with mode: 0644]

index 50a61ec6d1e6b1af9041411587d5e0a1886d9537..ced7e284050cccc2c3dbfe1532bf1b1110daf803 100644 (file)
@@ -37,6 +37,8 @@
                </service-properties>\r
        </service>\r
 \r
+       <service ref="slcRepoManager" interface="org.argeo.slc.repo.SlcRepoManager" />\r
+\r
        <service ref="mavenProxyService" interface="org.argeo.slc.repo.MavenProxyService" />\r
        <service ref="rpmProxyService" interface="org.argeo.slc.rpmfactory.RpmProxyService" />\r
 \r
index 490bf9059fb4333b0d1670770094398d5aa23628..42f077ae380f49e3b48a99ed6e160424a9d0e9bb 100644 (file)
                </property>
        </bean>
 
-       <!-- Maven Proxy -->
-       <bean id="mavenProxyService" class="org.argeo.slc.repo.maven.MavenProxyServiceImpl"
-               init-method="init" destroy-method="destroy" depends-on="ROLE_SLC">
-               <property name="jcrRepository" ref="javaRepository" />
-               <property name="proxyWorkspace" value="${slc.repo.jcr.proxyWorkspace}" />
-               <property name="defaultRepositories" ref="defaultMavenRepositories" />
+       <bean id="slcRepoManager" class="org.argeo.slc.repo.core.SlcRepoManagerImpl"
+               init-method="init" destroy-method="destroy">
+               <property name="javaRepoManager" ref="javaRepoManager" />
        </bean>
 
-       <bean id="mavenProxyIndexer" class="org.argeo.slc.repo.RepoIndexer"
-               init-method="init" destroy-method="destroy">
-               <property name="jcrRepository" ref="javaRepository" />
-               <property name="workspace" value="${slc.repo.jcr.proxyWorkspace}" />
+       <!-- Java -->
+       <bean id="javaRepoManager" class="org.argeo.slc.repo.core.JavaRepoManagerImpl"
+               init-method="init" destroy-method="destroy" depends-on="ROLE_SLC">
                <property name="nodeIndexers">
                        <list>
                                <bean class="org.argeo.slc.repo.ArtifactIndexer" />
                                <bean class="org.argeo.slc.repo.JarFileIndexer" />
                        </list>
                </property>
+               <property name="jcrRepository" ref="javaRepository" />
        </bean>
 
-       <!-- RPM Proxy -->
-       <bean id="rpmProxyService" class="org.argeo.slc.rpmfactory.core.RpmProxyServiceImpl"
+       <bean id="mavenProxyService" class="org.argeo.slc.repo.maven.MavenProxyServiceImpl"
                init-method="init" destroy-method="destroy" depends-on="ROLE_SLC">
-               <property name="jcrRepository" ref="rpmRepository" />
+               <property name="jcrRepository" ref="javaRepository" />
                <property name="proxyWorkspace" value="${slc.repo.jcr.proxyWorkspace}" />
-               <property name="defaultRepositories" ref="defaultRpmRepositories" />
+               <property name="defaultRepositories" ref="defaultMavenRepositories" />
        </bean>
 
-       <bean id="rpmProxyIndexer" class="org.argeo.slc.repo.RepoIndexer"
-               init-method="init" destroy-method="destroy">
-               <property name="jcrRepository" ref="rpmRepository" />
-               <property name="workspace" value="${slc.repo.jcr.proxyWorkspace}" />
+       <!-- RPM -->
+       <bean id="rpmRepoManager" class="org.argeo.slc.repo.core.RpmRepoManagerImpl"
+               init-method="init" destroy-method="destroy" depends-on="ROLE_SLC">
                <property name="nodeIndexers">
                        <list>
                                <bean class="org.argeo.slc.repo.RpmIndexer" />
                        </list>
                </property>
+               <property name="jcrRepository" ref="rpmRepository" />
+       </bean>
+
+       <bean id="rpmProxyService" class="org.argeo.slc.rpmfactory.core.RpmProxyServiceImpl"
+               init-method="init" destroy-method="destroy" depends-on="ROLE_SLC">
+               <property name="jcrRepository" ref="rpmRepository" />
+               <property name="proxyWorkspace" value="${slc.repo.jcr.proxyWorkspace}" />
+               <property name="defaultRepositories" ref="defaultRpmRepositories" />
        </bean>
 </beans>
\ No newline at end of file
index 462739c7d3736274083ba11960cb8ed242003fd3..f62142254bb6a27e7d9cc429804d03fe6ba2ad44 100644 (file)
@@ -34,6 +34,7 @@ import org.sonatype.aether.artifact.Artifact;
  */
 public class ArtifactIndexer implements NodeIndexer {
        private Log log = LogFactory.getLog(ArtifactIndexer.class);
+       private Boolean force = false;
 
        public Boolean support(String path) {
                String relativePath = getRelativePath(path);
@@ -52,9 +53,13 @@ public class ArtifactIndexer implements NodeIndexer {
        public void index(Node fileNode) {
                Artifact artifact = null;
                try {
-                       if(!support(fileNode.getPath()))
+                       if (!support(fileNode.getPath()))
                                return;
-                       
+
+                       // Already indexed
+                       if (!force && fileNode.isNodeType(SlcTypes.SLC_ARTIFACT))
+                               return;
+
                        if (!fileNode.isNodeType(NodeType.NT_FILE))
                                return;
 
@@ -148,4 +153,9 @@ public class ArtifactIndexer implements NodeIndexer {
                String relativePath = nodePath.substring(basePath.length());
                return relativePath;
        }
+
+       public void setForce(Boolean force) {
+               this.force = force;
+       }
+
 }
index d3abf9bad0c52434c9753e8a2fbc00c0914c1bc3..7e41168aa1405500dd1058043a2ed101ab9b8282 100644 (file)
@@ -50,6 +50,7 @@ import org.osgi.framework.Version;
  */
 public class JarFileIndexer implements NodeIndexer, SlcNames {
        private final static Log log = LogFactory.getLog(JarFileIndexer.class);
+       private Boolean force = false;
 
        public Boolean support(String path) {
                return FilenameUtils.getExtension(path).equals("jar");
@@ -62,9 +63,13 @@ public class JarFileIndexer implements NodeIndexer, SlcNames {
                ByteArrayInputStream bi = null;
                Binary manifestBinary = null;
                try {
-                       if(!support(fileNode.getPath()))
+                       if (!support(fileNode.getPath()))
                                return;
-                       
+
+                       // Already indexed
+                       if (!force && fileNode.isNodeType(SlcTypes.SLC_JAR_FILE))
+                               return;
+
                        if (!fileNode.isNodeType(NodeType.NT_FILE))
                                return;
 
@@ -400,4 +405,8 @@ public class JarFileIndexer implements NodeIndexer, SlcNames {
                                        version.getQualifier());
        }
 
+       public void setForce(Boolean force) {
+               this.force = force;
+       }
+
 }
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/JavaRepoManager.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/JavaRepoManager.java
new file mode 100644 (file)
index 0000000..4d7c3ef
--- /dev/null
@@ -0,0 +1,7 @@
+package org.argeo.slc.repo;
+
+/** Java-specific operations */
+public interface JavaRepoManager {
+       public void createWorkspace(String workspaceName);
+
+}
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoIndexer.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoIndexer.java
deleted file mode 100644 (file)
index c189114..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.repo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.observation.Event;
-import javax.jcr.observation.EventIterator;
-import javax.jcr.observation.EventListener;
-
-import org.argeo.jcr.JcrUtils;
-import org.argeo.slc.SlcException;
-
-/** Repository backend, maintain the JCR repository, mainly through listeners */
-public class RepoIndexer {
-
-       private Repository jcrRepository;
-       private String workspace = null;
-
-       // Internal
-       private Session adminSession;
-       private FilesListener artifactListener;
-
-       /** order may be important */
-       private List<NodeIndexer> nodeIndexers = new ArrayList<NodeIndexer>();
-
-       public void init() {
-               try {
-                       adminSession = jcrRepository.login(workspace);
-                       artifactListener = new FilesListener();
-                       adminSession
-                                       .getWorkspace()
-                                       .getObservationManager()
-                                       .addEventListener(artifactListener, Event.NODE_ADDED, "/",
-                                                       true, null, null, true);
-               } catch (RepositoryException e) {
-                       throw new SlcException("Cannot initialize repository backend", e);
-               }
-       }
-
-       public void destroy() {
-               JcrUtils.logoutQuietly(adminSession);
-       }
-
-       public void setJcrRepository(Repository jcrRepository) {
-               this.jcrRepository = jcrRepository;
-       }
-
-       public void setNodeIndexers(List<NodeIndexer> nodeIndexers) {
-               this.nodeIndexers = nodeIndexers;
-       }
-
-       public void setWorkspace(String workspace) {
-               this.workspace = workspace;
-       }
-
-       class FilesListener implements EventListener {
-
-               public void onEvent(EventIterator events) {
-                       while (events.hasNext()) {
-                               Event event = events.nextEvent();
-                               try {
-                                       String newNodePath = event.getPath();
-                                       Node newNode = null;
-                                       for (NodeIndexer nodeIndexer : nodeIndexers) {
-                                               try {
-                                                       if (nodeIndexer.support(newNodePath)) {
-                                                               if (newNode == null)
-                                                                       newNode = adminSession.getNode(newNodePath);
-                                                               nodeIndexer.index(newNode);
-                                                       }
-                                               } catch (RuntimeException e) {
-                                                       e.printStackTrace();
-                                                       throw e;
-                                               }
-                                       }
-                                       if (newNode != null)
-                                               adminSession.save();
-                               } catch (RepositoryException e) {
-                                       throw new SlcException("Cannot process event " + event, e);
-                               } finally {
-                                       JcrUtils.discardQuietly(adminSession);
-                               }
-                       }
-
-               }
-
-       }
-
-}
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoNames.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoNames.java
deleted file mode 100644 (file)
index 14d4486..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.repo;
-
-import org.argeo.slc.jcr.SlcNames;
-
-/**
- * Names used for items (nodes and properties).
- * 
- * @deprecated use {@link SlcNames} instead
- */
-public interface RepoNames extends SlcNames {
-}
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoTypes.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoTypes.java
deleted file mode 100644 (file)
index 9e51d0f..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.argeo.slc.repo;
-
-import org.argeo.slc.jcr.SlcTypes;
-
-/**
- * Node types used programatically.
- * 
- * @deprecated use {@link SlcTypes} instead
- */
-public interface RepoTypes extends SlcTypes {
-}
index a91081d1762447e4a1b22cd53ef6db759baf18f7..57b93b8ec26f365a2df7b3ed7ad41072f9572058 100644 (file)
@@ -9,6 +9,7 @@ import java.nio.channels.Channels;
 
 import javax.jcr.Node;
 import javax.jcr.Property;
+import javax.jcr.nodetype.NodeType;
 
 import org.apache.commons.io.FilenameUtils;
 import org.argeo.slc.SlcException;
@@ -22,6 +23,7 @@ import org.freecompany.redline.header.Header;
 
 /** Indexes an RPM file. */
 public class RpmIndexer implements NodeIndexer, SlcNames {
+       private Boolean force = false;
 
        @Override
        public Boolean support(String path) {
@@ -31,6 +33,16 @@ public class RpmIndexer implements NodeIndexer, SlcNames {
        @Override
        public void index(Node node) {
                try {
+                       if (!support(node.getPath()))
+                               return;
+
+                       // Already indexed
+                       if (!force && node.isNodeType(SlcTypes.SLC_RPM))
+                               return;
+
+                       if (!node.isNodeType(NodeType.NT_FILE))
+                               return;
+
                        InputStream in = node.getNode(Node.JCR_CONTENT)
                                        .getProperty(Property.JCR_DATA).getBinary().getStream();
                        ReadableChannelWrapper channel = new ReadableChannelWrapper(
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RpmRepoManager.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RpmRepoManager.java
new file mode 100644 (file)
index 0000000..7535468
--- /dev/null
@@ -0,0 +1,5 @@
+package org.argeo.slc.repo;
+
+public interface RpmRepoManager {
+
+}
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/SlcRepoManager.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/SlcRepoManager.java
new file mode 100644 (file)
index 0000000..a0ba8e0
--- /dev/null
@@ -0,0 +1,10 @@
+package org.argeo.slc.repo;
+
+/** Coordinator of the various type of repository (Java, RPM, etc.) */
+public interface SlcRepoManager {
+       /** @return null if Java not supported. */
+       public JavaRepoManager getJavaRepoManager();
+
+       /** @return null if RPM not supported. */
+       public RpmRepoManager getRpmRepoManager();
+}
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/AbstractJcrRepoManager.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/AbstractJcrRepoManager.java
new file mode 100644 (file)
index 0000000..7eb57a2
--- /dev/null
@@ -0,0 +1,104 @@
+package org.argeo.slc.repo.core;
+
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcConstants;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.repo.NodeIndexer;
+
+/** Generic operations on a JCR-based repo. */
+abstract class AbstractJcrRepoManager {
+       private final static Log log = LogFactory
+                       .getLog(AbstractJcrRepoManager.class);
+       private String securityWorkspace = "security";
+
+       private Repository jcrRepository;
+       private Session adminSession;
+       private List<NodeIndexer> nodeIndexers;
+
+       // registries
+       private Map<String, Session> workspaceSessions = new TreeMap<String, Session>();
+       private Map<String, WorkspaceIndexer> workspaceIndexers = new TreeMap<String, WorkspaceIndexer>();
+
+       public void init() {
+               try {
+                       adminSession = jcrRepository.login();
+                       String[] workspaceNames = adminSession.getWorkspace()
+                                       .getAccessibleWorkspaceNames();
+                       for (String workspaceName : workspaceNames) {
+                               if (workspaceName.equals(securityWorkspace))
+                                       continue;
+                               if (workspaceName.equals(adminSession.getWorkspace().getName()))
+                                       continue;
+                               workspaceInit(workspaceName);
+                       }
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot initialize repo manager", e);
+               }
+       }
+
+       public void destroy() {
+               for (String key : workspaceIndexers.keySet()) {
+                       workspaceIndexers.get(key).close();
+               }
+
+               for (String key : workspaceSessions.keySet()) {
+                       JcrUtils.logoutQuietly(workspaceSessions.get(key));
+               }
+               JcrUtils.logoutQuietly(adminSession);
+       }
+
+       public void createWorkspace(String workspaceName) {
+               try {
+                       try {
+                               jcrRepository.login(workspaceName);
+                               throw new SlcException("Workspace " + workspaceName
+                                               + " exists already.");
+                       } catch (NoSuchWorkspaceException e) {
+                               // try to create workspace
+                               adminSession.getWorkspace().createWorkspace(workspaceName);
+                               workspaceInit(workspaceName);
+                       }
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot create workspace " + workspaceName,
+                                       e);
+               }
+       }
+
+       protected void workspaceInit(String workspaceName) {
+               try {
+                       Session workspaceAdminSession = jcrRepository.login(workspaceName);
+                       workspaceSessions.put(workspaceName, adminSession);
+                       JcrUtils.addPrivilege(workspaceAdminSession, "/",
+                                       SlcConstants.ROLE_SLC, "jcr:all");
+                       WorkspaceIndexer workspaceIndexer = new WorkspaceIndexer(
+                                       workspaceAdminSession, nodeIndexers);
+                       workspaceIndexers.put(workspaceName, workspaceIndexer);
+               } catch (RepositoryException e) {
+                       log.error("Cannot initialize workspace " + workspaceName, e);
+               }
+       }
+
+       public void setJcrRepository(Repository jcrRepository) {
+               this.jcrRepository = jcrRepository;
+       }
+
+       public void setNodeIndexers(List<NodeIndexer> nodeIndexers) {
+               this.nodeIndexers = nodeIndexers;
+       }
+
+       public void setSecurityWorkspace(String securityWorkspace) {
+               this.securityWorkspace = securityWorkspace;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/JavaRepoManagerImpl.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/JavaRepoManagerImpl.java
new file mode 100644 (file)
index 0000000..dfd0c8a
--- /dev/null
@@ -0,0 +1,8 @@
+package org.argeo.slc.repo.core;
+
+import org.argeo.slc.repo.JavaRepoManager;
+
+/** Java-specific operations */
+public class JavaRepoManagerImpl extends AbstractJcrRepoManager implements
+               JavaRepoManager {
+}
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/RpmRepoManagerImpl.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/RpmRepoManagerImpl.java
new file mode 100644 (file)
index 0000000..6e83523
--- /dev/null
@@ -0,0 +1,8 @@
+package org.argeo.slc.repo.core;
+
+import org.argeo.slc.repo.RpmRepoManager;
+
+/** RPM-specific operations */
+public class RpmRepoManagerImpl extends AbstractJcrRepoManager implements
+               RpmRepoManager {
+}
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/SlcRepoManagerImpl.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/SlcRepoManagerImpl.java
new file mode 100644 (file)
index 0000000..bce6f03
--- /dev/null
@@ -0,0 +1,38 @@
+package org.argeo.slc.repo.core;
+
+import org.argeo.slc.repo.JavaRepoManager;
+import org.argeo.slc.repo.RpmRepoManager;
+import org.argeo.slc.repo.SlcRepoManager;
+
+/** Coordinator of the various repositories. */
+public class SlcRepoManagerImpl implements SlcRepoManager {
+       private JavaRepoManager javaRepoManager;
+       private RpmRepoManager rpmRepoManager;
+
+       public void init() {
+
+       }
+
+       public void destroy() {
+
+       }
+
+       @Override
+       public JavaRepoManager getJavaRepoManager() {
+               return javaRepoManager;
+       }
+
+       public void setJavaRepoManager(JavaRepoManager javaRepoManager) {
+               this.javaRepoManager = javaRepoManager;
+       }
+
+       @Override
+       public RpmRepoManager getRpmRepoManager() {
+               return rpmRepoManager;
+       }
+
+       public void setRpmRepoManager(RpmRepoManager rpmRepoManager) {
+               this.rpmRepoManager = rpmRepoManager;
+       }
+
+}
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/WorkspaceIndexer.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/core/WorkspaceIndexer.java
new file mode 100644 (file)
index 0000000..e5622aa
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.argeo.slc.repo.core;
+
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
+import org.argeo.slc.repo.NodeIndexer;
+
+/** Maintains the metadata of a workspace, using listeners */
+public class WorkspaceIndexer {
+       private final static Log log = LogFactory.getLog(WorkspaceIndexer.class);
+
+       private final Session adminSession;
+       private IndexingListener artifactListener;
+       /** order may be important */
+       private final List<NodeIndexer> nodeIndexers;
+
+       public WorkspaceIndexer(Session adminSession, List<NodeIndexer> nodeIndexers) {
+               this.adminSession = adminSession;
+               this.nodeIndexers = nodeIndexers;
+               try {
+                       artifactListener = new IndexingListener();
+                       adminSession
+                                       .getWorkspace()
+                                       .getObservationManager()
+                                       .addEventListener(artifactListener, Event.NODE_ADDED, "/",
+                                                       true, null, null, true);
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot initialize repository backend", e);
+               }
+       }
+
+       public void close() {
+               try {
+                       adminSession.getWorkspace().getObservationManager()
+                                       .removeEventListener(artifactListener);
+               } catch (RepositoryException e) {
+                       log.error("Cannot close workspace indexer "
+                                       + adminSession.getWorkspace().getName(), e);
+               }
+       }
+
+       class IndexingListener implements EventListener {
+
+               public void onEvent(EventIterator events) {
+                       while (events.hasNext()) {
+                               Event event = events.nextEvent();
+                               try {
+                                       String newNodePath = event.getPath();
+                                       Node newNode = null;
+                                       for (NodeIndexer nodeIndexer : nodeIndexers) {
+                                               try {
+                                                       if (nodeIndexer.support(newNodePath)) {
+                                                               if (newNode == null)
+                                                                       newNode = adminSession.getNode(newNodePath);
+                                                               nodeIndexer.index(newNode);
+                                                       }
+                                               } catch (RuntimeException e) {
+                                                       e.printStackTrace();
+                                                       throw e;
+                                               }
+                                       }
+                                       if (newNode != null)
+                                               adminSession.save();
+                               } catch (RepositoryException e) {
+                                       throw new SlcException("Cannot process event " + event, e);
+                               } finally {
+                                       JcrUtils.discardQuietly(adminSession);
+                               }
+                       }
+               }
+       }
+}