Package org.apache.geronimo.deployment.util.osgi

Source Code of org.apache.geronimo.deployment.util.osgi.OSGiMetaDataBuilder

/**
*  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.geronimo.deployment.util.osgi;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.geronimo.common.IllegalConfigurationException;
import org.apache.geronimo.kernel.GBeanNotFoundException;
import org.apache.geronimo.kernel.InternalKernelException;
import org.apache.geronimo.kernel.Kernel;
import org.apache.geronimo.kernel.repository.ArtifactResolver;
import org.apache.geronimo.kernel.repository.Environment;
import org.apache.geronimo.system.configuration.DependencyManager;
import org.apache.xbean.osgi.bundle.util.BundleDescription.ExportPackage;
import org.apache.xbean.osgi.bundle.util.HeaderParser;
import org.apache.xbean.osgi.bundle.util.HeaderParser.HeaderElement;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @version $Rev$ $Date$
*/
public class OSGiMetaDataBuilder {

    private static final Logger logger = LoggerFactory.getLogger(OSGiMetaDataBuilder.class);

    private static final boolean USE_FIXED_IMPORT_PACKAGE_VERSION = Boolean.parseBoolean(System.getProperty("org.apache.geronimo.deployment.import_package.fixed_version", "true"));

    private static final Version ZERO_VERSION = new Version(0, 0, 0);

    private BundleContext bundleContext;

    private ExportPackagesSelector exportPackagesSelector;

    public OSGiMetaDataBuilder(BundleContext bundleContext) {
        this.bundleContext = bundleContext;
        this.exportPackagesSelector = new HighVersionFirstExportPackagesSelector();
    }

    public OSGiMetaDataBuilder(BundleContext bundleContext, ExportPackagesSelector exportPackagesSelector) {
        this.bundleContext = bundleContext;
        this.exportPackagesSelector = exportPackagesSelector;
    }

    public void build(Environment environment) throws IllegalConfigurationException {
        build(environment, false);
    }

    public void build(Environment environment, boolean clientModule) throws IllegalConfigurationException {
        processClassloadingRules(environment);
        ServiceReference serviceReference = null;
        try {
            serviceReference = bundleContext.getServiceReference(DependencyManager.class.getName());
            DependencyManager dependencyManager = null;
            if (serviceReference != null) {
                dependencyManager = (DependencyManager) bundleContext.getService(serviceReference);
            }
            OSGiBuildContext context = createOSGiBuildContext(environment, dependencyManager, clientModule);
            processImportPackages(context);
        } finally {
            if (serviceReference != null) {
                bundleContext.ungetService(serviceReference);
            }
        }
    }

    protected void processClassloadingRules(Environment environment) {
        //Process Hidden Class
        for (String hiddenClassPrefix : environment.getClassLoadingRules().getHiddenRule().getClassPrefixes()) {
            String inversedImportPackage = hiddenClassPrefix.endsWith("*") ? hiddenClassPrefix : hiddenClassPrefix + "*";
            environment.addImportPackage("!" + inversedImportPackage);
        }
        //Non-Overridable-Classes
        /*for (String hiddenClassPrefix : environment.getClassLoadingRules().getHiddenRule().getClassPrefixes()) {
            environment.getImportPackages().add(hiddenClassPrefix);
        }*/
    }

