use of aQute.bnd.osgi.Instructions in project bnd by bndtools.
the class Project method prepare.
/**
* Set up all the paths
*/
public void prepare() throws Exception {
if (!isValid()) {
warning("Invalid project attempts to prepare: %s", this);
return;
}
synchronized (preparedPaths) {
if (preparedPaths.get()) {
return;
}
if (!workspace.trail.add(this)) {
throw new CircularDependencyException(workspace.trail.toString() + "," + this);
}
try {
String prefix = getBase().getAbsolutePath();
dependson.clear();
buildpath.clear();
sourcepath.clear();
allsourcepath.clear();
bootclasspath.clear();
// JIT
testpath.clear();
runpath.clear();
runbundles.clear();
runfw.clear();
// We use a builder to construct all the properties for
// use.
setProperty("basedir", getBase().getAbsolutePath());
// Otherwise, we just do the build properties.
if (!getPropertiesFile().isFile() && new File(getBase(), ".classpath").isFile()) {
// Get our Eclipse info, we might depend on other
// projects
// though ideally this should become empty and void
doEclipseClasspath();
}
// Calculate our source directories
Parameters srces = new Parameters(mergeProperties(Constants.DEFAULT_PROP_SRC_DIR), this);
if (srces.isEmpty())
srces.add(Constants.DEFAULT_PROP_SRC_DIR, new Attrs());
for (Entry<String, Attrs> e : srces.entrySet()) {
File dir = getFile(removeDuplicateMarker(e.getKey()));
if (!dir.getAbsolutePath().startsWith(prefix)) {
error("The source directory lies outside the project %s directory: %s", this, dir).header(Constants.DEFAULT_PROP_SRC_DIR).context(e.getKey());
continue;
}
if (!dir.isDirectory()) {
IO.mkdirs(dir);
}
if (dir.isDirectory()) {
sourcepath.put(dir, new Attrs(e.getValue()));
allsourcepath.add(dir);
} else
error("the src path (src property) contains an entry that is not a directory %s", dir).header(Constants.DEFAULT_PROP_SRC_DIR).context(e.getKey());
}
// Set default bin directory
output = getSrcOutput().getAbsoluteFile();
if (!output.exists()) {
IO.mkdirs(output);
getWorkspace().changedFile(output);
}
if (!output.isDirectory()) {
msgs.NoOutputDirectory_(output);
}
// Where we store all our generated stuff.
target = getTarget0();
// Where the launched OSGi framework stores stuff
String runStorageStr = getProperty(Constants.RUNSTORAGE);
runstorage = runStorageStr != null ? getFile(runStorageStr) : null;
// We might have some other projects we want build
// before we do anything, but these projects are not in
// our path. The -dependson allows you to build them before.
// The values are possibly negated globbing patterns.
// dependencies.add( getWorkspace().getProject("cnf"));
Set<String> requiredProjectNames = new LinkedHashSet<String>(getMergedParameters(Constants.DEPENDSON).keySet());
// Allow DependencyConstributors to modify requiredProjectNames
List<DependencyContributor> dcs = getPlugins(DependencyContributor.class);
for (DependencyContributor dc : dcs) dc.addDependencies(this, requiredProjectNames);
Instructions is = new Instructions(requiredProjectNames);
Set<Instruction> unused = new HashSet<Instruction>();
Collection<Project> projects = getWorkspace().getAllProjects();
Collection<Project> dependencies = is.select(projects, unused, false);
for (Instruction u : unused) msgs.MissingDependson_(u.getInput());
// We have two paths that consists of repo files, projects,
// or some other stuff. The doPath routine adds them to the
// path and extracts the projects so we can build them
// before.
doPath(buildpath, dependencies, parseBuildpath(), bootclasspath, false, BUILDPATH);
doPath(testpath, dependencies, parseTestpath(), bootclasspath, false, TESTPATH);
if (!delayRunDependencies) {
doPath(runfw, dependencies, parseRunFw(), null, false, RUNFW);
doPath(runpath, dependencies, parseRunpath(), null, false, RUNPATH);
doPath(runbundles, dependencies, parseRunbundles(), null, true, RUNBUNDLES);
}
// We now know all dependent projects. But we also depend
// on whatever those projects depend on. This creates an
// ordered list without any duplicates. This of course assumes
// that there is no circularity. However, this is checked
// by the inPrepare flag, will throw an exception if we
// are circular.
Set<Project> done = new HashSet<Project>();
done.add(this);
for (Project project : dependencies) project.traverse(dependson, done);
for (Project project : dependson) {
allsourcepath.addAll(project.getSourcePath());
}
// [cs] Testing this commented out. If bad issues, never
// setting this to true means that
// TONS of extra preparing is done over and over again on
// the same projects.
// if (isOk())
preparedPaths.set(true);
} finally {
workspace.trail.remove(this);
}
}
}
use of aQute.bnd.osgi.Instructions in project bnd by bndtools.
the class ProjectBuilder method doBaseline.
/**
* Compare this builder's JAR with a baseline
*
* @throws Exception
*/
@Override
public void doBaseline(Jar dot) throws Exception {
String diffignore = project.getProperty(Constants.DIFFIGNORE);
logger.debug("ignore headers & paths {}", diffignore);
differ.setIgnore(diffignore);
Instructions diffpackages = new Instructions(new Parameters(project.getProperty(Constants.DIFFPACKAGES), this));
logger.debug("diffpackages {}", diffpackages);
try (Jar fromRepo = getBaselineJar()) {
if (fromRepo == null) {
logger.debug("No baseline jar {}", getProperty(Constants.BASELINE));
return;
}
Version newer = new Version(getVersion());
Version older = new Version(fromRepo.getVersion());
if (!getBsn().equals(fromRepo.getBsn())) {
error("The symbolic name of this project (%s) is not the same as the baseline: %s", getBsn(), fromRepo.getBsn());
return;
}
if (newer.getWithoutQualifier().equals(older.getWithoutQualifier())) {
RepositoryPlugin rr = getBaselineRepo();
if (rr instanceof InfoRepository) {
ResourceDescriptor descriptor = ((InfoRepository) rr).getDescriptor(getBsn(), older);
if (descriptor != null && descriptor.phase != Phase.STAGING) {
error("Baselining %s against same version %s but the repository says the older repository version is not the required %s but is instead %s", getBsn(), getVersion(), Phase.STAGING, descriptor.phase);
return;
}
}
}
logger.debug("baseline {}-{} against: {}", getBsn(), getVersion(), fromRepo.getName());
Baseline baseliner = new Baseline(this, differ);
Set<Info> infos = baseliner.baseline(dot, fromRepo, diffpackages);
if (infos.isEmpty())
logger.debug("no deltas");
StringBuffer sb = new StringBuffer();
try (Formatter f = new Formatter(sb, Locale.US)) {
for (Info info : infos) {
if (!info.mismatch) {
continue;
}
sb.setLength(0);
Diff packageDiff = info.packageDiff;
f.format("Baseline mismatch for package %s, %s change. Current is %s, repo is %s, suggest %s or %s%n%#S", packageDiff.getName(), packageDiff.getDelta(), info.newerVersion, ((info.olderVersion != null) && info.olderVersion.equals(Version.LOWEST)) ? '-' : info.olderVersion, ((info.suggestedVersion != null) && info.suggestedVersion.compareTo(info.newerVersion) <= 0) ? "ok" : info.suggestedVersion, (info.suggestedIfProviders == null) ? "-" : info.suggestedIfProviders, packageDiff);
SetLocation l = error("%s", f.toString());
l.header(Constants.BASELINE);
fillInLocationForPackageInfo(l.location(), packageDiff.getName());
if (getPropertiesFile() != null)
l.file(getPropertiesFile().getAbsolutePath());
l.details(info);
}
BundleInfo binfo = baseliner.getBundleInfo();
if (binfo.mismatch) {
sb.setLength(0);
f.format("The bundle version (%s/%s) is too low, must be at least %s%n%#S", binfo.olderVersion, binfo.newerVersion, binfo.suggestedVersion, baseliner.getDiff());
SetLocation error = error("%s", f.toString());
error.context("Baselining");
error.header(Constants.BUNDLE_VERSION);
error.details(binfo);
FileLine fl = getHeader(Pattern.compile("^" + Constants.BUNDLE_VERSION, Pattern.MULTILINE));
if (fl != null) {
error.file(fl.file.getAbsolutePath());
error.line(fl.line);
error.length(fl.length);
}
}
}
}
}
use of aQute.bnd.osgi.Instructions in project bnd by bndtools.
the class Baseline method baseline.
/**
* This method compares a jar to a baseline jar and returns version
* suggestions if the baseline does not agree with the newer jar. The
* returned set contains all the exported packages.
*
* @param newer
* @param older
* @return null if ok, otherwise a set of suggested versions for all
* packages (also the ones that were ok).
* @throws Exception
*/
public Set<Info> baseline(Jar newer, Jar older, Instructions packageFilters) throws Exception {
Tree n = differ.tree(newer);
Parameters nExports = getExports(newer);
Tree o = differ.tree(older);
Parameters oExports = getExports(older);
if (packageFilters == null)
packageFilters = new Instructions();
return baseline(n, nExports, o, oExports, packageFilters);
}
use of aQute.bnd.osgi.Instructions in project bnd by bndtools.
the class SubsystemExporter method headers.
private void headers(final Project project, Attributes application) {
for (String key : project.getPropertyKeys(true)) {
if (!Verifier.HEADER_PATTERN.matcher(key).matches())
continue;
if (application.getValue(key) != null)
continue;
String value = project.getProperty(key);
if (value == null)
continue;
value = value.trim();
if (value.isEmpty() || Constants.EMPTY_HEADER.equals(value))
continue;
char c = value.charAt(0);
if (Character.isUpperCase(c))
application.putValue(key, value);
}
Instructions instructions = new Instructions(project.mergeProperties(REMOVEHEADERS));
Collection<Object> result = instructions.select(application.keySet(), false);
application.keySet().removeAll(result);
}
use of aQute.bnd.osgi.Instructions in project bnd by bndtools.
the class DSAnnotations method analyzeJar.
public boolean analyzeJar(Analyzer analyzer) throws Exception {
Parameters header = OSGiHeader.parseHeader(analyzer.getProperty(Constants.DSANNOTATIONS, "*"));
if (header.size() == 0)
return false;
minVersion = AnnotationReader.V1_3;
Parameters optionsHeader = OSGiHeader.parseHeader(analyzer.mergeProperties(Constants.DSANNOTATIONS_OPTIONS));
EnumSet<Options> options = EnumSet.noneOf(Options.class);
for (Map.Entry<String, Attrs> entry : optionsHeader.entrySet()) {
try {
Options.parseOption(entry, options, this);
} catch (IllegalArgumentException e) {
analyzer.error("Unrecognized %s value %s with attributes %s, expected values are %s", Constants.DSANNOTATIONS_OPTIONS, entry.getKey(), entry.getValue(), EnumSet.allOf(Options.class));
}
}
// obsolete but backwards compatible, use the options instead
if (Processor.isTrue(analyzer.getProperty("-dsannotations-inherit")))
options.add(Options.inherit);
if (Processor.isTrue(analyzer.getProperty("-ds-felix-extensions")))
options.add(Options.felixExtensions);
Instructions instructions = new Instructions(header);
Collection<Clazz> list = analyzer.getClassspace().values();
String sc = analyzer.getProperty(Constants.SERVICE_COMPONENT);
List<String> names = new ArrayList<String>();
if (sc != null && sc.trim().length() > 0)
names.add(sc);
TreeSet<String> provides = new TreeSet<String>();
TreeSet<String> requires = new TreeSet<String>();
Version maxVersion = AnnotationReader.V1_0;
XMLAttributeFinder finder = new XMLAttributeFinder(analyzer);
boolean componentProcessed = false;
for (Clazz c : list) {
for (Instruction instruction : instructions.keySet()) {
if (instruction.matches(c.getFQN())) {
if (instruction.isNegated())
break;
ComponentDef definition = AnnotationReader.getDefinition(c, analyzer, options, finder, minVersion);
if (definition != null) {
componentProcessed = true;
definition.sortReferences();
definition.prepare(analyzer);
String name = "OSGI-INF/" + analyzer.validResourcePath(definition.name, "Invalid component name") + ".xml";
names.add(name);
analyzer.getJar().putResource(name, new TagResource(definition.getTag()));
if (definition.service != null && !options.contains(Options.nocapabilities)) {
String[] objectClass = new String[definition.service.length];
for (int i = 0; i < definition.service.length; i++) {
Descriptors.TypeRef tr = definition.service[i];
objectClass[i] = tr.getFQN();
}
Arrays.sort(objectClass);
addServiceCapability(objectClass, provides);
}
if (!options.contains(Options.norequirements)) {
MergedRequirement serviceReqMerge = new MergedRequirement("osgi.service");
for (ReferenceDef ref : definition.references.values()) {
addServiceRequirement(ref, serviceReqMerge);
}
requires.addAll(serviceReqMerge.toStringList());
}
maxVersion = ComponentDef.max(maxVersion, definition.version);
}
}
}
}
if (componentProcessed && (options.contains(Options.extender) || (maxVersion.compareTo(AnnotationReader.V1_3) >= 0))) {
maxVersion = ComponentDef.max(maxVersion, AnnotationReader.V1_3);
addExtenderRequirement(requires, maxVersion);
}
sc = Processor.append(names.toArray(new String[0]));
analyzer.setProperty(Constants.SERVICE_COMPONENT, sc);
updateHeader(analyzer, Constants.REQUIRE_CAPABILITY, requires);
updateHeader(analyzer, Constants.PROVIDE_CAPABILITY, provides);
return false;
}
Aggregations