Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package aQute.bnd.main;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.BufferedReader;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.Formatter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.jar.Attributes;
import java.util.jar.Attributes.Name;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import aQute.bnd.build.Container;
import aQute.bnd.build.Project;
import aQute.bnd.build.ProjectBuilder;
import aQute.bnd.build.ProjectLauncher;
import aQute.bnd.build.ProjectTester;
import aQute.bnd.build.Run;
import aQute.bnd.build.Workspace;
import aQute.bnd.enroute.commands.EnrouteCommand;
import aQute.bnd.enroute.commands.EnrouteOptions;
import aQute.bnd.header.Attrs;
import aQute.bnd.header.OSGiHeader;
import aQute.bnd.header.Parameters;
import aQute.bnd.help.Syntax;
import aQute.bnd.main.BaselineCommands.baseLineOptions;
import aQute.bnd.main.BaselineCommands.schemaOptions;
import aQute.bnd.main.DiffCommand.diffOptions;
import aQute.bnd.main.RepoCommand.repoOptions;
import aQute.bnd.maven.MavenCommand;
import aQute.bnd.maven.PomFromManifest;
import aQute.bnd.osgi.About;
import aQute.bnd.osgi.Analyzer;
import aQute.bnd.osgi.Builder;
import aQute.bnd.osgi.Clazz;
import aQute.bnd.osgi.Clazz.Def;
import aQute.bnd.osgi.Constants;
import aQute.bnd.osgi.Descriptors.PackageRef;
import aQute.bnd.osgi.Descriptors.TypeRef;
import aQute.bnd.osgi.Domain;
import aQute.bnd.osgi.FileResource;
import aQute.bnd.osgi.Instruction;
import aQute.bnd.osgi.Instructions;
import aQute.bnd.osgi.Jar;
import aQute.bnd.osgi.Macro;
import aQute.bnd.osgi.Packages;
import aQute.bnd.osgi.Processor;
import aQute.bnd.osgi.Resource;
import aQute.bnd.osgi.Verifier;
import aQute.bnd.osgi.eclipse.EclipseClasspath;
import aQute.bnd.repository.maven.provider.NexusCommand;
import aQute.bnd.service.Actionable;
import aQute.bnd.service.RepositoryPlugin;
import aQute.bnd.service.action.Action;
import aQute.bnd.service.repository.InfoRepository;
import aQute.bnd.service.repository.SearchableRepository.ResourceDescriptor;
import aQute.bnd.version.Version;
import aQute.bnd.version.VersionRange;
import aQute.configurable.Config;
import aQute.lib.base64.Base64;
import aQute.lib.collections.ExtList;
import aQute.lib.collections.MultiMap;
import aQute.lib.collections.SortedList;
import aQute.lib.filter.Filter;
import aQute.lib.getopt.Arguments;
import aQute.lib.getopt.CommandLine;
import aQute.lib.getopt.Description;
import aQute.lib.getopt.Options;
import aQute.lib.hex.Hex;
import aQute.lib.io.IO;
import aQute.lib.justif.Justif;
import aQute.lib.settings.Settings;
import aQute.lib.strings.Strings;
import aQute.lib.tag.Tag;
import aQute.lib.utf8properties.UTF8Properties;
import aQute.libg.classdump.ClassDumper;
import aQute.libg.cryptography.MD5;
import aQute.libg.cryptography.SHA1;
import aQute.libg.forker.Forker;
import aQute.libg.generics.Create;
import aQute.libg.glob.Glob;
import aQute.libg.qtokens.QuotedTokenizer;
import aQute.libg.reporter.ReporterAdapter;
import aQute.libg.reporter.ReporterMessages;
import aQute.libg.sed.Sed;
import aQute.service.reporter.Reporter;
/**
* Utility to make bundles. @version $Revision: 1.14 $
*/
public class bnd extends Processor {
private final static Logger logger = LoggerFactory.getLogger(bnd.class);
static Pattern ASSIGNMENT = Pattern.compile( //
"([^=]+) (= ( ?: (\"|'|) (.+) \\3 )? ) ?", Pattern.COMMENTS);
Settings settings = new Settings();
final PrintStream err = System.err;
final public PrintStream out = System.out;
Justif justif = new Justif(80, 40, 42, 70);
BndMessages messages = ReporterMessages.base(this,
BndMessages.class);
private Workspace ws;
private char[] password;
private static final ThreadLocal noExit = new ThreadLocal() {
@Override
protected Boolean initialValue() {
return false;
};
};
private static final String DEFAULT_LOG_LEVEL_KEY = "org.slf4j.simpleLogger.defaultLogLevel";
static Pattern JARCOMMANDS = Pattern
.compile("(cv?0?(m|M)?f?)|(uv?0?M?f?)|(xv?f?)|(tv?f?)|(i)");
static Pattern COMMAND = Pattern.compile("\\w[\\w\\d]+");
static Pattern EMAIL_P = Pattern.compile(
"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?",
Pattern.CASE_INSENSITIVE);
@Description("OSGi Bundle Tool")
interface bndOptions extends Options {
@Description("Turns errors into warnings so command always succeeds")
boolean failok();
@Description("Report errors pedantically")
boolean pedantic();
@Description("Print out stack traces when there is an unexpected exception")
boolean exceptions();
@Description("Redirect output")
File output();
@Description("Use as base directory")
String base();
@Description("Trace progress")
boolean trace();
@Description("Error/Warning ignore patterns")
String[] ignore();
@Description("Provide a settings password")
char[] secret();
}
public bnd(Workspace ws) {
super(ws);
}
public bnd() {}
public static void main(String args[]) throws Exception {
Workspace.setDriver(Constants.BNDDRIVER_BND);
Workspace.addGestalt(Constants.GESTALT_SHELL, null);
Workspace.addGestalt(Constants.GESTALT_INTERACTIVE, null);
Workspace ws = Workspace.findWorkspace(IO.work);
try (bnd main = new bnd()) { // ws == null ? new bnd() : new bnd(ws);
main.start(args);
}
exitWithCode(0);
}
/**
* For testing
*/
static void mainNoExit(String args[]) throws Exception {
noExit.set(true);
main(args);
}
public void start(String args[]) throws Exception {
CommandLine cl = new CommandLine(this);
String help = cl.execute(this, "bnd", new ExtList<>(args));
check();
if (help != null)
err.println(help);
}
/**
* Rewrite the command line to mimic the jar command
*
* @param args
* @throws Exception
*/
private void rewrite(List args) throws Exception {
if (args.isEmpty())
return;
String arg = args.get(0);
if (arg.equals("maven")) {
// ensure that we do not much with options
// because the maven command does not like
// that
args.add(0, "maven");
return;
}
if (arg.equals("-version")) {
args.set(0, "version");
return;
}
Matcher m = JARCOMMANDS.matcher(arg);
if (m.matches()) {
rewriteJarCmd(args);
return;
}
// Project project = getProject();
// if (project != null) {
// Action a = project.getActions().get(arg);
// if (a != null) {
// args.add(0, "project");
// }
// }
m = COMMAND.matcher(args.get(0));
if (!m.matches()) {
args.add(0, "do");
}
}
private void rewriteJarCmd(List args) {
String jarcmd = args.remove(0);
char cmd = jarcmd.charAt(0);
switch (cmd) {
case 'c' :
args.add(0, "create");
break;
case 'u' :
args.add(0, "update");
break;
case 'x' :
args.add(0, "extract");
break;
case 't' :
args.add(0, "type");
break;
case 'i' :
args.add(0, "index");
break;
}
int start = 1;
for (int i = 1; i < jarcmd.length(); i++) {
switch (jarcmd.charAt(i)) {
case 'v' :
args.add(start++, "--verbose");
break;
case '0' :
args.add(start++, "--nocompression");
break;
case 'm' :
args.add(start++, "--manifest");
start++; // make the manifest file the parameter
break;
case 'M' :
args.add(start++, "--nomanifest");
break;
case 'f' :
args.add(start++, "--file");
break;
}
}
}
/**
* Main command. This has options the bnd base options and will then run
* another command.
*
* @param options
* @throws Exception
*/
@Description("The swiss army tool for OSGi")
public void _bnd(bndOptions options) throws Exception {
try {
set(FAIL_OK, options.failok() + "");
setExceptions(options.exceptions());
setTrace(options.trace());
if (options.trace()) {
System.setProperty(DEFAULT_LOG_LEVEL_KEY, "trace");
} else {
System.setProperty(DEFAULT_LOG_LEVEL_KEY, "warn");
}
setPedantic(options.pedantic());
if (options.base() != null)
setBase(getFile(getBase(), options.base()));
// And the properties
for (Entry entry : options._properties()
.entrySet()) {
setProperty(entry.getKey(), entry.getValue());
}
CommandLine handler = options._command();
List arguments = options._arguments();
// Rewrite command line to match jar commands and
// handle commands that provide file names
rewrite(arguments);
logger.debug("rewritten {}", arguments);
if (arguments.isEmpty()) {
Justif f = new Justif(80, 20, 22, 72);
handler.help(f.formatter(), this);
err.append(f.wrap());
} else {
String cmd = arguments.remove(0);
String help = handler.execute(this, cmd, arguments);
if (help != null) {
err.println(help);
}
}
if (options.secret() != null) {
password = options.secret();
settings.load(password);
}
} catch (Throwable t) {
while (t instanceof InvocationTargetException)
t = t.getCause();
exception(t, "%s", t);
}
out.flush();
err.flush();
if (ws != null)
getInfo(ws);
if (!check(options.ignore())) {
System.err.flush();
System.err.flush();
Thread.sleep(1000);
exitWithCode(getErrors().size());
}
}
/**
* Options for the jar create command.
*/
@Description("Equivalent jar command c[v0mf] command (supports the jar tool's syntax). Will wrap the bundle unless --wrapnot is specified")
interface createOptions extends Options {
@Description("Verbose (v option)")
boolean verbose();
@Description("No compression (0 option)")
boolean nocompression();
@Description("No manifest (M option)")
boolean Manifest();
@Description("Use manifest (m option)")
String manifest();
@Description("Jar file (f option)")
String file();
@Description("directory")
String cdir();
@Description("Wrap")
boolean wrap();
@Description("Properties for wrapping")
String properties();
@Description("Bundle Symbolic Name for wrap")
String bsn();
@Description("Bundle Version for wrap")
Version version();
@Description("Force write event if there are errors")
boolean force();
}
/**
* Create jar file
*
*
* jar c[v0M]f jarfile [-C dir] inputfiles [-Joption]
* jar c[v0]mf manifest jarfile [-C dir] inputfiles [-Joption] jar c[v0M]
* [-C dir] inputfiles [-Joption] jar c[v0]m manifest [-C dir] inputfiles
* [-Joption]
*
*
* @param options
* @throws Exception
*/
@Description("Create jar, used to support backward compatible java jar commands")
public void _create(createOptions options) throws Exception {
Jar jar = new Jar("dot");
File dir = getBase().getAbsoluteFile();
String sdir = options.cdir();
if (sdir != null)
dir = getFile(sdir);
if (options._arguments()
.isEmpty())
add(jar, dir, ".", options.verbose());
else
for (String f : options._arguments()) {
f = IO.normalizePath(f);
add(jar, dir, f, options.verbose());
}
String manifest = options.manifest();
if (manifest != null) {
if (options.verbose())
err.printf("Adding manifest from %s\n", manifest);
jar.setManifest(getFile(manifest));
}
if (options.Manifest()) {
jar.setManifest((Manifest) null);
} else {
if (options.wrap()) {
Analyzer w = new Analyzer(this);
addClose(w);
w.setBase(getBase());
w.use(this);
w.setDefaults(options.bsn(), options.version());
w.calcManifest();
getInfo(w);
w.setJar((Jar) null);
w.close();
}
}
if (options.nocompression())
jar.setCompression(Jar.Compression.STORE);
if (isOk()) {
String jarFile = options.file();
if (jarFile == null)
jar.write(System.out);
else
jar.write(jarFile);
}
jar.close();
}
/**
* Helper for the jar create function, adds files to the jar
*
* @param jar
* @param base
* @param path
* @param report
* @throws IOException
*/
private void add(Jar jar, File base, String path, boolean report) throws IOException {
if (path.endsWith("/"))
path = path.substring(0, path.length() - 1);
File f;
if (path.equals("."))
f = base;
else
f = getFile(base, path);
err.printf("Adding: %s\n", path);
if (f.isFile()) {
jar.putResource(path, new FileResource(f));
} else if (f.isDirectory()) {
if (path.equals("."))
path = "";
else
path += "/";
String[] subs = f.list();
for (String sub : subs) {
add(jar, base, path + sub, report);
}
}
}
/**
* Extract a file from the JAR
*/
@Description("Extract files from a JAR file, equivalent jar command x[vf] (syntax supported)")
interface extractOptions extends Options {
@Description("Verbose (v option)")
boolean verbose();
@Description("Jar file (f option)")
String file();
@Description("Directory where to store")
String cdir();
}
@Description("Extract files from a JAR file, equivalent jar command x[vf] (syntax supported)")
public void _extract(extractOptions opts) throws Exception {
Jar jar;
if (opts.file() != null) {
File f = getFile(opts.file());
if (!f.isFile()) {
messages.NoSuchFile_(f);
return;
}
jar = new Jar(f);
} else {
jar = new Jar("cin", System.in);
}
try {
Instructions instructions = new Instructions(opts._arguments());
Collection selected = instructions.select(jar.getResources()
.keySet(), true);
File store = getBase();
if (opts.cdir() != null)
store = getFile(opts.cdir());
IO.mkdirs(store);
Jar.Compression compression = jar.hasCompression();
for (String path : selected) {
if (opts.verbose())
System.err.printf("%8s: %s\n", compression.toString()
.toLowerCase(), path);
File f = getFile(store, path);
File pf = f.getParentFile();
IO.mkdirs(pf);
Resource r = jar.getResource(path);
IO.copy(r.openInputStream(), f);
}
} finally {
jar.close();
}
}
/**
* List the contents of the JAR
*/
@Description("List files int a JAR file, equivalent jar command t[vf] (syntax supported)")
interface typeOptions extends Options {
@Description("Verbose (v option)")
boolean verbose();
@Description("Jar file (f option)")
String file();
}
@Description("List files int a JAR file, equivalent jar command t[vf] (syntax supported)")
public void _type(typeOptions opts) throws Exception {
Jar jar;
if (opts.file() != null) {
File f = getFile(opts.file());
if (!f.isFile()) {
messages.NoSuchFile_(f);
return;
}
jar = new Jar(f);
} else {
jar = new Jar("cin", System.in);
}
try {
Instructions instructions = new Instructions(opts._arguments());
Collection selected = instructions.select(jar.getResources()
.keySet(), true);
for (String path : selected) {
if (opts.verbose()) {
Resource r = jar.getResource(path);
err.printf("%8s %-32s %s\n", r.size(), new Date(r.lastModified()), path);
} else
err.printf("%s\n", path);
}
} finally {
jar.close();
}
}
@Description("Execute a file based on its extension. Supported extensions are: bnd (build), bndrun (run), and jar (print)")
interface dooptions extends Options {
@Description("The output file")
String output();
@Description("Force even when there are errors")
boolean force();
}
/**
* The do command interprets files and does a default action for each file
*
* @throws Exception
*/
@Description("Execute a file based on its extension. Supported extensions are: bnd (build), bndrun (run), and jar (print)")
public void _do(dooptions options) throws Exception {
for (String path : options._arguments()) {
if (path.endsWith(Constants.DEFAULT_BND_EXTENSION)) {
build(options.output(), options.force(), path);
} else if (path.endsWith(Constants.DEFAULT_JAR_EXTENSION)
|| path.endsWith(Constants.DEFAULT_BAR_EXTENSION)) {
try (Jar jar = getJar(path)) {
doPrint(jar, MANIFEST, null);
}
} else if (path.endsWith(Constants.DEFAULT_BNDRUN_EXTENSION)) {
doRun(Arrays.asList(path), false, null);
} else
messages.UnrecognizedFileType_(path);
}
}
public void build(String dest, boolean force, String path) throws IOException, Exception {
try (Builder b = new Builder()) {
File f = getFile(path);
if (!f.isFile()) {
error("No such file %s", f);
return;
}
b.use(this);
b.setProperties(f);
List subs = b.getSubBuilders();
for (Builder bb : subs) {
logger.debug("building {}", bb.getPropertiesFile());
bb.build();
File out = bb.getOutputFile(dest);
getInfo(bb, bb.getBsn() + ": ");
if (isOk()) {
bb.save(out, force);
}
getInfo(bb, bb.getBsn() + ": "); // pickup any save errors
if (!isOk()) {
IO.delete(out);
}
}
}
}
/**
* Project command, executes actions.
*/
@Description("Execute a Project action, or if no parms given, show information about the project")
@Arguments(arg = {})
interface projectOptions extends Options {
@Description("Identify another project")
String project();
}
@Description("Execute a Project action, or if no parms given, show information about the project")
public void _project(projectOptions options) throws Exception {
Project project = getProject(options.project());
if (project == null) {
messages.NoProject();
return;
}
List l = new ArrayList<>(options._arguments());
if (l.isEmpty()) {
err.printf("Name %s\n", project.getName());
err.printf("Actions %s\n", project.getActions()
.keySet());
err.printf("Directory %s\n", project.getBase());
err.printf("Depends on %s\n", project.getDependson());
try (ProjectBuilder pb = project.getBuilder(null)) {
err.printf("Sub builders %s\n", pb.getSubBuilders());
}
return;
}
String cmd = null;
String arg = null;
if (!l.isEmpty())
cmd = l.remove(0);
if (!l.isEmpty())
arg = l.remove(0);
if (!l.isEmpty()) {
messages.MoreArgumentsThanNeeded_(options._arguments());
return;
}
if (cmd == null) {
messages.NoCommandForProject(project);
return;
}
Action a = project.getActions()
.get(cmd);
if (a != null) {
a.execute(project, arg);
getInfo(project);
return;
}
}
@Description("Bumps the version of a project. Will take the current version and then increment "
+ "with a major, minor, or micro increment. The default bump is minor.")
@Arguments(arg = "")
interface bumpoptions extends Options {
@Description("Path to another project than the current project")
String project();
}
/**
* Bump a version number
*
* @throws Exception
*/
@Description("Bumps the version of a project")
public void _bump(bumpoptions options) throws Exception {
Project project = getProject(options.project());
if (project == null) {
messages.NoProject();
return;
}
String mask = null;
if (!options._arguments()
.isEmpty()) {
mask = options._arguments()
.get(0);
if (mask.equalsIgnoreCase("major"))
mask = "+00";
else if (mask.equalsIgnoreCase("minor"))
mask = "=+0";
else if (mask.equalsIgnoreCase("micro"))
mask = "==+";
else if (!mask.matches("[+=0]{1,3}")) {
messages.InvalidBumpMask_(mask);
return;
}
}
if (mask == null)
project.bump();
else
project.bump(mask);
getInfo(project);
err.println(project.getProperty(BUNDLE_VERSION, "No version found"));
}
interface PerProject {
void doit(Project p) throws Exception;
}
public void perProject(projectOptions opts, PerProject run) throws Exception {
Collection list;
Project project = getProject(opts.project());
if (project == null) {
Workspace ws = Workspace.findWorkspace(getBase());
if (!ws.isValid()) {
messages.NoValidWorkspace(getBase());
}
list = ws.getAllProjects();
if (list.isEmpty()) {
out.println("No projects");
}
return;
} else {
list = Arrays.asList(project);
}
for (Project p : list) {
run.doit(p);
getInfo(p, p + ": ");
}
}
@Description("Build a project. This will create the jars defined in the bnd.bnd and sub-builders.")
@Arguments(arg = {})
interface buildoptions extends projectOptions {
@Description("Build for test")
boolean test();
@Description("Do full")
boolean full();
}
@Description("Build a project. This will create the jars defined in the bnd.bnd and sub-builders.")
public void _build(final buildoptions opts) throws Exception {
perProject(opts, new PerProject() {
@Override
public void doit(Project p) throws Exception {
p.build(opts.test());
}
});
}
@Arguments(arg = {})
interface CompileOptions extends projectOptions {
@Description("Compile for test")
boolean test();
}
@Description("Compile a project or the workspace")
public void _compile(final CompileOptions opts) throws Exception {
perProject(opts, new PerProject() {
@Override
public void doit(Project p) throws Exception {
p.compile(opts.test());
}
});
}
@Description("Test a project according to an OSGi test")
@Arguments(arg = {
"testclass[:method]..."
})
interface testOptions extends projectOptions {
@Description("Verify all the dependencies before launching (runpath, runbundles, testpath)")
boolean verify();
@Description("Launch the test even if this bundle does not contain " + Constants.TESTCASES)
boolean force();
@Description("Set the -testcontinuous flag")
boolean continuous();
@Description("Set the -runtrace flag")
boolean trace();
}
@Description("Test a project according to an OSGi test")
public void _test(final testOptions opts) throws Exception {
perProject(opts, new PerProject() {
@Override
public void doit(Project project) throws Exception {
List testNames = opts._arguments();
if (!testNames.isEmpty())
project.setProperty(TESTCASES, "");
if (project.is(NOJUNITOSGI) && !opts.force()) {
warning("%s is set to true on this bundle. Use -f/--force to try this test anyway", NOJUNITOSGI);
return;
}
if (project.getProperty(TESTCASES) == null)
if (opts.force())
project.setProperty(TESTCASES, "");
else {
warning(
"No %s set on this bundle. Use -f/--force to try this test anyway (this works if another bundle provides the testcases)",
TESTCASES);
return;
}
if (opts.continuous())
project.setProperty(TESTCONTINUOUS, "true");
if (opts.trace() || isTrace())
project.setProperty(RUNTRACE, "true");
project.test(testNames);
}
});
}
@Description("Test a project with plain JUnit")
public void _junit(testOptions opts) throws Exception {
perProject(opts, new PerProject() {
@Override
public void doit(Project p) throws Exception {
p.junit();
}
});
}
private boolean verifyDependencies(Project project, boolean implies, boolean test) throws Exception {
if (!implies) {
return true;
}
project.verifyDependencies(test);
getInfo(project);
if (isOk())
return true;
return false;
}
@Description("Run a project in the OSGi launcher. If not bndrun is specified, the current project is used for the run specification")
@Arguments(arg = "[bndrun]")
interface runOptions extends Options {
@Description("Path to another project than the current project. Only valid if no bndrun is specified")
String project();
@Description("Verify all the dependencies before launching (runpath, runbundles)")
boolean verify();
}
@Description("Run a project in the OSGi launcher")
public void _run(runOptions opts) throws Exception {
doRun(opts._arguments(), opts.verify(), opts.project());
}
private void doRun(List args, boolean verify, String project) throws Exception {
Project run = null;
if (args.isEmpty()) {
run = getProject(project);
if (run == null) {
messages.NoProject();
return;
}
} else {
File f = getFile(args.get(0));
File dir = f.getParentFile();
File wsdir = dir.getParentFile();
if (wsdir == null) {
// We are in the filesystem root?? Create a standalone run.
run = Run.createRun(null, f);
} else {
Workspace workspace = Workspace.getWorkspaceWithoutException(wsdir);
run = Run.createRun(workspace, f);
}
}
verifyDependencies(run, verify, false);
try {
run.run();
} catch (Exception e) {
messages.Failed__(e, "Running " + run);
}
getInfo(run);
getInfo(run.getWorkspace());
}
@Description("Clean a project")
interface cleanOptions extends Options {
@Description("Path to another project than the current project")
String project();
}
@Description("Clean a project")
public void _clean(cleanOptions opts) throws Exception {
Project project = getProject(opts.project());
if (project == null) {
messages.NoProject();
return;
}
project.clean();
getInfo(project);
}
@Description("Access the internal bnd database of keywords and options")
@Arguments(arg = {
"header|instruction", "..."
})
interface syntaxOptions extends Options {
@Description("The width of the printout")
int width();
}
@Description("Access the internal bnd database of keywords and options")
public void _syntax(syntaxOptions opts) throws Exception {
int w = opts.width() < 80 ? 120 : opts.width();
Justif justif = new Justif(w, opts.width(), 40, 42, w - 10);
List args = opts._arguments();
StringBuilder sb = new StringBuilder();
Formatter f = new Formatter(sb);
for (String s : args) {
f.format(" \n[%s]\n", s);
Syntax sx = Syntax.HELP.get(s);
if (s == null)
f.format("Unknown");
else {
print(f, sx, " ");
}
}
f.flush();
justif.wrap(sb);
err.println(sb);
}
private void print(Formatter f, Syntax sx, String indent) {
if (sx == null)
return;
f.format("%s%s\n\n", indent, sx.getLead());
if (sx.getValues() != null)
f.format("%sValues\t1:\t2%s\n", indent, sx.getValues());
if (sx.getPattern() != null)
f.format("%sPattern \t1:\t2%s\n", indent, sx.getPattern());
if (sx.getExample() != null)
f.format("%sExample \t1:\t2%s\n", indent, sx.getExample());
if (sx.getChildren() != null) {
for (Syntax child : sx.getChildren()) {
f.format("\n%s[%s]\t1:\t2", indent, child.getHeader());
print(f, child, indent + " ");
}
}
}
@Description("Package a bnd or bndrun file into a single jar that executes with java -jar <>.jar. The JAR contains all dependencies, including the framework and the launcher. "
+ "A profile can be specified which will be used to find properties. If a property is not found, a property with the name []NAME will be looked up. This allows "
+ "you to make different profiles for testing and runtime.")
@Arguments(arg = {
"", "[...]"
})
interface packageOptions extends Options {
@Description("Where to store the resulting file. Default the name of the bnd file with a .jar extension.")
String output();
@Description("Profile name. Default no profile")
String profile();
}
/**
* Package a bnd or bndrun file for packaging.
*
* @throws Exception
*/
@Description("Package a bnd or bndrun file into a single jar that executes with java -jar <>.jar")
public void _package(packageOptions opts) throws Exception {
List cmdline = opts._arguments();
File output = null;
if (opts.output() != null) {
output = getFile(opts.output());
} else
output = getBase();
if (opts._arguments()
.size() > 1) {
IO.mkdirs(output);
} else {
File pf = output.getParentFile();
IO.mkdirs(pf);
}
String profile = opts.profile() == null ? "exec" : opts.profile();
if (cmdline.isEmpty())
cmdline.add(Project.BNDFILE); // default project itself
for (String path : cmdline) {
Run run;
File file = getFile(path);
if (file.isDirectory())
file = new File(file, Project.BNDFILE);
if (!file.isFile()) {
messages.NoSuchFile_(file);
continue;
}
File dir = file.getParentFile();
File workspaceDir = dir.getParentFile();
if (workspaceDir == null) {
// We are in the filesystem root?? Create a standalone run.
run = Run.createRun(null, file);
} else {
Workspace ws = Workspace.getWorkspaceWithoutException(workspaceDir);
run = Run.createRun(ws, file);
}
// Tricky because we can be run inside the context of a
// project (in which case
// we need to inherit from the project or outside.
run.setProperty(PROFILE, profile);
run.use(this);
try {
Jar jar = run.pack(profile);
path = path.replaceAll(".bnd(run)?$", "") + ".jar";
File out = output;
if (output.isDirectory())
out = new File(output, path);
jar.write(out);
jar.close();
} catch (Exception e) {
messages.ForProject_File_FailedToCreateExecutableException_(run, path, e);
}
getInfo(run);
}
}
/**
* List all deliverables for this workspace.
*/
@Description("Show all deliverables from this workspace. with their current version and path.")
@Arguments(arg = {})
interface deliverableOptions extends Options {
@Description("Path to project, default current directory")
String project();
@Description("Only provide deliverables of this project")
boolean limit();
}
@Description("Show all deliverables from this workspace. with their current version and path.")
public void _deliverables(deliverableOptions options) throws Exception {
Project project = getProject(options.project());
if (project == null) {
messages.NoProject();
return;
}
Collection projects;
if (options.limit())
projects = Arrays.asList(project);
else
projects = project.getWorkspace()
.getAllProjects();
List containers = new ArrayList<>();
for (Project p : projects) {
containers.addAll(p.getDeliverables());
}
for (Container c : containers) {
Version v = new Version(c.getVersion());
err.printf("%-40s %8s %s\n", c.getBundleSymbolicName(), v.getWithoutQualifier(), c.getFile());
}
getInfo(project);
}
@Description("Show macro value. Macro can contain the ${ and } parentheses but it is also ok without. You can use the ':' instead of the ';' in a macro")
@Arguments(arg = {
"", "[...]"
})
interface macroOptions extends Options {
@Description("Path to project, default current directory")
String project();
}
/**
* Show the value of a macro
*
* @throws Exception
*/
@Description("Show macro value")
public void _macro(macroOptions options) throws Exception {
Project project = getProject(options.project());
if (project == null) {
messages.NoProject();
return;
}
StringBuilder sb = new StringBuilder();
Macro r = project.getReplacer();
getInfo(project);
String del = "";
for (String s : options._arguments()) {
if (!s.startsWith("${")) {
s = "${" + s;
}
if (!s.endsWith("}")) {
s += "}";
}
s = s.replace(':', ';');
String p = r.process(s);
sb.append(del);
sb.append(p);
del = " ";
}
getInfo(project);
err.println(sb);
}
@Description("Release this project")
interface releaseOptions extends Options {
@Description("Path to project, default is current project")
String project();
@Description("Release with test build")
boolean test();
@Description("Set the release repository")
String repo();
@Description("Release all bundles in in the workspace")
boolean workspace();
}
/**
* Release the project
*
* @throws Exception
*/
@Description("Release this project")
public void _release(releaseOptions options) throws Exception {
Set projects = new LinkedHashSet<>();
Workspace ws = Workspace.findWorkspace(getBase());
if (ws == null) {
error("Workspace option was specified but cannot find a workspace from %s", getBase());
return;
}
if (options.workspace()) {
projects.addAll(ws.getAllProjects());
}
Project project = getProject(options.project());
if (project != null) {
projects.add(project);
}
if (projects.isEmpty()) {
error("Cannot find any projects");
return;
}
String repo = options.repo();
if (repo != null) {
RepositoryPlugin repository = ws.getRepository(repo);
if (repository == null) {
error("No such release repo %s%nFound:%n%s", repository, Strings.join("\n", ws.getRepositories()));
}
}
for (Project p : projects) {
if (repo != null) {
p.setProperty(Constants.RELEASEREPO, repo);
}
p.release(options.test());
}
getInfo(project);
}
@Description("Show a cross references for all classes in a set of jars.")
@Arguments(arg = {
"", "[...]"
})
interface xrefOptions extends Options {
@Description("Show classes instead of packages")
boolean classes();
@Description("Show references to other classes/packages (>)")
boolean to();
@Description("Show references from other classes/packages (<)")
boolean from();
@Description("Filter for class names, a globbing expression")
List match();
}
static public class All {
public Map> classes = new HashMap<>();
public Map> packages = new HashMap<>();
}
/**
* Cross reference every class in the jar file to the files it references
*/
@Description("Show a cross references for all classes in a set of jars.")
public void _xref(xrefOptions options) throws IOException, Exception {
Analyzer analyzer = new Analyzer();
final MultiMap table = new MultiMap<>();
final MultiMap packages = new MultiMap<>();
Set set = Create.set();
Instructions filter = new Instructions(options.match());
for (String arg : options._arguments()) {
try {
File file = new File(arg);
try (Jar jar = new Jar(file.getName(), file)) {
for (Map.Entry entry : jar.getResources()
.entrySet()) {
String key = entry.getKey();
Resource r = entry.getValue();
if (key.endsWith(".class")) {
TypeRef ref = analyzer.getTypeRefFromPath(key);
if (filter.matches(ref.toString())) {
set.add(ref);
try (InputStream in = r.openInputStream()) {
Clazz clazz = new Clazz(analyzer, key, r);
// TODO use the proper bcp instead
// of using the default layout
Set s = clazz.parseClassFile();
for (Iterator t = s.iterator(); t.hasNext();) {
TypeRef tr = t.next();
if (tr.isJava() || tr.isPrimitive())
t.remove();
else
packages.add(ref.getPackageRef(), tr.getPackageRef());
}
table.addAll(ref, s);
set.addAll(s);
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
boolean to = options.to();
boolean from = options.from();
if (to == false && from == false)
to = from = true;
if (options.classes()) {
if (to)
printxref(table, ">");
if (from)
printxref(table.transpose(), "<");
} else {
if (to)
printxref(packages, ">");
if (from)
printxref(packages.transpose(), "<");
}
}
private void printxref(MultiMap map, String direction) {
SortedList labels = new SortedList