/* * 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; } }