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/22 19:43:15 UTC

svn commit: r688132 - in /incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event: EventPropertiesMap.java EventUtil.java impl/AbstractRepositoryEventHandler.java impl/JobEventHandler.java

Author: cziegeler
Date: Fri Aug 22 10:43:15 2008
New Revision: 688132

URL: http://svn.apache.org/viewvc?rev=688132&view=rev
Log:
Move property handling to EventUtil.

Added:
    incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventPropertiesMap.java   (with props)
Modified:
    incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventUtil.java
    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/JobEventHandler.java

Added: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventPropertiesMap.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventPropertiesMap.java?rev=688132&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventPropertiesMap.java (added)
+++ incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventPropertiesMap.java Fri Aug 22 10:43:15 2008
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.sling.event;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.service.event.Event;
+
+/**
+ * An implementation of a map that wrapps an OSGi event.
+ */
+public class EventPropertiesMap implements Map<String, Object> {
+
+    private final Map<String, Object> delegatee = new HashMap<String, Object>();
+
+    public EventPropertiesMap(final Event event) {
+        if ( event.getPropertyNames() != null ) {
+            final String[] names = event.getPropertyNames();
+            for(final String key : names) {
+                this.delegatee.put(key, event.getProperty(key));
+            }
+        }
+    }
+
+    /**
+     * @see java.util.Map#clear()
+     */
+    public void clear() {
+        throw new UnsupportedOperationException("Clear is not supported.");
+    }
+
+    /**
+     * @see java.util.Map#put(java.lang.Object, java.lang.Object)
+     */
+    public Object put(String key, Object value) {
+        throw new UnsupportedOperationException("Clear is not supported.");
+    }
+
+    /**
+     * @see java.util.Map#putAll(java.util.Map)
+     */
+    public void putAll(Map<? extends String, ? extends Object> t) {
+        throw new UnsupportedOperationException("Clear is not supported.");
+    }
+
+    /**
+     * @see java.util.Map#remove(java.lang.Object)
+     */
+    public Object remove(Object key) {
+        throw new UnsupportedOperationException("Clear is not supported.");
+    }
+
+    public boolean containsKey(Object key) {
+        return delegatee.containsKey(key);
+    }
+
+    public boolean containsValue(Object value) {
+        return delegatee.containsValue(value);
+    }
+
+    public Set<java.util.Map.Entry<String, Object>> entrySet() {
+        return delegatee.entrySet();
+    }
+
+    public boolean equals(Object o) {
+        return delegatee.equals(o);
+    }
+
+    public Object get(Object key) {
+        return delegatee.get(key);
+    }
+
+    public int hashCode() {
+        return delegatee.hashCode();
+    }
+
+    public boolean isEmpty() {
+        return delegatee.isEmpty();
+    }
+
+    public Set<String> keySet() {
+        return delegatee.keySet();
+    }
+
+    public int size() {
+        return delegatee.size();
+    }
+
+    public Collection<Object> values() {
+        return delegatee.values();
+    }
+}

Propchange: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventPropertiesMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventPropertiesMap.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventPropertiesMap.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventUtil.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventUtil.java?rev=688132&r1=688131&r2=688132&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventUtil.java (original)
+++ incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/EventUtil.java Fri Aug 22 10:43:15 2008
@@ -18,10 +18,30 @@
  */
 package org.apache.sling.event;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+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.Enumeration;
+import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
 
+import org.apache.jackrabbit.util.ISO9075;
 import org.apache.sling.event.EventUtil.JobStatusNotifier.NotifierContext;
 import org.osgi.service.event.Event;
 import org.slf4j.Logger;
@@ -244,4 +264,172 @@
          */
         void execute(Runnable job);
     }
