blob: 25258b422a1b8e7fa1ce2edac35f8baa3784fec9 [file] [log] [blame]
/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed 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.axis2.osgi.deployment;
import org.apache.axis2.AxisFault;
import org.apache.axis2.util.Utils;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.deployment.DeploymentEngine;
import org.apache.axis2.deployment.ModuleBuilder;
import org.apache.axis2.description.AxisModule;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.AxisServiceGroup;
import org.apache.axis2.description.Version;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.modules.Module;
import static org.apache.axis2.osgi.deployment.OSGiAxis2Constants.OSGi_BUNDLE_ID;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import java.io.IOException;
import java.net.URL;
import java.util.*;
/**
* @see org.osgi.framework.BundleListener
*/
public class ModuleRegistry extends AbstractRegistry<AxisModule> {
private static Log log = LogFactory.getLog(ModuleRegistry.class);
private Registry serviceRegistry;
public ModuleRegistry(BundleContext context, ConfigurationContext configCtx,
Registry serviceRegistry) {
super(context, configCtx);
this.serviceRegistry = serviceRegistry;
}
public void register(Bundle bundle) {
lock.lock();
try {
addModules(bundle);
} finally {
lock.unlock();
}
}
public void unRegister(Bundle bundle, boolean uninstall) {
lock.lock();
try {
List<AxisModule> moduleList = resolvedBundles.get(bundle);
if (moduleList != null) {
List<Long> stopBundleList = new ArrayList<Long>();
for (AxisModule module : moduleList) {
AxisConfiguration axisConfig = configCtx.getAxisConfiguration();
for (Iterator iterator = axisConfig.getServiceGroups(); iterator.hasNext();) {
AxisServiceGroup axisServiceGroup = (AxisServiceGroup) iterator.next();
if (axisServiceGroup.isEngaged(module)) {
Long value = (Long) axisServiceGroup.getParameterValue(OSGi_BUNDLE_ID);
if (value != null) {
stopBundleList.add(value);
}
}
}
//
HashMap serviceMap = axisConfig.getServices();
Collection values = serviceMap.values();
for (Object value1 : values) {
AxisService axisService = (AxisService) value1;
if (axisService.isEngaged(module)) {
Long value = (Long) axisService.getParameterValue(OSGi_BUNDLE_ID);
if (value != null && !stopBundleList.contains(value)) {
stopBundleList.add(value);
}
}
for (Iterator iterator1 = axisService.getOperations(); iterator1.hasNext();)
{
AxisOperation axisOperation = (AxisOperation) iterator1.next();
if (axisOperation.isEngaged(module)) {
Long value = (Long) axisOperation.getParameterValue(OSGi_BUNDLE_ID);
if (value != null && !stopBundleList.contains(value)) {
stopBundleList.add(value);
}
}
}
}
Module moduleInterface = module.getModule();
if (moduleInterface != null) {
try {
moduleInterface.shutdown(configCtx);
} catch (AxisFault e) {
String msg = "Error while shutting down the module : " +
module.getName() + " : " +
module.getVersion() + " moduel in Bundle - " +
bundle.getSymbolicName();
log.error(msg, e);
}
}
axisConfig.removeModule(module.getName(), module.getVersion());
if (resolvedBundles.containsKey(bundle)) {
resolvedBundles.remove(bundle);
}
log.info("[Axis2/OSGi] Stopping :" + module.getName() + " : " +
module.getVersion() + " moduel in Bundle - " +
bundle.getSymbolicName());
}
for (Long bundleId : stopBundleList) {
Bundle unRegBundle = context.getBundle(bundleId);
if (unRegBundle != null) {
serviceRegistry.unRegister(unRegBundle, false);
}
}
}
} finally {
lock.unlock();
}
}
/**
* When the bundle is activated, this method will look for xml files that ends with "module.xml".
* Thus, a given bundle can have n number of Axis2 modules with differen names suffixed with module.xml.
* Ex: rampart_module.xml; rahas_module.xml addressingmodule.xml
* <p/>
* <p/>
* If there are n number of *module.xml and out of which failed modules will be ignored and and all the
* successful *module.xml files will use to crate the proper AxisModule. It is utmost important that
* that if n number of *module.xml files are present, module should be give a proper name.
*
* @param bundle started bundle
*/
private void addModules(Bundle bundle) {
if (!resolvedBundles.containsKey(bundle)) {
Enumeration enumeration = bundle.findEntries("META-INF", "*module.xml", false);
List<AxisModule> moduleList = null;
if (enumeration != null) {
moduleList = new ArrayList<AxisModule>();
}
while (enumeration != null && enumeration.hasMoreElements()) {
try {
URL url = (URL) enumeration.nextElement();
AxisModule axismodule = new AxisModule();
ClassLoader loader =
new BundleClassLoader(bundle, Registry.class.getClassLoader());
axismodule.setModuleClassLoader(loader);
AxisConfiguration axisConfig = configCtx.getAxisConfiguration();
ModuleBuilder builder =
new ModuleBuilder(url.openStream(), axismodule, axisConfig);
Dictionary headers = bundle.getHeaders();
String bundleSymbolicName = (String) headers.get("Bundle-SymbolicName");
if (bundleSymbolicName != null && bundleSymbolicName.length() != 0) {
axismodule.setName(bundleSymbolicName);
}
String bundleVersion = (String) headers.get("Bundle-Version");
if (bundleVersion != null && bundleVersion.length() != 0) {
/*
Bundle version is defined as
version ::=
major( '.' minor ( '.' micro ( '.' qualifier )? )? )?
major ::= number
minor ::= number
micro ::= number
qualifier ::= ( alphanum | ’_’ | '-' )+
*/
String[] versionSplit = bundleVersion.split("\\.");
int[] components = new int[Math.min(versionSplit.length, 3)];
for (int i=0; i<components.length; i++) {
components[i] = Integer.parseInt(versionSplit[i]);
}
axismodule.setVersion(new Version(components, versionSplit.length > 3 ?
versionSplit[3] : null));
}
builder.populateModule();
axismodule.setParent(axisConfig);
AxisModule module = axisConfig.getModule(axismodule.getName());
if (module == null) {
DeploymentEngine.addNewModule(axismodule, axisConfig);
//initialze the module if the module contains Module interface.
Module moduleObj = axismodule.getModule();
if (moduleObj != null) {
moduleObj.init(configCtx, axismodule);
}
moduleList.add(axismodule);
log.info("[Axis2/OSGi] Starting any modules in Bundle - " +
bundle.getSymbolicName() + " - Module Name : " +
axismodule.getName() + " - Module Version : " +
axismodule.getVersion());
} else {
log.info("[ModuleRegistry] Module : " + axismodule.getName() +
" is already available.");
}
// set in default map if necessary
Utils.calculateDefaultModuleVersion(axisConfig.getModules(), axisConfig);
serviceRegistry.resolve();
} catch (IOException e) {
String msg = "Error while reading module.xml";
log.error(msg, e);
}
}
if (moduleList != null && moduleList.size() > 0) {
resolvedBundles.put(bundle, moduleList);
}
}
}
public void remove(Bundle bundle) {
unRegister(bundle, true);
}
}