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 2009/09/25 17:58:11 UTC

svn commit: r818893 - in /sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event: EventUtil.java impl/AbstractRepositoryEventHandler.java impl/EventHelper.java impl/JobEventHandler.java impl/TimedJobHandler.java

Author: cziegeler
Date: Fri Sep 25 15:58:10 2009
New Revision: 818893

URL: http://svn.apache.org/viewvc?rev=818893&view=rev
Log:
SLING-1125 : Deprecate internal methods

Modified:
    sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/EventUtil.java
    sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/AbstractRepositoryEventHandler.java
    sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/EventHelper.java
    sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/JobEventHandler.java
    sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/TimedJobHandler.java

Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/EventUtil.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/EventUtil.java?rev=818893&r1=818892&r2=818893&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/EventUtil.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/EventUtil.java Fri Sep 25 15:58:10 2009
@@ -336,7 +336,9 @@
      * @param ignoreProps optional list of property which should be ignored
      * @param binPropertyName The name of the binary property.
      * @throws RepositoryException
+     * @deprecated
      */
+    @Deprecated
     public static void addProperties(final Node node,
                                      final Map<String, Object> properties,
                                      final String[] ignoreProps,
@@ -356,7 +358,9 @@
      * @param ignoreProps optional list of property which should be ignored
      * @param binPropertyName The name of the binary property.
      * @throws RepositoryException
+     * @deprecated
      */
+    @Deprecated
     public static void addProperties(final Node node,
                                      final EventPropertiesMap properties,
                                      final String[] ignoreProps,
@@ -410,34 +414,20 @@
      * loader is used to load these objects.
      * @throws RepositoryException
      * @throws ClassNotFoundException
+     * @deprecated
      */
+    @Deprecated
     public static EventPropertiesMap readProperties(final Node node,
                                                     final String binPropertyName,
                                                     final String[] ignorePrefixes)
     throws RepositoryException, ClassNotFoundException {
-        return readProperties(node, binPropertyName, ignorePrefixes, Thread.currentThread().getContextClassLoader());
-    }
-
-    /**
-     * Read properties from a repository node and create a property map.
-     * As the properties might contain serialized java objects, a class loader can be specified
-     * for loading classes of the serialized java objects.
-     * @throws RepositoryException
-     * @throws ClassNotFoundException
-     * @since 2.0.6
-     */
-    public static EventPropertiesMap readProperties(final Node node,
-                                                    final String binPropertyName,
-                                                    final String[] ignorePrefixes,
-                                                    final ClassLoader objectClassLoader)
-    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(),
-                        objectClassLoader);
+                        Thread.currentThread().getContextClassLoader());
                 int length = ois.readInt();
                 for(int i=0;i<length;i++) {
                     final String key = (String)ois.readObject();
@@ -503,7 +493,9 @@
      * Return the converted repository property name
      * @param name The java object property name
      * @return The converted name or null if not possible.
+     * @deprecated
      */
+    @Deprecated
     public static String getNodePropertyName(final String name) {
         // if name contains a colon, we can't set it as a property
         if ( name.indexOf(':') != -1 ) {
@@ -517,7 +509,9 @@
      * @param valueFactory The value factory
      * @param eventValue The event value
      * @return The converted value or null if not possible
+     * @deprecated
      */
+    @Deprecated
     public static Value getNodePropertyValue(final ValueFactory valueFactory, final Object eventValue) {
         final Value val;
         if (eventValue instanceof Calendar) {
@@ -541,7 +535,9 @@
      * @param value
      * @return
      * @throws RepositoryException
+     * @deprecated
      */
+    @Deprecated
     private static Object getPropertyValue(final Value value)
     throws RepositoryException {
         final Object o;
@@ -569,7 +565,9 @@
      * @param node
      * @return
      * @throws RepositoryException
+     * @deprecated
      */
+    @Deprecated
     private static boolean setProperty(String name, Object value, Node node)
     throws RepositoryException {
         final String propName = getNodePropertyName(name);

Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/AbstractRepositoryEventHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/AbstractRepositoryEventHandler.java?rev=818893&r1=818892&r2=818893&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/AbstractRepositoryEventHandler.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/AbstractRepositoryEventHandler.java Fri Sep 25 15:58:10 2009
@@ -32,8 +32,6 @@
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
 import org.apache.sling.commons.osgi.OsgiUtil;
 import org.apache.sling.engine.SlingSettingsService;
-import org.apache.sling.event.EventPropertiesMap;
-import org.apache.sling.event.EventUtil;
 import org.apache.sling.event.JobStatusProvider;
 import org.apache.sling.event.ThreadPool;
 import org.apache.sling.jcr.api.SlingRepository;
@@ -101,19 +99,6 @@
 
     public static String APPLICATION_ID;
 
-    /** List of ignored properties to write to the repository. */
-    private static final String[] IGNORE_PROPERTIES = new String[] {
-        EventUtil.PROPERTY_DISTRIBUTE,
-        EventUtil.PROPERTY_APPLICATION,
-        JobStatusProvider.PROPERTY_EVENT_ID,
-        EventUtil.JobStatusNotifier.CONTEXT_PROPERTY_NAME
-    };
-
-    /** List of ignored prefixes to read from the repository. */
-    private static final String[] IGNORE_PREFIXES = new String[] {
-        EventHelper.EVENT_PREFIX
-    };
-
     /**
      * Activate this component.
      * @param context
@@ -273,10 +258,7 @@
         eventNode.setProperty(EventHelper.NODE_PROPERTY_TOPIC, e.getTopic());
         eventNode.setProperty(EventHelper.NODE_PROPERTY_APPLICATION, this.applicationId);
 
-        EventUtil.addProperties(eventNode,
-                                new EventPropertiesMap(e),
-                                IGNORE_PROPERTIES,
-                                EventHelper.NODE_PROPERTY_PROPERTIES);
+        EventHelper.writeEventProperties(eventNode, e);
         this.addNodeProperties(eventNode, e);
         rootNode.save();
 
@@ -292,26 +274,19 @@
      */
     protected Event readEvent(Node eventNode)
     throws RepositoryException, ClassNotFoundException {
-        final ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
-        try {
-            Thread.currentThread().setContextClassLoader(this.classLoaderManager.getDynamicClassLoader());
-            final String topic = eventNode.getProperty(EventHelper.NODE_PROPERTY_TOPIC).getString();
-            final EventPropertiesMap eventProps = EventUtil.readProperties(eventNode,
-                    EventHelper.NODE_PROPERTY_PROPERTIES,
-                    IGNORE_PREFIXES);
+        final String topic = eventNode.getProperty(EventHelper.NODE_PROPERTY_TOPIC).getString();
+        final Dictionary<String, Object> eventProps = EventHelper.readEventProperties(eventNode,
+                this.classLoaderManager.getDynamicClassLoader());
 
-            eventProps.put(JobStatusProvider.PROPERTY_EVENT_ID, eventNode.getPath());
-            this.addEventProperties(eventNode, eventProps);
-            try {
-                final Event event = new Event(topic, (Dictionary)eventProps);
-                return event;
-            } catch (IllegalArgumentException iae) {
-                // this exception occurs if the topic is not correct (it should never happen,
-                // but you never know)
-                throw new RepositoryException("Unable to read event: " + iae.getMessage(), iae);
-            }
-        } finally {
-            Thread.currentThread().setContextClassLoader(oldCL);
+        eventProps.put(JobStatusProvider.PROPERTY_EVENT_ID, eventNode.getPath());
+        this.addEventProperties(eventNode, eventProps);
+        try {
+            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,
+            // but you never know)
+            throw new RepositoryException("Unable to read event: " + iae.getMessage(), iae);
         }
     }
 

Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/EventHelper.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/EventHelper.java?rev=818893&r1=818892&r2=818893&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/EventHelper.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/EventHelper.java Fri Sep 25 15:58:10 2009
@@ -18,9 +18,32 @@
  */
 package org.apache.sling.event.impl;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
 import java.io.UnsupportedEncodingException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+
+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;
+import org.apache.sling.event.JobStatusProvider;
+import org.osgi.service.event.Event;
 
 
 /**
@@ -60,6 +83,19 @@
     /** Replacement characters for unallowed characters in a node name */
     private static final char REPLACEMENT_CHAR = '_';
 
+    /** List of ignored properties to write to the repository. */
+    private static final String[] IGNORE_PROPERTIES = new String[] {
+        EventUtil.PROPERTY_DISTRIBUTE,
+        EventUtil.PROPERTY_APPLICATION,
+        JobStatusProvider.PROPERTY_EVENT_ID,
+        EventUtil.JobStatusNotifier.CONTEXT_PROPERTY_NAME
+    };
+
+    /** List of ignored prefixes to read from the repository. */
+    private static final String[] IGNORE_PREFIXES = new String[] {
+        EventHelper.EVENT_PREFIX
+    };
+
     /**
      * Filter the node name for not allowed characters and replace them.
      * @param nodeName The suggested node name.
@@ -138,4 +174,281 @@
         }
         return res.toString();
     }
+
+    /**
+     * Check if this property should be ignored
+     */
+    private static boolean ignoreProperty(final String name) {
+        for(final String prop : IGNORE_PROPERTIES) {
+            if ( prop.equals(name) ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 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 event The event.
+     * @throws RepositoryException
+     */
+    public static void writeEventProperties(final Node node,
+                                            final Event event)
+    throws RepositoryException {
+        if ( event != null ) {
+            final String[] propNames = event.getPropertyNames();
+            if ( propNames != null && propNames.length > 0 ) {
+                // 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 name : propNames) {
+
+                    if ( !ignoreProperty(name) ) {
+                        // sanity check
+                        final Object value = event.getProperty(name);
+                        if ( value != null ) {
+                            if ( !setProperty(name, value, node) ) {
+                                propsAsBlob.add(name);
+                            }
+                        }
+                    }
+                }
+                // 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);
+                            try {
+                                oos.writeObject(event.getProperty(propName));
+                            } catch (IOException ioe) {
+                                throw new RepositoryException("Unable to serialize property " + propName, ioe);
+                            }
+                        }
+                        oos.close();
+                        node.setProperty(EventHelper.NODE_PROPERTY_PROPERTIES, new ByteArrayInputStream(baos.toByteArray()));
+                    } catch (IOException ioe) {
+                        throw new RepositoryException("Unable to serialize event " + EventUtil.toString(event), ioe);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Read event properties from a repository node and create a property map (dictionary).
+     * As the properties might contain serialized java objects, a class loader can be specified
+     * for loading classes of the serialized java objects.
+     * @throws RepositoryException
+     * @throws ClassNotFoundException
+     */
+    public static Dictionary<String, Object> readEventProperties(final Node node,
+                                                                 final ClassLoader objectClassLoader)
+    throws RepositoryException, ClassNotFoundException {
+        final Dictionary<String, Object> properties = new Hashtable<String, Object>();
+
+        // check the properties blob
+        if ( node.hasProperty(EventHelper.NODE_PROPERTY_PROPERTIES) ) {
+            try {
+                final ObjectInputStream ois = new ObjectInputStream(node.getProperty(EventHelper.NODE_PROPERTY_PROPERTIES).getStream(),
+                        objectClassLoader);
+                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 (java.io.InvalidClassException ice) {
+                throw new ClassNotFoundException("Found invalid class.", ice);
+            } 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();
+            boolean ignore = p.getName().startsWith("jcr:");
+            if ( !ignore) {
+                int index = 0;
+                while ( !ignore && index < IGNORE_PREFIXES.length ) {
+                    ignore = p.getName().startsWith(IGNORE_PREFIXES[index]);
+                    index++;
+                }
+            }
+            if ( !ignore ) {
+                final String name = ISO9075.decode(p.getName());
+                if ( p.getDefinition().isMultiple() ) {
+                    final Value[] values = p.getValues();
+                    if ( values.length > 0 ) {
+                        // get first value
+                        final Object firstObject = getPropertyValue(values[0]);
+                        final Object[] array;
+                        if ( firstObject instanceof Boolean ) {
+                            array = new Boolean[values.length];
+                        } else if ( firstObject instanceof Calendar ) {
+                            array = new Calendar[values.length];
+                        } else if ( firstObject instanceof Double ) {
+                            array = new Double[values.length];
+                        } else if ( firstObject instanceof Long ) {
+                            array = new Long[values.length];
+                        } else {
+                            array = new String[values.length];
+                        }
+                        array[0] = firstObject;
+                        int index = 1;
+                        while ( index < values.length ) {
+                            array[index] = getPropertyValue(values[index]);
+                            index++;
+                        }
+                        properties.put(name, array);
+                    }
+                } else {
+                    final Value value = p.getValue();
+                    final Object o = getPropertyValue(value);
+                    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 instanceof Calendar) {
+            val = valueFactory.createValue((Calendar)eventValue);
+        } else if (eventValue instanceof Long) {
+            val = valueFactory.createValue((Long)eventValue);
+        } else if (eventValue instanceof Double) {
+            val = valueFactory.createValue(((Double)eventValue).doubleValue());
+        } else if (eventValue instanceof Boolean) {
+            val = valueFactory.createValue((Boolean) eventValue);
+        } else if (eventValue instanceof String) {
+            val = valueFactory.createValue((String)eventValue);
+        } else {
+            val = null;
+        }
+        return val;
+    }
+
+    /**
+     * Convert the value back to an object.
+     * @param value
+     * @return
+     * @throws RepositoryException
+     */
+    private static Object getPropertyValue(final Value value)
+    throws RepositoryException {
+        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();
+        }
+        return o;
+    }
+
+    /**
+     * 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();
+        // check for multi value
+        if ( value.getClass().isArray() ) {
+            final Object[] array = (Object[])value;
+            // now we try to convert each value
+            // and check if all converted values have the same type
+            final Value[] values = new Value[array.length];
+            int index = 0;
+            for(final Object v : array ) {
+                values[index] = getNodePropertyValue(fac, v);
+                if ( values[index] == null ) {
+                    return false;
+                }
+                if ( index > 0 && !values[index-1].getClass().equals(values[index].getClass()) ) {
+                    return false;
+                }
+                index++;
+            }
+            node.setProperty(propName, values);
+            return true;
+        }
+        final Value val = getNodePropertyValue(fac, value);
+        if ( val != null ) {
+            node.setProperty(propName, val);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * This is an extended version of the object input stream which uses the
+     * thread context class loader.
+     */
+    private static class ObjectInputStream extends java.io.ObjectInputStream {
+
+        private ClassLoader classloader;
+
+        public ObjectInputStream(final InputStream in, final ClassLoader classLoader) throws IOException {
+            super(in);
+            this.classloader = classLoader;
+        }
+
+        /**
+         * @see java.io.ObjectInputStream#resolveClass(java.io.ObjectStreamClass)
+         */
+        @Override
+        protected Class<?> resolveClass(java.io.ObjectStreamClass classDesc) throws IOException, ClassNotFoundException {
+            if ( this.classloader != null ) {
+                return Class.forName(classDesc.getName(), true, this.classloader);
+            }
+            return super.resolveClass(classDesc);
+        }
+    }
 }

Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/JobEventHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/JobEventHandler.java?rev=818893&r1=818892&r2=818893&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/JobEventHandler.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/JobEventHandler.java Fri Sep 25 15:58:10 2009
@@ -1365,10 +1365,10 @@
                     while ( i.hasNext() ) {
                         final Map.Entry<String, Object> current = i.next();
                         // check prop name first
-                        final String propName = EventUtil.getNodePropertyName(current.getKey());
+                        final String propName = EventHelper.getNodePropertyName(current.getKey());
                         if ( propName != null ) {
                             // check value
-                            final Value value = EventUtil.getNodePropertyValue(s.getValueFactory(), current.getValue());
+                            final Value value = EventHelper.getNodePropertyValue(s.getValueFactory(), current.getValue());
                             if ( value != null ) {
                                 if ( first ) {
                                     first = false;

Modified: sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/TimedJobHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/TimedJobHandler.java?rev=818893&r1=818892&r2=818893&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/TimedJobHandler.java (original)
+++ sling/trunk/bundles/extensions/event/src/main/java/org/apache/sling/event/impl/TimedJobHandler.java Fri Sep 25 15:58:10 2009
@@ -693,10 +693,10 @@
                     while ( i.hasNext() ) {
                         final Map.Entry<String, Object> current = i.next();
                         // check prop name first
-                        final String propName = EventUtil.getNodePropertyName(current.getKey());
+                        final String propName = EventHelper.getNodePropertyName(current.getKey());
                         if ( propName != null ) {
                             // check value
-                            final Value value = EventUtil.getNodePropertyValue(s.getValueFactory(), current.getValue());
+                            final Value value = EventHelper.getNodePropertyValue(s.getValueFactory(), current.getValue());
                             if ( value != null ) {
                                 if ( first ) {
                                     first = false;