+
+    /**
+     * Add all java properties as properties to the node.
+     * If the name and the value of a map entry can easily converted into
+     * a repository property, it is directly added. All other java
+     * properties are stored in one binary property.
+     *
+     * @param node The node where all properties are added to
+     * @param properties The map of properties.
+     * @param ignoreProps optional list of property which should be ignored
+     * @param binPropertyName The name of the binary property.
+     * @throws RepositoryException
+     */
+    public static void addProperties(final Node node,
+                                     final Map<String, Object> properties,
+                                     final List<String> ignoreProps,
+                                     final String binPropertyName)
+    throws RepositoryException {
+        if ( properties != 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>();
+
+            final Iterator<Map.Entry<String, Object>> i = properties.entrySet().iterator();
+            while ( i.hasNext() ) {
+                final Map.Entry<String, Object> current = i.next();
+
+                if (ignoreProps == null || !ignoreProps.contains(current.getKey()) ) {
+                    // sanity check
+                    if ( current.getValue() != null ) {
+                        if ( !setProperty(current.getKey(), current.getValue(), node) ) {
+                            propsAsBlob.add(current.getKey());
+                        }
+                    }
+                }
+            }
+            // write the remaining properties as a blob
+            if ( propsAsBlob.size() > 0 ) {
+                try {
+                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    final ObjectOutputStream oos = new ObjectOutputStream(baos);
+                    oos.writeInt(propsAsBlob.size());
+                    for(final String propName : propsAsBlob) {
+                        oos.writeObject(propName);
+                        oos.writeObject(properties.get(propName));
+                    }
+                    oos.close();
+                    node.setProperty(binPropertyName, new ByteArrayInputStream(baos.toByteArray()));
+                } catch (IOException ioe) {
+                    throw new RepositoryException("Unable to serialize properties.", ioe);
+                }
+            }
+        }
+    }
+
+    /**
+     * Read properties from a repository node and create a property map.
+     * @throws RepositoryException
+     * @throws ClassNotFoundException
+     */
+    public static Map<String, Object> readProperties(final Node node,
+                                                     final String binPropertyName,
+                                                     final List<String> ignorePrefixes)
+    throws RepositoryException, ClassNotFoundException {
+        final Map<String, Object> properties = new HashMap<String, Object>();
+
+        // check the properties blob
+        if ( node.hasProperty(binPropertyName) ) {
+            try {
+                final ObjectInputStream ois = new ObjectInputStream(node.getProperty(binPropertyName).getStream());
+                int length = ois.readInt();
+                for(int i=0;i<length;i++) {
+                    final String key = (String)ois.readObject();
+                    final Object value = ois.readObject();
+                    properties.put(key, value);
+                }
+            } catch (IOException ioe) {
+                throw new RepositoryException("Unable to deserialize event properties.", ioe);
+            }
+        }
+        // now all properties that have been set directly
+        final PropertyIterator pI = node.getProperties();
+        while ( pI.hasNext() ) {
+            final Property p = pI.nextProperty();
+            if ( !p.getName().startsWith("jcr:") &&
+                 (ignorePrefixes == null || !ignorePrefixes.contains(p.getName())))  {
+                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);
+            }
+        }
+        return properties;
+    }
+
+    /**
+     * Return the converted repository property name
+     * @param name The java object property name
+     * @return The converted name or null if not possible.
+     */
+    public static String getNodePropertyName(final String name) {
+        // if name contains a colon, we can't set it as a property
+        if ( name.indexOf(':') != -1 ) {
+            return null;
+        }
+        return ISO9075.encode(name);
+    }
+
+    /**
+     * Return the converted repository property value
+     * @param valueFactory The value factory
+     * @param eventValue The event value
+     * @return The converted value or null if not possible
+     */
+    public static Value getNodePropertyValue(final ValueFactory valueFactory, final Object eventValue) {
+        final Value val;
+        if (eventValue.getClass().isAssignableFrom(Calendar.class)) {
+            val = valueFactory.createValue((Calendar)eventValue);
+        } else if (eventValue.getClass().isAssignableFrom(Long.class)) {
+            val = valueFactory.createValue((Long)eventValue);
+        } else if (eventValue.getClass().isAssignableFrom(Double.class)) {
+            val = valueFactory.createValue(((Double)eventValue).doubleValue());
+        } else if (eventValue.getClass().isAssignableFrom(Boolean.class)) {
+            val = valueFactory.createValue((Boolean) eventValue);
+        } else if (eventValue instanceof String) {
+            val = valueFactory.createValue((String)eventValue);
+        } else {
+            val = null;
+        }
+        return val;
+    }
+
+    /**
+     * Try to set the java property as a property of the node.
+     * @param name
+     * @param value
+     * @param node
+     * @return
+     * @throws RepositoryException
+     */
+    private static boolean setProperty(String name, Object value, Node node)
+    throws RepositoryException {
+        final String propName = getNodePropertyName(name);
+        if ( propName == null ) {
+            return false;
+        }
+        final ValueFactory fac = node.getSession().getValueFactory();
+        final Value val = getNodePropertyValue(fac, value);
+        if ( val != null ) {
+            node.setProperty(propName, val);
+            return true;
+        }
+        return false;
+    }
 }

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=688132&r1=688131&r2=688132&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 Fri Aug 22 10:43:15 2008
@@ -18,36 +18,28 @@
  */
 package org.apache.sling.event.impl;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 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.Map;
 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;
 import org.apache.sling.commons.threads.ThreadPoolManager;
 import org.apache.sling.engine.SlingSettingsService;
+import org.apache.sling.event.EventPropertiesMap;
 import org.apache.sling.event.EventUtil;
 import org.apache.sling.jcr.api.SlingRepository;
 import org.osgi.service.component.ComponentContext;
@@ -109,6 +101,20 @@
      *  Sling settings service. */
     protected SlingSettingsService settingsService;
 
