Exemplo n.º 1
0
  // TODO Have an input for number of tabs?
  @Override
  public String toGraphVizString() {
    StringBuilder builder = new StringBuilder();
    int i = 0;

    builder.append("\"");
    builder.append(this.fullName);
    builder.append("\" [\n\tshape = ");
    builder.append(this.shape);
    builder.append(",\n\tlabel = \"{");
    // TODO Change for other types of classes.
    if ((this.accessType & Opcodes.ACC_INTERFACE) == Opcodes.ACC_INTERFACE) {
      builder.append("\\<\\<");
      builder.append(this.fullName);
      builder.append("\\>\\>");
    } else {
      builder.append(this.fullName);
    }

    for (String s : this.patternNames) {
      builder.append("\\n\\<\\<");
      builder.append(s);
      builder.append("\\>\\>");
    }

    if (this.fields.size() != 0
        || this.methods.size() != 0) { // TODO Shouldn't this always do this?
      builder.append("|");
    }
    i = 0;
    for (UMLField f : this.fields) {
      if (i > MAX_ROWS) {
        builder.append("...");
        break;
      }
      builder.append(f.toGraphVizString());
      i++;
    }
    builder.append("|");
    i = 0;
    for (UMLMethod m : this.methods) {
      if (i > MAX_ROWS) {
        builder.append("...");
        break;
      }
      builder.append(m.toGraphVizString());
      i++;
    }
    builder.append("}\"\nstyle=filled\nfillcolor=\"");
    builder.append(this.fillColor);
    builder.append("\"");
    builder.append("\ncolor=\"").append(this.color).append("\"\n];\n");
    for (UMLArrow arrow : this.arrows) {
      builder.append(arrow.toGraphVizString());
    }
    return builder.toString();
  }
Exemplo n.º 2
0
 public ArrayList<UMLClass> getAllUsedClasses() {
   ArrayList<UMLClass> usedClasses = new ArrayList<UMLClass>();
   for (UMLArrow arrow : this.arrows) {
     if (arrow.isUsesArrow()) {
       usedClasses.add(arrow.getEndClass());
     }
   }
   return usedClasses;
 }
Exemplo n.º 3
0
  /**
   * This method is only useful if the graph has been built, and {@link #generateArrows(ArrayList)}
   * has been called on all classes. This method removes any arrows that point to classes that are
   * super classes of classes that this class has arrows to.
   */
  public void removeExtraArrows() {
    ArrayList<UMLClass> pointedTo = new ArrayList<UMLClass>();
    for (UMLArrow arrow : this.arrows) {
      pointedTo.add(arrow.getEndClass());
    }

    // If the used class is in a field, ignore it.
    for (UMLClass firstClass : new ArrayList<UMLClass>(pointedTo)) {
      for (UMLClass secondClass : new ArrayList<UMLClass>(pointedTo)) {
        if (firstClass.checkExtendsOrImplements(secondClass)) {
          pointedTo.remove(secondClass);
        } else if (secondClass.checkExtendsOrImplements(firstClass)) {
          pointedTo.remove(firstClass);
        }
      }
    }

    // Add back in extends/implements arrows
    for (UMLArrow arrow : this.arrows) {
      if (arrow.extendsOrImplements()) {
        pointedTo.add(arrow.getEndClass());
      }
    }

    for (UMLArrow arrow : new ArrayList<UMLArrow>(this.arrows)) {
      if ((!pointedTo.contains(arrow.getEndClass())) && arrow.isUsesArrow()) {
        this.arrows.remove(arrow);
      }
    }
  }
Exemplo n.º 4
0
  public ArrayList<UMLClass> getAllExtendsOrImplements() {
    ArrayList<UMLClass> finalList = new ArrayList<UMLClass>();
    ArrayList<UMLClass> extendsOrImplements = new ArrayList<UMLClass>();

    for (UMLArrow arrow : this.arrows) {
      if (arrow.extendsOrImplements()) {
        extendsOrImplements.add(arrow.getEndClass());
      }
    }

    for (UMLClass uClass : extendsOrImplements) {
      finalList.addAll(uClass.getAllExtendsOrImplementsHelper());
    }

    return finalList;
  }
Exemplo n.º 5
0
 /**
  * Helper method for {@link #toGraphVizString()}. Adds an arrow to an ArrayList if there isn't an
  * arrow that already connects the two.
  *
  * @param arrows ArrayList of UMLArrows that the arrow (may) be added to.
  * @param firstName Full name of the class the arrow will start from.
  * @param secondName Full name of the class the arrow will end at.
  * @param arrowType The type of arrowhead. See GraphViz documentation.
  * @param lineType The type of line. See GraphViz documentation.
  */
 private void addArrow(UMLClass end, String arrowType, String lineType) {
   // TODO Instead of just checking to see if the arrow exists, check the priority of the arrow.
   // eg association overwrites uses so it's no longer dependant on what arrows we make first.
   boolean isConnected = false;
   for (UMLArrow arrow : arrows) {
     if (arrow.connects(this, end)) {
       //				if(		(arrowType.equals("onormal") && arrow.extendsOrImplements()) {
       //						||
       //						(arrowType.equals("vee") && lineType.equals("dashed")) ||
       //						(arrow.isAssociationArrow() && arrowType.equals("vee") &&
       // lineType.equals("dashed"))) {
       isConnected = true;
       break;
       //				}
     }
   }
   if (!isConnected) {
     arrows.add(new UMLArrow(this, end, arrowType, lineType));
   }
 }
