Package aQute.library.bnd

Source Code of aQute.library.bnd.Index

package aQute.library.bnd;

import java.io.*;
import java.util.*;

import aQute.bnd.version.*;
import aQute.lib.converter.*;
import aQute.lib.io.*;
import aQute.lib.json.*;
import aQute.libg.reporter.*;
import aQute.service.library.*;
import aQute.service.library.Library.RevisionRef;
import aQute.service.reporter.*;
import aQute.struct.*;

public class Index {
  Reporter  reporter  = new ReporterAdapter(System.out);

  static public class Repo extends struct {
    public int              version;
    public List<Library.RevisionRef>  revisionRefs  = list();
    public int              increment;
    public long              date;
    public boolean            learning    = true;
    public boolean            recurse      = true;

    // Manually print this so that we
    // have 1 line per resource, making it easier on git
    // to compare.
    void write(Formatter format) throws Exception {
      format.format("{\n\"version\"      :%s,\n" + "\"increment\"   :%s,\n" + "\"date\"        :%s,\n"
          + "\"revisionRefs\"   : [\n", version, increment, date);
      String del = "";

      for (Library.RevisionRef resource : revisionRefs) {
        format.format(del);
        format.flush();
        codec.enc().to(format.out()).put(resource);
        del = ",\n";
      }
      format.format("\n]}\n");
      format.flush();
    }
  }

  private static final SortedSet<Version>            EMPTY_VERSIONS  = Collections
                                            .unmodifiableSortedSet(new TreeSet<Version>());

  private File                        indexFile;

  private Map<String,SortedMap<Version,Library.RevisionRef>>  cache;

  private Repo                        repo;

  public Index(File file) {
    this.indexFile = file;
  }

  static final JSONCodec  codec  = new JSONCodec();

  private boolean      dirty;

  private void init() throws Exception {
    if (repo == null) {
      cache = new TreeMap<String,SortedMap<Version,Library.RevisionRef>>();

      if (indexFile.isFile() && indexFile.length() > 100) {
        repo = codec.dec().from(indexFile).get(new TypeReference<Repo>() {});
        for (Library.RevisionRef r : repo.revisionRefs) {
          SortedMap<Version,Library.RevisionRef> map = cache.get(r.bsn);
          if (map == null) {
            map = new TreeMap<Version,Library.RevisionRef>(Collections.reverseOrder());
            cache.put(r.bsn, map);
          }
          Version v = toVersion(r.baseline, r.qualifier);
          map.put(v, r);
        }
      } else {
        repo = new Repo();
        repo.version = 1;
      }
    }
  }

  public Set<String> getBsns() throws Exception {
    init();
    return cache.keySet();
  }

  public SortedSet<Version> getVersions(String bsn) throws Exception {
    init();

    Map<Version,Library.RevisionRef> map = cache.get(bsn);
    if (map == null)
      return EMPTY_VERSIONS;

    return (SortedSet<Version>) map.keySet();
  }

  public boolean addRevision(Library.RevisionRef ref) throws Exception {
    init();
    Version v = toVersion(ref.baseline, ref.qualifier);
    SortedMap<Version,Library.RevisionRef> map = cache.get(ref.bsn);
    if (map == null) {
      map = new TreeMap<Version,Library.RevisionRef>();
      cache.put(ref.bsn, map);
    }

    boolean result = map.put(v, ref) != null;
    repo.increment++;
    dirty = true;
    return result;
  }

  public Library.RevisionRef getRevisionRef(String bsn, Version version) throws Exception {
    init();
    Map<Version,Library.RevisionRef> map = cache.get(bsn);
    if (map == null)
      return null;

    return map.get(version);
  }

  public boolean delete(String bsn, Version v) throws Exception {
    init();
    Map<Version,Library.RevisionRef> map = cache.get(bsn);
    if (map != null) {
      try {
        Library.RevisionRef removed = map.remove(v);
        if (removed != null) {
          for (Iterator<RevisionRef> i = repo.revisionRefs.iterator(); i.hasNext();) {
            RevisionRef other = i.next();
            if (Arrays.equals(other.revision, removed.revision)) {
              i.remove();
            }
          }
          repo.revisionRefs.remove(removed);
          repo.increment++;
          dirty = true;
          return true;
        }
      }
      finally {
        if (map.isEmpty())
          cache.remove(bsn);
      }
    }

    return false;
  }

  public void save(Writer out) throws Exception {
    init();
    repo.date = System.currentTimeMillis();
    repo.revisionRefs = getRevisionRefs();
    Formatter f = new Formatter(out);
    repo.write(f);
  }

  public void save(OutputStream out) throws Exception {
    save(new OutputStreamWriter(out));
  }

  public void save(File out) throws Exception {
    File tmp = IO.createTempFile(out.getParentFile(), out.getName(), ".tmp");
    FileWriter fout = new FileWriter(tmp);
    try {
      save(fout);
      tmp.renameTo(out);
    }
    finally {
      fout.close();
    }
  }

  public void save() throws Exception {
    if (dirty)
      save(indexFile);
    dirty = false;
  }

  static Version toVersion(String baseline, String qualifier) {
    if (qualifier == null || qualifier.isEmpty())
      return new Version(baseline);
    else
      return new Version(baseline + "." + qualifier);
  }

  public static Version toVersion(Library.RevisionRef ref) {
    return toVersion(ref.baseline, ref.qualifier);
  }

  public Library.RevisionRef getRevisionRef(byte[] sha) throws Exception {
    init();
    for (SortedMap<Version, ? extends RevisionRef> list : cache.values()) {
      for (RevisionRef r : list.values()) {
        if (Arrays.equals(sha, r.revision))
          return r;
      }
    }
    return null;
  }

  public List<RevisionRef> getRevisionRefs() {
    List<RevisionRef> refs = new ArrayList<Library.RevisionRef>();
    for (SortedMap<Version, ? extends RevisionRef> list : cache.values()) {
      refs.addAll(list.values());
    }
    return refs;
  }

  public void setReporter(Reporter reporter) {
    this.reporter = reporter;
  }

  public boolean isLearning() {
    return repo.learning;
  }

  public void setLearning(boolean learning) {
    dirty |= repo.learning != learning;
    repo.learning = learning;

  }

  public boolean isRecurse() {
    return repo.recurse;
  }

  public void setRecurse(boolean learning) {
    dirty |= repo.recurse != learning;
    repo.recurse = learning;

  }
}
TOP

Related Classes of aQute.library.bnd.Index

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.