+    /** List of ignored properties to write to the repository. */
+    private static final List<String> IGNORE_PROPERTIES = new ArrayList<String>();
+    static {
+        IGNORE_PROPERTIES.add(EventUtil.PROPERTY_DISTRIBUTE);
+        IGNORE_PROPERTIES.add(EventUtil.PROPERTY_APPLICATION);
+        IGNORE_PROPERTIES.add(EventUtil.JobStatusNotifier.CONTEXT_PROPERTY_NAME);
+    }
+
+    /** List of ignored prefixes to read from the repository. */
+    private static final List<String> IGNORE_PREFIXES = new ArrayList<String>();
+    static {
+        IGNORE_PREFIXES.add(EventHelper.EVENT_PREFIX);
+    }
+
     /**
      * Activate this component.
      * @param context
@@ -300,48 +306,14 @@
         eventNode.setProperty(EventHelper.NODE_PROPERTY_TOPIC, e.getTopic());
         eventNode.setProperty(EventHelper.NODE_PROPERTY_APPLICATION, this.applicationId);
 
-        final String[] names = e.getPropertyNames();
-
         // 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);
-                        }
-                    }
-                }
-            }
-            // write the remaining properties as a blob
-            if ( propsAsBlob.size() > 0 ) {
-                try {
-                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    final ObjectOutputStream oos = new ObjectOutputStream(baos);
-                    oos.writeInt(propsAsBlob.size());
-                    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);
-                }
-            }
-        }
+        EventUtil.addProperties(eventNode,
+                                new EventPropertiesMap(e),
+                                IGNORE_PROPERTIES,
+                                EventHelper.NODE_PROPERTY_PROPERTIES);
         this.addNodeProperties(eventNode, e);
         rootNode.save();
 
@@ -349,66 +321,6 @@
     }
 
     /**
-     * Return the converted repository property name
-     * @param name The OSGi event property name
-     * @return The converted name or null if not possible.
-     */
-    protected String getNodePropertyName(final String name) {
-        // if name contains a colon, we can't set it as a property
-        if ( name.indexOf(':') != -1 ) {
-            return null;
-        }
-        return ISO9075.encode(name);
-    }
-
-    /**
-     * Return the converted repository property value
-     * @param valueFactory The value factory
-     * @param eventValue The event value
-     * @return The converted value or null if not possible
-     */
-    protected Value getNodePropertyValue(final ValueFactory valueFactory, final Object eventValue) {
-        final Value val;
-        if (eventValue.getClass().isAssignableFrom(Calendar.class)) {
-            val = valueFactory.createValue((Calendar)eventValue);
-        } else if (eventValue.getClass().isAssignableFrom(Long.class)) {
-            val = valueFactory.createValue((Long)eventValue);
-        } else if (eventValue.getClass().isAssignableFrom(Double.class)) {
-            val = valueFactory.createValue(((Double)eventValue).doubleValue());
-        } else if (eventValue.getClass().isAssignableFrom(Boolean.class)) {
-            val = valueFactory.createValue((Boolean) eventValue);
-        } else if (eventValue instanceof String) {
-            val = valueFactory.createValue((String)eventValue);
-        } else {
-            val = null;
-        }
-        return val;
-    }
-
-    /**
-     * 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 {
-        final String propName = this.getNodePropertyName(name);
-        if ( propName == null ) {
-            return false;
-        }
-        final ValueFactory fac = node.getSession().getValueFactory();
-        final Value val = this.getNodePropertyValue(fac, value);
-        if ( val != null ) {
-            node.setProperty(propName, val);
-            return true;
-        }
-        return false;
-    }
-
-    /**
      * Read an event from the repository.
      * @return
      * @throws RepositoryException
@@ -418,49 +330,14 @@
     protected Event readEvent(Node eventNode)
     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());
-                int length = ois.readInt();
-                for(int i=0;i<length;i++) {
-                    final String key = (String)ois.readObject();
-                    final Object value = ois.readObject();
-                    properties.put(key, value);
-                }
-            } catch (IOException ioe) {
-                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);
+        final Map<String, Object> properties = EventUtil.readProperties(eventNode,
+                EventHelper.NODE_PROPERTY_PROPERTIES,
+                IGNORE_PREFIXES);
+
+        final Dictionary<String, Object> eventProps = new Hashtable<String, Object>(properties);
+        this.addEventProperties(eventNode, eventProps);
         try {
-            final Event event = new Event(topic, properties);
+            final Event event = new Event(topic, eventProps);
             return event;
         } catch (IllegalArgumentException iae) {
             // this exception occurs if the topic is not correct (it should never happen,

Modified: incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/JobEventHandler.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/JobEventHandler.java?rev=688132&r1=688131&r2=688132&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/JobEventHandler.java (original)
+++ incubator/sling/trunk/extensions/event/src/main/java/org/apache/sling/event/impl/JobEventHandler.java Fri Aug 22 10:43:15 2008
@@ -974,10 +974,10 @@
                 while ( i.hasNext() ) {
                     final Map.Entry<String, Object> current = i.next();
                     // check prop name first
-                    final String propName = this.getNodePropertyName(current.getKey());
+                    final String propName = EventUtil.getNodePropertyName(current.getKey());
                     if ( propName != null ) {
                         // check value
-                        final Value value = this.getNodePropertyValue(s.getValueFactory(), current.getValue());
+                        final Value value = EventUtil.getNodePropertyValue(s.getValueFactory(), current.getValue());
                         if ( value != null ) {
                             buffer.append(" and @");
                             buffer.append(propName);