Exemplo n.º 6
0
  /**
   * This method is only useful if the graph has been built, and {@link #generateArrows(ArrayList)}
   * has been called on all classes.
   *
   * @param c The class to check if this class (directly or indirectly) extends or implements.
   * @return Whether or not this class extends or implements c.
   */
  public boolean checkExtendsOrImplements(UMLClass c) {
    if ((this.extension == null || this.extension.isEmpty()) && this.implementations.isEmpty()) {
      return false;
    }

    ArrayList<UMLClass> extImpl = new ArrayList<UMLClass>();
    for (UMLArrow arrow : this.arrows) {
      if (arrow.extendsOrImplements()) {
        extImpl.add(arrow.getEndClass());
      }
    }

    for (UMLClass cls : extImpl) {
      if (cls.getName().equals(c.getName())) {
        return true;
      } else if (cls.checkExtendsOrImplements(c)) {
        return true;
      }
    }
    return false;
  }
Exemplo n.º 7
0
  private ArrayList<UMLClass> getAllExtendsOrImplementsHelper() {
    ArrayList<UMLClass> finalList = new ArrayList<UMLClass>();
    ArrayList<UMLClass> extendsOrImplements = new ArrayList<UMLClass>();

    for (UMLArrow arrow : this.arrows) {
      if (arrow.extendsOrImplements()) {
        extendsOrImplements.add(arrow.getEndClass());
      }
    }

    for (UMLClass uClass : extendsOrImplements) {
      ArrayList<UMLClass> temp = uClass.getAllExtendsOrImplementsHelper();
      for (UMLClass uClass2 : temp) {
        if (!finalList.contains(uClass2)) {
          finalList.add(uClass2);
        }
      }
    }

    finalList.add(this);
    return finalList;
  }
Exemplo n.º 8
0
  // TODO Move these methods into UMLGraph where it makes more sense?
  // TODO Have a seperate array stored for all of the arrows?
  public void removeRedundantUsesArrows() {
    ArrayList<UMLClass> extendsOrImplements = this.getAllExtendsOrImplements();
    ArrayList<UMLClass> thisUsed = this.getAllUsedClasses();

    // Go through everything this class extends or implements (directly or
    // indirectly)
    for (UMLClass extendedClass : extendsOrImplements) {
      ArrayList<UMLClass> otherUsed = extendedClass.getAllUsedClasses();
      // Go through all of the classes that this class uses
      for (UMLClass usedClass : thisUsed) {
        boolean removeArrow = true;
        // If the other class uses the same thing as this class, check
        // to see
        // if all instances where that is used is the same in both
        // classes
        // or not used in this class. If so, remove the arrow from this
        // class.
        if (otherUsed.contains(usedClass)) {
          // Check if the used class is within a field
          boolean foundField = false;
          for (UMLField field : this.getFields()) {
            if (field.getType().getFullBaseDataType().equals(usedClass.getName())) {
              foundField = true;
              removeArrow = false;
            }
          }
          // If the used class is in a field, don't remove the arrow,
          // so skip the arrow checks.
          if (!foundField) {
            // Check everything for type, and if they are the same
            // in the two
            // If everything is the same, remove this class' used
            // arrow for that thing
            for (UMLMethod thisMethod : this.methods) {
              boolean wasUsed = false;
              // Check to see if this method uses the used class
              // at all
              for (TypeData d : thisMethod.getClassesUsed()) {
                if (d.getFullBaseDataType().equals(usedClass.getName())) {
                  wasUsed = true;
                  break;
                }
              }
              // The class was used in the method. Check to see if
              // there is an identical method in the other.
              if (wasUsed) {
                boolean isSame = false;
                for (UMLMethod extendedMethod : extendedClass.getMethods()) {
                  // If the methods have the same signature
                  if (thisMethod.sameSignature(extendedMethod)) {
                    isSame = true;
                    break;
                  }
                }
                if (!isSame) {
                  removeArrow = false;
                  break;
                }
              }
            }
          }
          if (removeArrow) {
            for (UMLArrow arrow : new ArrayList<UMLArrow>(this.arrows)) {
              if (arrow.isUsesArrow()
                  && arrow.getEndClass().getName().equals(usedClass.getName())) {
                this.arrows.remove(arrow);
                break;
              }
            }
          }
        }
      }
    }
  }