All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aQute.bnd.obr.OBRFragment Maven / Gradle / Ivy

There is a newer version: 7.0.0
Show newest version
package aQute.bnd.obr;

import java.io.File;
import java.util.Formatter;
import java.util.Map;
import java.util.Map.Entry;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.namespace.BundleNamespace;
import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.framework.namespace.PackageNamespace;
import org.osgi.namespace.service.ServiceNamespace;
import org.osgi.resource.Capability;
import org.osgi.resource.Namespace;
import org.osgi.service.repository.ContentNamespace;

import aQute.bnd.header.Attrs;
import aQute.bnd.header.Parameters;
import aQute.bnd.osgi.Domain;
import aQute.bnd.osgi.Jar;
import aQute.bnd.osgi.Processor;
import aQute.bnd.osgi.resource.CapReqBuilder;
import aQute.bnd.osgi.resource.ResourceBuilder;
import aQute.bnd.version.VersionRange;
import aQute.libg.cryptography.SHA1;
import aQute.libg.map.MAP;
import aQute.service.reporter.Reporter;

public class OBRFragment {

	// The mime-type of an OSGi bundle
	static final String	MIME_TYPE_OSGI_BUNDLE	= "application/vnd.osgi.bundle";
	static Pattern		EE_PATTERN				= Pattern.compile("[^.]-([\\d]+(?:\\.[\\d]+(?:\\.[\\d]+(?:\\.)?)?)?)");

