View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.slc.repo.core;
17  
18  import java.util.List;
19  
20  import javax.jcr.Node;
21  import javax.jcr.RepositoryException;
22  import javax.jcr.Session;
23  import javax.jcr.observation.Event;
24  import javax.jcr.observation.EventIterator;
25  import javax.jcr.observation.EventListener;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.argeo.jcr.JcrUtils;
30  import org.argeo.slc.SlcException;
31  import org.argeo.slc.repo.NodeIndexer;
32  
33  /** Maintains the metadata of a workspace, using listeners */
34  public class WorkspaceIndexer {
35  	private final static Log log = LogFactory.getLog(WorkspaceIndexer.class);
36  
37  	private final Session adminSession;
38  	private IndexingListener artifactListener;
39  	/** order may be important */
40  	private final List<NodeIndexer> nodeIndexers;
41  
42  	public WorkspaceIndexer(Session adminSession, List<NodeIndexer> nodeIndexers) {
43  		this.adminSession = adminSession;
44  		this.nodeIndexers = nodeIndexers;
45  		try {
46  			artifactListener = new IndexingListener();
47  			adminSession
48  					.getWorkspace()
49  					.getObservationManager()
50  					.addEventListener(artifactListener, Event.NODE_ADDED, "/",
51  							true, null, null, true);
52  		} catch (RepositoryException e) {
53  			throw new SlcException("Cannot initialize repository backend", e);
54  		}
55  	}
56  
57  	public void close() {
58  		try {
59  			adminSession.getWorkspace().getObservationManager()
60  					.removeEventListener(artifactListener);
61  		} catch (RepositoryException e) {
62  			log.error("Cannot close workspace indexer "
63  					+ adminSession.getWorkspace().getName(), e);
64  		}
65  	}
66  
67  	class IndexingListener implements EventListener {
68  
69  		public void onEvent(EventIterator events) {
70  			while (events.hasNext()) {
71  				Event event = events.nextEvent();
72  				try {
73  					String newNodePath = event.getPath();
74  					Node newNode = null;
75  					for (NodeIndexer nodeIndexer : nodeIndexers) {
76  						try {
77  							if (nodeIndexer.support(newNodePath)) {
78  								if (newNode == null)
79  									newNode = adminSession.getNode(newNodePath);
80  								nodeIndexer.index(newNode);
81  							}
82  						} catch (RuntimeException e) {
83  							e.printStackTrace();
84  							throw e;
85  						}
86  					}
87  					if (newNode != null)
88  						adminSession.save();
89  				} catch (RepositoryException e) {
90  					throw new SlcException("Cannot process event " + event, e);
91  				} finally {
92  					JcrUtils.discardQuietly(adminSession);
93  				}
94  			}
95  		}
96  	}
97  }