You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2008/08/14 16:08:52 UTC

svn commit: r685903 - in /incubator/sling/trunk/extensions/event/src: main/java/org/apache/sling/event/impl/ main/resources/SLING-INF/nodetypes/ test/java/org/apache/sling/event/impl/

Author: cziegeler
Date: Thu Aug 14 07:08:51 2008
New Revision: 685903

URL: http://svn.apache.org/viewvc?rev=685903&view=rev
Log:
SLING-611 - Save event properties as jcr properties if possible.

Modified:
    incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/AbstractRepositoryEventHandler.java
    incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/EventHelper.java
    incubator/sling/trunk/extensions/event/src/main/resources/SLING-INF/nodetypes/event.cnd
    incubator/sling/trunk/extensions/event/src/test/java/org/apache/sling/event/impl/DistributingEventHandlerTest.java

Modified: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/AbstractRepositoryEventHandler.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/AbstractRepositoryEventHandler.java?rev=685903&r1=685902&r2=685903&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/AbstractRepositoryEventHandler.java (original)
+++ incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/AbstractRepositoryEventHandler.java Thu Aug 14 07:08:51 2008
@@ -23,18 +23,26 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Dictionary;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.StringTokenizer;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 
 import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
 import javax.jcr.observation.EventListener;
 
+import org.apache.jackrabbit.util.ISO9075;
 import org.apache.sling.commons.osgi.OsgiUtil;
 import org.apache.sling.commons.threads.ThreadPool;
 import org.apache.sling.commons.threads.ThreadPoolConfig;
@@ -42,6 +50,7 @@
 import org.apache.sling.engine.SlingSettingsService;
 import org.apache.sling.event.EventUtil;
 import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.resource.internal.helper.LazyInputStream;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventAdmin;
@@ -293,40 +302,44 @@
         eventNode.setProperty(EventHelper.NODE_PROPERTY_APPLICATION, this.applicationId);
 
         final String[] names = e.getPropertyNames();
