Package com.springsource.bundlor.support.partialmanifest

Source Code of com.springsource.bundlor.support.partialmanifest.StandardPartialManifestResolver

/*
* Copyright 2008-2009 SpringSource
*
* 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 com.springsource.bundlor.support.partialmanifest;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.util.StringUtils;

import com.springsource.bundlor.support.PartialManifestResolver;
import com.springsource.bundlor.support.TemplateHeaderReader;
import com.springsource.bundlor.util.MatchUtils;
import com.springsource.bundlor.util.SimpleParserLogger;
import com.springsource.util.osgi.manifest.BundleManifest;
import com.springsource.util.osgi.manifest.BundleManifestFactory;
import com.springsource.util.osgi.manifest.ExportedPackage;
import com.springsource.util.osgi.manifest.ImportedPackage;
import com.springsource.util.osgi.manifest.Resolution;
import com.springsource.util.osgi.manifest.parse.HeaderDeclaration;
import com.springsource.util.osgi.manifest.parse.HeaderParserFactory;
import com.springsource.util.parser.manifest.ManifestContents;

/**
* Resolves a {@link StandardReadablePartialManifest} against the {@link ManifestContents} template, creating a
* {@link BundleManifest} with valid OSGi <code>Import-Package</code> and <code>Export-Package</code> headers.
*
* @author Rob Harrop
* @autor Ben Hale
*/
public final class StandardPartialManifestResolver implements TemplateHeaderReader, PartialManifestResolver {

    private static final String ATTR_BUNDLE_VERSION = "Bundle-Version";

    private static final String ATTR_EXPORT_TEMPLATE = "Export-Template";

    private static final String ATTR_IMPORT_TEMPLATE = "Import-Template";

    public List<String> getTemplateOnlyHeaderNames() {
        return Arrays.asList(ATTR_EXPORT_TEMPLATE, ATTR_IMPORT_TEMPLATE);
    }

    /**
     * {@inheritDoc}
     */
    public BundleManifest resolve(ManifestContents templateManifest, ReadablePartialManifest partial) {
        BundleManifest result = BundleManifestFactory.createBundleManifest(new SimpleParserLogger());

        processImports(result, templateManifest, partial);
        processExports(result, templateManifest, partial);

        return result;
    }

    /**
     * Resolves the exports.
     */
    private void processExports(BundleManifest result, ManifestContents templateManifest, ReadablePartialManifest partial) {
        String bundleVersion = templateManifest.getMainAttributes().get(ATTR_BUNDLE_VERSION);
        String exportTemplate = templateManifest.getMainAttributes().get(ATTR_EXPORT_TEMPLATE);

        List<HeaderDeclaration> exportTemplateDeclarations = parseTemplate(exportTemplate);

        List<ExportedPackage> packageExports = new ArrayList<ExportedPackage>();
        for (String exportedPackage : partial.getExportedPackages()) {
            HeaderDeclaration declaration = findMostSpecificDeclaration(exportTemplateDeclarations, exportedPackage);

            ExportedPackage export = result.getExportPackage().addExportedPackage(exportedPackage);

            if (declaration != null) {
                export.getAttributes().putAll(declaration.getAttributes());
                Map<String, String> directives = declaration.getDirectives();
                addCommaSeparated(export.getExclude(), directives.get("excluded"));
                addCommaSeparated(export.getInclude(), directives.get("include"));
                addCommaSeparated(export.getMandatory(), directives.get("mandatory"));
                addCommaSeparated(export.getUses(), directives.get("uses"));

            }

            Set<String> uses = partial.getUses(exportedPackage);
            export.getUses().addAll(uses);

            String version = resolveVersion(declaration, bundleVersion);
            if (StringUtils.hasText(version)) {
                export.getAttributes().put("version", version);
            }
            packageExports.add(export);
        }
    }

    /**
     * Resolves the imports.
     */
    private void processImports(BundleManifest result, ManifestContents template, ReadablePartialManifest partial) {

        String importTemplate = template.getMainAttributes().get(ATTR_IMPORT_TEMPLATE);

        List<HeaderDeclaration> importTemplateDeclarations = parseTemplate(importTemplate);

        List<ImportedPackage> packageImports = new ArrayList<ImportedPackage>();
        for (String importedPackage : partial.getImportedPackages()) {
            HeaderDeclaration match = findMostSpecificDeclaration(importTemplateDeclarations, importedPackage);

            ImportedPackage packageImport = result.getImportPackage().addImportedPackage(importedPackage);
            if (match != null) {
                packageImport.getAttributes().putAll(match.getAttributes());
                packageImport.setResolution(parseResolution(match));
            }
            packageImports.add(packageImport);
        }
    }

    /**
     * Parses <code>value</code> as a comma-separated value and adds all elements to the supplied {@link Collection}.
     */
    private void addCommaSeparated(Collection<String> target, String value) {
        if (value != null) {
            if (value.startsWith("\"")) {
                value = value.substring(1);
            }
            if (value.endsWith("\"")) {
                value = value.substring(0, value.length() - 1);
            }
        }
        String[] array = StringUtils.commaDelimitedListToStringArray(value);
        Collections.addAll(target, array);
    }

    private HeaderDeclaration findMostSpecificDeclaration(List<HeaderDeclaration> declarations, String packageName) {
        HeaderDeclaration match = null;
        int matchSpecificity = -1;

        for (HeaderDeclaration headerDeclaration : declarations) {
            for (String stem : headerDeclaration.getNames()) {
                int m = MatchUtils.rankedMatch(packageName, stem);
                if (m > matchSpecificity) {
                    match = headerDeclaration;
                    matchSpecificity = m;
                }
            }
        }
        return match;
    }

    /**
     * Resolves the <code>version</code> for supplied {@link HeaderDeclaration}, returning <code>defaultVersion</code>
     * if none is specified.
     */
    private String resolveVersion(HeaderDeclaration declaration, String defaultVersion) {
        String version = declaration != null ? declaration.getAttributes().get("version") : null;
        if (!StringUtils.hasText(version)) {
            version = defaultVersion;
        }
        return version;
    }

    /**
     * Parses the <code>resolution</code> directive for the supplied header.
     */
    private Resolution parseResolution(HeaderDeclaration declaration) {
        if ("optional".equals(declaration.getDirectives().get("resolution"))) {
            return Resolution.OPTIONAL;
        } else {
            return Resolution.MANDATORY;
        }
    }

    private List<HeaderDeclaration> parseTemplate(String template) {
        if (StringUtils.hasText(template)) {
            return HeaderParserFactory.newHeaderParser(new SimpleParserLogger()).parseHeader(template);
        } else {
            return new ArrayList<HeaderDeclaration>(0);
        }
    }
}
TOP

Related Classes of com.springsource.bundlor.support.partialmanifest.StandardPartialManifestResolver

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.