Package biz.aQute.resolve.internal

Source Code of biz.aQute.resolve.internal.BndrunResolveContext

package biz.aQute.resolve.internal;

import java.io.*;
import java.util.*;
import java.util.Map.Entry;

import org.osgi.framework.*;
import org.osgi.framework.namespace.*;
import org.osgi.resource.*;
import org.osgi.resource.Resource;
import org.osgi.service.log.*;
import org.osgi.service.repository.*;

import aQute.bnd.build.*;
import aQute.bnd.build.model.*;
import aQute.bnd.build.model.clauses.*;
import aQute.bnd.header.*;
import aQute.bnd.osgi.*;
import aQute.bnd.osgi.Constants;
import aQute.bnd.osgi.resource.*;
import aQute.bnd.service.*;
import aQute.bnd.service.resolve.hook.*;
import aQute.libg.filters.*;
import aQute.libg.filters.Filter;
import biz.aQute.resolve.*;

public class BndrunResolveContext extends GenericResolveContext {

  public static final String      RUN_EFFECTIVE_INSTRUCTION  = "-resolve.effective";
  public static final String      PROP_RESOLVE_PREFERENCES  = "-resolve.preferences";

  private Registry          registry;

  private EE              ee;

  private List<ExportedPackage>    sysPkgsExtra = new ArrayList<ExportedPackage>();
  private Parameters          sysCapsExtraParams = new Parameters();
  private Parameters          resolvePrefs;

  private Version            frameworkResourceVersion  = null;
  private FrameworkResourceRepository  frameworkResourceRepo;
  private final Processor        properties;

