This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-mongodb.git
commit de303c8c6788b27e70e33f6967b820c99f38b88c Author: Carsten Ziegeler <[email protected]> AuthorDate: Tue Oct 2 09:33:35 2012 +0000 Send notification events for changes git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1392811 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 6 +- .../apache/sling/mongodb/impl/MongoDBContext.java | 82 ++++++++++++++-------- .../mongodb/impl/MongoDBResourceProvider.java | 68 +++++++++--------- .../impl/MongoDBResourceProviderFactory.java | 30 ++++++-- 4 files changed, 117 insertions(+), 69 deletions(-) diff --git a/pom.xml b/pom.xml index f73379a..b491fbb 100644 --- a/pom.xml +++ b/pom.xml @@ -76,10 +76,14 @@ <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> - <version>2.8.0</version> + <version>2.9.1</version> <scope>provided</scope> </dependency> <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + </dependency> + <dependency> <groupId>org.apache.felix</groupId> <artifactId>org.apache.felix.scr.annotations</artifactId> </dependency> diff --git a/src/main/java/org/apache/sling/mongodb/impl/MongoDBContext.java b/src/main/java/org/apache/sling/mongodb/impl/MongoDBContext.java index c801e8b..b1dc3fa 100644 --- a/src/main/java/org/apache/sling/mongodb/impl/MongoDBContext.java +++ b/src/main/java/org/apache/sling/mongodb/impl/MongoDBContext.java @@ -16,20 +16,24 @@ */ package org.apache.sling.mongodb.impl; -import java.util.ArrayList; +import java.util.Dictionary; import java.util.HashSet; -import java.util.List; +import java.util.Hashtable; import java.util.Set; +import org.apache.sling.api.SlingConstants; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventAdmin; + import com.mongodb.DB; public class MongoDBContext { /** The roots. */ - private final String[] roots; + private final String root; /** The roots ended by a slash. */ - private final String[] rootsWithSlash; + private final String rootWithSlash; /** Don't show these collections. */ private final Set<String> filterCollectionNames = new HashSet<String>(); @@ -37,46 +41,45 @@ public class MongoDBContext { /** The database to be used. */ private final DB database; + private final EventAdmin eventAdmin; + public MongoDBContext(final DB database, - final String[] configuredRoots, - final String[] configuredFilterCollectionNames) { + final String configuredRoot, + final String[] configuredFilterCollectionNames, + final EventAdmin eventAdmin) { this.database = database; - if ( configuredRoots != null ) { - final List<String> rootsList = new ArrayList<String>(); - final List<String> rootsWithSlashList = new ArrayList<String>(); - for(final String r : configuredRoots) { - if ( r != null ) { - final String value = r.trim(); - if ( value.length() > 0 ) { - if ( value.endsWith("/") ) { - rootsWithSlashList.add(value); - rootsList.add(value.substring(0, value.length() - 1)); - } else { - rootsWithSlashList.add(value + "/"); - rootsList.add(value); - } - } + if ( configuredRoot != null ) { + final String value = configuredRoot.trim(); + if ( value.length() > 0 ) { + if ( value.endsWith("/") ) { + this.rootWithSlash = configuredRoot; + this.root = configuredRoot.substring(0, configuredRoot.length() - 1); + } else { + this.rootWithSlash = configuredRoot + "/"; + this.root = configuredRoot; } + } else { + this.root = ""; + this.rootWithSlash = "/"; } - this.roots = rootsList.toArray(new String[rootsList.size()]); - this.rootsWithSlash = rootsWithSlashList.toArray(new String[rootsWithSlashList.size()]); } else { - this.roots = new String[0]; - this.rootsWithSlash = new String[0]; + this.root = ""; + this.rootWithSlash = "/"; } if ( configuredFilterCollectionNames != null ) { for(final String name : configuredFilterCollectionNames) { this.filterCollectionNames.add(name); } } + this.eventAdmin = eventAdmin; } - public String[] getRoots() { - return roots; + public String getRoot() { + return root; } - public String[] getRootsWithSlash() { - return this.rootsWithSlash; + public String getRootWithSlash() { + return this.rootWithSlash; } public boolean isFilterCollectionName(final String name) { @@ -90,4 +93,25 @@ public class MongoDBContext { public DB getDatabase() { return this.database; } + + public void notifyRemoved(final String[] info) { + final Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(SlingConstants.PROPERTY_PATH, this.rootWithSlash + info[0] + '/' + info[1]); + final Event event = new Event(SlingConstants.TOPIC_RESOURCE_REMOVED, props); + this.eventAdmin.postEvent(event); + } + + public void notifyAddeed(final String[] info) { + final Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(SlingConstants.PROPERTY_PATH, this.rootWithSlash + info[0] + '/' + info[1]); + final Event event = new Event(SlingConstants.TOPIC_RESOURCE_ADDED, props); + this.eventAdmin.postEvent(event); + } + + public void notifyUpdated(final String[] info) { + final Dictionary<String, Object> props = new Hashtable<String, Object>(); + props.put(SlingConstants.PROPERTY_PATH, this.rootWithSlash + info[0] + '/' + info[1]); + final Event event = new Event(SlingConstants.TOPIC_RESOURCE_CHANGED, props); + this.eventAdmin.postEvent(event); + } } diff --git a/src/main/java/org/apache/sling/mongodb/impl/MongoDBResourceProvider.java b/src/main/java/org/apache/sling/mongodb/impl/MongoDBResourceProvider.java index 49356b5..b362e16 100644 --- a/src/main/java/org/apache/sling/mongodb/impl/MongoDBResourceProvider.java +++ b/src/main/java/org/apache/sling/mongodb/impl/MongoDBResourceProvider.java @@ -86,7 +86,7 @@ public class MongoDBResourceProvider implements ResourceProvider, ModifyingResou * @see org.apache.sling.api.resource.ModifyingResourceProvider#create(org.apache.sling.api.resource.ResourceResolver, java.lang.String, java.util.Map) */ public Resource create(final ResourceResolver resolver, final String path, final Map<String, Object> properties) - throws PersistenceException { + throws PersistenceException { final String[] info = this.extractResourceInfo(path); if ( info != null && info.length == 2) { final boolean deleted = this.deletedResources.remove(path); @@ -122,7 +122,7 @@ public class MongoDBResourceProvider implements ResourceProvider, ModifyingResou * @see org.apache.sling.api.resource.ModifyingResourceProvider#delete(org.apache.sling.api.resource.ResourceResolver, java.lang.String) */ public void delete(final ResourceResolver resolver, final String path) - throws PersistenceException { + throws PersistenceException { final String[] info = this.extractResourceInfo(path); if ( info != null ) { boolean deletedResource = false; @@ -183,20 +183,26 @@ public class MongoDBResourceProvider implements ResourceProvider, ModifyingResou // check if the collection still exists final DBCollection col = this.getCollection(info[0]); if ( col != null ) { - col.findAndRemove(QueryBuilder.start(PROP_PATH).is(info[1]).get()); + if ( col.findAndRemove(QueryBuilder.start(PROP_PATH).is(info[1]).get()) != null ) { + this.context.notifyRemoved(info); + } } } for(final MongoDBResource changed : this.changedResources.values()) { final DBCollection col = this.context.getDatabase().getCollection(changed.getCollection()); if ( col != null ) { + final String[] info = new String[] {changed.getCollection(), + changed.getProperties().get(PROP_PATH).toString()}; // create or update? if ( changed.getProperties().get(PROP_ID) != null ) { col.update(QueryBuilder.start(PROP_PATH).is(changed.getProperties().get(PROP_PATH)).get(), - changed.getProperties()); + changed.getProperties()); + this.context.notifyUpdated(info); } else { // create col.save(changed.getProperties()); + this.context.notifyUpdated(info); } } else { throw new PersistenceException("Unable to create collection " + changed.getCollection(), null, changed.getPath(), null); @@ -279,7 +285,7 @@ public class MongoDBResourceProvider implements ResourceProvider, ModifyingResou final DBObject query = QueryBuilder.start(PROP_PATH).regex(Pattern.compile(pattern)).get(); final DBCursor cur = col.find(query). - sort(BasicDBObjectBuilder.start(PROP_PATH, 1).get()); + sort(BasicDBObjectBuilder.start(PROP_PATH, 1).get()); return new Iterator<Resource>() { public boolean hasNext() { @@ -297,10 +303,10 @@ public class MongoDBResourceProvider implements ResourceProvider, ModifyingResou name = objPath.substring(lastSlash + 1); } return new MongoDBResource(parent.getResourceResolver(), - parent.getPath() + '/' + name, - info[0], - obj, - MongoDBResourceProvider.this); + parent.getPath() + '/' + name, + info[0], + obj, + MongoDBResourceProvider.this); } public void remove() { @@ -318,8 +324,8 @@ public class MongoDBResourceProvider implements ResourceProvider, ModifyingResou */ @SuppressWarnings("javadoc") public Resource getResource(final ResourceResolver resourceResolver, - final HttpServletRequest request, - final String path) { + final HttpServletRequest request, + final String path) { return this.getResource(resourceResolver, path); } @@ -327,27 +333,25 @@ public class MongoDBResourceProvider implements ResourceProvider, ModifyingResou * Extract info about collection and path */ private String[] extractResourceInfo(final String path) { - for(final String root : this.context.getRootsWithSlash()) { - if ( path.startsWith(root) ) { - if ( path.length() == root.length() ) { - // special resource - show all collections - return new String[0]; - } - final String info = path.substring(root.length()); - final int slashPos = info.indexOf('/'); - if ( slashPos != -1 ) { - return new String[] {info.substring(0, slashPos), info.substring(slashPos + 1)}; - } - // special resource - collection - return new String[] {info}; - } - } - for(final String root : this.context.getRoots()) { - if ( path.equals(root) ) { + if ( path.startsWith(this.context.getRootWithSlash()) ) { + if ( path.length() == this.context.getRootWithSlash().length() ) { // special resource - show all collections return new String[0]; } + final String info = path.substring(this.context.getRootWithSlash().length()); + final int slashPos = info.indexOf('/'); + if ( slashPos != -1 ) { + return new String[] {info.substring(0, slashPos), info.substring(slashPos + 1)}; + } + // special resource - collection + return new String[] {info}; + } + + if ( path.equals(this.context.getRoot()) ) { + // special resource - show all collections + return new String[0]; } + return null; } @@ -390,10 +394,10 @@ public class MongoDBResourceProvider implements ResourceProvider, ModifyingResou logger.debug("Found {}", obj); if ( obj != null ) { return new MongoDBResource(resourceResolver, - path, - info[0], - obj, - this); + path, + info[0], + obj, + this); } } diff --git a/src/main/java/org/apache/sling/mongodb/impl/MongoDBResourceProviderFactory.java b/src/main/java/org/apache/sling/mongodb/impl/MongoDBResourceProviderFactory.java index a632215..5eaeca0 100644 --- a/src/main/java/org/apache/sling/mongodb/impl/MongoDBResourceProviderFactory.java +++ b/src/main/java/org/apache/sling/mongodb/impl/MongoDBResourceProviderFactory.java @@ -24,11 +24,13 @@ import org.apache.felix.scr.annotations.ConfigurationPolicy; import org.apache.felix.scr.annotations.Properties; import org.apache.felix.scr.annotations.Property; import org.apache.felix.scr.annotations.PropertyUnbounded; +import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Service; import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.ResourceProvider; import org.apache.sling.api.resource.ResourceProviderFactory; import org.apache.sling.commons.osgi.PropertiesUtil; +import org.osgi.service.event.EventAdmin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,10 +42,10 @@ import com.mongodb.Mongo; * in MongoDB. */ @Component(label="%factory.name", - description="%factory.description", - configurationFactory=true, - policy=ConfigurationPolicy.REQUIRE, - metatype=true) +description="%factory.description", +configurationFactory=true, +policy=ConfigurationPolicy.REQUIRE, +metatype=true) @Service(value=ResourceProviderFactory.class) @Properties({ @Property(name=ResourceProvider.ROOTS, value="/mongo") @@ -74,21 +76,35 @@ public class MongoDBResourceProviderFactory implements ResourceProviderFactory { /** The global context passed to each resource provider. */ private MongoDBContext context; + @Reference + private EventAdmin eventAdmin; + @Activate protected void activate(final Map<String, Object> props) throws Exception { + final String[] roots = PropertiesUtil.toStringArray(props.get(ResourceProvider.ROOTS)); + if ( roots == null || roots.length == 0 ) { + throw new Exception("Roots configuration is missing."); + } + if ( roots.length > 1 ) { + throw new Exception("Only a single root should be configured."); + } + if ( roots[0] == null || roots[0].trim().length() == 0 ) { + throw new Exception("Roots configuration is missing."); + } final String host = PropertiesUtil.toString(props.get(PROP_HOST), DEFAULT_HOST); final int port = PropertiesUtil.toInteger(props.get(PROP_PORT), DEFAULT_PORT); final String db = PropertiesUtil.toString(props.get(PROP_DB), DEFAULT_DB); logger.info("Starting MongoDB resource provider with host={}, port={}, db={}", - new Object[] {host, port, db}); + new Object[] {host, port, db}); final Mongo m = new Mongo( host , port ); final DB database = m.getDB( db ); logger.info("Connected to database {}", database); this.context = new MongoDBContext(database, - PropertiesUtil.toStringArray(props.get(ResourceProvider.ROOTS)), - PropertiesUtil.toStringArray(props.get(PROP_FILTER_COLLECTIONS))); + roots[0], + PropertiesUtil.toStringArray(props.get(PROP_FILTER_COLLECTIONS)), + this.eventAdmin); } /** -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
