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