  public BndrunResolveContext(BndEditModel runModel, Registry registry, LogService log) {
    super(log);
    try {
      this.registry = registry;
      this.properties = runModel.getProperties();
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  protected synchronized void init() {
    if (initialised)
      return;

    try {
      loadEE();
      loadSystemPackagesExtra();
      loadSystemCapabilitiesExtra();
      loadpaths();
      loadRepositories();
      constructBlacklist();
      loadEffectiveSet();
      findFramework();
      constructInputRequirements();
      loadPreferences();
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
    super.init();
  }

  /**
   * Load the capabilities and packages from the -testpath and -runpath since
   * we make those available. Testpath is only added whent he Test-Cases header
   * is set in the lowest properties file.
   */
  private void loadpaths() throws Exception {
    loadpath(Constants.RUNPATH, "-runpath");
    if ( properties.get(Constants.TESTCASES) != null && !properties.is(Constants.NOJUNITOSGI))
      loadpath(Constants.TESTPATH, "-testpath");
  }

  /**
   * Read the bundles from a path (test/run) and copy their exported packages to the
   * packages extra list and their capabilities to the capabilities extra list just
   * like the launcher does. This only works when we have access to a project
   * or bndrun file parented by a project.
   */
  private void loadpath(String path, String source ) throws Exception {
    Processor parent = properties.getParent();
    if ( parent == null || ! (parent instanceof Project))
      return;

    //
    // Get the full contents of the path
    //
   
    Project p = (Project) parent;
    String header = properties.mergeProperties(path);
   
    //
    // Now, from this path, get the bundles
    //
   
    List<Container> bundles = p.getBundles(Strategy.HIGHEST, header, source);
    for ( Container c : bundles ) {
     
      if ( c.getAttributes() != null && Processor.isTrue(c.getAttributes().get("-skip:")))
          continue;
     
      //
      // If the container is ok, we add the exported packages and the capabilities
      // to the frameworks' extra packages/caps.
      //
     
      if ( c.getError() == null) {
        Domain domain = Domain.domain(c.getManifest());
        this.sysCapsExtraParams.putAll(domain.getProvideCapability());
        this.sysPkgsExtra.addAll( toExportedPackages( domain.getExportPackage()));
      } else
        p.warning("The %s contains an error %s for bundle %s", source, c.getError(), c.getBundleSymbolicName());
    }
  }

  private void loadEE() {
    EE tmp = EE.parse(properties.getProperty(Constants.RUNEE));
    ee = (tmp != null) ? tmp : EE.JavaSE_1_6;
  }

  private void loadEffectiveSet() {
    String effective = properties.getProperty(RUN_EFFECTIVE_INSTRUCTION);
    if (effective == null)
      effectiveSet = null;
    else {
      effectiveSet = new HashMap<String, Set<String>>();
      for (Entry<String,Attrs> entry : new Parameters(effective).entrySet()) {
        String skip = entry.getValue().get("skip:");
        Set<String> toSkip = skip == null ? new HashSet<String>() :
          new HashSet<String>(Arrays.asList(skip.split(",")));
        effectiveSet.put(entry.getKey(), toSkip);
      }
    }
  }

  private void loadSystemPackagesExtra() {
    Parameters p = new Parameters( properties.mergeProperties(Constants.RUNSYSTEMPACKAGES));

    sysPkgsExtra = toExportedPackages(p); // runModel.getSystemPackages();
  }

  private List<ExportedPackage> toExportedPackages(Parameters p) {
    List<ExportedPackage> list = new ArrayList<ExportedPackage>();
    for ( Entry<String,Attrs> e : p.entrySet()) {
      list.add( new ExportedPackage(Processor.removeDuplicateMarker(e.getKey()), e.getValue()));
    }

    return list;
  }

  private void loadSystemCapabilitiesExtra() {
    String header = properties.mergeProperties(Constants.RUNSYSTEMCAPABILITIES);
    sysCapsExtraParams.putAll( new Parameters(header));
  }

  private void loadRepositories() throws IOException {
    // Get all of the repositories from the plugin registry
    List<Repository> allRepos = registry.getPlugins(Repository.class);

    // Workspace ws = registry.getPlugin(Workspace.class);
    // if (ws != null) {
    // for (InfoRepository ir : registry.getPlugins(InfoRepository.class)) {
    // allRepos.add(new InfoRepositoryWrapper(ir, ws.getCache("ir-" +
    // ir.getName())));
    // }
    // }


    // Reorder/filter if specified by the run model

    String rn = properties.mergeProperties(Constants.RUNREPOS);
    if (rn == null) {
      // No filter, use all
      for (Repository repo : allRepos) {
        super.addRepository(repo);
      }
    } else {
      Parameters repoNames = new Parameters(rn);

      // Map the repository names...
      Map<String,Repository> repoNameMap = new HashMap<String,Repository>(allRepos.size());
      for (Repository repo : allRepos)
        repoNameMap.put(repo.toString(), repo);

      // Create the result list
      for (String repoName : repoNames.keySet()) {
        Repository repo = repoNameMap.get(repoName);
        if (repo != null)
          super.addRepository(repo);
      }
    }
  }

  private void findFramework() {
    Requirement frameworkReq = getFrameworkRequirement();
    if (frameworkReq == null)
      return;

    // Iterate over repos looking for matches
    for (Repository repo : repositories) {
      Map<Requirement,Collection<Capability>> providers = findProviders(repo, frameworkReq);
      Collection<Capability> frameworkCaps = providers.get(frameworkReq);
      if (frameworkCaps != null) {
        for (Capability frameworkCap : frameworkCaps) {
          if (findFrameworkContractCapability(frameworkCap.getResource()) != null) {
            Version foundVersion = toVersion(frameworkCap.getAttributes().get(
                IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE));
            if (foundVersion != null) {
              if (frameworkResourceVersion == null
                  || (foundVersion.compareTo(frameworkResourceVersion) > 0)) {
                systemResource = frameworkCap.getResource();
                frameworkResourceVersion = foundVersion;
                frameworkResourceRepo = new FrameworkResourceRepository(systemResource, ee,
                    sysPkgsExtra, sysCapsExtraParams);
                systemCapabilityIndex = frameworkResourceRepo.getCapabilityIndex();
              }
            }
          }
        }
      }
    }
  }

  private Requirement getFrameworkRequirement() {
    String header = properties.getProperty(Constants.RUNFW);
    if (header == null)
      return null;

    // Get the identity and version of the requested JAR
    Parameters params = new Parameters(header);
    if (params.size() > 1)
      throw new IllegalArgumentException("Cannot specify more than one OSGi Framework.");
    Entry<String,Attrs> entry = params.entrySet().iterator().next();
    String identity = entry.getKey();

    String versionStr = entry.getValue().getVersion();

    // Construct a filter & requirement to find matches
    Filter filter = new SimpleFilter(IdentityNamespace.IDENTITY_NAMESPACE, identity);
    if (versionStr != null)
      filter = new AndFilter().addChild(filter).addChild(new LiteralFilter(Filters.fromVersionRange(versionStr)));
    Requirement frameworkReq = new CapReqBuilder(IdentityNamespace.IDENTITY_NAMESPACE).addDirective(
        Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter.toString()).buildSyntheticRequirement();
    return frameworkReq;
  }

  @Override
  public Resource getInputResource() {
    if (inputResource != null) {
      return inputResource;
    }
    constructInputRequirements();
    return inputResource;
  }

  @Override
  public Resource getSystemResource() {
    if (systemResource != null) {
      return systemResource;
    }
    findFramework();
    return systemResource;
  }

  @Override
  public boolean isSystemResource(Resource resource) {
    Resource systemResource = getSystemResource();
    return resource == systemResource;
  }

  private void constructInputRequirements() {
    Parameters inputRequirements = new Parameters(properties.mergeProperties(Constants.RUNREQUIRES));
    if (inputRequirements == null || inputRequirements.isEmpty()) {
      inputResource = null;
    } else {
      List<Requirement> requires = CapReqBuilder.getRequirementsFrom(inputRequirements);

      ResourceBuilder resBuilder = new ResourceBuilder();
      CapReqBuilder identity = new CapReqBuilder(IdentityNamespace.IDENTITY_NAMESPACE).addAttribute(
          IdentityNamespace.IDENTITY_NAMESPACE, IDENTITY_INITIAL_RESOURCE);
      resBuilder.addCapability(identity);

      for (Requirement req : requires) {
        resBuilder.addRequirement(req);
      }

      inputResource = resBuilder.build();
    }
  }

  private void constructBlacklist() {
    Parameters blacklist = new Parameters(properties.mergeProperties(Constants.RUNBLACKLIST));
    if (blacklist != null && !blacklist.isEmpty()) {
      List<Requirement> reject = CapReqBuilder.getRequirementsFrom(blacklist);
      setBlackList(reject);
    }
  }


  private void loadPreferences() {
    resolvePrefs = new Parameters(properties.getProperty(PROP_RESOLVE_PREFERENCES));
  }

  protected void postProcessProviders(Requirement requirement, Set<Capability> wired, List<Capability> candidates) {
    if (candidates.size() == 0)
      return;

    // Call resolver hooks
    for (ResolverHook resolverHook : registry.getPlugins(ResolverHook.class)) {
      resolverHook.filterMatches(requirement, candidates);
    }

    // Process the resolve preferences
    boolean prefsUsed = false;
    if (resolvePrefs != null && !resolvePrefs.isEmpty()) {
      List<Capability> insertions = new LinkedList<Capability>();
      for (Iterator<Capability> iterator = candidates.iterator(); iterator.hasNext();) {
        Capability cap = iterator.next();
        if (resolvePrefs.containsKey(getResourceIdentity(cap.getResource()))) {
          iterator.remove();
          insertions.add(cap);
        }
      }

      if (!insertions.isEmpty()) {
        candidates.addAll(0, insertions);
        prefsUsed = true;
      }
    }

    // If preferences were applied, then don't need to call the callbacks
    if (!prefsUsed) {
      for (ResolutionCallback callback : callbacks) {
        callback.processCandidates(requirement, wired, candidates);
      }
    }
  }
}
TOP

Related Classes of biz.aQute.resolve.internal.BndrunResolveContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.