blob: 376df3e57488cdfa86fe16034a43f58922783f04 [file] [log] [blame]
/*
* 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 configuration
m_dataKey = subscriber.getAttribute("data_key");
}
String t = subscriber.getAttribute(DATA_TYPE_ATTRIBUTE);
if (t == null) { // Alternative configuration
t = subscriber.getAttribute("data_type");
}
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;
}
}