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;