org.apache.aries.util.FragmentBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/**
* 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.aries.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import org.apache.aries.util.internal.MessageUtil;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Constants;
public class FragmentBuilder {
private List importPackages = new ArrayList();
private List exportPackages = new ArrayList();
private Bundle hostBundle;
private String nameExtension;
private String bundleNameExtension;
private String fragmentName;
private Map files = new HashMap();
public FragmentBuilder(Bundle host) {
this(host, ".fragment", "Fragment");
}
public FragmentBuilder(Bundle host, String symbolicNameSuffix, String bundleNameSuffix) {
hostBundle = host;
nameExtension = symbolicNameSuffix;
bundleNameExtension = bundleNameSuffix;
// make sure we have an initial '.'
if (!!!nameExtension.startsWith(".")) {
nameExtension = "." + nameExtension;
}
}
public void setName(String name) {
fragmentName = name;
}
public void addImports(String... imports) {
importPackages.addAll(Arrays.asList(imports));
}
public void addExports(String... imports) {
exportPackages.addAll(Arrays.asList(imports));
}
public void addImportsFromExports(Bundle exportBundle) {
String exportString = (String) exportBundle.getHeaders().get(Constants.EXPORT_PACKAGE);
if (exportString != null) {
String exportVersion = exportBundle.getVersion().toString();
String bundleConstraint = Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE
+ "=\"" + exportBundle.getSymbolicName() + "\"";
String bundleVersionConstraint = Constants.BUNDLE_VERSION_ATTRIBUTE
+ "=\"[" + exportVersion + "," + exportVersion + "]\"";
List exports = parseDelimitedString(exportString, ",", true);
for (String export : exports) {
importPackages.add(convertExportToImport(export, bundleConstraint, bundleVersionConstraint));
}
}
}
/**
* Filter out directives in the export statement
*
* @param exportStatement
* @return
*/
private String convertExportToImport(String exportStatement,
String bundleConstraint,
String bundleVersionConstraint) {
StringBuffer result = new StringBuffer();
for (String fragment : exportStatement.split("\\s*;\\s*")) {
int pos = fragment.indexOf('=');
// similar to fragment.contains(":=") but looks for the first '='
// and checks whether this is part of ':='
// in this way we will not be fooled by attributes like
// a="something:=strange"
if (!!!(pos > 0 && fragment.charAt(pos - 1) == ':')) {
result.append(fragment);
result.append(';');
}
}
result.append(bundleConstraint);
result.append(';');
result.append(bundleVersionConstraint);
return result.toString();
}
public void addFile(String path, byte[] content) {
files.put(path, content);
}
public Bundle install(BundleContext ctx) throws IOException, BundleException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
JarOutputStream jos = null;
try {
jos = new JarOutputStream(baos, makeManifest());
addFileContent(jos);
} finally {
if (jos != null)
jos.close();
baos.close();
}
byte[] inMemoryJar = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(inMemoryJar);
return ctx.installBundle(getFragmentSymbolicName(), bais);
}
private void addFileContent(JarOutputStream jos) throws IOException {
for (Map.Entry entry : files.entrySet()) {
jos.putNextEntry(new JarEntry(entry.getKey()));
jos.write(entry.getValue());
}
}
public String getFragmentSymbolicName() {
return hostBundle.getSymbolicName() + nameExtension;
}
public String getFragmentBundleName() {
if (fragmentName != null) {
return fragmentName;
} else {
String bundleName = (String) hostBundle.getHeaders().get(Constants.BUNDLE_NAME);
if (bundleName != null && bundleNameExtension != null) {
return bundleName.trim() + " " + bundleNameExtension.trim();
}
}
return null;
}
private Manifest makeManifest() {
String commonVersion = hostBundle.getVersion().toString();
String fragmentHost = hostBundle.getSymbolicName() + ";"
+ Constants.BUNDLE_VERSION_ATTRIBUTE + "=\"" + commonVersion
+ "\"";
Manifest m = new Manifest();
Attributes manifestAttributes = m.getMainAttributes();
manifestAttributes.putValue(Attributes.Name.MANIFEST_VERSION.toString(), "1.0");
manifestAttributes.putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
manifestAttributes.putValue(Constants.BUNDLE_SYMBOLICNAME, getFragmentSymbolicName());
String bundleName = getFragmentBundleName();
if (bundleName != null) {
manifestAttributes.putValue(Constants.BUNDLE_NAME, bundleName);
}
manifestAttributes.putValue(Constants.BUNDLE_VERSION, commonVersion);
manifestAttributes.putValue(Constants.BUNDLE_VENDOR, "Apache");
manifestAttributes.putValue(Constants.FRAGMENT_HOST, fragmentHost);
addImportsAndExports(manifestAttributes);
return m;
}
private void addImportsAndExports(Attributes attrs) {
if (!!!importPackages.isEmpty()) {
attrs.putValue(Constants.IMPORT_PACKAGE, joinStrings(importPackages, ','));
}
if (!!!exportPackages.isEmpty()) {
attrs.putValue(Constants.EXPORT_PACKAGE, joinStrings(exportPackages, ','));
}
}
private String joinStrings(List strs, char separator) {
StringBuilder result = new StringBuilder();
boolean first = true;
for (String str : strs) {
if (first)
first = false;
else
result.append(separator);
result.append(str);
}
return result.toString();
}
private static List parseDelimitedString(String value, String delim, boolean includeQuotes) {
if (value == null) {
value = "";
}
List list = new ArrayList();
int CHAR = 1;
int DELIMITER = 2;
int STARTQUOTE = 4;
int ENDQUOTE = 8;
StringBuffer sb = new StringBuffer();
int expecting = (CHAR | DELIMITER | STARTQUOTE);
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
boolean isDelimiter = (delim.indexOf(c) >= 0);
boolean isQuote = (c == '"');
if (isDelimiter && ((expecting & DELIMITER) > 0)) {
list.add(sb.toString().trim());
sb.delete(0, sb.length());
expecting = (CHAR | DELIMITER | STARTQUOTE);
} else if (isQuote && ((expecting & STARTQUOTE) > 0)) {
if (includeQuotes) {
sb.append(c);
}
expecting = CHAR | ENDQUOTE;
} else if (isQuote && ((expecting & ENDQUOTE) > 0)) {
if (includeQuotes) {
sb.append(c);
}
expecting = (CHAR | STARTQUOTE | DELIMITER);
} else if ((expecting & CHAR) > 0) {
sb.append(c);
} else {
throw new IllegalArgumentException(MessageUtil.getMessage("UTIL0012E", value));
}
}
if (sb.length() > 0) {
list.add(sb.toString().trim());
}
return list;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy