Enhancing OnosJar to build OSGi jars and wars if required.
Also, simplifying onos.bucklet by using the rule
Change-Id: If89633db2d83cbfc56a8e70d2bea665ffaf186ff
diff --git a/bucklets/onos.bucklet b/bucklets/onos.bucklet
index e5e4b0a..cf8d276 100644
--- a/bucklets/onos.bucklet
+++ b/bucklets/onos.bucklet
@@ -114,6 +114,7 @@
api_description = NONE,
resources = NONE,
resources_root = None,
+ tests = None,
**kwargs
):
@@ -134,76 +135,42 @@
resources_root = RESOURCES_ROOT
if api_title != NONE:
- r = 'WEB-INF/classes/apidoc/swagger.json=bin/swagger.json'
+ r = 'WEB-INF/classes/apidoc/swagger.json=swagger.json'
include_resources = include_resources + ',' + r if include_resources != NONE else r
- bare_jar_name = name + '-jar'
- osgi_jar_name = name + '-osgi'
mvn_coords = group_id + ':' + name + ':' + version
-
onos_jar(
- name = bare_jar_name,
- srcs = srcs,
+ name = name,
+ srcs = srcs + glob(['src/main/webapp/**']),
deps = deps,
- visibility = [], #intentially, not visible
+ visibility = visibility,
resources = resources,
resources_root = resources_root,
+ bundle_name = name,
+ group_id = group_id,
+ bundle_version = version,
+ bundle_license = license,
+ bundle_description = description,
+ import_packages = import_packages,
+ export_packages = export_packages,
+ include_resources = include_resources,
+ dynamicimport_packages = dynamicimport_packages,
web_context = web_context,
api_title = api_title,
api_version = api_version,
api_package = api_package,
api_description = api_description,
+ tests = tests,
+ maven_coords = mvn_coords,
**kwargs
)
- cp = ':'.join(['$(classpath %s)' % c for c in deps]) if deps else '""'
-
- args = ( '$(location :%s)' % bare_jar_name, #input jar
- '$OUT', #output jar
- cp, #classpath
- name, #bundle name
- group_id, #group id
- version, #version
- license, #license url
- "'%s'" % import_packages, #packages to import
- "'%s'" % export_packages, #packages to export
- include_resources, #custom includes to classpath
- web_context, #web context (REST API only)
- "'%s'" % dynamicimport_packages, #DynamicImport-Package
- description, #description
- )
-
- #TODO stage_jar is a horrendous hack
- stage_jar = 'pushd $SRCDIR; mkdir bin; cd bin; jar xf $(location :%s); ls; popd; ' % bare_jar_name
- wrap_jar = '$(exe //utils/osgiwrap:osgi-jar) ' + ' '.join(args)
- bash = stage_jar + wrap_jar
- if debug:
- bash = stage_jar + DEBUG_ARG + ' ' + wrap_jar
- print bash
-
- # FIXME: make sure that /swagger.json gets filtered
- genrule(
- name = osgi_jar_name,
- bash = bash,
- out = '%s-%s.jar' % (name, version), #FIXME add version to jar file
- srcs = glob(['src/main/webapp/**']),
- visibility = [], #intentially, not visible
- )
-
- # TODO we really should shade the jar with maven flavor
- prebuilt_jar(
- name = name,
- maven_coords = mvn_coords,
- binary_jar = ':' + osgi_jar_name,
- visibility = visibility,
- )
-
### Checkstyle
checkstyle(
name = name + '-checkstyle-files',
srcs = srcs,
- jar_target = ':'+ bare_jar_name,
+ jar_target = ':'+ name,
)
java_doc(
@@ -219,7 +186,7 @@
# TODO add project config for intellij
# project_config(
- # src_target = ':' + bare_jar_name,
+ # src_target = ':' + name,
# src_roots = [ 'src/main/java' ],
# test_target = ':' + name + '-tests',
# test_roots = [ 'src/test/java' ],
@@ -247,6 +214,8 @@
def osgi_jar_with_tests(
name = None,
deps = [],
+ group_id = ONOS_GROUP_ID,
+ version = ONOS_VERSION,
test_srcs = None,
test_deps = [ '//lib:TEST' ],
test_resources = None,
@@ -260,7 +229,10 @@
osgi_jar(name = name,
deps = deps,
+ group_id = group_id,
+ version = version,
visibility = visibility,
+ tests = [':' + name + '-tests'],
**kwargs)
if test_resources and not test_resources_root:
@@ -275,16 +247,18 @@
if test_srcs is None:
test_srcs = glob([TEST + '/*.java'])
+ mvn_coords = group_id + ':' + name + ':jar:tests:' + version
+
java_test(
name = name + '-tests',
srcs = test_srcs,
deps = deps +
test_deps +
- [':' + name + '-jar'],
- source_under_test = [':' + name + '-jar'],
+ [':' + name + '#non-osgi'],
resources = test_resources,
resources_root = test_resources_root,
- visibility = visibility
+ maven_coords = mvn_coords,
+ visibility = visibility,
)
checkstyle(
@@ -292,5 +266,3 @@
srcs = test_srcs,
jar_target = ':' + name + '-tests',
)
-
- #FIXME need to run checkstyle on test sources
diff --git a/tools/build/buck-plugin/BUCK b/tools/build/buck-plugin/BUCK
index 62e2875..37f1e8e 100644
--- a/tools/build/buck-plugin/BUCK
+++ b/tools/build/buck-plugin/BUCK
@@ -1,19 +1,23 @@
+# Comment the remote_jar out for local buck development
remote_jar (
name = 'buck-api',
out = 'buck.jar',
- url = 'https://github.com/bocon13/buck/releases/download/v2016.07.29.01-wip/buck.jar',
- sha1 = 'f89324cb869b74fdcd4db9972233065a93d890a2',
+ url = 'https://github.com/bocon13/buck/releases/download/v2016.09.13.01/buck.jar',
+ sha1 = 'd5415b4326e5316675532a8cd48001a8456e8c9e',
visibility = [],
)
+# Uncomment the prebuilt_jar and copy buck-api to lib/buck.jar for local buck development
+# prebuilt_jar (
+# name = 'buck-api',
+# binary_jar = 'lib/buck.jar'
+# )
+
COMPILE = [
'//lib:qdox',
- #'//lib:jackson-core',
- #'//lib:jackson-databind',
- #'//lib:jackson-annotations',
-]
-
-RUNTIME = [
+ '//lib:guava',
+ '//lib:bndlib',
+ '//lib:org.apache.felix.scr.bnd'
]
java_library(
diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OSGiWrapper.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OSGiWrapper.java
new file mode 100644
index 0000000..aa529fc
--- /dev/null
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OSGiWrapper.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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 org.onosproject.onosjar;
+
+import aQute.bnd.header.Attrs;
+import aQute.bnd.header.Parameters;
+import aQute.bnd.osgi.Analyzer;
+import aQute.bnd.osgi.Builder;
+import aQute.bnd.osgi.FileResource;
+import aQute.bnd.osgi.Jar;
+import aQute.bnd.osgi.Resource;
+import com.facebook.buck.step.ExecutionContext;
+import com.facebook.buck.step.Step;
+import com.facebook.buck.step.StepExecutionResult;
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.apache.felix.scrplugin.bnd.SCRDescriptorBndPlugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.FileVisitResult;
+import java.nio.file.FileVisitor;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+
+import static java.nio.file.Files.walkFileTree;
+
+/**
+ * BND-based wrapper to convert Buck JARs to OSGi-compatible JARs.
+ */
+public class OSGiWrapper implements Step {
+
+ private Path inputJar;
+ private Path outputJar;
+ private Path sourcesDir;
+ private Path classesDir;
+ private List<String> classpath;
+
+ private String bundleName;
+ private String groupId;
+ private String bundleSymbolicName;
+ private String bundleVersion;
+
+ private String importPackages;
+ private String dynamicimportPackages;
+
+ private String exportPackages;
+ private String includeResources;
+ private Set<String> includedResources = Sets.newHashSet();
+
+ private String bundleDescription;
+ private String bundleLicense;
+
+ private String webContext;
+
+ private PrintStream stderr = System.err;
+
+ public OSGiWrapper(Path inputJar,
+ Path outputJar,
+ Path sourcesDir,
+ Path classesDir,
+ ImmutableSortedSet<Path> classpath,
+ String bundleName,
+ String groupId,
+ String bundleVersion,
+ String bundleLicense,
+ String importPackages,
+ String exportPackages,
+ String includeResources,
+ String webContext,
+ String dynamicimportPackages,
+ String bundleDescription) {
+ this.inputJar = inputJar;
+ this.sourcesDir = sourcesDir;
+ this.classesDir = classesDir;
+ this.classpath = Lists.newArrayList(
+ classpath.stream().map(Path::toString).collect(Collectors.toList()));
+ if (!this.classpath.contains(inputJar.toString())) {
+ this.classpath.add(0, inputJar.toString());
+ }
+ this.outputJar = outputJar;
+
+ this.bundleName = bundleName;
+ this.groupId = groupId;
+ this.bundleSymbolicName = String.format("%s.%s", groupId, bundleName);
+
+ this.bundleVersion = bundleVersion;
+ this.bundleLicense = bundleLicense;
+ this.bundleDescription = bundleDescription;
+
+ this.importPackages = importPackages;
+ this.dynamicimportPackages = dynamicimportPackages;
+ this.exportPackages = exportPackages;
+ this.includeResources = includeResources;
+
+ this.webContext = webContext;
+ }
+
+ private void setProperties(Analyzer analyzer) {
+ analyzer.setProperty(Analyzer.BUNDLE_NAME, bundleName);
+ analyzer.setProperty(Analyzer.BUNDLE_SYMBOLICNAME, bundleSymbolicName);
+ analyzer.setProperty(Analyzer.BUNDLE_VERSION, bundleVersion.replace('-', '.'));
+
+ if (bundleDescription != null) {
+ analyzer.setProperty(Analyzer.BUNDLE_DESCRIPTION, bundleDescription);
+ }
+ if (bundleLicense != null) {
+ analyzer.setProperty(Analyzer.BUNDLE_LICENSE, bundleLicense);
+ }
+
+ //TODO consider using stricter version policy
+ //analyzer.setProperty("-provider-policy", "${range;[===,==+)}");
+ //analyzer.setProperty("-consumer-policy", "${range;[===,==+)}");
+
+ // There are no good defaults so make sure you set the Import-Package
+ analyzer.setProperty(Analyzer.IMPORT_PACKAGE, importPackages);
+
+ analyzer.setProperty(Analyzer.DYNAMICIMPORT_PACKAGE, dynamicimportPackages);
+
+ // TODO include version in export, but not in import
+ analyzer.setProperty(Analyzer.EXPORT_PACKAGE, exportPackages);
+
+ // TODO we may need INCLUDE_RESOURCE, or that might be done by Buck
+ if (includeResources != null) {
+ analyzer.setProperty(Analyzer.INCLUDE_RESOURCE, includeResources);
+ }
+
+ if (isWab()) {
+ analyzer.setProperty(Analyzer.WAB, "src/main/webapp/");
+ analyzer.setProperty("Web-ContextPath", webContext);
+ analyzer.setProperty(Analyzer.IMPORT_PACKAGE, "*,org.glassfish.jersey.servlet,org.jvnet.mimepull\n");
+ }
+ }
+
+ public boolean execute() {
+ Analyzer analyzer = new Builder();
+ try {
+
+ Jar jar = new Jar(inputJar.toFile()); // where our data is
+ analyzer.setJar(jar); // give bnd the contents
+
+ // You can provide additional class path entries to allow
+ // bnd to pickup export version from the packageinfo file,
+ // Version annotation, or their manifests.
+ analyzer.addClasspath(classpath);
+
+ setProperties(analyzer);
+
+ //analyzer.setBase(classesDir.toFile());
+
+// analyzer.setProperty("DESTDIR");
+// analyzer.setBase();
+
+ // ------------- let's begin... -------------------------
+
+ // Analyze the target JAR first
+ analyzer.analyze();
+
+ // Scan the JAR for Felix SCR annotations and generate XML files
+ Map<String, String> properties = Maps.newHashMap();
+ properties.put("destdir", classesDir.toAbsolutePath().toString());
+ SCRDescriptorBndPlugin scrDescriptorBndPlugin = new SCRDescriptorBndPlugin();
+ scrDescriptorBndPlugin.setProperties(properties);
+ scrDescriptorBndPlugin.setReporter(analyzer);
+ scrDescriptorBndPlugin.analyzeJar(analyzer);
+
+ if (includeResources != null) {
+ doIncludeResources(analyzer);
+ }
+
+ // Repack the JAR as a WAR
+ doWabStaging(analyzer);
+
+ // Calculate the manifest
+ Manifest manifest = analyzer.calcManifest();
+ //OutputStream s = new FileOutputStream("/tmp/foo2.txt");
+ //manifest.write(s);
+ //s.close();
+
+ if (analyzer.isOk()) {
+ analyzer.getJar().setManifest(manifest);
+ if (analyzer.save(outputJar.toFile(), true)) {
+ log("Saved!\n");
+ } else {
+ warn("Failed to create jar \n");
+ return false;
+ }
+ } else {
+ warn("Analyzer Errors:\n%s\n", analyzer.getErrors());
+ return false;
+ }
+
+ analyzer.close();
+
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ private boolean isWab() {
+ return webContext != null;
+ }
+
+ private void doWabStaging(Analyzer analyzer) throws Exception {
+ if (!isWab()) {
+ return;
+ }
+ String wab = analyzer.getProperty(analyzer.WAB);
+ Jar dot = analyzer.getJar();
+
+ log("wab %s", wab);
+ analyzer.setBundleClasspath("WEB-INF/classes," +
+ analyzer.getProperty(analyzer.BUNDLE_CLASSPATH));
+
+ Set<String> paths = new HashSet<>(dot.getResources().keySet());
+
+ for (String path : paths) {
+ if (path.indexOf('/') > 0 && !Character.isUpperCase(path.charAt(0))) {
+ log("wab: moving: %s", path);
+ dot.rename(path, "WEB-INF/classes/" + path);
+ }
+ }
+
+ Path wabRoot = Paths.get(wab);
+ includeFiles(dot, null, wabRoot.toString());
+ }
+
+ /**
+ * Parse the Bundle-Includes header. Files in the bundles Include header are
+ * included in the jar. The source can be a directory or a file.
+ *
+ * @throws Exception
+ */
+ private void doIncludeResources(Analyzer analyzer) throws Exception {
+ String includes = analyzer.getProperty(Analyzer.INCLUDE_RESOURCE);
+ if (includes == null) {
+ return;
+ }
+ Parameters clauses = analyzer.parseHeader(includes);
+ Jar jar = analyzer.getJar();
+
+ for (Map.Entry<String, Attrs> entry : clauses.entrySet()) {
+ String name = entry.getKey();
+ Map<String, String> extra = entry.getValue();
+ // TODO consider doing something with extras
+
+ String[] parts = name.split("\\s*=\\s*");
+ String source = parts[0];
+ String destination = parts[0];
+ if (parts.length == 2) {
+ source = parts[1];
+ }
+
+ includeFiles(jar, destination, source);
+ }
+ }
+
+ private void includeFiles(Jar jar, String destinationRoot, String sourceRoot)
+ throws IOException {
+
+ Path classesBasedPath = classesDir.resolve(sourceRoot);
+ Path sourceBasedPath = sourcesDir.resolve(sourceRoot);
+
+ File classFile = classesBasedPath.toFile();
+ File sourceFile = sourceBasedPath.toFile();
+
+ if (classFile.isFile()) {
+ addFileToJar(jar, destinationRoot, classesBasedPath.toAbsolutePath().toString());
+ } else if (sourceFile.isFile()) {
+ addFileToJar(jar, destinationRoot, sourceBasedPath.toAbsolutePath().toString());
+ } else if (classFile.isDirectory()) {
+ includeDirectory(jar, destinationRoot, classesBasedPath);
+ } else if (sourceFile.isDirectory()) {
+ includeDirectory(jar, destinationRoot, sourceBasedPath);
+ } else {
+ warn("Skipping resource in bundle %s: %s (File Not Found)\n",
+ bundleSymbolicName, sourceRoot);
+ }
+ }
+
+ private void includeDirectory(Jar jar, String destinationRoot, Path sourceRoot)
+ throws IOException {
+ // iterate through sources
+ // put each source on the jar
+ FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+ Path relativePath = sourceRoot.relativize(file);
+ String destination = destinationRoot != null ?
+ destinationRoot + "/" + relativePath.toString() : //TODO
+ relativePath.toString();
+
+ addFileToJar(jar, destination, file.toAbsolutePath().toString());
+ return FileVisitResult.CONTINUE;
+ }
+ };
+
+ walkFileTree(sourceRoot, visitor);
+ }
+
+ private boolean addFileToJar(Jar jar, String destination, String sourceAbsPath) {
+ if (includedResources.contains(sourceAbsPath)) {
+ log("Skipping already included resource: %s\n", sourceAbsPath);
+ return false;
+ }
+ File file = new File(sourceAbsPath);
+ if (!file.isFile()) {
+ throw new RuntimeException(
+ String.format("Skipping non-existent file: %s\n", sourceAbsPath));
+ }
+ Resource resource = new FileResource(file);
+ if (jar.getResource(destination) != null) {
+ warn("Skipping duplicate resource: %s\n", destination);
+ return false;
+ }
+ jar.putResource(destination, resource);
+ includedResources.add(sourceAbsPath);
+ log("Adding resource: %s\n", destination);
+ return true;
+ }
+
+ private void log(String format, Object... objects) {
+ //System.err.printf(format, objects);
+ }
+
+ private void warn(String format, Object... objects) {
+ stderr.printf(format, objects);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("inputJar", inputJar)
+ .add("outputJar", outputJar)
+ .add("classpath", classpath)
+ .add("bundleName", bundleName)
+ .add("groupId", groupId)
+ .add("bundleSymbolicName", bundleSymbolicName)
+ .add("bundleVersion", bundleVersion)
+ .add("bundleDescription", bundleDescription)
+ .add("bundleLicense", bundleLicense)
+ .toString();
+
+ }
+
+ @Override
+ public StepExecutionResult execute(ExecutionContext executionContext)
+ throws IOException, InterruptedException {
+ stderr = executionContext.getStdErr();
+ boolean success = execute();
+ stderr = System.err;
+ return success ? StepExecutionResult.SUCCESS : StepExecutionResult.ERROR;
+ }
+
+ @Override
+ public String getShortName() {
+ return "osgiwrap";
+ }
+
+ @Override
+ public String getDescription(ExecutionContext executionContext) {
+ return "osgiwrap"; //FIXME
+ }
+}
diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJar.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJar.java
index a63c115..3c71968 100644
--- a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJar.java
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJar.java
@@ -17,6 +17,10 @@
import com.facebook.buck.jvm.java.CompileToJarStepFactory;
import com.facebook.buck.jvm.java.DefaultJavaLibrary;
+import com.facebook.buck.jvm.java.HasClasspathEntries;
+import com.facebook.buck.jvm.java.HasMavenCoordinates;
+import com.facebook.buck.jvm.java.JavaLibrary;
+import com.facebook.buck.jvm.java.MavenPublishable;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.rules.AddToRuleKey;
import com.facebook.buck.rules.BuildRule;
@@ -24,6 +28,7 @@
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
@@ -36,7 +41,8 @@
* Implementation of a build rule that generates a onosjar.json file for a set
* of Java sources.
*/
-public class OnosJar extends DefaultJavaLibrary {
+public class OnosJar extends DefaultJavaLibrary
+ implements MavenPublishable{
@AddToRuleKey
final Optional<String> webContext;
@@ -53,6 +59,8 @@
@AddToRuleKey
final Optional<String> apiDescription;
+ private final ImmutableSortedSet<HasMavenCoordinates> mavenDeps;
+
public OnosJar(BuildRuleParams params,
SourcePathResolver resolver,
Set<? extends SourcePath> srcs,
@@ -84,5 +92,32 @@
this.apiVersion = apiVersion;
this.apiPackage = apiPackage;
this.apiDescription = apiDescription;
+ this.mavenDeps = computeMavenDeps();
+ }
+
+ private ImmutableSortedSet<HasMavenCoordinates> computeMavenDeps() {
+ ImmutableSortedSet.Builder<HasMavenCoordinates> mavenDeps = ImmutableSortedSet.naturalOrder();
+ for (JavaLibrary javaLibrary : getTransitiveClasspathDeps()) {
+ if (this.equals(javaLibrary)) {
+ // no need to include ourself
+ continue;
+ } else if (HasMavenCoordinates.MAVEN_COORDS_PRESENT_PREDICATE.apply(javaLibrary)) {
+ mavenDeps.add(javaLibrary);
+ //FIXME BOC do we always want to exclude all of a maven jar's dependencies? probably.
+ mavenDeps.addAll(javaLibrary.getTransitiveClasspathDeps());
+ }
+ }
+ return mavenDeps.build();
+ }
+
+ @Override
+ public Iterable<HasMavenCoordinates> getMavenDeps() {
+ return mavenDeps;
+ }
+
+ @Override
+ public Iterable<BuildRule> getPackagedDependencies() {
+ //FIXME this is not supported at the moment
+ return ImmutableList.of();
}
}
diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarDescription.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarDescription.java
index 7632ade..dff37c0 100644
--- a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarDescription.java
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarDescription.java
@@ -19,13 +19,21 @@
import com.facebook.buck.jvm.java.CalculateAbi;
import com.facebook.buck.jvm.java.DefaultJavaLibrary;
import com.facebook.buck.jvm.java.JavaBuckConfig;
+import com.facebook.buck.jvm.java.JavaLibrary;
import com.facebook.buck.jvm.java.JavaLibraryDescription;
import com.facebook.buck.jvm.java.JavaOptions;
+import com.facebook.buck.jvm.java.JavaSourceJar;
import com.facebook.buck.jvm.java.JavacOptions;
import com.facebook.buck.jvm.java.JavacOptionsAmender;
import com.facebook.buck.jvm.java.JavacOptionsFactory;
+import com.facebook.buck.jvm.java.JavacToJarStepFactory;
+import com.facebook.buck.jvm.java.JavadocJar;
+import com.facebook.buck.jvm.java.MavenUberJar;
+import com.facebook.buck.maven.AetherUtil;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.Flavor;
+import com.facebook.buck.model.Flavored;
+import com.facebook.buck.model.ImmutableFlavor;
import com.facebook.buck.parser.NoSuchBuildTargetException;
import com.facebook.buck.rules.BuildRule;
import com.facebook.buck.rules.BuildRuleParams;
@@ -37,7 +45,9 @@
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePaths;
import com.facebook.buck.rules.TargetGraph;
+import com.google.common.base.Function;
import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
@@ -51,8 +61,16 @@
*
* Currently, this only does Swagger generation.
*/
-public class OnosJarDescription implements Description<OnosJarDescription.Arg> {
+public class OnosJarDescription implements Description<OnosJarDescription.Arg>, Flavored {
public static final BuildRuleType TYPE = BuildRuleType.of("onos_jar");
+ public static final Flavor NON_OSGI_JAR = ImmutableFlavor.of("non-osgi");
+
+ public static final ImmutableSet<Flavor> SUPPORTED_FLAVORS = ImmutableSet.of(
+ JavaLibrary.SRC_JAR,
+ JavaLibrary.MAVEN_JAR,
+ JavaLibrary.JAVADOC_JAR,
+ NON_OSGI_JAR);
+
private final JavacOptions defaultJavacOptions;
private final JavaOptions defaultJavaOptions;
@@ -89,6 +107,63 @@
ImmutableSortedSet<Flavor> flavors = target.getFlavors();
BuildRuleParams paramsWithMavenFlavor = null;
+ if (flavors.contains(JavaLibrary.MAVEN_JAR)) {
+ paramsWithMavenFlavor = params;
+
+ // Maven rules will depend upon their vanilla versions, so the latter have to be constructed
+ // without the maven flavor to prevent output-path conflict
+ params = params.copyWithBuildTarget(
+ params.getBuildTarget().withoutFlavors(ImmutableSet.of(JavaLibrary.MAVEN_JAR)));
+ }
+
+ if (flavors.contains(JavaLibrary.SRC_JAR)) {
+ args.mavenCoords = args.mavenCoords.transform(
+ new Function<String, String>() {
+ @Override
+ public String apply(String input) {
+ return AetherUtil.addClassifier(input, AetherUtil.CLASSIFIER_SOURCES);
+ }
+ });
+
+ if (!flavors.contains(JavaLibrary.MAVEN_JAR)) {
+ return new JavaSourceJar(
+ params,
+ pathResolver,
+ args.srcs.get(),
+ args.mavenCoords);
+ } else {
+ return MavenUberJar.SourceJar.create(
+ Preconditions.checkNotNull(paramsWithMavenFlavor),
+ pathResolver,
+ args.srcs.get(),
+ args.mavenCoords);
+ }
+ }
+
+ if (flavors.contains(JavaLibrary.JAVADOC_JAR)) {
+ args.mavenCoords = args.mavenCoords.transform(
+ new Function<String, String>() {
+ @Override
+ public String apply(String input) {
+ return AetherUtil.addClassifier(input, AetherUtil.CLASSIFIER_JAVADOC);
+ }
+ });
+
+ if (!flavors.contains(JavaLibrary.MAVEN_JAR)) {
+ return new JavadocJar(
+ params,
+ pathResolver,
+ args.srcs.get(),
+ args.mavenCoords);
+ } else {
+ return MavenUberJar.MavenJavadocJar.create(
+ Preconditions.checkNotNull(paramsWithMavenFlavor),
+ pathResolver,
+ args.srcs.get(),
+ args.mavenCoords);
+ }
+ }
+
JavacOptions javacOptions = JavacOptionsFactory.create(
defaultJavacOptions,
params,
@@ -101,45 +176,84 @@
ImmutableSortedSet<BuildRule> exportedDeps = resolver.getAllRules(args.exportedDeps.get());
- DefaultJavaLibrary defaultJavaLibrary =
- resolver.addToIndex(
- new OnosJar(
- params.appendExtraDeps(
- Iterables.concat(
- BuildRules.getExportedRules(
- Iterables.concat(
- params.getDeclaredDeps().get(),
- exportedDeps,
- resolver.getAllRules(args.providedDeps.get()))),
- pathResolver.filterBuildRuleInputs(
- javacOptions.getInputs(pathResolver)))),
- pathResolver,
- args.srcs.get(),
- validateResources(
- pathResolver,
- params.getProjectFilesystem(),
- args.resources.get()),
- javacOptions.getGeneratedSourceFolderName(),
- args.proguardConfig.transform(
- SourcePaths.toSourcePath(params.getProjectFilesystem())),
- args.postprocessClassesCommands.get(), // FIXME this should be forbidden
- exportedDeps,
- resolver.getAllRules(args.providedDeps.get()),
- new BuildTargetSourcePath(abiJarTarget),
- javacOptions.trackClassUsage(),
+ final DefaultJavaLibrary defaultJavaLibrary;
+ if (!flavors.contains(NON_OSGI_JAR)) {
+ defaultJavaLibrary =
+ resolver.addToIndex(
+ new OnosJar(
+ params.appendExtraDeps(
+ Iterables.concat(
+ BuildRules.getExportedRules(
+ Iterables.concat(
+ params.getDeclaredDeps().get(),
+ exportedDeps,
+ resolver.getAllRules(args.providedDeps.get()))),
+ pathResolver.filterBuildRuleInputs(
+ javacOptions.getInputs(pathResolver)))),
+ pathResolver,
+ args.srcs.get(),
+ validateResources(
+ pathResolver,
+ params.getProjectFilesystem(),
+ args.resources.get()),
+ javacOptions.getGeneratedSourceFolderName(),
+ args.proguardConfig.transform(
+ SourcePaths.toSourcePath(params.getProjectFilesystem())),
+ args.postprocessClassesCommands.get(), // FIXME this should be forbidden
+ exportedDeps,
+ resolver.getAllRules(args.providedDeps.get()),
+ new BuildTargetSourcePath(abiJarTarget),
+ javacOptions.trackClassUsage(),
/* additionalClasspathEntries */ ImmutableSet.<Path>of(),
- new OnosJarStepFactory(javacOptions, JavacOptionsAmender.IDENTITY,
- args.webContext, args.apiTitle, args.apiVersion,
- args.apiPackage, args.apiDescription, args.resources),
- args.resourcesRoot,
- args.mavenCoords,
- args.tests.get(),
- javacOptions.getClassesToRemoveFromJar(),
- args.webContext,
- args.apiTitle,
- args.apiVersion,
- args.apiPackage,
- args.apiDescription));
+ new OnosJarStepFactory(javacOptions, JavacOptionsAmender.IDENTITY,
+ args.webContext, args.apiTitle, args.apiVersion,
+ args.apiPackage, args.apiDescription, args.resources,
+ args.groupId, args.bundleName, args.bundleVersion,
+ args.bundleLicense, args.bundleDescription, args.importPackages,
+ args.exportPackages, args.includeResources, args.dynamicimportPackages),
+ args.resourcesRoot,
+ args.mavenCoords,
+ args.tests.get(),
+ javacOptions.getClassesToRemoveFromJar(),
+ args.webContext,
+ args.apiTitle,
+ args.apiVersion,
+ args.apiPackage,
+ args.apiDescription));
+ } else {
+ defaultJavaLibrary =
+ resolver.addToIndex(
+ new DefaultJavaLibrary(
+ params.appendExtraDeps(
+ Iterables.concat(
+ BuildRules.getExportedRules(
+ Iterables.concat(
+ params.getDeclaredDeps().get(),
+ exportedDeps,
+ resolver.getAllRules(args.providedDeps.get()))),
+ pathResolver.filterBuildRuleInputs(
+ javacOptions.getInputs(pathResolver)))),
+ pathResolver,
+ args.srcs.get(),
+ validateResources(
+ pathResolver,
+ params.getProjectFilesystem(),
+ args.resources.get()),
+ javacOptions.getGeneratedSourceFolderName(),
+ args.proguardConfig.transform(
+ SourcePaths.toSourcePath(params.getProjectFilesystem())),
+ args.postprocessClassesCommands.get(),
+ exportedDeps,
+ resolver.getAllRules(args.providedDeps.get()),
+ new BuildTargetSourcePath(abiJarTarget),
+ javacOptions.trackClassUsage(),
+ /* additionalClasspathEntries */ ImmutableSet.<Path>of(),
+ new JavacToJarStepFactory(javacOptions, JavacOptionsAmender.IDENTITY),
+ args.resourcesRoot,
+ args.mavenCoords,
+ args.tests.get(),
+ javacOptions.getClassesToRemoveFromJar()));
+ }
resolver.addToIndex(
CalculateAbi.of(
@@ -151,6 +265,10 @@
return defaultJavaLibrary;
}
+ @Override
+ public boolean hasFlavors(ImmutableSet<Flavor> flavors) {
+ return SUPPORTED_FLAVORS.containsAll(flavors);
+ }
public static class Arg extends JavaLibraryDescription.Arg {
public Optional<String> webContext;
@@ -158,5 +276,16 @@
public Optional<String> apiVersion;
public Optional<String> apiPackage;
public Optional<String> apiDescription;
+
+ public Optional<String> groupId;
+ public Optional<String> bundleName;
+ public Optional<String> bundleVersion;
+ public Optional<String> bundleLicense;
+ public Optional<String> bundleDescription;
+
+ public Optional<String> importPackages;
+ public Optional<String> exportPackages;
+ public Optional<String> includeResources;
+ public Optional<String> dynamicimportPackages;
}
}
\ No newline at end of file
diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarStepFactory.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarStepFactory.java
index aa0e9f6..ae2853b 100644
--- a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarStepFactory.java
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarStepFactory.java
@@ -28,12 +28,14 @@
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.step.Step;
+import com.facebook.buck.step.fs.CopyStep;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -49,6 +51,15 @@
private final String apiPackage;
private final String apiDescription;
private final Optional<ImmutableSortedSet<SourcePath>> resources;
+ private final String groupId;
+ private final String bundleName;
+ private final String bundleVersion;
+ private final String bundleLicense;
+ private final String bundleDescription;
+ private final String importPackages;
+ private final String exportPackages;
+ private final String includeResources;
+ private final String dynamicimportPackages;
public OnosJarStepFactory(JavacOptions javacOptions,
JavacOptionsAmender amender,
@@ -57,8 +68,26 @@
Optional<String> apiVersion,
Optional<String> apiPackage,
Optional<String> apiDescription,
- Optional<ImmutableSortedSet<SourcePath>> resources) {
+ Optional<ImmutableSortedSet<SourcePath>> resources,
+ Optional<String> groupId,
+ Optional<String> bundleName,
+ Optional<String> bundleVersion,
+ Optional<String> bundleLicense,
+ Optional<String> bundleDescription,
+ Optional<String> importPackages,
+ Optional<String> exportPackages,
+ Optional<String> includeResources,
+ Optional<String> dynamicimportPackages) {
super(javacOptions, amender);
+ this.bundleDescription = processParameter(bundleDescription);
+ this.importPackages = processParameter(importPackages);
+ this.exportPackages = processParameter(exportPackages);
+ this.includeResources = processParameter(includeResources);
+ this.dynamicimportPackages = processParameter(dynamicimportPackages);
+ this.groupId = processParameter(groupId);
+ this.bundleName = processParameter(bundleName);
+ this.bundleVersion = processParameter(bundleVersion);
+ this.bundleLicense = processParameter(bundleLicense);
this.webContext = processParameter(webContext);
this.apiTitle = processParameter(apiTitle);
this.apiVersion = processParameter(apiVersion);
@@ -114,6 +143,11 @@
apiPackage, apiDescription);
sourceFilePathBuilder.add(swaggerStep.apiRegistratorPath());
steps.add(swaggerStep);
+
+// steps.addAll(sourceFilePaths.stream()
+// .filter(sp -> sp.startsWith("src/main/webapp/"))
+// .map(sp -> CopyStep.forFile(filesystem, sp, outputDirectory))
+// .iterator());
}
createCompileStep(context,
@@ -132,6 +166,7 @@
// post compilation steps
+
// FIXME BOC: add mechanism to inject new Steps
//context.additionalStepFactory(JavaStep.class);
@@ -143,6 +178,28 @@
manifestFile.orNull(),
true,
blacklistBuilder.build()));
+
+ OSGiWrapper osgiStep = new OSGiWrapper(
+ outputJar, //input jar
+ outputJar, //Paths.get(outputJar.toString() + ".jar"), //output jar
+ invokingRule.getBasePath(), // sources dir
+ outputDirectory, // classes dir
+ declaredClasspathEntries, // classpath
+ bundleName, // bundle name
+ groupId, // groupId
+ bundleVersion, // bundle version
+ bundleLicense, // bundle license
+ importPackages, // import packages
+ exportPackages, // export packages
+ includeResources, // include resources
+ webContext, // web context
+ dynamicimportPackages, // dynamic import packages
+ bundleDescription // bundle description
+ );
+ steps.add(osgiStep);
+
+ //steps.add(CopyStep.forFile(filesystem, Paths.get(outputJar.toString() + ".jar"), outputJar));
+
}
private ImmutableSortedSet<Path> findSwaggerModelDefs(SourcePathResolver resolver,
diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/SwaggerGenerator.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/SwaggerGenerator.java
index 898be8c..14d401b 100644
--- a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/SwaggerGenerator.java
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/SwaggerGenerator.java
@@ -102,10 +102,12 @@
}
if (srcs != null) {
srcs.forEach(src -> {
- try {
- builder.addSource(src);
- } catch (IOException e) {
- throw new RuntimeException(e);
+ if (src.toString().endsWith(".java")) {
+ try {
+ builder.addSource(src);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
});
}