blob: 2c837a31acc15af756d0cd3fe81475081856fc3f [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.composite.service.importer;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import org.apache.felix.ipojo.CompositeHandler;
import org.apache.felix.ipojo.CompositeManager;
import org.apache.felix.ipojo.ServiceContext;
import org.apache.felix.ipojo.architecture.HandlerDescription;
import org.apache.felix.ipojo.metadata.Element;
import org.apache.felix.ipojo.util.Logger;
import org.osgi.framework.BundleContext;
/**
* This handler manages the import and the export of services from /
* to the parent context.
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class ImportExportHandler extends CompositeHandler {
/**
* Composite Manager.
*/
private CompositeManager m_manager;
/**
* Service Scope.
*/
private ServiceContext m_scope;
/**
* Parent context.
*/
private BundleContext m_context;
/**
* List of importers.
*/
private List m_importers = new ArrayList();
/**
* List of exporters.
*/
private List m_exporters = new ArrayList();
/**
* Is the handler valid ?
*/
private boolean m_valid;
/**
* Configure the handler.
*
* @param im : the instance manager
* @param metadata : the metadata of the component
* @param conf : the instance configuration
* @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
* org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
*/
public void configure(CompositeManager im, Element metadata, Dictionary conf) {
m_manager = im;
m_context = im.getContext();
m_scope = m_manager.getServiceContext();
Element[] imp = metadata.getElements("requires");
//DEPRECATED BLOCK:
if (imp.length == 0) {
imp = metadata.getElements("import");
if (imp.length != 0) {
im.getFactory().getLogger().log(Logger.WARNING, "Import is deprecated, please use 'requires' instead of 'import'");
}
}
// END OF DEPRECATED BLOCK
Element[] exp = metadata.getElements("export");
for (int i = 0; i < imp.length; i++) {
boolean optional = false;
boolean aggregate = false;
String specification = null;
if (!imp[i].containsAttribute("specification")) { // Malformed import
im.getFactory().getLogger().log(Logger.ERROR, "Malformed import : the specification attribute is mandatory");
} else {
specification = imp[i].getAttribute("specification");
String filter = "(&(objectClass=" + specification + ")(!(service.pid=" + m_manager.getInstanceName() + ")))"; // Cannot import yourself
if (imp[i].containsAttribute("optional") && imp[i].getAttribute("optional").equalsIgnoreCase("true")) {
optional = true;
}
if (imp[i].containsAttribute("aggregate") && imp[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
aggregate = true;
}
if (imp[i].containsAttribute("filter")) {
if (!imp[i].getAttribute("filter").equals("")) {
filter = "(&" + filter + imp[i].getAttribute("filter") + ")";
}
}
ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, m_context, m_scope, this);
m_importers.add(si);
}
}
for (int i = 0; i < exp.length; i++) {
boolean optional = false;
boolean aggregate = false;
String specification = null;
if (!exp[i].containsAttribute("specification")) { // Malformed exports
im.getFactory().getLogger().log(Logger.ERROR, "Malformed exports : the specification attribute is mandatory");
} else {
specification = exp[i].getAttribute("specification");
String filter = "(objectClass=" + specification + ")";
if (exp[i].containsAttribute("optional") && exp[i].getAttribute("optional").equalsIgnoreCase("true")) {
optional = true;
}
if (exp[i].containsAttribute("aggregate") && exp[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
aggregate = true;
}
if (exp[i].containsAttribute("filter")) {
String classnamefilter = "(objectClass=" + specification + ")";
filter = "";
if (!imp[i].getAttribute("filter").equals("")) {
filter = "(&" + classnamefilter + exp[i].getAttribute("filter") + ")";
} else {
filter = classnamefilter;
}
}
ServiceExporter si = new ServiceExporter(specification, filter, aggregate, optional, m_scope, m_context, this);
// Update the component type description
m_manager.getComponentDescription().addProvidedServiceSpecification(specification);
m_exporters.add(si);
}
}
if (m_importers.size() > 0 || m_exporters.size() > 0) {
im.register(this);
}
}
/**
* Start the handler.
* Start importers and exporters.
* @see org.apache.felix.ipojo.CompositeHandler#start()
*/
public void start() {
for (int i = 0; i < m_importers.size(); i++) {
ServiceImporter si = (ServiceImporter) m_importers.get(i);
si.start();
}
for (int i = 0; i < m_exporters.size(); i++) {
ServiceExporter se = (ServiceExporter) m_exporters.get(i);
se.start();
}
}
/**
* Stop the handler.
* Stop all importers and exporters.
* @see org.apache.felix.ipojo.CompositeHandler#stop()
*/
public void stop() {
for (int i = 0; i < m_importers.size(); i++) {
ServiceImporter si = (ServiceImporter) m_importers.get(i);
si.stop();
}
for (int i = 0; i < m_exporters.size(); i++) {
ServiceExporter se = (ServiceExporter) m_exporters.get(i);
se.stop();
}
}
/**
* Check the handler validity.
* @return true if all importers and exporters are valid
* @see org.apache.felix.ipojo.CompositeHandler#isValid()
*/
public boolean isValid() {
for (int i = 0; i < m_importers.size(); i++) {
ServiceImporter si = (ServiceImporter) m_importers.get(i);
if (!si.isSatisfied()) {
m_valid = false;
return false;
}
}
for (int i = 0; i < m_exporters.size(); i++) {
ServiceExporter se = (ServiceExporter) m_exporters.get(i);
if (!se.isSatisfied()) {
m_valid = false;
return false;
}
}
m_valid = true;
return true;
}
/**
* Notify the handler that an importer is no more valid.
*
* @param importer : the implicated importer.
*/
protected void invalidating(ServiceImporter importer) {
// An import is no more valid
if (m_valid) {
m_manager.checkInstanceState();
}
}
/**
* Notify the handler that an importer becomes valid.
*
* @param importer : the implicated importer.
*/
protected void validating(ServiceImporter importer) {
// An import becomes valid
if (!m_valid && isValid()) {
m_manager.checkInstanceState();
}
}
/**
* Notify the handler that an exporter becomes invalid.
*
* @param exporter : the implicated exporter.
*/
protected void invalidating(ServiceExporter exporter) {
// An import is no more valid
if (m_valid) {
m_manager.checkInstanceState();
}
}
/**
* Notify the handler that an exporter becomes valid.
*
* @param exporter : the implicated exporter.
*/
protected void validating(ServiceExporter exporter) {
// An import becomes valid
if (!m_valid && isValid()) {
m_manager.checkInstanceState();
}
}
/**
* Get the composite manager.
* @return the attached composite manager.
*/
protected CompositeManager getManager() {
return m_manager;
}
/**
* Get the import / export handler description.
* @return the handler description
* @see org.apache.felix.ipojo.CompositeHandler#getDescription()
*/
public HandlerDescription getDescription() {
return new ImportExportDescription(this.getClass().getName(), isValid(), m_importers, m_exporters);
}
}