Search in sources :

Example 21 with Instructions

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);
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Parameters(aQute.bnd.header.Parameters) Attrs(aQute.bnd.header.Attrs) Instructions(aQute.bnd.osgi.Instructions) Instruction(aQute.bnd.osgi.Instruction) DependencyContributor(aQute.bnd.service.DependencyContributor) File(java.io.File) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 22 with Instructions

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);
                }
            }
        }
    }
}
Also used : Parameters(aQute.bnd.header.Parameters) Diff(aQute.bnd.service.diff.Diff) Formatter(java.util.Formatter) RepositoryPlugin(aQute.bnd.service.RepositoryPlugin) Instructions(aQute.bnd.osgi.Instructions) Baseline(aQute.bnd.differ.Baseline) BundleInfo(aQute.bnd.differ.Baseline.BundleInfo) Info(aQute.bnd.differ.Baseline.Info) InfoRepository(aQute.bnd.service.repository.InfoRepository) BundleInfo(aQute.bnd.differ.Baseline.BundleInfo) Version(aQute.bnd.version.Version) Jar(aQute.bnd.osgi.Jar) ResourceDescriptor(aQute.bnd.service.repository.SearchableRepository.ResourceDescriptor)

Example 23 with Instructions

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);
}
Also used : Parameters(aQute.bnd.header.Parameters) Tree(aQute.bnd.service.diff.Tree) Instructions(aQute.bnd.osgi.Instructions)

Example 24 with Instructions

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);
}
Also used : Instructions(aQute.bnd.osgi.Instructions)

Example 25 with Instructions

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;
}
Also used : Attrs(aQute.bnd.header.Attrs) ArrayList(java.util.ArrayList) Instruction(aQute.bnd.osgi.Instruction) XMLAttributeFinder(aQute.bnd.xmlattribute.XMLAttributeFinder) Version(aQute.bnd.version.Version) TreeSet(java.util.TreeSet) Clazz(aQute.bnd.osgi.Clazz) Descriptors(aQute.bnd.osgi.Descriptors) Parameters(aQute.bnd.header.Parameters) Instructions(aQute.bnd.osgi.Instructions) Map(java.util.Map)

Aggregations

Instructions (aQute.bnd.osgi.Instructions)27 File (java.io.File)15 Jar (aQute.bnd.osgi.Jar)11 Description (aQute.lib.getopt.Description)10 Parameters (aQute.bnd.header.Parameters)9 Attrs (aQute.bnd.header.Attrs)6 Instruction (aQute.bnd.osgi.Instruction)6 FileResource (aQute.bnd.osgi.FileResource)5 ArrayList (java.util.ArrayList)5 Clazz (aQute.bnd.osgi.Clazz)4 Resource (aQute.bnd.osgi.Resource)4 Tree (aQute.bnd.service.diff.Tree)4 HashSet (java.util.HashSet)4 TypeRef (aQute.bnd.osgi.Descriptors.TypeRef)3 Version (aQute.bnd.version.Version)3 MultiMap (aQute.lib.collections.MultiMap)3 IOException (java.io.IOException)3 PrintWriter (java.io.PrintWriter)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)3 Date (java.util.Date)3