blob: 5d845b75cf8fda5192567d05a8a2abe3134c73ee [file] [log] [blame]
/*
* 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.felix.bundlerepository.impl;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.felix.bundlerepository.Capability;
import org.apache.felix.bundlerepository.DataModelHelper;
import org.apache.felix.bundlerepository.Property;
import org.apache.felix.bundlerepository.Repository;
import org.apache.felix.bundlerepository.Requirement;
import org.apache.felix.bundlerepository.Resource;
import org.apache.felix.utils.filter.FilterImpl;
import org.apache.felix.utils.manifest.Attribute;
import org.apache.felix.utils.manifest.Clause;
import org.apache.felix.utils.manifest.Directive;
import org.apache.felix.utils.manifest.Parser;
import org.apache.felix.utils.version.VersionCleaner;
import org.apache.felix.utils.version.VersionRange;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.Version;
public class DataModelHelperImpl implements DataModelHelper
{
public static final String BUNDLE_LICENSE = "Bundle-License";
public static final String BUNDLE_SOURCE = "Bundle-Source";
public Requirement requirement(String name, String filter)
{
RequirementImpl req = new RequirementImpl();
req.setName(name);
if (filter != null)
{
req.setFilter(filter);
}
return req;
}
public Filter filter(String filter)
{
try
{
return FilterImpl.newInstance(filter);
}
catch (InvalidSyntaxException e)
{
IllegalArgumentException ex = new IllegalArgumentException();
ex.initCause(e);
throw ex;
}
}
public Repository repository(final URL url) throws Exception
{
InputStream is = null;
try
{
if (url.getPath().endsWith(".zip"))
{
ZipInputStream zin = new ZipInputStream(FileUtil.openURL(url));
ZipEntry entry = zin.getNextEntry();
while (entry != null)
{
if (entry.getName().equals("repository.xml") || entry.getName().equals("index.xml"))
{
is = zin;
break;
}
entry = zin.getNextEntry();
}
// as the ZipInputStream is not used further it would not be closed.
if (is == null)
{
try
{
zin.close();
}
catch (IOException ex)
{
// Not much we can do.
}
}
}
else if (url.getPath().endsWith(".gz"))
{
is = new GZIPInputStream(FileUtil.openURL(url));
}
else
{
is = FileUtil.openURL(url);
}
if (is != null)
{
String repositoryUri = url.toExternalForm();
String baseUri;
if (repositoryUri.endsWith(".zip")) {
baseUri = new StringBuilder("jar:").append(repositoryUri).append("!/").toString();
} else if (repositoryUri.endsWith(".xml")) {
baseUri = repositoryUri.substring(0, repositoryUri.lastIndexOf('/') + 1);
} else {
baseUri = repositoryUri;
}
RepositoryImpl repository = repository(is, URI.create(baseUri));
repository.setURI(repositoryUri);
return repository;
}
else
{
// This should not happen.
throw new Exception("Unable to get input stream for repository.");
}
}
finally
{
try
{
if (is != null)
{
is.close();
}
}
catch (IOException ex)
{
// Not much we can do.
}
}
}
public RepositoryImpl repository(InputStream is, URI baseURI) throws Exception
{
RepositoryParser parser = RepositoryParser.getParser();
RepositoryImpl repository = parser.parseRepository(is, baseURI);
return repository;
}
public Repository repository(Resource[] resources)
{
return new RepositoryImpl(resources);
}
public Capability capability(String name, Map properties)
{
CapabilityImpl cap = new CapabilityImpl(name);
for (Iterator it = properties.entrySet().iterator(); it.hasNext();)
{
Map.Entry e = (Map.Entry) it.next();
cap.addProperty((String) e.getKey(), (String) e.getValue());
}
return cap;
}
public String writeRepository(Repository repository)
{
try
{
StringWriter sw = new StringWriter();
writeRepository(repository, sw);
return sw.toString();
}
catch (IOException e)
{
IllegalStateException ex = new IllegalStateException(e);
ex.initCause(e);
throw ex;
}
}
public void writeRepository(Repository repository, Writer writer) throws IOException
{
XmlWriter w = new XmlWriter(writer);
toXml(w, repository);
}
public String writeResource(Resource resource)
{
try
{
StringWriter sw = new StringWriter();
writeResource(resource, sw);
return sw.toString();
}
catch (IOException e)
{
IllegalStateException ex = new IllegalStateException(e);
ex.initCause(e);
throw ex;
}
}
public void writeResource(Resource resource, Writer writer) throws IOException
{
XmlWriter w = new XmlWriter(writer);
toXml(w, resource);
}
public String writeCapability(Capability capability)
{
try
{
StringWriter sw = new StringWriter();
writeCapability(capability, sw);
return sw.toString();
}
catch (IOException e)
{
IllegalStateException ex = new IllegalStateException(e);
ex.initCause(e);
throw ex;
}
}
public void writeCapability(Capability capability, Writer writer) throws IOException
{
XmlWriter w = new XmlWriter(writer);
toXml(w, capability);
}
public String writeRequirement(Requirement requirement)
{
try
{
StringWriter sw = new StringWriter();
writeRequirement(requirement, sw);
return sw.toString();
}
catch (IOException e)
{
IllegalStateException ex = new IllegalStateException(e);
ex.initCause(e);
throw ex;
}
}
public void writeRequirement(Requirement requirement, Writer writer) throws IOException
{
XmlWriter w = new XmlWriter(writer);
toXml(w, requirement);
}
public String writeProperty(Property property)
{
try
{
StringWriter sw = new StringWriter();
writeProperty(property, sw);
return sw.toString();
}
catch (IOException e)
{
IllegalStateException ex = new IllegalStateException(e);
ex.initCause(e);
throw ex;
}
}
public void writeProperty(Property property, Writer writer) throws IOException
{
XmlWriter w = new XmlWriter(writer);
toXml(w, property);
}
private static void toXml(XmlWriter w, Repository repository) throws IOException
{
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmss.SSS");
w.element(RepositoryParser.REPOSITORY)
.attribute(RepositoryParser.NAME, repository.getName())
.attribute(RepositoryParser.LASTMODIFIED, format.format(new Date(repository.getLastModified())));
if (repository instanceof RepositoryImpl)
{
Referral[] referrals = ((RepositoryImpl) repository).getReferrals();
for (int i = 0; referrals != null && i < referrals.length; i++)
{
w.element(RepositoryParser.REFERRAL)
.attribute(RepositoryParser.DEPTH, new Integer(referrals[i].getDepth()))
.attribute(RepositoryParser.URL, referrals[i].getUrl())
.end();
}
}
Resource[] resources = repository.getResources();
for (int i = 0; resources != null && i < resources.length; i++)
{
toXml(w, resources[i]);
}
w.end();
}
private static void toXml(XmlWriter w, Resource resource) throws IOException
{
w.element(RepositoryParser.RESOURCE)
.attribute(Resource.ID, resource.getId())
.attribute(Resource.SYMBOLIC_NAME, resource.getSymbolicName())
.attribute(Resource.PRESENTATION_NAME, resource.getPresentationName())
.attribute(Resource.URI, getRelativeUri(resource, Resource.URI))
.attribute(Resource.VERSION, resource.getVersion().toString());
w.textElement(Resource.DESCRIPTION, resource.getProperties().get(Resource.DESCRIPTION))
.textElement(Resource.SIZE, resource.getProperties().get(Resource.SIZE))
.textElement(Resource.DOCUMENTATION_URI, getRelativeUri(resource, Resource.DOCUMENTATION_URI))
.textElement(Resource.SOURCE_URI, getRelativeUri(resource, Resource.SOURCE_URI))
.textElement(Resource.JAVADOC_URI, getRelativeUri(resource, Resource.JAVADOC_URI))
.textElement(Resource.LICENSE_URI, getRelativeUri(resource, Resource.LICENSE_URI));
String[] categories = resource.getCategories();
for (int i = 0; categories != null && i < categories.length; i++)
{
w.element(RepositoryParser.CATEGORY)
.attribute(RepositoryParser.ID, categories[i])
.end();
}
Capability[] capabilities = resource.getCapabilities();
for (int i = 0; capabilities != null && i < capabilities.length; i++)
{
toXml(w, capabilities[i]);
}
Requirement[] requirements = resource.getRequirements();
for (int i = 0; requirements != null && i < requirements.length; i++)
{
toXml(w, requirements[i]);
}
w.end();
}
private static String getRelativeUri(Resource resource, String name)
{
String uri = (String) resource.getProperties().get(name);
if (resource instanceof ResourceImpl)
{
try
{
uri = URI.create(((ResourceImpl) resource).getRepository().getURI()).relativize(URI.create(uri)).toASCIIString();
}
catch (Throwable t)
{
}
}
return uri;
}
private static void toXml(XmlWriter w, Capability capability) throws IOException
{
w.element(RepositoryParser.CAPABILITY)
.attribute(RepositoryParser.NAME, capability.getName());
Property[] props = capability.getProperties();
for (int j = 0; props != null && j < props.length; j++)
{
toXml(w, props[j]);
}
w.end();
}
private static void toXml(XmlWriter w, Property property) throws IOException
{
w.element(RepositoryParser.P)
.attribute(RepositoryParser.N, property.getName())
.attribute(RepositoryParser.T, property.getType())
.attribute(RepositoryParser.V, property.getValue())
.end();
}
private static void toXml(XmlWriter w, Requirement requirement) throws IOException
{
w.element(RepositoryParser.REQUIRE)
.attribute(RepositoryParser.NAME, requirement.getName())
.attribute(RepositoryParser.FILTER, requirement.getFilter())
.attribute(RepositoryParser.EXTEND, Boolean.toString(requirement.isExtend()))
.attribute(RepositoryParser.MULTIPLE, Boolean.toString(requirement.isMultiple()))
.attribute(RepositoryParser.OPTIONAL, Boolean.toString(requirement.isOptional()))
.text(requirement.getComment().trim())
.end();
}
public Resource createResource(final Bundle bundle)
{
final Dictionary dict = bundle.getHeaders();
return createResource(new Headers()
{
public String getHeader(String name)
{
return (String) dict.get(name);
}
});
}
public Resource createResource(final URL bundleUrl) throws IOException
{
ResourceImpl resource = createResource(new Headers()
{
private final Manifest manifest;
private Properties localization;
{
// Do not use a JarInputStream so that we can read the manifest even if it's not
// the first entry in the JAR.
byte[] man = loadEntry(JarFile.MANIFEST_NAME);
if (man == null)
{
throw new IllegalArgumentException("The specified url is not a valid jar (can't read manifest): " + bundleUrl);
}
manifest = new Manifest(new ByteArrayInputStream(man));
}
public String getHeader(String name)
{
String value = manifest.getMainAttributes().getValue(name);
if (value != null && value.startsWith("%"))
{
if (localization == null)
{
try
{
localization = new Properties();
String path = manifest.getMainAttributes().getValue(Constants.BUNDLE_LOCALIZATION);
if (path == null)
{
path = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
}
path += ".properties";
byte[] loc = loadEntry(path);
if (loc != null)
{
localization.load(new ByteArrayInputStream(loc));
}
}
catch (IOException e)
{
// TODO: ?
}
}
value = value.substring(1);
value = localization.getProperty(value, value);
}
return value;
}
private byte[] loadEntry(String name) throws IOException
{
ZipInputStream zis = new ZipInputStream(FileUtil.openURL(bundleUrl));
try
{
for (ZipEntry e = zis.getNextEntry(); e != null; e = zis.getNextEntry())
{
if (name.equalsIgnoreCase(e.getName()))
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n;
while ((n = zis.read(buf, 0, buf.length)) > 0)
{
baos.write(buf, 0, n);
}
return baos.toByteArray();
}
}
}
finally
{
zis.close();
}
return null;
}
});
if (resource != null)
{
if ("file".equals(bundleUrl.getProtocol()))
{
try {
File f = new File(bundleUrl.toURI());
resource.put(Resource.SIZE, Long.toString(f.length()), null);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
resource.put(Resource.URI, bundleUrl.toExternalForm(), null);
}
return resource;
}
public Resource createResource(final Attributes attributes)
{
return createResource(new Headers()
{
public String getHeader(String name)
{
return attributes.getValue(name);
}
});
}
public ResourceImpl createResource(Headers headers)
{
String bsn = headers.getHeader(Constants.BUNDLE_SYMBOLICNAME);
if (bsn == null)
{
return null;
}
ResourceImpl resource = new ResourceImpl();
populate(headers, resource);
return resource;
}
static void populate(Headers headers, ResourceImpl resource)
{
String bsn = getSymbolicName(headers);
String v = getVersion(headers);
resource.put(Resource.ID, bsn + "/" + v);
resource.put(Resource.SYMBOLIC_NAME, bsn);
resource.put(Resource.VERSION, v);
if (headers.getHeader(Constants.BUNDLE_NAME) != null)
{
resource.put(Resource.PRESENTATION_NAME, headers.getHeader(Constants.BUNDLE_NAME));
}
if (headers.getHeader(Constants.BUNDLE_DESCRIPTION) != null)
{
resource.put(Resource.DESCRIPTION, headers.getHeader(Constants.BUNDLE_DESCRIPTION));
}
if (headers.getHeader(BUNDLE_LICENSE) != null)
{
resource.put(Resource.LICENSE_URI, headers.getHeader(BUNDLE_LICENSE));
}
if (headers.getHeader(Constants.BUNDLE_COPYRIGHT) != null)
{
resource.put(Resource.COPYRIGHT, headers.getHeader(Constants.BUNDLE_COPYRIGHT));
}
if (headers.getHeader(Constants.BUNDLE_DOCURL) != null)
{
resource.put(Resource.DOCUMENTATION_URI, headers.getHeader(Constants.BUNDLE_DOCURL));
}
if (headers.getHeader(BUNDLE_SOURCE) != null)
{
resource.put(Resource.SOURCE_URI, headers.getHeader(BUNDLE_SOURCE));
}
doCategories(resource, headers);
doBundle(resource, headers);
doImportExportServices(resource, headers);
doFragment(resource, headers);
doRequires(resource, headers);
doExports(resource, headers);
doImports(resource, headers);
doExecutionEnvironment(resource, headers);
doProvides(resource, headers);
}
private static void doCategories(ResourceImpl resource, Headers headers)
{
Clause[] clauses = Parser.parseHeader(headers.getHeader(Constants.BUNDLE_CATEGORY));
for (int i = 0; clauses != null && i < clauses.length; i++)
{
resource.addCategory(clauses[i].getName());
}
}
private static void doImportExportServices(ResourceImpl resource, Headers headers)
{
Clause[] imports = Parser.parseHeader(headers.getHeader(Constants.IMPORT_SERVICE));
for (int i = 0; imports != null && i < imports.length; i++) {
RequirementImpl ri = new RequirementImpl(Capability.SERVICE);
ri.setFilter(createServiceFilter(imports[i]));
ri.addText("Import Service " + imports[i].getName());
String avail = imports[i].getDirective("availability");
String mult = imports[i].getDirective("multiple");
ri.setOptional("optional".equalsIgnoreCase(avail));
ri.setMultiple(!"false".equalsIgnoreCase(mult));
resource.addRequire(ri);
}
Clause[] exports = Parser.parseHeader(headers.getHeader(Constants.EXPORT_SERVICE));
for (int i = 0; exports != null && i < exports.length; i++) {
CapabilityImpl cap = createServiceCapability(exports[i]);
resource.addCapability(cap);
}
}
private static String createServiceFilter(Clause clause) {
String f = clause.getAttribute("filter");
StringBuffer filter = new StringBuffer();
if (f != null) {
filter.append("(&");
}
filter.append("(");
filter.append(Capability.SERVICE);
filter.append("=");
filter.append(clause.getName());
filter.append(")");
if (f != null) {
if (!f.startsWith("("))
{
filter.append("(").append(f).append(")");
}
else
{
filter.append(f);
}
filter.append(")");
}
return filter.toString();
}
private static CapabilityImpl createServiceCapability(Clause clause) {
CapabilityImpl capability = new CapabilityImpl(Capability.SERVICE);
capability.addProperty(Capability.SERVICE, clause.getName());
Attribute[] attributes = clause.getAttributes();
for (int i = 0; attributes != null && i < attributes.length; i++)
{
capability.addProperty(attributes[i].getName(), attributes[i].getValue());
}
return capability;
}
private static void doFragment(ResourceImpl resource, Headers headers)
{
// Check if we are a fragment
Clause[] clauses = Parser.parseHeader(headers.getHeader(Constants.FRAGMENT_HOST));
if (clauses != null && clauses.length == 1)
{
// We are a fragment, create a requirement
// to our host.
RequirementImpl r = new RequirementImpl(Capability.BUNDLE);
StringBuffer sb = new StringBuffer();
sb.append("(&(symbolicname=");
sb.append(clauses[0].getName());
sb.append(")");
appendVersion(sb, VersionRange.parseVersionRange(clauses[0].getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE)));
sb.append(")");
r.setFilter(sb.toString());
r.addText("Required Host " + clauses[0].getName());
r.setExtend(true);
r.setOptional(false);
r.setMultiple(false);
resource.addRequire(r);
// And insert a capability that we are available
// as a fragment. ### Do we need that with extend?
CapabilityImpl capability = new CapabilityImpl(Capability.FRAGMENT);
capability.addProperty("host", clauses[0].getName());
capability.addProperty("version", Property.VERSION, getVersion(clauses[0]));
resource.addCapability(capability);
}
}
private static void doRequires(ResourceImpl resource, Headers headers)
{
Clause[] clauses = Parser.parseHeader(headers.getHeader(Constants.REQUIRE_BUNDLE));
for (int i = 0; clauses != null && i < clauses.length; i++) {
RequirementImpl r = new RequirementImpl(Capability.BUNDLE);
VersionRange v = VersionRange.parseVersionRange(clauses[i].getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE));
StringBuffer sb = new StringBuffer();
sb.append("(&(symbolicname=");
sb.append(clauses[i].getName());
sb.append(")");
appendVersion(sb, v);
sb.append(")");
r.setFilter(sb.toString());
r.addText("Require Bundle " + clauses[i].getName() + "; " + v);
r.setOptional(Constants.RESOLUTION_OPTIONAL.equalsIgnoreCase(clauses[i].getDirective(Constants.RESOLUTION_DIRECTIVE)));
resource.addRequire(r);
}
}
private static void doBundle(ResourceImpl resource, Headers headers) {
CapabilityImpl capability = new CapabilityImpl(Capability.BUNDLE);
capability.addProperty(Resource.SYMBOLIC_NAME, getSymbolicName(headers));
if (headers.getHeader(Constants.BUNDLE_NAME) != null)
{
capability.addProperty(Resource.PRESENTATION_NAME, headers.getHeader(Constants.BUNDLE_NAME));
}
capability.addProperty(Resource.VERSION, Property.VERSION, getVersion(headers));
capability.addProperty(Resource.MANIFEST_VERSION, getManifestVersion(headers));
resource.addCapability(capability);
}
private static void doExports(ResourceImpl resource, Headers headers)
{
Clause[] clauses = Parser.parseHeader(headers.getHeader(Constants.EXPORT_PACKAGE));
for (int i = 0; clauses != null && i < clauses.length; i++)
{
CapabilityImpl capability = createCapability(Capability.PACKAGE, clauses[i]);
resource.addCapability(capability);
}
}
private static void doProvides(ResourceImpl resource, Headers headers) {
Clause[] clauses = Parser.parseHeader(headers.getHeader(Constants.PROVIDE_CAPABILITY));
if (clauses != null) {
for (Clause clause : clauses) {
CapabilityImpl capability = createCapability(clause.getName(), clause);
resource.addCapability(capability);
}
}
}
private static CapabilityImpl createCapability(String name, Clause clause)
{
CapabilityImpl capability = new CapabilityImpl(NamespaceTranslator.getFelixNamespace(name));
capability.addProperty(name, clause.getName());
capability.addProperty(Resource.VERSION, Property.VERSION, getVersion(clause));
Attribute[] attributes = clause.getAttributes();
for (int i = 0; attributes != null && i < attributes.length; i++)
{
String key = attributes[i].getName();
if (key.equalsIgnoreCase(Constants.PACKAGE_SPECIFICATION_VERSION) || key.equalsIgnoreCase(Constants.VERSION_ATTRIBUTE) || key.equalsIgnoreCase("version:Version"))
{
continue;
}
else
{
String value = attributes[i].getValue();
capability.addProperty(key, value);
}
}
Directive[] directives = clause.getDirectives();
for (int i = 0; directives != null && i < directives.length; i++)
{
String key = directives[i].getName();
String value = directives[i].getValue();
capability.addProperty(key + ":", value);
}
return capability;
}
private static void doImports(ResourceImpl resource, Headers headers)
{
Clause[] clauses = Parser.parseHeader(headers.getHeader(Constants.IMPORT_PACKAGE));
for (int i = 0; clauses != null && i < clauses.length; i++)
{
RequirementImpl requirement = new RequirementImpl(Capability.PACKAGE);
createImportFilter(requirement, Capability.PACKAGE, clauses[i]);
requirement.addText("Import package " + clauses[i]);
requirement.setOptional(Constants.RESOLUTION_OPTIONAL.equalsIgnoreCase(clauses[i].getDirective(Constants.RESOLUTION_DIRECTIVE)));
resource.addRequire(requirement);
}
}
private static void createImportFilter(RequirementImpl requirement, String name, Clause clause)
{
StringBuffer filter = new StringBuffer();
filter.append("(&(");
filter.append(name);
filter.append("=");
filter.append(clause.getName());
filter.append(")");
appendVersion(filter, getVersionRange(clause));
Attribute[] attributes = clause.getAttributes();
Set attrs = doImportPackageAttributes(requirement, filter, attributes);
// The next code is using the subset operator
// to check mandatory attributes, it seems to be
// impossible to rewrite. It must assert that whateber
// is in mandatory: must be in any of the attributes.
// This is a fundamental shortcoming of the filter language.
if (attrs.size() > 0)
{
String del = "";
filter.append("(mandatory:<*");
for (Iterator i = attrs.iterator(); i.hasNext();)
{
filter.append(del);
filter.append(i.next());
del = ", ";
}
filter.append(")");
}
filter.append(")");
requirement.setFilter(filter.toString());
}
private static Set doImportPackageAttributes(RequirementImpl requirement, StringBuffer filter, Attribute[] attributes)
{
HashSet set = new HashSet();
for (int i = 0; attributes != null && i < attributes.length; i++)
{
String name = attributes[i].getName();
String value = attributes[i].getValue();
if (name.equalsIgnoreCase(Constants.PACKAGE_SPECIFICATION_VERSION) || name.equalsIgnoreCase(Constants.VERSION_ATTRIBUTE))
{
continue;
}
else if (name.equalsIgnoreCase(Constants.RESOLUTION_DIRECTIVE + ":"))
{
requirement.setOptional(Constants.RESOLUTION_OPTIONAL.equalsIgnoreCase(value));
}
if (name.endsWith(":"))
{
// Ignore
}
else
{
filter.append("(");
filter.append(name);
filter.append("=");
filter.append(value);
filter.append(")");
set.add(name);
}
}
return set;
}
private static void doExecutionEnvironment(ResourceImpl resource, Headers headers)
{
Clause[] clauses = Parser.parseHeader(headers.getHeader(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT));
if (clauses != null && clauses.length > 0)
{
StringBuffer sb = new StringBuffer();
sb.append("(|");
for (int i = 0; i < clauses.length; i++)
{
sb.append("(");
sb.append(Capability.EXECUTIONENVIRONMENT);
sb.append("=");
sb.append(clauses[i].getName());
sb.append(")");
}
sb.append(")");
RequirementImpl req = new RequirementImpl(Capability.EXECUTIONENVIRONMENT);
req.setFilter(sb.toString());
req.addText("Execution Environment " + sb.toString());
resource.addRequire(req);
}
}
private static String getVersion(Clause clause)
{
String v = clause.getAttribute(Constants.VERSION_ATTRIBUTE);
if (v == null)
{
v = clause.getAttribute(Constants.PACKAGE_SPECIFICATION_VERSION);
}
if (v == null)
{
v = clause.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE);
}
if (v == null)
{
v = clause.getAttribute("version:Version");
}
return VersionCleaner.clean(v);
}
private static VersionRange getVersionRange(Clause clause)
{
String v = clause.getAttribute(Constants.VERSION_ATTRIBUTE);
if (v == null)
{
v = clause.getAttribute(Constants.PACKAGE_SPECIFICATION_VERSION);
}
if (v == null)
{
v = clause.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE);
}
return VersionRange.parseVersionRange(v);
}
private static String getSymbolicName(Headers headers)
{
String bsn = headers.getHeader(Constants.BUNDLE_SYMBOLICNAME);
if (bsn == null)
{
bsn = headers.getHeader(Constants.BUNDLE_NAME);
if (bsn == null)
{
bsn = "Untitled-" + headers.hashCode();
}
}
Clause[] clauses = Parser.parseHeader(bsn);
return clauses[0].getName();
}
private static String getVersion(Headers headers)
{
String v = headers.getHeader(Constants.BUNDLE_VERSION);
return VersionCleaner.clean(v);
}
private static String getManifestVersion(Headers headers)
{
String v = headers.getHeader(Constants.BUNDLE_MANIFESTVERSION);
if (v == null)
{
v = "1";
}
return v;
}
private static void appendVersion(StringBuffer filter, VersionRange version)
{
if (version != null)
{
if ( !version.isOpenFloor() )
{
if ( !Version.emptyVersion.equals(version.getFloor()) )
{
filter.append("(");
filter.append(Constants.VERSION_ATTRIBUTE);
filter.append(">=");
filter.append(version.getFloor());
filter.append(")");
}
}
else
{
filter.append("(!(");
filter.append(Constants.VERSION_ATTRIBUTE);
filter.append("<=");
filter.append(version.getFloor());
filter.append("))");
}
if (!VersionRange.INFINITE_VERSION.equals(version.getCeiling()))
{
if ( !version.isOpenCeiling() )
{
filter.append("(");
filter.append(Constants.VERSION_ATTRIBUTE);
filter.append("<=");
filter.append(version.getCeiling());
filter.append(")");
}
else
{
filter.append("(!(");
filter.append(Constants.VERSION_ATTRIBUTE);
filter.append(">=");
filter.append(version.getCeiling());
filter.append("))");
}
}
}
}
interface Headers
{
String getHeader(String name);
}
public Repository readRepository(String xml) throws Exception
{
try
{
return readRepository(new StringReader(xml));
}
catch (IOException e)
{
IllegalStateException ex = new IllegalStateException(e);
ex.initCause(e);
throw ex;
}
}
public Repository readRepository(Reader reader) throws Exception
{
return RepositoryParser.getParser().parseRepository(reader);
}
public Resource readResource(String xml) throws Exception
{
try
{
return readResource(new StringReader(xml));
}
catch (IOException e)
{
IllegalStateException ex = new IllegalStateException(e);
ex.initCause(e);
throw ex;
}
}
public Resource readResource(Reader reader) throws Exception
{
return RepositoryParser.getParser().parseResource(reader);
}
public Capability readCapability(String xml) throws Exception
{
try
{
return readCapability(new StringReader(xml));
}
catch (IOException e)
{
IllegalStateException ex = new IllegalStateException(e);
ex.initCause(e);
throw ex;
}
}
public Capability readCapability(Reader reader) throws Exception
{
return RepositoryParser.getParser().parseCapability(reader);
}
public Requirement readRequirement(String xml) throws Exception
{
try
{
return readRequirement(new StringReader(xml));
}
catch (IOException e)
{
IllegalStateException ex = new IllegalStateException(e);
ex.initCause(e);
throw ex;
}
}
public Requirement readRequirement(Reader reader) throws Exception
{
return RepositoryParser.getParser().parseRequirement(reader);
}
public Property readProperty(String xml) throws Exception
{
try
{
return readProperty(new StringReader(xml));
}
catch (IOException e)
{
IllegalStateException ex = new IllegalStateException(e);
ex.initCause(e);
throw ex;
}
}
public Property readProperty(Reader reader) throws Exception
{
return RepositoryParser.getParser().parseProperty(reader);
}
}