	@SuppressWarnings("deprecation")
	public static Reporter parse(Jar jar, ResourceBuilder resource) throws Exception {
		Manifest m = jar.getManifest();
		if (m == null)
			return null;

		Domain d = Domain.domain(m);
		d.setTranslation(jar);
		Entry bundleSymbolicName = d.getBundleSymbolicName();

		if (bundleSymbolicName == null)
			return null;

		boolean singleton = "true".equals(bundleSymbolicName.getValue().get(Constants.SINGLETON_DIRECTIVE + ":"));
		boolean isFragment = d.get(Constants.FRAGMENT_HOST) != null;
		Version version = d.getBundleVersion() == null ? Version.emptyVersion : new Version(d.getBundleVersion());

		CapReqBuilder identity = new CapReqBuilder(IdentityNamespace.IDENTITY_NAMESPACE);
		identity.addAttribute(IdentityNamespace.IDENTITY_NAMESPACE, bundleSymbolicName.getKey());
		identity.addAttribute(IdentityNamespace.CAPABILITY_COPYRIGHT_ATTRIBUTE,
				d.translate(Constants.BUNDLE_COPYRIGHT));
		identity.addAttribute(IdentityNamespace.CAPABILITY_DESCRIPTION_ATTRIBUTE,
				d.translate(Constants.BUNDLE_DESCRIPTION));
		identity.addAttribute(IdentityNamespace.CAPABILITY_DOCUMENTATION_ATTRIBUTE,
				d.translate(Constants.BUNDLE_DOCURL));
		identity.addAttribute(IdentityNamespace.CAPABILITY_LICENSE_ATTRIBUTE,
				d.translate(aQute.bnd.osgi.Constants.BUNDLE_LICENSE));
		if (singleton)
			identity.addAttribute(IdentityNamespace.CAPABILITY_SINGLETON_DIRECTIVE, "true");
		identity.addAttribute(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE,
				isFragment ? IdentityNamespace.TYPE_FRAGMENT : IdentityNamespace.TYPE_BUNDLE);
		identity.addAttribute(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, new Version(d.getBundleVersion()));

		resource.addCapability(identity);

		if (isFragment) {

			//
			// Fragment-Host
			//

			Entry fragmentHost = d.getFragmentHost();
			CapReqBuilder fragment = new CapReqBuilder(HostNamespace.HOST_NAMESPACE);
			String v = fragmentHost.getValue().get("version");
			if (v == null)
				v = "0";
			Version fragmentVersion = new Version(v);
			String filter = filter(PackageNamespace.PACKAGE_NAMESPACE, fragmentHost.getKey(), fragmentHost.getValue());
			fragment.addDirective(HostNamespace.REQUIREMENT_FILTER_DIRECTIVE, filter.toString());
			resource.addRequirement(fragment);
		} else {

			//
			// Bundle-SymbolicName
			//

			CapReqBuilder bundle = new CapReqBuilder(BundleNamespace.BUNDLE_NAMESPACE);
			CapReqBuilder host = new CapReqBuilder(HostNamespace.HOST_NAMESPACE);

			bundle.addAttribute("version", version);
			host.addAttribute("version", version);

			for (Entry e : bundleSymbolicName.getValue().entrySet()) {
				String key = e.getKey();
				if (key.endsWith(":")) {
					String directive = key.substring(0, key.length() - 1);
					if (Constants.FRAGMENT_ATTACHMENT_DIRECTIVE.equalsIgnoreCase(directive)) {
						if (Constants.FRAGMENT_ATTACHMENT_NEVER.equalsIgnoreCase(e.getValue()))
							host = null;

					} else if (!Constants.SINGLETON_DIRECTIVE.equalsIgnoreCase(directive)) {
						bundle.addDirective(directive, e.getValue());
					}
					if (host != null)
						host.addDirective(directive, e.getValue());
					bundle.addDirective(directive, e.getValue());
				} else {
					if (host != null)
						host.addAttribute(key, e.getValue());
					bundle.addAttribute(key, e.getValue());
				}
			}
			if (host != null)
				resource.addCapability(host);
			resource.addCapability(bundle);
		}

		//
		// Export-Package
		//

		Parameters exports = d.getExportPackage();
		for (Entry entry : exports.entrySet()) {
			CapReqBuilder exported = new CapReqBuilder(PackageNamespace.PACKAGE_NAMESPACE);

			String pkgName = Processor.removeDuplicateMarker(entry.getKey());
			exported.addAttribute(PackageNamespace.PACKAGE_NAMESPACE, pkgName);

			String versionStr = entry.getValue().get(Constants.VERSION_ATTRIBUTE);
			Version v = Version.parseVersion(entry.getValue().get("version"));

			exported.addAttribute(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, version);

			for (Entry attribEntry : entry.getValue().entrySet()) {
				String key = attribEntry.getKey();
				if (key.endsWith(":")) {
					String directive = key.substring(0, key.length() - 1);
					exported.addDirective(directive, attribEntry.getValue());
				} else {
					if (key.equals("specification-version") || key.equals("version"))
						exported.addAttribute("version", Version.parseVersion(attribEntry.getValue()));
					else
						exported.addAttribute(key, attribEntry.getValue());
				}
			}

			exported.addAttribute(PackageNamespace.CAPABILITY_BUNDLE_SYMBOLICNAME_ATTRIBUTE,
					bundleSymbolicName.getKey());
			exported.addAttribute(PackageNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE, version);

			resource.addCapability(exported);
		}

		//
		// Import-Package
		//

		Parameters imports = d.getImportPackage();
		for (Entry entry : imports.entrySet()) {
			CapReqBuilder imported = new CapReqBuilder(PackageNamespace.PACKAGE_NAMESPACE);
			String name = Processor.removeDuplicateMarker(entry.getKey());
			String filter = filter(PackageNamespace.PACKAGE_NAMESPACE, Processor.removeDuplicateMarker(entry.getKey()),
					entry.getValue());
			imported.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter);
			resource.addRequirement(imported);
		}

		//
		// Require-Bundle
		//

