You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2013/02/27 16:51:10 UTC
svn commit: r1450816 [7/7] - in /felix/trunk/ipojo/handler/eventadmin: ./
doc/ eventadmin-handler-it/ eventadmin-handler-it/src/
eventadmin-handler-it/src/it/ eventadmin-handler-it/src/it/event-admin-it/
eventadmin-handler-it/src/it/event-admin-it/src/...
Added: felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandlerDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandlerDescription.java?rev=1450816&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandlerDescription.java (added)
+++ felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherHandlerDescription.java Wed Feb 27 15:51:08 2013
@@ -0,0 +1,102 @@
+/*
+ * 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.felix.ipojo.handlers.event.publisher;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Handler Description for Event Admin Publisher.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class EventAdminPublisherHandlerDescription extends HandlerDescription {
+
+ /**
+ * The list of publishers.
+ */
+ List/*<PublisherDescription>*/ m_publishersDescriptions;
+
+ // FIXME : Add listener interface for
+ // : onServiceArrival, onServiceDeparture, onServiceBound, onServiceUnbound
+ // : methods.
+
+ /**
+ * Creates the {@link EventAdminPublisherHandlerDescription}.
+ * @param handler the handler
+ * @param publishers the list of publishers
+ */
+ public EventAdminPublisherHandlerDescription(Handler handler, Collection/*<Publisher>*/ publishers) {
+ super(handler);
+
+ m_publishersDescriptions = new ArrayList/*<PublisherDescription>*/();
+ if (publishers != null) {
+ Iterator iterator = publishers.iterator();
+ while (iterator.hasNext()){
+ Publisher p = (Publisher) iterator.next();
+ m_publishersDescriptions.add(new PublisherDescription(p));
+ }
+ }
+
+ }
+
+ /**
+ * Gets the publisher descriptions.
+ * @return the descriptions.
+ */
+ public PublisherDescription[] getPublisherDescriptions() {
+ return (PublisherDescription[])
+ m_publishersDescriptions.toArray(new PublisherDescription[m_publishersDescriptions.size()]);
+ }
+
+ /**
+ * Gets the handler description.
+ * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+ */
+ public Element getHandlerInfo() {
+ Element root = super.getHandlerInfo();
+ for (int i = 0; i < m_publishersDescriptions.size(); i++) {
+ PublisherDescription p = (PublisherDescription) m_publishersDescriptions.get(i);
+ Element publisher = new Element("Publisher", "");
+ publisher.addAttribute(new Attribute("name", p.getName()));
+ publisher.addAttribute(new Attribute("synchronous", String.valueOf(p.isSynchronous())));
+ publisher.addAttribute(new Attribute("data_key", p.getDataKey()));
+ Element topics = new Element("Topics", "");
+ if (p.getTopics() != null) {
+ for (int j = 0; j < p.getTopics().length; j++) {
+ String topic = p.getTopics()[j];
+ Element e_topic = new Element("topic","");
+ topics.addElement(e_topic);
+ e_topic.addAttribute(new Attribute("name",topic));
+ }
+ }
+ publisher.addElement(topics);
+ root.addElement(publisher);
+ }
+ return root;
+ }
+
+}
Added: felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java?rev=1450816&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java (added)
+++ felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java Wed Feb 27 15:51:08 2013
@@ -0,0 +1,242 @@
+/*
+ * 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.felix.ipojo.handlers.event.publisher;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.handlers.event.EventUtil;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ParseUtils;
+
+/**
+ * Represent a publisher.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+class EventAdminPublisherMetadata {
+
+ // Names of metadata attributes
+
+ /**
+ * The name attribute in the component metadata.
+ */
+ public static final String NAME_ATTRIBUTE = "name";
+
+ /**
+ * The field attribute in the component metadata.
+ */
+ public static final String FIELD_ATTRIBUTE = "field";
+
+ /**
+ * The topics attribute in the component metadata.
+ */
+ public static final String TOPICS_ATTRIBUTE = "topics";
+
+ /**
+ * The synchronous attribute in the component metadata.
+ */
+ public static final String SYNCHRONOUS_ATTRIBUTE = "synchronous";
+
+ /**
+ * The data key attribute in the component metadata.
+ */
+ public static final String DATA_KEY_ATTRIBUTE = "data-key";
+
+ // Default values
+
+ /**
+ * The data key attribute's default value.
+ */
+ public static final String DEFAULT_DATA_KEY_VALUE = "user.data";
+
+ /**
+ * The synchronous attribute's default value.
+ */
+ public static final boolean DEFAULT_SYNCHRONOUS_VALUE = false;
+
+ /**
+ * The name which acts as an identifier.
+ */
+ private final String m_name;
+
+ /**
+ * The name of the field representing the publisher in the component.
+ */
+ private final String m_field;
+
+ /**
+ * Topics to which events are sent.
+ */
+ private String[] m_topics;
+
+ /**
+ * Events sending mode.
+ */
+ private final boolean m_synchronous;
+
+ /**
+ * The key where user data are stored in the event dictionary.
+ */
+ private final String m_dataKey;
+
+ /**
+ * Constructs a publisher from its metadata description.
+ *
+ * @param publisher the publisher metadata description.
+ * @throws ConfigurationException if the configuration of the component or
+ * the instance is invalid.
+ */
+ public EventAdminPublisherMetadata(Element publisher)
+ throws ConfigurationException {
+
+ /**
+ * Setup required attributes
+ */
+
+ // NAME_ATTRIBUTE
+ if (publisher.containsAttribute(NAME_ATTRIBUTE)) {
+ m_name = publisher.getAttribute(NAME_ATTRIBUTE);
+ } else {
+ throw new ConfigurationException(
+ "Missing required attribute in component configuration : "
+ + NAME_ATTRIBUTE);
+ }
+
+ // FIELD_ATTRIBUTE
+ if (publisher.containsAttribute(FIELD_ATTRIBUTE)) {
+ m_field = publisher.getAttribute(FIELD_ATTRIBUTE);
+ } else {
+ throw new ConfigurationException(
+ "Missing required attribute in component configuration : "
+ + FIELD_ATTRIBUTE);
+ }
+
+ // TOPICS_ATTRIBUTE
+ if (publisher.containsAttribute(TOPICS_ATTRIBUTE)) {
+ setTopics(publisher.getAttribute(TOPICS_ATTRIBUTE));
+ } else {
+ m_topics = null;
+ // Nothing to do if TOPICS_ATTRIBUTE is not present as it can be
+ // overridden in the instance configuration.
+ }
+
+ /**
+ * Setup optional attributes
+ */
+
+ // SYNCHRONOUS_ATTRIBUTE
+ if (publisher.containsAttribute(SYNCHRONOUS_ATTRIBUTE)) {
+ m_synchronous = "true".equalsIgnoreCase(publisher
+ .getAttribute(SYNCHRONOUS_ATTRIBUTE));
+ } else {
+ m_synchronous = DEFAULT_SYNCHRONOUS_VALUE;
+ }
+
+ // DATA_KEY_ATTRIBUTE
+ if (publisher.containsAttribute(DATA_KEY_ATTRIBUTE)) {
+ m_dataKey = publisher.getAttribute(DATA_KEY_ATTRIBUTE);
+ } else if (publisher.containsAttribute("data_key")) {
+ // XML Case
+ m_dataKey = publisher.getAttribute("data_key");
+ } else if (publisher.containsAttribute("dataKey")) {
+ // Annotation case.
+ m_dataKey = publisher.getAttribute("dataKey");
+ } else {
+ m_dataKey = DEFAULT_DATA_KEY_VALUE;
+ }
+ }
+
+ /**
+ * Sets the topics attribute of the publisher.
+ *
+ * @param topicsString the comma separated list of the topics on which
+ * events are sent
+ * @throws ConfigurationException the specified topic string is malformed
+ */
+ public void setTopics(String topicsString) throws ConfigurationException {
+ String[] newTopics = ParseUtils.split(topicsString,
+ EventUtil.TOPIC_SEPARATOR);
+ // Check each topic is valid
+ for (int i = 0; i < newTopics.length; i++) {
+ String topic = newTopics[i];
+ if (!EventUtil.isValidTopic(topic)) {
+ throw new ConfigurationException("Invalid topic : \"" + topic
+ + "\".");
+ }
+ }
+ m_topics = newTopics;
+ }
+
+ /**
+ * Checks that the required instance configurable attributes are all set.
+ *
+ * @throws ConfigurationException if a required attribute is missing
+ */
+ public void check() throws ConfigurationException {
+ if (m_topics == null || m_topics.length == 0) {
+ throw new ConfigurationException(
+ "Missing required attribute in component or instance configuration : "
+ + TOPICS_ATTRIBUTE);
+ }
+ }
+
+ /**
+ * Gets the name attribute of the publisher.
+ *
+ * @return the name
+ */
+ public String getName() {
+ return m_name;
+ }
+
+ /**
+ * Gets the field attribute of the publisher.
+ *
+ * @return the field
+ */
+ public String getField() {
+ return m_field;
+ }
+
+ /**
+ * Gets the topics attribute of the publisher.
+ *
+ * @return the topics
+ */
+ public String[] getTopics() {
+ return m_topics;
+ }
+
+ /**
+ * Gets the synchronous attribute of the publisher.
+ *
+ * @return the synchronous mode
+ */
+ public boolean isSynchronous() {
+ return m_synchronous;
+ }
+
+ /**
+ * Gets the dataKey attribute of the publisher.
+ *
+ * @return the data key
+ */
+ public String getDataKey() {
+ return m_dataKey;
+ }
+}
Added: felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/Publisher.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/Publisher.java?rev=1450816&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/Publisher.java (added)
+++ felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/Publisher.java Wed Feb 27 15:51:08 2013
@@ -0,0 +1,70 @@
+/*
+ * 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.felix.ipojo.handlers.event.publisher;
+
+import java.util.Dictionary;
+
+/**
+ * An Publisher is the interface between the EventAdminPublisherHandler and a
+ * component instance. The POJO can send event through the handler by calling a
+ * {@code send} method.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Publisher {
+
+ /**
+ * Sends an event with the specified content.
+ *
+ * @param content the content of the event
+ */
+ void send(Dictionary content);
+
+ /**
+ * Sends a data event.
+ *
+ * @param o the data to send
+ */
+ void sendData(Object o);
+
+ /**
+ * Gets the published topics.
+ * @return the list of topics.
+ */
+ String[] getTopics();
+
+ /**
+ * Checks is the publisher send data synchronously.
+ * @return <code>true</code> if the publisher is synchronous.
+ */
+ boolean isSynchronous();
+
+ /**
+ * Gets the data key if used.
+ * @return the data key or <code>null</code>
+ */
+ String getDataKey();
+
+ /**
+ * Gets the publisher name if any.
+ * @return the publisher name
+ */
+ String getName();
+
+}
Added: felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherDescription.java?rev=1450816&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherDescription.java (added)
+++ felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherDescription.java Wed Feb 27 15:51:08 2013
@@ -0,0 +1,76 @@
+/*
+ * 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.felix.ipojo.handlers.event.publisher;
+
+/**
+ * Publisher Description.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PublisherDescription {
+
+ /**
+ * The described publisher
+ */
+ private Publisher m_publisher;
+
+ /**
+ * Creates a {@link PublisherDescription} based
+ * on the given {@link Publisher}
+ * @param p the publisher
+ */
+ public PublisherDescription(Publisher p) {
+ m_publisher = p;
+ }
+
+
+ /**
+ * Gets the topic list.
+ * @return the list of published topics
+ */
+ public String[] getTopics() {
+ return m_publisher.getTopics();
+ }
+
+ /**
+ * Checks if the publisher is synchronous.
+ * @return <code>true</code> if the publisher is synchronous
+ */
+ public boolean isSynchronous() {
+ return m_publisher.isSynchronous();
+ }
+
+ /**
+ * Gets the data key if used.
+ * @return the data key
+ */
+ public String getDataKey() {
+ return m_publisher.getDataKey();
+ }
+
+ /**
+ * Gets the publisher name if any.
+ * @return the publisher name
+ */
+ public String getName() {
+ return m_publisher.getName();
+ }
+
+
+}
Added: felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherImpl.java?rev=1450816&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherImpl.java (added)
+++ felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/PublisherImpl.java Wed Feb 27 15:51:08 2013
@@ -0,0 +1,145 @@
+/*
+ * 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.felix.ipojo.handlers.event.publisher;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.service.event.Event;
+
+/**
+ * The PublisherImpl class is the implementation of the Publisher object used by
+ * components to send events.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PublisherImpl implements Publisher {
+
+ /**
+ * The key where the component instance name is stored.
+ */
+ public static final String INSTANCE_NAME_PROPERTY = "publisher.instance.name";
+
+ /**
+ * The managing handler.
+ */
+ private EventAdminPublisherHandler m_handler;
+
+ /**
+ * The topics of sent events.
+ */
+ private final String[] m_topics;
+
+ /**
+ * The sending mode of events.
+ */
+ private final boolean m_synchronous;
+
+ /**
+ * The key, in the content of the event, where user data are stored.
+ */
+ private final String m_dataKey;
+
+ /**
+ * The name of the component instance using this publisher.
+ */
+ private final String m_instanceName;
+
+ /**
+ * Constructs an Publisher with given parameters.
+ *
+ * @param handler the handler that will manage this publisher
+ * @param topics the topics on which events are sent
+ * @param synchronous the sending mode of events
+ * @param dataKey The key, in the content of the event, where user data are
+ * stored (may be {@code null})
+ * @param instanceName the name of the instance creating this publisher.
+ */
+ public PublisherImpl(EventAdminPublisherHandler handler, String[] topics,
+ boolean synchronous, String dataKey, String instanceName) {
+
+ // Initialize the publisher's fields
+ m_handler = handler;
+ m_topics = topics;
+ m_synchronous = synchronous;
+ m_dataKey = dataKey;
+ m_instanceName = instanceName;
+ }
+
+ /**
+ * Sends an event with the specified content.
+ *
+ * @param content the content of the event
+ */
+ public void send(Dictionary content) {
+ // Add instance information in the event
+ content.put(INSTANCE_NAME_PROPERTY, m_instanceName);
+ // We sent the event on each topic
+ for (int i = 0; i < m_topics.length; i++) {
+ // Create an event with the given topic and content
+ Event e = new Event(m_topics[i], content);
+ // Send the event, depending on the sending mode
+ if (!m_synchronous) {
+ m_handler.getEventAdminService().postEvent(e); // Asynchronous
+ } else {
+ m_handler.getEventAdminService().sendEvent(e); // Synchronous
+ }
+ }
+ }
+
+ /**
+ * Sends a data event.
+ *
+ * @param object the data to send
+ */
+ public void sendData(Object object) {
+ // Construct the content of the event with the given object
+ Dictionary content = new Hashtable();
+ content.put(m_dataKey, object);
+ send(content);
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.handlers.event.publisher.Publisher#getTopics()
+ */
+ public String[] getTopics() {
+ return m_topics;
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.handlers.event.publisher.Publisher#isSynchronous()
+ */
+ public boolean isSynchronous() {
+ return m_synchronous;
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.handlers.event.publisher.Publisher#getDataKey()
+ */
+ public String getDataKey() {
+ return m_dataKey;
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.handlers.event.publisher.Publisher#getName()
+ */
+ public String getName() {
+ return m_instanceName;
+ }
+}
Added: felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandler.java?rev=1450816&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandler.java (added)
+++ felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandler.java Wed Feb 27 15:51:08 2013
@@ -0,0 +1,421 @@
+/*
+ * 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.felix.ipojo.handlers.event.subscriber;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.PrimitiveHandler;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.apache.felix.ipojo.handlers.event.EventUtil;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.MethodMetadata;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Callback;
+import org.osgi.framework.Filter;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+
+/**
+ * Event Subscriber Handler.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class EventAdminSubscriberHandler extends PrimitiveHandler implements
+ EventHandler {
+
+ /**
+ * The handler namespace.
+ */
+ public static final String NAMESPACE = "org.apache.felix.ipojo.handlers.event";
+
+ // Names of instance configuration properties.
+
+ /**
+ * The event's topics instance configuration property.
+ */
+ public static final String TOPICS_PROPERTY = "event.topics";
+
+ /**
+ * The event's filter instance configuration property.
+ */
+ public static final String FILTER_PROPERTY = "event.filter";
+
+ /**
+ * The prefix for logged messages.
+ */
+ private static final String LOG_PREFIX = "EVENT ADMIN SUBSCRIBER HANDLER : ";
+
+ /**
+ * The instance manager.
+ */
+ private InstanceManager m_manager;
+
+ /**
+ * The list of subscriber accessible by name.
+ */
+ private final Map m_subscribersByName = new HashMap();
+
+ /**
+ * The list of callbacks accessible by subscribers' names.
+ */
+ private final Map m_callbacksByName = new Hashtable();
+
+ /**
+ * The iPOJO properties representing all the topics.
+ * Immutable.
+ */
+ private String[] m_topics;
+
+ /**
+ * Listening to received events ?
+ */
+ private boolean m_isListening;
+
+ /**
+ * The handler description
+ */
+ private EventAdminSubscriberHandlerDescription m_description;
+
+ /**
+ * Initializes the component type.
+ *
+ * @param cd component type description to populate.
+ * @param metadata component type metadata.
+ * @throws ConfigurationException if the metadata are incorrect.
+ * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(
+ * org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
+ */
+ public void initializeComponentFactory(ComponentTypeDescription cd,
+ Element metadata)
+ throws ConfigurationException {
+
+ // Update the current component description
+ Dictionary dict = new Properties();
+ cd.addProperty(new PropertyDescription(TOPICS_PROPERTY,
+ Dictionary.class.getName(), dict.toString()));
+ dict = new Properties();
+ cd.addProperty(new PropertyDescription(FILTER_PROPERTY,
+ Dictionary.class.getName(), dict.toString()));
+
+ // Get Metadata subscribers
+ Element[] subscribers = metadata.getElements("subscriber", NAMESPACE);
+ if (subscribers != null) {
+
+ // Maps used to check name and field are unique
+ Set nameSet = new HashSet();
+ Set callbackSet = new HashSet();
+
+ // Check all subscribers are well formed
+ for (int i = 0; i < subscribers.length; i++) {
+
+ // Check the subscriber configuration is correct by creating an
+ // unused subscriber metadata
+ EventAdminSubscriberMetadata subscriberMetadata = new EventAdminSubscriberMetadata(
+ getFactory().getBundleContext(), subscribers[i]);
+
+ String name = subscriberMetadata.getName();
+ info(LOG_PREFIX + "Checking subscriber " + name);
+
+ // Determine the event callback prototype
+ PojoMetadata pojoMetadata = getPojoMetadata();
+ String callbackType;
+ if (subscriberMetadata.getDataKey() == null) {
+ callbackType = Event.class.getName();
+ } else {
+ callbackType = subscriberMetadata.getDataType().getName();
+ }
+
+ // Check the event callback method is present
+ MethodMetadata methodMetadata = pojoMetadata.getMethod(
+ subscriberMetadata.getCallback(),
+ new String[] { callbackType });
+ String callbackSignature = subscriberMetadata.getCallback()
+ + "(" + callbackType + ")";
+ if (methodMetadata == null) {
+ throw new ConfigurationException(
+ "Cannot find callback method " + callbackSignature);
+ }
+
+ // Warn if the same callback is used by several subscribers
+ if (callbackSet.contains(callbackSignature)) {
+ warn("The callback method is already used by another subscriber : "
+ + callbackSignature);
+ } else {
+ callbackSet.add(callbackSignature);
+ }
+
+ // Check name is unique
+ if (nameSet.contains(name)) {
+ throw new ConfigurationException(
+ "A subscriber with the same name already exists : "
+ + name);
+ }
+ nameSet.add(name);
+ }
+
+ m_description = new EventAdminSubscriberHandlerDescription(this,
+ subscribers);
+
+ } else {
+ info(LOG_PREFIX + "No subscriber to check");
+ }
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param metadata the omponent type metadata
+ * @param conf the instance configuration
+ * @throws ConfigurationException if one event subscription is not correct
+ * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+ */
+ public void configure(Element metadata, Dictionary conf)
+ throws ConfigurationException {
+
+ // Store the component manager
+ m_manager = getInstanceManager();
+
+ // Get the topics and filter instance configuration
+ Dictionary instanceTopics = (Dictionary) conf.get(TOPICS_PROPERTY);
+ Dictionary instanceFilter = (Dictionary) conf.get(FILTER_PROPERTY);
+
+ // Get Metadata subscribers
+ Element[] subscribers = metadata.getElements("subscriber", NAMESPACE);
+
+ // The topics to listen
+ Set topics = new TreeSet();
+
+ if (subscribers != null) {
+
+ // Configure all subscribers
+ for (int i = 0; i < subscribers.length; i++) {
+
+ // Extract the subscriber configuration
+ EventAdminSubscriberMetadata subscriberMetadata = new EventAdminSubscriberMetadata(
+ m_manager.getContext(), subscribers[i]);
+ String name = subscriberMetadata.getName();
+ info(LOG_PREFIX + "Configuring subscriber " + name);
+
+ // Get the topics instance configuration if redefined
+ String topicsString = (instanceTopics != null) ? (String) instanceTopics.get(name) : null;
+ if (topicsString != null) {
+ subscriberMetadata.setTopics(topicsString);
+ }
+
+ // Get the filter instance configuration if redefined
+ String filterString = (instanceFilter != null) ? (String) instanceFilter.get(name) : null;
+ if (filterString != null) {
+ subscriberMetadata.setFilter(filterString);
+ }
+
+ // Check the publisher is correctly configured
+ subscriberMetadata.check();
+
+ // Add this subscriber's topics to the global list
+ String[] subscriberTopics = subscriberMetadata.getTopics();
+ for (int j = 0; j < subscriberTopics.length; j++) {
+ topics.add(subscriberTopics[j]);
+ }
+
+ // Determine the event callback prototype
+ PojoMetadata pojoMetadata = getPojoMetadata();
+ String callbackType;
+ if (subscriberMetadata.getDataKey() == null) {
+ callbackType = Event.class.getName();
+ } else {
+ callbackType = subscriberMetadata.getDataType().getName();
+ }
+
+ // Create the specified callback and register it
+ MethodMetadata methodMetadata = pojoMetadata.getMethod(
+ subscriberMetadata.getCallback(),
+ new String[] { callbackType });
+ Callback callback = new Callback(methodMetadata, m_manager);
+ m_callbacksByName.put(name, callback);
+
+ // Add the subscriber list gloal map
+ m_subscribersByName.put(name, subscriberMetadata);
+ }
+
+ // Construct the global topic list
+ m_topics = new String[topics.size()];
+ int i = 0;
+ for (Iterator iterator = topics.iterator(); iterator.hasNext();) {
+ String tmp = (String) iterator.next();
+ m_topics[i++] = tmp;
+ }
+
+ m_description = new EventAdminSubscriberHandlerDescription(this,
+ subscribers);
+
+ } else {
+ info(LOG_PREFIX + "No subscriber to configure");
+ }
+ }
+
+ /**
+ * Handler start method.
+ *
+ * @see org.apache.felix.ipojo.Handler#start()
+ */
+ public synchronized void start() {
+ m_isListening = true;
+ }
+
+ /**
+ * Handler stop method.
+ *
+ * @see org.apache.felix.ipojo.Handler#stop()
+ */
+ public synchronized void stop() {
+ m_isListening = false;
+ }
+
+ /**
+ * @see org.apache.felix.ipojo.Handler#getDescription()
+ */
+ public HandlerDescription getDescription() {
+ return m_description;
+ }
+
+ /***************************************************************************
+ * OSGi EventHandler callback
+ **************************************************************************/
+
+ /**
+ * Receives an event. The event is dispatch to attached subscribers.
+ *
+ * @param event the received event.
+ * @see org.osgi.service.event.EventHandler#handleEvent(org.osgi.service.event.Event)
+ */
+ public void handleEvent(final Event event) {
+ EventAdminSubscriberMetadata subscriberMetadata = null;
+ // Retrieve the event's topic
+ String topic = event.getTopic();
+
+ // For each subscribers
+ Collection subscribers = m_subscribersByName.values();
+ for (Iterator i = subscribers.iterator(); i.hasNext();) {
+ subscriberMetadata = (EventAdminSubscriberMetadata) i.next();
+
+ // Stack confinement
+ boolean isListening = false;
+
+ Object callbackParam = null;
+ Callback callback = null;
+
+ synchronized (this) {
+ isListening = m_isListening;
+ }
+
+ // Check if the subscriber's topic and filter match
+ Filter filter = subscriberMetadata.getFilter();
+
+ if (EventUtil.matches(topic, subscriberMetadata.getTopics())
+ && (filter == null || event.matches(filter))) {
+
+ String name = subscriberMetadata.getName();
+ callback = (Callback) m_callbacksByName.get(name);
+
+ try {
+ // Depending on the subscriber type...
+ callbackParam = getCallbackParameter(event,
+ subscriberMetadata);
+ } catch (ClassCastException e) {
+ // Ignore the data event if type doesn't match
+ warn(LOG_PREFIX + "Ignoring data event : Bad data type", e);
+ } catch (NoSuchFieldException e) {
+ // Ignore events without data field for data events
+ // subscriber
+ warn(LOG_PREFIX + "Ignoring data event : No data", e);
+ }
+ }
+
+
+ // Run the callback (final check to avoid
+ // NullPointerExceptions)
+ if (isListening && callback != null && callbackParam != null) {
+ try {
+ callback.call(new Object[] { callbackParam });
+ } catch (InvocationTargetException e) {
+ error(LOG_PREFIX
+ + "The callback has thrown an exception",
+ e.getTargetException());
+ } catch (Exception e) {
+ error(LOG_PREFIX
+ + "Unexpected exception when calling callback",
+ e);
+ }
+ }
+
+ }
+ }
+
+ /**
+ * Computes the callback parameter.
+ * @param event the event
+ * @param subscriberMetadata the subscribe metadata
+ * @param dataKey the data key
+ * @return the parameter of the callback
+ * @throws ClassCastException the data class does not match the found value.
+ * @throws NoSuchFieldException the datakey is not present in the event.
+ */
+ private Object getCallbackParameter(final Event event,
+ final EventAdminSubscriberMetadata subscriberMetadata
+ ) throws ClassCastException,NoSuchFieldException {
+ String dataKey = subscriberMetadata.getDataKey();
+ if (dataKey == null) {
+ // Generic event subscriber : pass the event to the
+ // registered callback
+ return event;
+ } else {
+ // Check for a data key in the event
+ boolean dataKeyPresent = false;
+ String[] properties = event.getPropertyNames();
+ for (int j = 0; j < properties.length && !dataKeyPresent; j++) {
+ if (dataKey.equals(properties[j])) {
+ dataKeyPresent = true;
+ }
+ }
+
+ if (dataKeyPresent) {
+ // Data event : check type compatibility and
+ // pass the given object to the registered
+ // callback
+ Object data = event.getProperty(dataKey);
+ Class dataType = subscriberMetadata.getDataType();
+ Class dataClazz = data.getClass();
+ if (dataType.isAssignableFrom(dataClazz)) {
+ return data;
+ } else {
+ throw new ClassCastException("Cannot convert " + dataClazz.getName() + " to "
+ + dataType.getName());
+ }
+ } else {
+ throw new java.lang.NoSuchFieldException(dataKey);
+ }
+
+ }
+ }
+}
Added: felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandlerDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandlerDescription.java?rev=1450816&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandlerDescription.java (added)
+++ felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberHandlerDescription.java Wed Feb 27 15:51:08 2013
@@ -0,0 +1,61 @@
+/*
+ * 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.felix.ipojo.handlers.event.subscriber;
+
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Event Admin Subscriber Handler Description.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class EventAdminSubscriberHandlerDescription extends HandlerDescription {
+
+ /**
+ * List of subscribers.
+ */
+ private Element[] m_subscribersDescriptions;
+
+ /**
+ * Creates a {@link EventAdminSubscriberHandlerDescription}
+ * @param handler the handler
+ * @param subscribers the subscribers
+ */
+ public EventAdminSubscriberHandlerDescription(Handler handler, Element[] subscribers) {
+ super(handler);
+ m_subscribersDescriptions = subscribers;
+ }
+
+ /**
+ * Gets the handler info.
+ * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+ */
+ public Element getHandlerInfo() {
+ Element root = super.getHandlerInfo();
+ if (m_subscribersDescriptions != null) {
+ for (int i = 0; i < m_subscribersDescriptions.length; i++) {
+ Element description = m_subscribersDescriptions[i];
+ root.addElement(description);
+ }
+ }
+ return root;
+ }
+}
Added: felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java?rev=1450816&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java (added)
+++ felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java Wed Feb 27 15:51:08 2013
@@ -0,0 +1,305 @@
+/*
+ * 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.felix.ipojo.handlers.event.subscriber;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.handlers.event.EventUtil;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ParseUtils;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * Represent an subscriber.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+class EventAdminSubscriberMetadata {
+
+ // Names of metadata attributes
+
+ /**
+ * The name attribute in the component metadata.
+ */
+ public static final String NAME_ATTRIBUTE = "name";
+
+ /**
+ * The callback attribute in the component metadata.
+ */
+ public static final String CALLBACK_ATTRIBUTE = "callback";
+
+ /**
+ * The topics attribute in the component metadata.
+ */
+ public static final String TOPICS_ATTRIBUTE = "topics";
+
+ /**
+ * The data key attribute in the component metadata.
+ */
+ public static final String DATA_KEY_ATTRIBUTE = "data-key";
+
+ /**
+ * The data type attribute in the component metadata.
+ */
+ public static final String DATA_TYPE_ATTRIBUTE = "data-type";
+
+ /**
+ * The filter attribute in the component metadata.
+ */
+ public static final String FILTER_ATTRIBUTE = "filter";
+
+ // Default values
+
+ /**
+ * The data type atttribute's default value.
+ */
+ public static final Class DEFAULT_DATA_TYPE_VALUE = java.lang.Object.class;
+
+ /**
+ * The name which acts as an identifier.
+ */
+ private final String m_name;
+
+ /**
+ * Name of the callback method.
+ */
+ private final String m_callback;
+
+ /**
+ * Listened topics.
+ */
+ private String[] m_topics;
+
+ /**
+ * The key where user data are stored in the event dictionary.
+ */
+ private String m_dataKey;
+
+ /**
+ * The type of received data.
+ */
+ private final Class m_dataType;
+
+ /**
+ * Event filter.
+ */
+ private Filter m_filter;
+
+ /**
+ * The context of the bundle.
+ */
+ private final BundleContext m_bundleContext;
+
+ /**
+ * Constructor.
+ *
+ * @param bundleContext the bundle context of the managed instance.
+ * @param subscriber the subscriber metadata.
+ * @throws ConfigurationException if the configuration of the component or
+ * the instance is invalid.
+ */
+ public EventAdminSubscriberMetadata(BundleContext bundleContext,
+ Element subscriber) throws ConfigurationException {
+ m_bundleContext = bundleContext;
+
+ /**
+ * Setup required attributes
+ */
+
+ // NAME_ATTRIBUTE
+ if (subscriber.containsAttribute(NAME_ATTRIBUTE)) {
+ m_name = subscriber.getAttribute(NAME_ATTRIBUTE);
+ } else {
+ throw new ConfigurationException(
+ "Missing required attribute in component configuration : "
+ + NAME_ATTRIBUTE);
+ }
+
+ // CALLBACK_ATTRIBUTE
+ if (subscriber.containsAttribute(CALLBACK_ATTRIBUTE)) {
+ m_callback = subscriber.getAttribute(CALLBACK_ATTRIBUTE);
+ } else if (subscriber.containsAttribute("method")) {
+ m_callback = subscriber.getAttribute("method");
+ } else {
+ throw new ConfigurationException(
+ "Missing required attribute in component configuration : "
+ + CALLBACK_ATTRIBUTE);
+ }
+
+ // TOPICS_ATTRIBUTE
+ if (subscriber.containsAttribute(TOPICS_ATTRIBUTE)) {
+ setTopics(subscriber.getAttribute(TOPICS_ATTRIBUTE));
+ } else {
+ m_topics = null;
+ // Nothing to do if TOPICS_ATTRIBUTE is not present as it can be
+ // overridden in the instance configuration.
+ }
+
+ /**
+ * Setup optional attributes
+ */
+
+ // DATA_KEY_ATTRIBUTE
+ m_dataKey = subscriber.getAttribute(DATA_KEY_ATTRIBUTE);
+ if (m_dataKey == null) { // Alternative configurations (data_key and dataKey)
+ // XML
+ m_dataKey = subscriber.getAttribute("data_key");
+ if (m_dataKey == null) {
+ // Annotation
+ m_dataKey = subscriber.getAttribute("dataKey");
+ }
+ }
+
+ String t = subscriber.getAttribute(DATA_TYPE_ATTRIBUTE);
+ if (t == null) { // Alternative configurations
+ // XML
+ t = subscriber.getAttribute("data_type");
+ if (t == null) {
+ /// Annotation
+ t = subscriber.getAttribute("dataType");
+ }
+ }
+
+ if (t != null) {
+ // Check that the data-key attribute is set.
+ if (m_dataKey == null) {
+ throw new ConfigurationException(
+ "Missing attribute in component configuration : "
+ + DATA_KEY_ATTRIBUTE);
+ }
+ Class type;
+ try {
+ type = m_bundleContext.getBundle().loadClass(t);
+ } catch (ClassNotFoundException e) {
+ throw new ConfigurationException("Data type class not found : "
+ + t);
+ }
+ m_dataType = type;
+ } else {
+ m_dataType = DEFAULT_DATA_TYPE_VALUE;
+ }
+
+ // FILTER_ATTRIBUTE
+ if (subscriber.containsAttribute(FILTER_ATTRIBUTE)) {
+ setFilter(subscriber.getAttribute(FILTER_ATTRIBUTE));
+ }
+ }
+
+ /**
+ * Sets the topics attribute of the subscriber.
+ *
+ * @param topicsString the comma separated list of the topics to listen
+ * @throws ConfigurationException if the specified topic list is malformed
+ */
+ public void setTopics(String topicsString) throws ConfigurationException {
+ String[] newTopics = ParseUtils.split(topicsString,
+ EventUtil.TOPIC_SEPARATOR);
+ // Check each topic is valid
+ for (int i = 0; i < newTopics.length; i++) {
+ String topicScope = newTopics[i];
+ if (!EventUtil.isValidTopicScope(topicScope)) {
+ throw new ConfigurationException("Invalid topic scope : \""
+ + topicScope + "\".");
+ }
+ }
+ m_topics = newTopics;
+ }
+
+ /**
+ * Sets the filter attribute of the subscriber.
+ *
+ * @param filterString the string representation of the event filter
+ * @throws ConfigurationException if the LDAP filter is malformed
+ */
+ public void setFilter(String filterString) throws ConfigurationException {
+ try {
+ m_filter = m_bundleContext.createFilter(filterString);
+ } catch (InvalidSyntaxException e) {
+ throw new ConfigurationException("Invalid filter syntax");
+ }
+ }
+
+ /**
+ * Checks that the required instance configurable attributes are all set.
+ *
+ * @throws ConfigurationException if a required attribute is missing
+ */
+ public void check() throws ConfigurationException {
+ if (m_topics == null || m_topics.length == 0) {
+ throw new ConfigurationException(
+ "Missing required attribute in component or instance configuration : "
+ + TOPICS_ATTRIBUTE);
+ }
+ }
+
+ /**
+ * Gets the name attribute of the subscriber.
+ *
+ * @return the name
+ */
+ public String getName() {
+ return m_name;
+ }
+
+ /**
+ * Gets the topics attribute of the subscriber.
+ *
+ * @return the topics
+ */
+ public String[] getTopics() {
+ return m_topics;
+ }
+
+ /**
+ * Gets the callback attribute of the subscriber.
+ *
+ * @return the callback
+ */
+ public String getCallback() {
+ return m_callback;
+ }
+
+ /**
+ * Gets the data key attribute of the subscriber.
+ *
+ * @return the dataKey
+ */
+ public String getDataKey() {
+ return m_dataKey;
+ }
+
+ /**
+ * Gets the data type attribute of the subscriber.
+ *
+ * @return the dataType
+ */
+ public Class getDataType() {
+ return m_dataType;
+ }
+
+ /**
+ * Gets the filter attribute of the subscriber.
+ *
+ * @return the filter
+ */
+ public Filter getFilter() {
+ return m_filter;
+ }
+}
Added: felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/resources/event-admin.xsd
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/resources/event-admin.xsd?rev=1450816&view=auto
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/resources/event-admin.xsd (added)
+++ felix/trunk/ipojo/handler/eventadmin/eventadmin-handler/src/main/resources/event-admin.xsd Wed Feb 27 15:51:08 2013
@@ -0,0 +1,90 @@
+<!--
+ 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.
+-->
+<xs:schema targetNamespace="org.apache.felix.ipojo.handlers.event"
+ xmlns="org.apache.felix.ipojo.handlers.event"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+
+ <xs:complexType name="PublisherType">
+ <xs:annotation>
+ <xs:documentation>Description of an event publisher.</xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="name" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation>The name of the event publisher, acting as a unique identifier.
+The name of the POJO's field that will be used to send events. The field is initialized at component instantiation time. The type of the field must be "org.apache.felix.ipojo.handlers.event.publisher.Publisher".</xs:documentation>
+ </xs:annotation></xs:attribute>
+ <xs:attribute name="field" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation>The name of the POJO field associated to this event publisher.
+Despite it creates a dependency between the component code and the handler, this system allows hiding the whole complexity of event sending.</xs:documentation>
+ </xs:annotation></xs:attribute>
+ <xs:attribute name="topics" type="xs:string" use="optional">
+ <xs:annotation>
+ <xs:documentation>The comma-separated-list of the topics on which events will be sent. All subscribers that are listening to one of these topics will receive the events.</xs:documentation></xs:annotation></xs:attribute>
+ <xs:attribute name="synchronous" type="xs:boolean" use="optional">
+ <xs:annotation>
+ <xs:documentation>Determines if event sending is synchronous or not. By default, events are sent asynchronously, but you can specify there the desired behaviour of the Publisher.
+The default value of this attribute is "false".</xs:documentation>
+ </xs:annotation></xs:attribute>
+ <xs:attribute name="data-key" type="xs:string" use="optional">
+ <xs:annotation>
+ <xs:documentation>The data key is used when you want to send data events. This attribute's value is the key, in the event's dictionary, in which sent data are stored. When you use the sendData method of the Publisher, the given object is placed in the event dictionary, associated with the specified data-key.
+The default value of this attribute is user.data.</xs:documentation></xs:annotation></xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="SubscriberType">
+ <xs:annotation>
+ <xs:documentation>Description of an event subscriber.</xs:documentation>
+ </xs:annotation>
+ <xs:attribute name="name" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation>The name of the event subscriber, acting as a unique identifier.</xs:documentation></xs:annotation></xs:attribute>
+ <xs:attribute name="callback" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation>The name of the POJO's method that will be called each time an event is received.
+This method takes only one parameter, of typeorg.osgi.service.event.Eventby default, but this type can be overridden by defining the data-key and/or the data-type attributes.</xs:documentation>
+ </xs:annotation></xs:attribute>
+ <xs:attribute name="topics" type="xs:string" use="optional">
+ <xs:annotation>
+ <xs:documentation>The comma-separated-list of the topics that the handler will listen to. Each event sent on a topic present in this list will be sent to the specified callback method.</xs:documentation></xs:annotation></xs:attribute>
+ <xs:attribute name="filter" type="xs:string" use="optional">
+ <xs:annotation>
+ <xs:documentation>The event filter is used to filter incoming events before sending them to the callback.
+The syntax of this field is described in the OSGi EventAdmin Specification. If you don't specify a filter, all events sent on the listened topics will be considered.</xs:documentation>
+ </xs:annotation></xs:attribute>
+ <xs:attribute name="data-key" type="xs:string" use="optional">
+ <xs:annotation>
+ <xs:documentation>The data key is used when you want to receive data events. This attribute's value is the key corresponding to the received data in the event's dictionary.
+If you use this attribute, the parameter passed to the callback method is the the value associated to this key, not the whole event.
+This attribute is generally used with the data-typeattribute to specify the received object type.
+If an event is received and it does not contain such a key, it is ignored (with a warning message).</xs:documentation>
+ </xs:annotation></xs:attribute>
+ <xs:attribute name="data-type" type="xs:string" use="optional">
+ <xs:annotation>
+ <xs:documentation>This attribute is associated to the data-key attribute. It specifies the type of objects (java.lang.Object by default) that the callback expects.
+It is used to determine the unique callback method (in case of multiple methods with the same name) and to check type compliance at event reception.
+Data events that are not corresponding to the specified type will be ignored (with a warning message).</xs:documentation>
+ </xs:annotation></xs:attribute>
+ </xs:complexType>
+
+ <xs:element name="publisher" type="PublisherType"></xs:element>
+ <xs:element name="subscriber" type="SubscriberType"></xs:element>
+
+</xs:schema>
\ No newline at end of file
Modified: felix/trunk/ipojo/handler/eventadmin/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/pom.xml?rev=1450816&r1=1450815&r2=1450816&view=diff
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/pom.xml (original)
+++ felix/trunk/ipojo/handler/eventadmin/pom.xml Wed Feb 27 15:51:08 2013
@@ -16,107 +16,112 @@
specific language governing permissions and limitations
under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <groupId>org.apache.felix</groupId>
- <artifactId>felix-parent</artifactId>
- <version>1.2.1</version>
- <relativePath>../../pom/pom.xml</relativePath>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <packaging>bundle</packaging>
- <name>Apache Felix iPOJO Event Admin Handler</name>
- <artifactId>org.apache.felix.ipojo.handler.eventadmin</artifactId>
- <version>1.9.0-SNAPSHOT</version>
-
- <description>
- iPOJO extension to easily interact with the OSGi Event Admin.
- </description>
- <url>http://felix.apache.org/site/event-admin-handlers.html</url>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.ipojo</artifactId>
- <version>1.6.0</version>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <version>4.0.0</version>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <version>4.0.0</version>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
<groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>1.4.3</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>org.apache.felix.ipojo.handlers.event*;version="1.2.0"</Export-Package>
- <Bundle-Name>${project.name}</Bundle-Name>
- <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
- <Bundle-Description> iPOJO Event Admin Handlers
- </Bundle-Description>
- <Bundle-DocURL>
- http://felix.apache.org/site/event-admin-handlers.html
- </Bundle-DocURL>
- <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
- <Include-Resource>
- META-INF/LICENSE=LICENSE,
- META-INF/NOTICE=NOTICE,
- META-INF/DEPENDENCIES=DEPENDENCIES
- </Include-Resource>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-ipojo-plugin</artifactId>
- <version>1.9.0-SNAPSHOT</version>
- <executions>
- <execution>
- <goals>
- <goal>ipojo-bundle</goal>
- </goals>
- <configuration>
- <metadata>metadata.xml</metadata>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>rat-maven-plugin</artifactId>
- <configuration>
- <excludeSubProjects>false</excludeSubProjects>
- <useEclipseDefaultExcludes>true</useEclipseDefaultExcludes>
- <useMavenDefaultExcludes>true</useMavenDefaultExcludes>
- <excludes>
- <param>doc/**/*</param>
- <param>maven-eclipse.xml</param>
- <param>.checkstyle</param>
- <param>.externalToolBuilders/*</param>
- <param>LICENSE.asm</param>
- </excludes>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-checkstyle-plugin</artifactId>
- <configuration>
- <enableRulesSummary>false</enableRulesSummary>
- <violationSeverity>warning</violationSeverity>
- <configLocation>http://felix.apache.org/ipojo/dev/checkstyle_ipojo.xml</configLocation>
- </configuration>
- </plugin>
- </plugins>
- </build>
+ <artifactId>felix-parent</artifactId>
+ <version>1.2.1</version>
+ <relativePath>../../pom/pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>org.apache.felix.ipojo.handler.event-admin-handler-project</artifactId>
+ <version>1.9.0-SNAPSHOT</version>
+ <name>Apache Felix iPOJO Event Admin Handler Project</name>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>eventadmin-handler</module>
+ <module>eventadmin-handler-it</module>
+ </modules>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ </resource>
+ <resource>
+ <directory>.</directory>
+ <targetPath>META-INF</targetPath>
+ <includes>
+ <include>LICENSE*</include>
+ <include>NOTICE*</include>
+ <include>DEPENDENCIES*</include>
+ </includes>
+ </resource>
+ </resources>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>test</id>
+ <modules>
+ <module>core-it</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>test-all</id>
+ <modules>
+ <module>core-it</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>project</descriptorRef>
+ </descriptorRefs>
+ <!-- we don't want to attach all the assemblies, such as bz2 -->
+ <attach>false</attach>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <!-- only attach the project and bin assemblies, in tar.gz and zip flavors -->
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-assemblies</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>
+ ${project.build.directory}/${project.artifactId}-${project.version}-project.tar.gz
+ </file>
+ <classifier>project</classifier>
+ <type>tar.gz</type>
+ </artifact>
+ <artifact>
+ <file>
+ ${project.build.directory}/${project.artifactId}-${project.version}-project.zip
+ </file>
+ <classifier>project</classifier>
+ <type>zip</type>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
</project>