-        // we will  not write the distributable property, so length must be greater 1
-        if ( names != null && names.length > 1 ) {
-            // if the application property is available, we will override it
-            // if it is not available we will add it
-            boolean addApplication = false;
-            boolean removeNotifierContextProperty = false;
-            if ( e.getProperty(EventUtil.PROPERTY_APPLICATION) == null ) {
-                addApplication = true;
-            }
-            if ( e.getProperty(EventUtil.JobStatusNotifier.CONTEXT_PROPERTY_NAME) != null ) {
-                removeNotifierContextProperty = true;
-            }
-            try {
-                final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                final ObjectOutputStream oos = new ObjectOutputStream(baos);
-                oos.writeInt(names.length  - 1 + (addApplication ? 1 : 0) - (removeNotifierContextProperty ? 1 : 0));
-                for(int i=0;i<names.length;i++) {
-                    if ( names[i].equals(EventUtil.PROPERTY_APPLICATION) ) {
-                        oos.writeObject(names[i]);
-                        oos.writeObject(this.applicationId);
-                    } else if ( !names[i].equals(EventUtil.PROPERTY_DISTRIBUTE)
-                             && !names[i].equals(EventUtil.JobStatusNotifier.CONTEXT_PROPERTY_NAME) ) {
-                        oos.writeObject(names[i]);
-                        oos.writeObject(e.getProperty(names[i]));
+
+        // if the application property is available, we will override it
+        // if it is not available we will add it
+        eventNode.setProperty(EventUtil.PROPERTY_APPLICATION, this.applicationId);
+
+        if ( names != null ) {
+            // check which props we can write directly and
+            // which we need to write as a binary blob
+            final List<String> propsAsBlob = new ArrayList<String>();
+
+            for(final String propName : names) {
+                // ignore application, distribute and context property
+                if ( !propName.equals(EventUtil.PROPERTY_DISTRIBUTE)
+                    && !propName.equals(EventUtil.PROPERTY_APPLICATION)
+                    && !propName.equals(EventUtil.JobStatusNotifier.CONTEXT_PROPERTY_NAME) ) {
+                    final Object value = e.getProperty(propName);
+                    // sanity check
+                    if ( value != null ) {
+                        if ( !this.setProperty(propName, value, eventNode) ) {
+                            propsAsBlob.add(propName);
+                        }
                     }
                 }
-                if ( addApplication ) {
-                    oos.writeObject(EventUtil.PROPERTY_APPLICATION);
-                    oos.writeObject(this.applicationId);
+            }
+            // write the remaining properties as a blob
+            if ( propsAsBlob.size() > 0 ) {
+                try {
+                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    final ObjectOutputStream oos = new ObjectOutputStream(baos);
+                    for(final String propName : propsAsBlob) {
+                        oos.writeObject(propName);
+                        oos.writeObject(e.getProperty(propName));
+                    }
+                    oos.close();
+                    eventNode.setProperty(EventHelper.NODE_PROPERTY_PROPERTIES, new ByteArrayInputStream(baos.toByteArray()));
+                } catch (IOException ioe) {
+                    throw new RepositoryException("Unable to serialize event properties.", ioe);
                 }
-                oos.close();
-                eventNode.setProperty(EventHelper.NODE_PROPERTY_PROPERTIES, new ByteArrayInputStream(baos.toByteArray()));
-            } catch (IOException ioe) {
-                throw new RepositoryException("Unable to serialize event properties.", ioe);
             }
         }
         this.addNodeProperties(eventNode, e);
@@ -336,6 +349,42 @@
     }
 
     /**
+     * Try to set the OSGi event property as a property of the node.
+     * @param name
+     * @param value
+     * @param node
+     * @return
+     * @throws RepositoryException
+     */
+    private boolean setProperty(String name, Object value, Node node)
+    throws RepositoryException {
+        // if name contains a colon, we can't set it as a property
+        if ( name.indexOf(':') != -1 ) {
+            return false;
+        }
+        final ValueFactory fac = node.getSession().getValueFactory();
+        final Value val;
+        if (value.getClass().isAssignableFrom(Calendar.class)) {
+            val = fac.createValue((Calendar)value);
+        } else if (value.getClass().isAssignableFrom(Long.class)) {
+            val = fac.createValue((Long)value);
+        } else if (value.getClass().isAssignableFrom(Double.class)) {
+            val = fac.createValue(((Double)value).doubleValue());
+        } else if (value.getClass().isAssignableFrom(Boolean.class)) {
+            val = fac.createValue((Boolean) value);
+        } else if (value instanceof String) {
+            val = fac.createValue((String)value);
+        } else {
+            val = null;
+        }
+        if ( val != null ) {
+            node.setProperty(ISO9075.encode(name), val);
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Read an event from the repository.
      * @return
      * @throws RepositoryException
@@ -346,6 +395,7 @@
     throws RepositoryException, ClassNotFoundException {
         final String topic = eventNode.getProperty(EventHelper.NODE_PROPERTY_TOPIC).getString();
         final Dictionary<String, Object> properties = new Hashtable<String, Object>();
+        // check the properties blob
         if ( eventNode.hasProperty(EventHelper.NODE_PROPERTY_PROPERTIES) ) {
             try {
                 final ObjectInputStream ois = new ObjectInputStream(eventNode.getProperty(EventHelper.NODE_PROPERTY_PROPERTIES).getStream());
@@ -359,6 +409,31 @@
                 throw new RepositoryException("Unable to deserialize event properties.", ioe);
             }
         }
+        // now all properties that have been set directly
+        final PropertyIterator pI = eventNode.getProperties();
+        while ( pI.hasNext() ) {
+            final Property p = pI.nextProperty();
+            if ( !p.getName().startsWith("jcr:") && !p.getName().startsWith(EventHelper.EVENT_PREFIX) ) {
+                final String name = ISO9075.decode(p.getName());
+                final Value value = p.getValue();
+                final Object o;
+                switch (value.getType()) {
+                    case PropertyType.BOOLEAN:
+                        o = value.getBoolean(); break;
+                    case PropertyType.DATE:
+                        o = value.getDate(); break;
+                    case PropertyType.DOUBLE:
+                        o = value.getDouble(); break;
+                    case PropertyType.LONG:
+                        o = value.getLong(); break;
+                    case PropertyType.STRING:
+                        o = value.getString(); break;
+                    default: // this should never happen - we convert to a string...
+                        o = value.getString();
+                }
+                properties.put(name, o);
+            }
+        }
         this.addEventProperties(eventNode, properties);
         try {
             final Event event = new Event(topic, properties);

Modified: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/EventHelper.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/EventHelper.java?rev=685903&r1=685902&r2=685903&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/EventHelper.java (original)
+++ incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/EventHelper.java Thu Aug 14 07:08:51 2008
@@ -26,6 +26,8 @@
 
     public static final String THREAD_POOL_NAME = "SLING_EVENTING";
 
+    public static final String EVENT_PREFIX = "slingevent:";
+
     public static final String NODE_PROPERTY_TOPIC = "slingevent:topic";
     public static final String NODE_PROPERTY_APPLICATION = "slingevent:application";
     public static final String NODE_PROPERTY_CREATED = "slingevent:created";

Modified: incubator/sling/trunk/extensions/event/src/main/resources/SLING-INF/nodetypes/event.cnd
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/event/src/main/resources/SLING-INF/nodetypes/event.cnd?rev=685903&r1=685902&r2=685903&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/event/src/main/resources/SLING-INF/nodetypes/event.cnd (original)
+++ incubator/sling/trunk/extensions/event/src/main/resources/SLING-INF/nodetypes/event.cnd Thu Aug 14 07:08:51 2008
@@ -30,7 +30,7 @@
 [slingevent:Jobs] > nt:folder, mix:lockable
   + * (slingevent:Job)
   
-[slingevent:Event] > nt:base
+[slingevent:Event] > nt:unstructured
   - slingevent:topic (string)
   - slingevent:application (string)
   - slingevent:created (date)

Modified: incubator/sling/trunk/extensions/event/src/test/java/org/apache/sling/event/impl/DistributingEventHandlerTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/event/src/test/java/org/apache/sling/event/impl/DistributingEventHandlerTest.java?rev=685903&r1=685902&r2=685903&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/event/src/test/java/org/apache/sling/event/impl/DistributingEventHandlerTest.java (original)
+++ incubator/sling/trunk/extensions/event/src/test/java/org/apache/sling/event/impl/DistributingEventHandlerTest.java Thu Aug 14 07:08:51 2008
@@ -28,6 +28,7 @@
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 
+import org.apache.jackrabbit.util.ISO9075;
 import org.apache.sling.event.EventUtil;
 import org.jmock.Mockery;
 import org.jmock.integration.junit4.JMock;
@@ -65,7 +66,7 @@
         assertEquals(handler.applicationId, eventNode.getProperty(EventHelper.NODE_PROPERTY_APPLICATION).getString());
         assertTrue(Calendar.getInstance().compareTo(eventNode.getProperty(EventHelper.NODE_PROPERTY_CREATED).getDate()) >= 0);
         // as a starting point we just check if the properties property exists
-        assertTrue(eventNode.hasProperty(EventHelper.NODE_PROPERTY_PROPERTIES));
+        assertTrue(eventNode.hasProperty(ISO9075.encode("a property")));
     }
 
     @org.junit.Test public void testWriteEventPlusAppId() throws Exception {
@@ -83,6 +84,6 @@
         assertEquals(handler.applicationId, eventNode.getProperty(EventHelper.NODE_PROPERTY_APPLICATION).getString());
         assertTrue(Calendar.getInstance().compareTo(eventNode.getProperty(EventHelper.NODE_PROPERTY_CREATED).getDate()) >= 0);
         // as a starting point we just check if the properties property exists
-        assertTrue(eventNode.hasProperty(EventHelper.NODE_PROPERTY_PROPERTIES));
+        assertTrue(eventNode.hasProperty(ISO9075.encode("a property")));
     }
 }