		Parameters requires = d.getRequireBundle();
		for (Entry entry : requires.entrySet()) {
			CapReqBuilder req = new CapReqBuilder(BundleNamespace.BUNDLE_NAMESPACE);
			String bsn = Processor.removeDuplicateMarker(entry.getKey());
			String filter = filter(BundleNamespace.BUNDLE_NAMESPACE, bsn, entry.getValue());
			req.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter);
			resource.addRequirement(req);
		}

		//
		// Bundle-RequiredExecutionEnvironment
		//

		Parameters brees = d.getBundleRequiredExecutionEnvironment();
		Formatter formatter = new Formatter();
		try {
			formatter.format("(|");

			for (Entry bree : brees.entrySet()) {
				String name = Processor.removeDuplicateMarker(bree.getKey());
				Matcher matcher = EE_PATTERN.matcher(name);
				if (matcher.matches()) {
					name = matcher.group(1);
					Version v = Version.parseVersion(matcher.group(2));
					formatter.format("%s", filter(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE, name,
							MAP.$("version", v.toString())));
				}
			}
			formatter.format(")");

			CapReqBuilder breeReq = new CapReqBuilder(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
			breeReq.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, formatter.toString());

			//
			// Export-Service (deprecated)
			//

			for (Entry export : d.getParameters(Constants.EXPORT_SERVICE).entrySet()) {
				CapReqBuilder exportedService = new CapReqBuilder(ServiceNamespace.SERVICE_NAMESPACE);
				String service = Processor.removeDuplicateMarker(export.getKey());
				exportedService.addAttribute(ServiceNamespace.SERVICE_NAMESPACE, service);
				exportedService.addAttribute(ServiceNamespace.CAPABILITY_OBJECTCLASS_ATTRIBUTE,
						export.getValue().get("objectclass"));
				resource.addCapability(exportedService);
			}

			//
			// Import-Service (deprecated)
			//

			for (Entry imported : d.getParameters(Constants.IMPORT_SERVICE).entrySet()) {
				CapReqBuilder importedService = new CapReqBuilder(ServiceNamespace.SERVICE_NAMESPACE);
				String service = Processor.removeDuplicateMarker(imported.getKey());
				importedService.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE,
						filter(ServiceNamespace.SERVICE_NAMESPACE, service, imported.getValue()));
				resource.addRequirement(importedService);
			}

			//
			// Provide-Capability
			//

			for (Entry rc : d.getProvideCapability().entrySet()) {
				resource.addCapability(toCapability(rc.getKey(), rc.getValue()));
			}

			//
			// Require-Capability
			//

			for (Entry rc : d.getRequireCapability().entrySet()) {
				resource.addCapability(toRequirement(rc.getKey(), rc.getValue()));
			}
		} finally {
			formatter.close();
		}

		return null;
	}

	private static Capability toRequirement(String key, Attrs value) {
		// TODO Auto-generated method stub
		return null;
	}

	private static Capability toCapability(String key, Attrs value) {
		// TODO Auto-generated method stub
		return null;
	}

	public static Reporter parse(File file, ResourceBuilder resource, String base) throws Exception {
		Jar jar = new Jar(file);
		try {
			Reporter reporter = parse(jar, resource);
			if (!reporter.isOk())
				return reporter;

			CapReqBuilder content = new CapReqBuilder(ContentNamespace.CONTENT_NAMESPACE);
			String sha = SHA1.digest(file).asHex();
			content.addAttribute(ContentNamespace.CONTENT_NAMESPACE, sha);
			content.addAttribute(ContentNamespace.CAPABILITY_SIZE_ATTRIBUTE, (long) file.length());
			content.addAttribute(ContentNamespace.CAPABILITY_MIME_ATTRIBUTE, MIME_TYPE_OSGI_BUNDLE);

			if (base != null) {
				String path = file.getAbsolutePath();
				if (base.startsWith(path)) {
					content.addAttribute(ContentNamespace.CAPABILITY_URL_ATTRIBUTE,
							path.substring(base.length()).replace(File.separatorChar, '/'));
				} else {
					reporter.error("Base path %s is not parent of file path: %s", base, file.getAbsolutePath());
				}
			}

			resource.addCapability(content);
			return reporter;
		} finally {
			jar.close();
		}
	}

	// TODO finish
	private static String filter(String ns, String primary, Map value) {
		Formatter f = new Formatter();
		try {
			f.format("(&(%s=%s)", ns, primary);
			for (String key : value.keySet()) {
				if (key.equals("version") || key.equals("bundle-version")) {
					VersionRange vr = new VersionRange(value.get(key));
				} else {
					f.format("(%s=%s)", key, value.get(key));
				}
			}

			f.format(")");
		} finally {
			f.close();
		}
		return null;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy