Package aQute.bnd.deployer.repository.wrapper

Source Code of aQute.bnd.deployer.repository.wrapper.InfoRepositoryWrapper

package aQute.bnd.deployer.repository.wrapper;

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

import org.osgi.framework.*;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
import org.osgi.resource.Resource;
import org.osgi.service.indexer.ResourceIndexer.IndexResult;
import org.osgi.service.indexer.impl.*;
import org.osgi.service.repository.*;

import aQute.bnd.build.*;
import aQute.bnd.osgi.resource.*;
import aQute.bnd.service.repository.*;
import aQute.bnd.service.repository.SearchableRepository.ResourceDescriptor;
import aQute.bnd.version.Version;
import aQute.lib.collections.*;
import aQute.lib.filter.Filter;
import aQute.lib.hex.*;
import aQute.lib.persistentmap.*;

public class InfoRepositoryWrapper implements Repository {
  final RepoIndex                repoIndexer;
  final PersistentMap<PersistentResource>    persistent;
  final Collection< ? extends InfoRepository>  repos;              ;
  long                    lastTime  = 0;
  private Properties              augments  = new Properties();

  // private boolean inited;

  public InfoRepositoryWrapper(File dir, Collection< ? extends InfoRepository> repos) throws Exception {
    this.repoIndexer = new RepoIndex();
   
    KnownBundleAnalyzer knownBundleAnalyzer = new KnownBundleAnalyzer();
    this.augments = new Properties();
    knownBundleAnalyzer.setKnownBundlesExtra(this.augments);
   
    this.repoIndexer.addAnalyzer(knownBundleAnalyzer, FrameworkUtil.createFilter("(name=*)"));
    this.repos = repos;
    this.persistent = new PersistentMap<PersistentResource>(dir, PersistentResource.class);
  }

  boolean init() {
    try {
      if (System.currentTimeMillis() < lastTime + 10000)
        return true;
    }
    finally {
      lastTime = System.currentTimeMillis();
    }

    Set<String> errors = new LinkedHashSet<String>();

    try {
      //
      // Get the current repo contents
      //

      Set<String> toBeDeleted = new HashSet<String>(persistent.keySet());
      Map<String,DownloadBlocker> blockers = new HashMap<String,DownloadBlocker>();

      for (InfoRepository repo : repos) {
        Map<String,ResourceDescriptor> map = collectKeys(repo);

        for (final Map.Entry<String,ResourceDescriptor> entry : map.entrySet()) {
          final String id = entry.getKey();

          toBeDeleted.remove(id);

          if (persistent.containsKey(id))
            continue;

          final ResourceDescriptor rd = entry.getValue();

          DownloadBlocker blocker = new DownloadBlocker(null) {

            //
            // We steal the thread of the downloader to index
            //

            @Override
            public void success(File file) throws Exception {
              try {
                IndexResult index = repoIndexer.indexFile(file);

                ResourceBuilder rb = new ResourceBuilder();

                //
                // Unfortunately, we need to convert the
                // caps/reqs
                // since they are not real caps/reqs
                //

                for (org.osgi.service.indexer.Capability capability : index.capabilities) {
                  CapReqBuilder cb = new CapReqBuilder(capability.getNamespace());
                  cb.addAttributes(capability.getAttributes());
                  cb.addDirectives(capability.getDirectives());
                  rb.addCapability(cb.buildSyntheticCapability());
                }
                for (org.osgi.service.indexer.Requirement requirement : index.requirements) {
                  CapReqBuilder cb = new CapReqBuilder(requirement.getNamespace());
                  cb.addAttributes(requirement.getAttributes());
                  cb.addDirectives(requirement.getDirectives());
                  rb.addRequirement(cb.buildSyntheticRequirement());
                }

                Resource resource = rb.build();

                PersistentResource pr = new PersistentResource(resource);
                persistent.put(id, pr);
              }
              finally {
                super.success(file);
              }
            }
          };
          blockers.put(entry.getKey(), blocker);
          repo.get(rd.bsn, rd.version, null, blocker);
        }

      }

      for (Entry<String,DownloadBlocker> entry : blockers.entrySet()) {
        String key = entry.getKey();
        DownloadBlocker blocker = entry.getValue();

        String reason = blocker.getReason();
        if (reason != null) {
          errors.add(key + ": " + reason);
        }
      }
      persistent.keySet().removeAll(toBeDeleted);
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }

    if (!errors.isEmpty())
      throw new IllegalStateException("Cannot index " + repos + " due to " + errors);

    return true;
  }

  /**
   * The repository method
   *
   * @param result2
   */

  public void findProviders(Map<Requirement,List<Capability>> result, Collection< ? extends Requirement> requirements) {
    init();

    nextReq: for (Requirement req : requirements) {
      String f = req.getDirectives().get("filter");
      if (f == null)
        continue nextReq;

      Filter filter = new Filter(f);

      for (PersistentResource presource : persistent.values()) {
        Resource resource = presource.getResource();
        List<Capability> provided = resource.getCapabilities(req.getNamespace());
        if (provided != null)
          for (Capability cap : provided) {
            if (filter.matchMap(cap.getAttributes())) {
              List<Capability> l = result.get(req);
              if (l == null)
                result.put(req, l = new ArrayList<Capability>());
              l.add(cap);
            }
          }
      }
    }
  }

  @SuppressWarnings({
      "unchecked", "rawtypes"
  })
  public Map<Requirement,Collection<Capability>> findProviders(Collection< ? extends Requirement> requirements) {
    MultiMap<Requirement,Capability> result = new MultiMap<Requirement,Capability>();
    findProviders(result, requirements);
    return (Map) result;
  }

  /*
   * Get all the shas from the repo
   */
  private Map<String,ResourceDescriptor> collectKeys(InfoRepository repo) throws Exception {
    Map<String,ResourceDescriptor> map = new HashMap<String,ResourceDescriptor>();

    for (String bsn : repo.list(null)) {
      for (Version version : repo.versions(bsn)) {
        ResourceDescriptor rd = repo.getDescriptor(bsn, version);
        map.put(Hex.toHexString(rd.id), rd);
      }
    }
    return map;
  }

  public String toString() {
    return "InfoRepositoryWrapper[" + repos + "]";
  }

  public void close() throws IOException {
    persistent.close();
  }

  public void addAugment(Properties properties) {
    augments.putAll(properties);
  }

  public void clear() {
    this.persistent.clear();
  }

  /**
   * Clear all files that were indexed before this date
   * @param lastModified
   */
  public void clear(long whenOlder) {
    persistent.clear(whenOlder);
  }

}
TOP

Related Classes of aQute.bnd.deployer.repository.wrapper.InfoRepositoryWrapper

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.