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);