/**
   * Scan all output dirs for artifacts and remove those files (artifacts?) that are not recognized
   * as such, in the javac_state file.
   */
  public void removeUnidentifiedArtifacts() {
    Set<File> allKnownArtifacts = new HashSet<>();
    for (Package pkg : prev.packages().values()) {
      for (File f : pkg.artifacts().values()) {
        allKnownArtifacts.add(f);
      }
    }
    // Do not forget about javac_state....
    allKnownArtifacts.add(javacState);

    for (File f : binArtifacts) {
      if (!allKnownArtifacts.contains(f)) {
        Log.debug("Removing " + f.getPath() + " since it is unknown to the javac_state.");
        f.delete();
      }
    }
    for (File f : headerArtifacts) {
      if (!allKnownArtifacts.contains(f)) {
        Log.debug("Removing " + f.getPath() + " since it is unknown to the javac_state.");
        f.delete();
      }
    }
    for (File f : gensrcArtifacts) {
      if (!allKnownArtifacts.contains(f)) {
        Log.debug("Removing " + f.getPath() + " since it is unknown to the javac_state.");
        f.delete();
      }
    }
  }
 /** Lookup the artifacts generated for this package in the previous build. */
 private Map<String, File> fetchPrevArtifacts(String pkg) {
   Package p = prev.packages().get(pkg);
   if (p != null) {
     return p.artifacts();
   }
   return new HashMap<>();
 }
 /**
  * Check whether a given application version is compatible with the version of JHotDraw currently
  * loaded in the Java VM. A version number is available if there is a corresponding version entry
  * in the JHotDraw jar file for the framework package.
  */
 public static boolean isCompatibleVersion(String compareVersionString) {
   //		Package pack = VersionManagement.class.getPackage();
   Package pack = packages[4];
   if (compareVersionString == null) {
     return pack.getSpecificationVersion() == null;
   } else {
     return pack.isCompatibleWith(compareVersionString);
   }
 }
 /**
  * Propagate recompilation through the dependency chains. Avoid re-tainting packages that have
  * already been compiled.
  */
 public void taintPackagesDependingOnChangedPackages(
     Set<String> pkgs, Set<String> recentlyCompiled) {
   for (Package pkg : prev.packages().values()) {
     for (String dep : pkg.dependencies()) {
       if (pkgs.contains(dep) && !recentlyCompiled.contains(pkg.name())) {
         taintPackage(pkg.name(), " its depending on " + dep);
       }
     }
   }
 }
 /** If artifacts have gone missing, force a recompile of the packages they belong to. */
 public void taintPackagesThatMissArtifacts() {
   for (Package pkg : prev.packages().values()) {
     for (File f : pkg.artifacts().values()) {
       if (!f.exists()) {
         // Hmm, the artifact on disk does not exist! Someone has removed it....
         // Lets rebuild the package.
         taintPackage(pkg.name(), "" + f + " is missing.");
       }
     }
   }
 }
 /** Mark a java package as tainted, ie it needs recompilation. */
 public void taintPackage(String name, String because) {
   if (!taintedPackages.contains(name)) {
     if (because != null)
       Log.debug("Tainting " + Util.justPackageName(name) + " because " + because);
     // It has not been tainted before.
     taintedPackages.add(name);
     needsSaving();
     Package nowp = now.packages().get(name);
     if (nowp != null) {
       for (String d : nowp.dependents()) {
         taintPackage(d, because);
       }
     }
   }
 }
  public static String getPackageVersion(final Package lookupPackage) {
    if (lookupPackage == null) {
      return null;
    }

    String specVersion = lookupPackage.getSpecificationVersion();
    if (specVersion != null) {
      return specVersion;
    } else {
      // search in parent package
      String normalizedPackageName = normalizePackageName(lookupPackage.getName());
      String nextPackageName = getNextPackage(normalizedPackageName);
      return getPackageVersion(Package.getPackage(nextPackageName));
    }
  }
 public String getVersion(Class<?> api) {
   log.trace("getVersion for {}", api);
   Package pkg = api.getPackage();
   log.trace("    -> {}/{}", pkg.getImplementationVersion(), pkg.getSpecificationVersion());
   String version = pkg.getSpecificationVersion();
   if (version == null) version = pkg.getImplementationVersion();
   if (version == null) {
     try {
       version = readVersionFromManifest(api);
     } catch (IOException e) {
       log.error("Could not extract version for " + api, e);
       return null;
     }
   }
   return version;
 }
  public void generate(String inputFileName) throws Exception {
    List<MetaClass> metaClasses = new ArrayList<>();
    List<LifeLine> lifeLines = new ArrayList<>();
    List<MethodInvocation> rootMessages = new ArrayList<>();
    MethodInvocation parentMessage = new MethodInvocation();
    GsonBuilder builder = new GsonBuilder();
    List<MethodInvocation> methodInvocations = new ArrayList<>();
    Package mainPackage = new Package();
    List<Guard> listOfGuards = new ArrayList<>();
    Map<Guard, Instruction> guardToCFMap = new HashMap<>();
    List<Instruction> combinedFragments = new ArrayList<Instruction>();
    List<Operation> operationsList = new ArrayList<>();

    builder.registerTypeAdapter(RefObject.class, new RefObjectJsonDeSerializer());
    Gson gson = builder.create();

    Element myTypes = gson.fromJson(new FileReader(inputFileName), Element.class);
    if (myTypes._type.equals("Project")) {
      List<Element> umlElements =
          myTypes
              .ownedElements
              .stream()
              .filter(f -> f._type.equals("UMLModel"))
              .collect(Collectors.toList());
      if (umlElements.size() > 0) { // There has be to atleast one UMLModel package
        Element element = umlElements.get(0);
        // package that the classes are supposed to be in
        mainPackage.setName(element.name);
        List<Element> umlPackages =
            element
                .ownedElements
                .stream()
                .filter(g -> g._type.equals("UMLPackage"))
                .collect(Collectors.toList());
        if (umlPackages.size()
            > 1) { // There has to be two packages- one for class one for behaviour
          Element classes = umlPackages.get(0);
          Element behaviour = umlPackages.get(1);
          // *--------------------------CLASSES-------------------------------*//
          // in the first pass, get all classes that are defined in the diagram
          // get details that can be directly inferred from the json like, fields and operations,
          // which do not refer to other classes
          for (Element umlClass : classes.getOwnedElements()) {
            MetaClass metaClass = new MetaClass(umlClass.name, umlClass._id);

            // check if class is interface or not because there is no distinction in json
            if (umlClass._type.equals("UMLClass")) {
              metaClass.setInterface(false);
            } else {
              metaClass.setInterface(true);
            }
            if (umlClass.operations != null) {
              metaClass.setOperations(umlClass.operations);
              operationsList.addAll(metaClass.operations);
            }
            if (umlClass.attributes != null) {
              metaClass.setFields(umlClass.attributes);
            }
            metaClasses.add(metaClass);
          }

          // in second pass, define associations and generalizations for these classes
          for (Element umlClass : classes.getOwnedElements()) {
            if (umlClass.ownedElements != null) {
              // find corresponding metaclass, then populate the secondary inferences
              List<MetaClass> correspondingMetaClassList =
                  metaClasses
                      .stream()
                      .filter(f -> f._id.equals(umlClass._id))
                      .collect(Collectors.toList());
              MetaClass correspondingMetaClass = correspondingMetaClassList.get(0);
              List<Element> umlAssociations =
                  umlClass
                      .ownedElements
                      .stream()
                      .filter(f -> f._type.equals("UMLAssociation"))
                      .collect(Collectors.toList());

              if (umlAssociations.size() > 0) {
                correspondingMetaClass.setAssociations(metaClasses, umlAssociations);
              }
              List<Element> umlGeneralization =
                  umlClass
                      .ownedElements
                      .stream()
                      .filter(f -> f._type.equals("UMLGeneralization"))
                      .collect(Collectors.toList());
              if (umlGeneralization.size() > 0) {
                correspondingMetaClass.setGeneralizations(metaClasses, umlGeneralization);
              }
              List<Element> umlRealization =
                  umlClass
                      .ownedElements
                      .stream()
                      .filter(f -> f._type.equals("UMLInterfaceRealization"))
                      .collect(Collectors.toList());
              if (umlRealization.size() > 0) {
                correspondingMetaClass.setInterfaceRealization(metaClasses, umlRealization);
              }
            }
          }

          // *--------------------------CLASSES-------------------------------*//

          // *-----------------------  BEHAVIOUR---------------------------------*//
          for (Element umlCollaboration : behaviour.getOwnedElements()) {
            // Role to Class mapping
            ArrayList<Element> attributes = umlCollaboration.attributes;
            HashMap<String, MetaClass> roleToClassMap = new HashMap<>();
            if (attributes != null) {
              for (Element attribute : attributes) {
                List<MetaClass> roleClass =
                    metaClasses
                        .stream()
                        .filter(f -> f._id.equals(attribute.type.$ref))
                        .collect(Collectors.toList());
                roleToClassMap.put(attribute._id, roleClass.get(0));
              }
            }

            for (Element umlInteraction : umlCollaboration.ownedElements) {

              // mapping lifelines to the classes they correspond
              ArrayList<Element> participants = umlInteraction.participants;
              if (participants != null && participants.size() > 0) {
                for (Element participant : participants) {
                  MetaClass participantClass = roleToClassMap.get(participant.represent.$ref);
                  LifeLine lifeLine = new LifeLine();
                  lifeLine.setName(participant.name);
                  lifeLine.setId(participant._id);
                  lifeLine.setMetaClass(participantClass);
                  lifeLines.add(lifeLine);
                }
              }
              // first parse all the combined fragments and get ready
              if (umlInteraction.fragments != null) {
                for (Element fragment :
                    umlInteraction.fragments) { // depending on the fragment set the class
                  Instruction instruction = null;
                  if (fragment.interactionOperator.equals("loop")) {
                    Loop loop = new Loop();
                    loop.setId(fragment._id);
                    loop.setWeight(0);
                    Guard guard = new Guard(fragment.operands.get(0)._id);
                    // loop can have only one condition--- one condition-- condition is made up of
                    // AND or OR's
                    guard.setCondition(fragment.operands.get(0).guard);
                    loop.setGuard(guard);
                    instruction = loop;
                    combinedFragments.add(loop);
                    listOfGuards.add(guard);
                    guardToCFMap.put(guard, loop);
                  }

                  if (fragment.interactionOperator.equals("alt")) {
                    Conditional c = new Conditional();
                    c.setId(fragment._id);
                    c.setWeight(0);
                    instruction = c;
                    combinedFragments.add(c);

                    Guard consequence = new Guard(fragment.operands.get(0)._id);
                    consequence.setCondition(fragment.operands.get(0).guard);
                    c.setCons(consequence);
                    listOfGuards.add(consequence);
                    guardToCFMap.put(consequence, c);
                    consequence.setConsequence(true);

                    if (fragment.operands.size() > 1) {
                      Guard alternate = new Guard(fragment.operands.get(1)._id);
                      alternate.setCondition(fragment.operands.get(1).guard);
                      c.setAlt(alternate);
                      listOfGuards.add(alternate);
                      guardToCFMap.put(alternate, c);
                      alternate.setAlternative(true);
                    }
                  }

                  if (fragment.tags != null) {
                    for (Element tag : fragment.tags) {
                      if (tag.name.equals("parent")) {
                        List<Instruction> instructionList =
                            combinedFragments
                                .stream()
                                .filter(e -> e.getId().equals(tag.reference.$ref))
                                .collect(Collectors.toList());
                        if (instructionList.size() > 0) {
                          instructionList.get(0).getBlock().add(instruction);
                          instruction.setParent(instructionList.get(0));
                        }
                      }
                    }
                  }
                }
              }

              // parsing the messages and make nodes out them to later build a tree from the
              // lifelines
              ArrayList<Element> messages = umlInteraction.messages;
              Element startMessage = messages.get(0);
              String sourceRef = startMessage.source.$ref;
              String targetRef = startMessage.target.$ref;
              Element endMessage = null;

              LifeLine sourceLifeLine = getLifeLine(lifeLines, sourceRef);
              LifeLine targetLifeLine = getLifeLine(lifeLines, targetRef);

              // First message processing
              parentMessage = new MethodInvocation();
              parentMessage.setAssignmentTarget(startMessage.assignmentTarget);
              parentMessage.setMessageSort(startMessage.messageSort);
              parentMessage.setSource(sourceLifeLine.getMetaClass());
              parentMessage.setTarget(targetLifeLine.getMetaClass());
              parentMessage.setName(startMessage.name);
              parentMessage.setId(startMessage._id);
              if (sourceLifeLine.getId().equals(targetLifeLine.getId())) {
                parentMessage.setCallerObject("this");
              } else {
                parentMessage.setCallerObject(targetLifeLine.getName());
              }
              int weight = 0;
              parentMessage.setWeight(weight++);
              if (startMessage.signature != null) {
                parentMessage.setSignature(startMessage.signature.$ref);
              }

              if (startMessage.tags != null) {
                for (Element tag : startMessage.tags) {
                  //                                    if (tag.name.equals("CF")) {
                  //                                        parentMessage.setInCF(true);
                  //
                  // parentMessage.setCfID(tag.reference.$ref);
                  //                                    }
                  if (tag.name.equals("operand")) {
                    parentMessage.setOperandId(tag.reference.$ref);
                  }
                }
              }

              MethodInvocation rootMessage = parentMessage;
              methodInvocations.add(rootMessage);
              rootMessages.add(rootMessage);
              Iterator<Element> iter = messages.iterator();
              while (iter.hasNext()) {
                if (iter.next() == endMessage) {
                  continue;
                }

                iter.remove();
                List<Element> childMessages = getChildMessages(messages, targetRef);
                for (Element child : childMessages) {

                  LifeLine childSource = getLifeLine(lifeLines, child.source.$ref);
                  LifeLine childTarget = getLifeLine(lifeLines, child.target.$ref);

                  MethodInvocation childMessage = new MethodInvocation();
                  childMessage.setMessageSort(child.messageSort);
                  childMessage.setSource(childSource.getMetaClass());
                  childMessage.setTarget(childTarget.getMetaClass());
                  childMessage.setAssignmentTarget(child.assignmentTarget);
                  childMessage.setName(child.name);
                  childMessage.setId(child._id);
                  childMessage.setWeight(weight++);
                  childMessage.setArguments(child.arguments);

                  if (childSource.getId().equals(childTarget.getId())) {
                    childMessage.setCallerObject("this");
                  } else {
                    childMessage.setCallerObject(childTarget.getName());
                  }

                  if (child.signature != null) {
                    childMessage.setSignature(child.signature.$ref);
                  }

                  if (child.tags != null) {
                    for (Element tag : child.tags) {
                      //                                            if (tag.name.equals("CF")) {
                      //                                                childMessage.setInCF(true);
                      //
                      // childMessage.setCfID(tag.reference.$ref);
                      //                                            }
                      if (tag.name.equals("operand")) {
                        childMessage.setOperandId(tag.reference.$ref);
                      }
                    }
                  }

                  parentMessage.childNodes.add(childMessage);
                  methodInvocations.add(childMessage);
                }

                if (childMessages.size() > 0) {
                  List<MethodInvocation> nextMessage =
                      parentMessage
                          .childNodes
                          .stream()
                          .filter(f -> !f.source.equals(f.target))
                          .collect(Collectors.toList());
                  List<Element> startMessageNext =
                      childMessages
                          .stream()
                          .filter(f -> !f.source.$ref.equals(f.target.$ref))
                          .collect(Collectors.toList());
                  startMessage = startMessageNext.get(0);
                  targetRef = startMessage.target.$ref;
                  sourceRef = startMessage.source.$ref;

                  parentMessage = nextMessage.get(0);

                  if (childMessages.size() > 1) {
                    endMessage = childMessages.get(childMessages.size() - 1);
                  }
                }
              }
            }

            for (MethodInvocation methodInvocation : methodInvocations) {
              List<Operation> matchingOperation =
                  operationsList
                      .stream()
                      .filter(f -> f._id.equals(methodInvocation.getSignature()))
                      .collect(Collectors.toList());
              if (matchingOperation.size() > 0) {
                operationMap.put(methodInvocation, matchingOperation.get(0)._id);
                methodInvocation.setOperation(matchingOperation.get(0));
              }
            }

            Stack stack = new Stack();
            for (MethodInvocation root : methodInvocations) {
              stack.push(root);
              while (!stack.empty()) {
                MethodInvocation methodInvocation = (MethodInvocation) stack.pop();
                Operation currentOperation = methodInvocation.getOperation();

                if (currentOperation != null) {
                  // all child nodes of this node make up its body
                  List<MethodInvocation> childNodes = methodInvocation.childNodes;
                  for (MethodInvocation child : childNodes) {
                    stack.push(child);
                  }
                  for (MethodInvocation childNode : childNodes) {
                    if (childNode.getOperandId() != null) {
                      List<Instruction> combinedFragmentsList =
                          combinedFragments
                              .stream()
                              .filter(f -> f.getId().equals(childNode.getCfID()))
                              .collect(Collectors.toList());

                      List<Guard> guardList =
                          listOfGuards
                              .stream()
                              .filter(f -> f.id.equals(childNode.getOperandId()))
                              .collect(Collectors.toList());

                      if (guardList.size() > 0) {
                        Guard currentGuard = guardList.get(0);
                        Instruction instruction = guardToCFMap.get(guardList.get(0));
                        // get the topmost CF if it is in a tree
                        Instruction parent = instruction.getParent();

                        while (instruction.getParent() != null) {
                          instruction = instruction.getParent();
                        }

                        if (currentGuard.isConsequence) {
                          Conditional conditional = (Conditional) instruction;
                          if (!conditional.getConsequence().contains(childNode)) {
                            conditional.getConsequence().add(childNode);
                          }
                        }
                        if (currentGuard.isAlternative) {
                          Conditional conditional = (Conditional) instruction;
                          if (!conditional.getAlternative().contains(childNode)) {
                            conditional.getAlternative().add(childNode);
                          }
                        }
                        if (!currentGuard.isAlternative && !currentGuard.isConsequence) {
                          Loop loop = (Loop) instruction;
                          loop.getBlock().add(childNode);
                        } else {
                          if (!currentOperation.getBlock().contains(instruction)) {
                            currentOperation.getBlock().add(instruction);
                          }
                        }
                      }
                    } else {
                      if (!currentOperation.getBlock().contains(childNode)) {
                        currentOperation.getBlock().add(childNode);
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    //
    ////        printAllData(metaClasses);
    //        while (parentMessage.childNodes != null || parentMessage.childNodes.size() > 0) {
    //            System.out.println("parent " + parentMessage.name);
    //            for (com.cbpro.main.MethodInvocation child : parentMessage.childNodes) {
    //                System.out.println("child " + child.name);
    //            }
    //            if (parentMessage.childNodes.size() > 0) {
    //                parentMessage = parentMessage.childNodes.get(0);
    //            } else {
    //                break;
    //            }
    //        }

    mainPackage.print();
    File dir = new File("/home/ramyashenoy/Desktop/DemoFolder/" + mainPackage.getName());

    boolean successful = dir.mkdir();
    if (successful) {
      System.out.println("directory was created successfully");
      for (MetaClass metaClass : metaClasses) {
        if (metaClass.name.equals("Main")) {
          continue;
        } else {
          String data = metaClass.print();
          BufferedWriter out = null;
          try {
            FileWriter fstream =
                new FileWriter(
                    dir.getPath() + "/" + metaClass.name + ".java",
                    true); // true tells to append data.
            out = new BufferedWriter(fstream);
            out.write(data);
          } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
          } finally {
            if (out != null) {
              out.close();
            }
          }
        }
      }
    } else {
      // creating the directory failed
      System.out.println("failed trying to create the directory");
    }

    mainPackage.setClasses(metaClasses);
  }
  /**
   * For all packages, find all sources belonging to the package, group the sources based on their
   * transformers and apply the transformers on each source code group.
   */
  private boolean perform(File outputDir, Map<String, Transformer> suffixRules) {
    boolean rc = true;
    // Group sources based on transforms. A source file can only belong to a single transform.
    Map<Transformer, Map<String, Set<URI>>> groupedSources = new HashMap<>();
    for (Source src : now.sources().values()) {
      Transformer t = suffixRules.get(src.suffix());
      if (t != null) {
        if (taintedPackages.contains(src.pkg().name()) && !src.isLinkedOnly()) {
          addFileToTransform(groupedSources, t, src);
        }
      }
    }
    // Go through the transforms and transform them.
    for (Map.Entry<Transformer, Map<String, Set<URI>>> e : groupedSources.entrySet()) {
      Transformer t = e.getKey();
      Map<String, Set<URI>> srcs = e.getValue();
      // These maps need to be synchronized since multiple threads will be writing results into
      // them.
      Map<String, Set<URI>> packageArtifacts =
          Collections.synchronizedMap(new HashMap<String, Set<URI>>());
      Map<String, Set<String>> packageDependencies =
          Collections.synchronizedMap(new HashMap<String, Set<String>>());
      Map<String, String> packagePublicApis =
          Collections.synchronizedMap(new HashMap<String, String>());

      boolean r =
          t.transform(
              srcs,
              visibleSrcs,
              visibleClasses,
              prev.dependents(),
              outputDir.toURI(),
              packageArtifacts,
              packageDependencies,
              packagePublicApis,
              0,
              isIncremental(),
              numCores,
              out,
              err);
      if (!r) rc = false;

      for (String p : srcs.keySet()) {
        recompiledPackages.add(p);
      }
      // The transform is done! Extract all the artifacts and store the info into the Package
      // objects.
      for (Map.Entry<String, Set<URI>> a : packageArtifacts.entrySet()) {
        Module mnow = now.findModuleFromPackageName(a.getKey());
        mnow.addArtifacts(a.getKey(), a.getValue());
      }
      // Extract all the dependencies and store the info into the Package objects.
      for (Map.Entry<String, Set<String>> a : packageDependencies.entrySet()) {
        Set<String> deps = a.getValue();
        Module mnow = now.findModuleFromPackageName(a.getKey());
        mnow.setDependencies(a.getKey(), deps);
      }
      // Extract all the pubapis and store the info into the Package objects.
      for (Map.Entry<String, String> a : packagePublicApis.entrySet()) {
        Module mprev = prev.findModuleFromPackageName(a.getKey());
        List<String> pubapi = Package.pubapiToList(a.getValue());
        Module mnow = now.findModuleFromPackageName(a.getKey());
        mnow.setPubapi(a.getKey(), pubapi);
        if (mprev.hasPubapiChanged(a.getKey(), pubapi)) {
          // Aha! The pubapi of this package has changed!
          // It can also be a new compile from scratch.
          if (mprev.lookupPackage(a.getKey()).existsInJavacState()) {
            // This is an incremental compile! The pubapi
            // did change. Trigger recompilation of dependents.
            packagesWithChangedPublicApis.add(a.getKey());
            Log.info("The pubapi of " + Util.justPackageName(a.getKey()) + " has changed!");
          }
        }
      }
    }
    return rc;
  }
  /** Load a javac_state file. */
  public static JavacState load(
      String[] args,
      File binDir,
      File gensrcDir,
      File headerDir,
      boolean permitUnidentifiedArtifacts,
      PrintStream out,
      PrintStream err) {
    JavacState db =
        new JavacState(
            args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, false, out, err);
    Module lastModule = null;
    Package lastPackage = null;
    Source lastSource = null;
    boolean noFileFound = false;
    boolean foundCorrectVerNr = false;
    boolean newCommandLine = false;
    boolean syntaxError = false;

    try (BufferedReader in = new BufferedReader(new FileReader(db.javacStateFilename))) {
      for (; ; ) {
        String l = in.readLine();
        if (l == null) break;
        if (l.length() >= 3 && l.charAt(1) == ' ') {
          char c = l.charAt(0);
          if (c == 'M') {
            lastModule = db.prev.loadModule(l);
          } else if (c == 'P') {
            if (lastModule == null) {
              syntaxError = true;
              break;
            }
            lastPackage = db.prev.loadPackage(lastModule, l);
          } else if (c == 'D') {
            if (lastModule == null || lastPackage == null) {
              syntaxError = true;
              break;
            }
            lastPackage.loadDependency(l);
          } else if (c == 'I') {
            if (lastModule == null || lastPackage == null) {
              syntaxError = true;
              break;
            }
            lastPackage.loadPubapi(l);
          } else if (c == 'A') {
            if (lastModule == null || lastPackage == null) {
              syntaxError = true;
              break;
            }
            lastPackage.loadArtifact(l);
          } else if (c == 'S') {
            if (lastModule == null || lastPackage == null) {
              syntaxError = true;
              break;
            }
            lastSource = db.prev.loadSource(lastPackage, l, false);
          } else if (c == 'G') {
            if (lastModule == null || lastPackage == null) {
              syntaxError = true;
              break;
            }
            lastSource = db.prev.loadSource(lastPackage, l, true);
          } else if (c == 'R') {
            String ncmdl = "R " + db.theArgs;
            if (!l.equals(ncmdl)) {
              newCommandLine = true;
            }
          } else if (c == '#') {
            if (l.startsWith("# javac_state ver ")) {
              int sp = l.indexOf(" ", 18);
              if (sp != -1) {
                String ver = l.substring(18, sp);
                if (!ver.equals("0.3")) {
                  break;
                }
                foundCorrectVerNr = true;
              }
            }
          }
        }
      }
    } catch (FileNotFoundException e) {
      // Silently create a new javac_state file.
      noFileFound = true;
    } catch (IOException e) {
      Log.info("Dropping old javac_state because of errors when reading it.");
      db =
          new JavacState(
              args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
      foundCorrectVerNr = true;
      newCommandLine = false;
      syntaxError = false;
    }
    if (foundCorrectVerNr == false && !noFileFound) {
      Log.info("Dropping old javac_state since it is of an old version.");
      db =
          new JavacState(
              args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
    } else if (newCommandLine == true && !noFileFound) {
      Log.info("Dropping old javac_state since a new command line is used!");
      db =
          new JavacState(
              args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
    } else if (syntaxError == true) {
      Log.info("Dropping old javac_state since it contains syntax errors.");
      db =
          new JavacState(
              args, binDir, gensrcDir, headerDir, permitUnidentifiedArtifacts, true, out, err);
    }
    db.prev.calculateDependents();
    return db;
  }
Example #12
0
    private void unpackSegment(InputStream in, JarOutputStream out) throws IOException {
      _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS, "0");
      // Process the output directory or jar output.
      new PackageReader(pkg, in).read();

      if (_props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug");
      if (_props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile");
      _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS, "50");
      pkg.ensureAllClassFiles();
      // Now write out the files.
      HashSet classesToWrite = new HashSet(pkg.getClasses());
      for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) {
        Package.File file = (Package.File) i.next();
        String name = file.nameString;
        JarEntry je = new JarEntry(Utils.getJarEntryName(name));
        boolean deflate;

        deflate =
            (keepDeflateHint)
                ? (((file.options & Constants.FO_DEFLATE_HINT) != 0)
                    || ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0))
                : deflateHint;

        boolean needCRC = !deflate; // STORE mode requires CRC

        if (needCRC) crc.reset();
        bufOut.reset();
        if (file.isClassStub()) {
          Package.Class cls = file.getStubClass();
          assert (cls != null);
          new ClassWriter(cls, needCRC ? crcOut : bufOut).write();
          classesToWrite.remove(cls); // for an error check
        } else {
          // collect data & maybe CRC
          file.writeTo(needCRC ? crcOut : bufOut);
        }
        je.setMethod(deflate ? JarEntry.DEFLATED : JarEntry.STORED);
        if (needCRC) {
          if (verbose > 0)
            Utils.log.info("stored size=" + bufOut.size() + " and crc=" + crc.getValue());

          je.setMethod(JarEntry.STORED);
          je.setSize(bufOut.size());
          je.setCrc(crc.getValue());
        }
        if (keepModtime) {
          je.setTime(file.modtime);
          // Convert back to milliseconds
          je.setTime((long) file.modtime * 1000);
        } else {
          je.setTime((long) modtime * 1000);
        }
        out.putNextEntry(je);
        bufOut.writeTo(out);
        out.closeEntry();
        if (verbose > 0) Utils.log.info("Writing " + Utils.zeString((ZipEntry) je));
      }
      assert (classesToWrite.isEmpty());
      _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS, "100");
      pkg.reset(); // reset for the next segment, if any
    }
 /**
  * Return the version of the main package of the framework. A version number is available if there
  * is a corresponding version entry in the JHotDraw jar file for the framework package.
  */
 public static String getJHotDrawVersion() {
   // look for the framework main package
   Package pack = packages[4];
   return pack.getSpecificationVersion();
 }
/**
 * Collection of utility methods that are useful for dealing with version information retrieved from
 * reading jar files or package loaded by the class manager. Some methods also help comparing
 * version information. The method getJHotDrawVersion() can be used to retrieve the current version
 * of JHotDraw as loaded by the class manager.
 *
 * @author Wolfram Kaiser
 * @version <$CURRENT_VERSION$>
 */
public class VersionManagement {
  public static String JHOTDRAW_COMPONENT = "CH.ifa.draw/";
  public static String JHOTDRAW_JAR = "jhotdraw.jar";

  public static Package[] packages = {
    Package.getPackage("CH.ifa.draw.applet"),
    Package.getPackage("CH.ifa.draw.application"),
    Package.getPackage("CH.ifa.draw.contrib"),
    Package.getPackage("CH.ifa.draw.figures"),
    Package.getPackage("CH.ifa.draw.framework"),
    Package.getPackage("CH.ifa.draw.standard"),
    Package.getPackage("CH.ifa.draw.util")
  };

  /**
   * Return the version of the main package of the framework. A version number is available if there
   * is a corresponding version entry in the JHotDraw jar file for the framework package.
   */
  public static String getJHotDrawVersion() {
    // look for the framework main package
    Package pack = packages[4];
    return pack.getSpecificationVersion();
  }

  /** */
  public static String getPackageVersion(final Package lookupPackage) {
    if (lookupPackage == null) {
      return null;
    }

    String specVersion = lookupPackage.getSpecificationVersion();
    if (specVersion != null) {
      return specVersion;
    } else {
      // search in parent package
      String normalizedPackageName = normalizePackageName(lookupPackage.getName());
      String nextPackageName = getNextPackage(normalizedPackageName);
      return getPackageVersion(Package.getPackage(nextPackageName));
    }
  }

  /**
   * Check whether a given application version is compatible with the version of JHotDraw currently
   * loaded in the Java VM. A version number is available if there is a corresponding version entry
   * in the JHotDraw jar file for the framework package.
   */
  public static boolean isCompatibleVersion(String compareVersionString) {
    //		Package pack = VersionManagement.class.getPackage();
    Package pack = packages[4];
    if (compareVersionString == null) {
      return pack.getSpecificationVersion() == null;
    } else {
      return pack.isCompatibleWith(compareVersionString);
    }
  }

  /**
   * Read the version information from a file with a given file name. The file must be a jar
   * manifest file and all its entries are searched for package names and their specification
   * version information. All information is collected in a map for later lookup of package names
   * and their versions.
   *
   * @param versionFileName name of the jar file containing version information
   */
  public static String readVersionFromFile(String applicationName, String versionFileName) {
    try {
      FileInputStream fileInput = new FileInputStream(versionFileName);
      Manifest manifest = new Manifest();
      manifest.read(fileInput);

      Map entries = manifest.getEntries();
      // Now write out the pre-entry attributes
      Iterator entryIterator = entries.entrySet().iterator();
      while (entryIterator.hasNext()) {
        Map.Entry currentEntry = (Map.Entry) entryIterator.next();
        String packageName = currentEntry.getKey().toString();
        packageName = normalizePackageName(packageName);
        Attributes attributes = (Attributes) currentEntry.getValue();
        String packageSpecVersion = attributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
        packageSpecVersion = extractVersionInfo(packageSpecVersion);
        return packageSpecVersion;
      }
    } catch (IOException exception) {
      exception.printStackTrace();
    }

    // no version found
    return null;
  }

  /**
   * Get the super package of a package specifier. The super package is the package specifier
   * without the latest package name, e.g. the next package for "org.jhotdraw.tools" would be
   * "org.jhotdraw".
   *
   * @param searchPackage package specifier
   * @return next package if one is available, null otherwise
   */
  public static String getNextPackage(String searchPackage) {
    if (searchPackage == null) {
      return null;
    }

    int foundNextPackage = searchPackage.lastIndexOf('.');
    if (foundNextPackage > 0) {
      return searchPackage.substring(0, foundNextPackage);
    } else {
      return null;
    }
  }

  /**
   * A package name is normalized by replacing all path delimiters by "." to retrieve a valid
   * standardized package specifier used in package declarations in Java source files.
   *
   * @param toBeNormalized package name to be normalized
   * @return normalized package name
   */
  public static String normalizePackageName(String toBeNormalized) {
    // first, replace the standard package delimiter used in jars
    String replaced = toBeNormalized.replace('/', '.');
    // then, replace the default path separator in case this one was used as well
    replaced = replaced.replace(File.pathSeparatorChar, '.');
    if (replaced.endsWith(".")) {
      int lastSeparator = replaced.lastIndexOf('.');
      return replaced.substring(0, lastSeparator);
    } else {
      return replaced;
    }
  }

  /**
   * Get the version information specified in a jar manifest file without any leading or trailing
   * "\"".
   *
   * @param versionString a version string with possibly leading or trailing "\""
   * @return stripped version information
   */
  public static String extractVersionInfo(String versionString) {
    // guarding conditions
    if (versionString == null) {
      return null;
    }
    if (versionString.length() == 0) {
      return "";
    }

    int startIndex = versionString.indexOf("\"");
    if (startIndex < 0) {
      startIndex = 0;
    } else {
      // start from next character
      startIndex++;
    }

    int endIndex = versionString.lastIndexOf("\"");
    if (endIndex < 0) {
      endIndex = versionString.length();
    }

    return versionString.substring(startIndex, endIndex);
  }
}