    protected OSGiBuildContext createOSGiBuildContext(Environment environment, DependencyManager dependencyManager, boolean clientModule) throws IllegalConfigurationException {
        List<String> hiddenImportPackageNamePrefixes = new ArrayList<String>();
        Set<String> hiddenImportPackageNames = new HashSet<String>();

        Set<String> removedImportPackages = new HashSet<String>();
        for (String initialImportPackageName : environment.getImportPackages()) {
            String importPackageName = initialImportPackageName.trim();
            if (importPackageName.length() == 0) {
                removedImportPackages.add(initialImportPackageName);
                continue;
            }
            if (importPackageName.startsWith("!")) {
                importPackageName = importPackageName.substring(1);
                boolean wildcardImportPakcageName = importPackageName.endsWith("*");
                if (wildcardImportPakcageName) {
                    importPackageName = importPackageName.substring(0, importPackageName.length() - 1);
                }
                if (importPackageName.endsWith(".")) {
                    importPackageName = importPackageName.substring(0, importPackageName.length() - 1);
                }
                if (wildcardImportPakcageName) {
                    hiddenImportPackageNamePrefixes.add(importPackageName);
                } else {
                    hiddenImportPackageNames.add(importPackageName);
                }
                removedImportPackages.add(initialImportPackageName);
            } else {
                if (importPackageName.endsWith("*")) {
                    throw new IllegalConfigurationException("wildchar * could not be used in the import-package " + importPackageName + " without ! prefix");
                }
            }
        }
        environment.removeImportPackages(removedImportPackages);

        //Use current filter configurations to re-validate existing import packages
        //This is used to handle the scenario that org.test and !org.test are configured at the same time
        removedImportPackages.clear();
        for (String importPackageName : environment.getImportPackages()) {
            if (hiddenImportPackageNames.contains(importPackageName)) {
                removedImportPackages.add(importPackageName);
                continue;
            }
            for (String hiddenImportPackageNamePrefix : hiddenImportPackageNamePrefixes) {
                if (importPackageName.startsWith(hiddenImportPackageNamePrefix)) {
                    removedImportPackages.add(importPackageName);
                    break;
                }
            }
        }
        environment.removeImportPackages(removedImportPackages);

        //If the users configured import packages, those will take the highest precedence.
        //It has the same effect as !org.test is configured.
        for (String importPackageName : environment.getImportPackages()) {
            List<HeaderElement> elements = HeaderParser.parseHeader(importPackageName);
            for (HeaderElement headerElement : elements) {
                hiddenImportPackageNames.add(headerElement.getName());
            }
        }

        Set<String> removedDynamicImportPackages = new HashSet<String>();
        for (String initialDynamicImportPackageName : environment.getDynamicImportPackages()) {
            String dynamicImportPackageName = initialDynamicImportPackageName.trim();
            if (dynamicImportPackageName.length() == 0) {
                removedDynamicImportPackages.add(initialDynamicImportPackageName);
                continue;
            }
            if (dynamicImportPackageName.startsWith("!")) {
                throw new IllegalConfigurationException("DynamicImport-Package " + dynamicImportPackageName + " could not be configured with ! prefix");
            } else {
                List<HeaderElement> elements = HeaderParser.parseHeader(dynamicImportPackageName);
                for (HeaderElement headerElement : elements) {
                    hiddenImportPackageNames.add(headerElement.getName());
                }
            }
        }
        environment.removeDynamicImportPackages(removedDynamicImportPackages);

        OSGiBuildContext osgiBuildContext = new OSGiBuildContext(environment, hiddenImportPackageNamePrefixes, hiddenImportPackageNames, dependencyManager, environment.getClassLoadingRules()
                .isInverseClassLoading());
        osgiBuildContext.setClientModule(clientModule);
        if (clientModule) {
            osgiBuildContext.setClientArtifactResolver(getClientArtifactResolver());
        }
        return osgiBuildContext;
    }

    protected void processImportPackages(OSGiBuildContext context) {
        Environment environment = context.getEnvironment();
        Map<Long, Set<ExportPackage>> selectedExportPackages = exportPackagesSelector.select(context);
        for (Map.Entry<Long, Set<ExportPackage>> entry : selectedExportPackages.entrySet()) {
            if (context.isInverseClassLoading()) {
                for (ExportPackage exportPackage : entry.getValue()) {
                    String importPackageName = toImportPackageName(exportPackage);
                    if (importPackageName == null) {
                        continue;
                    }
                    environment.addDynamicImportPackage(importPackageName);
                }
            } else {
                for (ExportPackage exportPackage : entry.getValue()) {
                    String importPackageName = toImportPackageName(exportPackage);
                    if (importPackageName == null) {
                        continue;
                    }
                    environment.addImportPackage(importPackageName);
                }
            }
        }
        selectedExportPackages.clear();
    }

    protected String toImportPackageName(ExportPackage exportPackage) {
        /* If mandatory attribute exists, do we need to handle it ?
        if (exportPackage.getAttributes().get("mandatory") != null) {
            logger.info("Export package " + exportPackage.getName() + " has mandatory attribute, it will not be considered, if it is required, please add in the deployment plan");
            return null;
        }*/
        if (USE_FIXED_IMPORT_PACKAGE_VERSION) {
            return exportPackage.getName() + ";version=" + "\"[" + exportPackage.getVersion() + "," + exportPackage.getVersion() + "]\"";
        } else {
            return exportPackage.getVersion().equals(ZERO_VERSION) ? exportPackage.getName() : exportPackage.getName() + ";version=" + exportPackage.getVersion();
        }
    }

    private ArtifactResolver getClientArtifactResolver() {
        ServiceReference kernelReference = null;
        try {
            kernelReference = bundleContext.getServiceReference(Kernel.class.getName());
            if (kernelReference == null) {
                return null;
            }
            Kernel kernel = (Kernel) bundleContext.getService(kernelReference);
            return (ArtifactResolver) kernel.getGBean("ClientArtifactResolver");
        } catch (GBeanNotFoundException e) {
            logger.warn("Fail to get client artifact resolver, OSGi metadata for client module might not generate correctly", e);
            return null;
        } catch (InternalKernelException e) {
            logger.warn("Fail to get client artifact resolver, OSGi metadata for client module might not generate correctly", e);
            return null;
        } catch (IllegalStateException e) {
            logger.warn("Fail to get client artifact resolver, OSGi metadata for client module might not generate correctly", e);
            return null;
        } finally {
            if (kernelReference != null)
                try {
                    bundleContext.ungetService(kernelReference);
                } catch (Exception e) {
                }
        }
    }
}
TOP

Related Classes of org.apache.geronimo.deployment.util.osgi.OSGiMetaDataBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.