예제 #1
0
 /** Resets the text handler so objects and messages can be read once again. */
 protected void reset() {
   super.reset();
   String[] titleString = grep.parse("(?s).*#!\\[([^\n\r]*?)\\].*", text());
   if (titleString == null) {
     title = null;
   } else {
     title = titleString[0];
   }
   String[] descString = grep.parse("(?s).*#!>>(.*)#!<<.*", text());
   if (descString == null) {
     description = null;
   } else {
     description = descString[0].trim().split("\n");
   }
   for (int i = 0; description != null && i < description.length; i++) {
     description[i] = description[i].trim();
     if (!description[i].startsWith("#!")) {
       description = null;
     } else {
       description[i] = description[i].replaceFirst("#!", "");
     }
   }
   section = -1;
   annotations.clear();
 }
예제 #2
0
 private void generateMapFile(
     Diagram diagram, TextHandler textHandler, String mapName, File target) throws IOException {
   String encoding = ConfigurationManager.getGlobalConfiguration().getFileEncoding();
   FileOutputStream fos = new FileOutputStream(target);
   OutputStreamWriter osw = new OutputStreamWriter(fos, encoding);
   PrintWriter pw = new PrintWriter(osw);
   pw.println("<!-- Generated by Quick Sequence Diagram Editor -->");
   pw.println("<!-- encoding: " + encoding + " -->");
   pw.println(
       "<!-- You may append '#!href=\"<url>\"' to an object declaration\nin order to set"
           + " the 'href' attribute of an AREA tag -->");
   pw.println("<map id=\"" + mapName + "\" name=\"" + mapName + "\">");
   for (Lifeline lifeline : diagram.getAllLifelines()) {
     String annotation = textHandler.getAnnotation(lifeline);
     String file = lifeline.getName();
     if (annotation != null) {
       String href[] = Grep.parse("^.*?href=\"(.*?)\".*$", annotation);
       if (href != null) {
         file = href[0];
       }
     }
     Drawable drawable = lifeline.getHead();
     int x1 = drawable.getLeft();
     int y1 = drawable.getTop();
     int x2 = drawable.getRight();
     int y2 = drawable.getBottom();
     String coords = x1 + "," + y1 + "," + x2 + "," + y2;
     pw.println("  <area shape=\"rect\" coords=\"" + coords + "\"" + " href=\"" + file + "\"/>");
   }
   pw.println("</map>");
   pw.flush();
   pw.close();
 }
예제 #3
0
 /**
  * If the current line specifies an association of a note to the current vertical position of a
  * lifeline, this method returns a pair consisting of the lifeline and the note number.
  *
  * @return a pair of a lifeline and a note number, if the current line specifies and association
  *     between the note and the lifeline, otherwise <tt>null</tt>
  */
 public Pair<Lifeline, Integer> getEventAssociation() throws SyntaxError {
   if (section == 0) {
     throw new IllegalStateException("not all objects have been read");
   }
   if (currentLine() == null) {
     throw new IllegalStateException("nothing to read");
   }
   String[] parts = grep.parse("\\((\\d+)\\)\\s*(\\w+)", currentLine());
   if (parts == null) {
     return null;
   }
   int number = Integer.parseInt(parts[0]);
   String obj = parts[1];
   Lifeline line = diagram.getLifeline(obj);
   if (line == null) {
     throw new SyntaxError(this, obj + " does not exist");
   }
   return new Pair<Lifeline, Integer>(line, number);
 }
예제 #4
0
  /**
   * If there is a note specified at the current line and the subsequent lines, a {@linkplain Note}
   * representation is returned, otherwise <tt>null</tt>
   *
   * @return a note, if one is specified at the current position in text, otherwise <tt>null</tt>
   */
  public Note getNote() throws SyntaxError {
    if (section == 0) {
      throw new IllegalStateException("not all objects have been read");
    }
    if (currentLine() == null) {
      throw new IllegalStateException("nothing to read");
    }
    String[] parts = grep.parse("\\s*(\\*|\\+)(\\d+)\\s*(.+)", currentLine());
    if (parts == null) {
      return null;
    }
    boolean consuming = parts[0].equals("+");
    int number = -1;
    try {
      number = Integer.parseInt(parts[1]);
    } catch (NumberFormatException nfe) {
      /* empty */
    }
    if (number < 0) {
      throw new SyntaxError(this, "bad note number: " + parts[1]);
    }
    String obj = parts[2];
    Lifeline line = diagram.getLifeline(obj);
    if (line == null) {
      throw new SyntaxError(this, obj + " does not exist");
    }
    int oldBegin = getLineBegin();
    int oldEnd = getLineEnd();
    line = line.getRightmost();
    List<String> desc = new LinkedList<String>();
    boolean more;
    do {
      if (!advance(false)) {
        reset(oldBegin, oldEnd);
        throw new SyntaxError(this, "The note is not closed.");
      }
      more = !currentLine().trim().equals(parts[0] + parts[1]);
    } while (more && desc.add(currentLine()));
    if (desc.size() == 0) {
      reset(oldBegin, oldEnd);
      throw new SyntaxError(this, "The note is empty.");
    }
    String[] noteText = desc.toArray(new String[0]);
    URI link = null;
    if (noteText.length == 1) {
      String linkString = noteText[0].trim();

      if (linkString.startsWith("link:")) {
        try {
          linkString = linkString.substring(5).trim();

          link = new URI(linkString);
          if (link.getPath() == null) {
            throw new SyntaxError(this, "Empty path in URI: " + linkString);
          }
          noteText[0] = link.getPath();

        } catch (URISyntaxException e) {
          throw new SyntaxError(this, "Bad URI syntax: " + e.getMessage());
        }
      }
    }
    Note note = new Note(line, number, noteText, consuming);
    note.setLink(link);
    return note;
  }
예제 #5
0
  /**
   * Returns the {@linkplain Lifeline} object made from the current line}.
   *
   * @return the {@linkplain Lifeline} object made from the current line
   * @throws SyntaxError if the next object declaration is not well-formed
   */
  public Lifeline nextObject() throws SyntaxError {
    if (section == 1) {
      throw new IllegalStateException("reading objects has already been finished");
    }
    if (currentLine() == null) {
      throw new IllegalStateException("nothing to read");
    }
    if (currentLine().indexOf(':') == -1) {
      throw new SyntaxError(this, "not a valid object declaration - ':' missing");
    }
    ArrayList<Region> regions = new ArrayList<Region>();
    String[] parts =
        grep.parse("(\\/?.+?):([^\\[\\]]+?)\\s*(\\[.*?\\]|)\\s*(\".*\"|)", currentLine(), regions);
    if (parts == null || parts.length != 4) {
      String msg;
      if (currentLine().indexOf('.') >= 0) {
        msg =
            "not a valid object declaration, perhaps you forgot to "
                + "enter an empty line before the message section";
      } else {
        msg = "not a valid object declaration";
      }
      throw new SyntaxError(this, msg);
    }
    setCurrentLine(null);
    String name = parts[0];
    String type = parts[1];
    String flags = parts[2];
    String label = parts[3];
    if (!label.equals("")) {
      label = label.substring(1, label.length() - 1);
    }

    boolean anon = flags.indexOf('a') >= 0;
    boolean role = flags.indexOf('r') >= 0;
    boolean process = flags.indexOf('p') >= 0;
    boolean hasThread = flags.indexOf('t') >= 0;
    boolean autoDestroy = flags.indexOf('x') >= 0;
    boolean external = flags.indexOf('e') >= 0;
    boolean saveSpace = reuseSpace && flags.indexOf('f') == -1;

    Lifeline lifeline;

    //		if (external && !process) {
    //			throw new SyntaxError(this,
    //					"only processes can be declared external");
    //		}

    if (name.startsWith("/")) {
      if (type.equals("Actor") || process) {
        throw new SyntaxError(this, "processes and actors must be visible");
      }
      /*
      if (hasThread) {
      	throw new SyntaxError(this,
      			"invisible objects cannot have their own thread");
      }*/
      lifeline =
          new Lifeline(
              name.substring(1),
              type,
              label,
              false,
              anon,
              role,
              false,
              false,
              autoDestroy,
              external,
              saveSpace,
              diagram);
    } else {

      if (type.equals("Actor")) {
        if (anon) {
          throw new SyntaxError(this, "actors cannot be anonymous");
        }
      }
      if ((type.equals("Actor") || process) && hasThread) {
        throw new SyntaxError(this, "actors cannot have their own thread");
      }
      if ((type.equals("Actor") || process) && autoDestroy) {
        throw new SyntaxError(this, "actors cannot be (automatically) destroyed");
      }

      lifeline =
          new Lifeline(
              parts[0],
              parts[1],
              label,
              true,
              anon,
              role,
              process,
              hasThread,
              autoDestroy,
              external,
              false,
              diagram);
    }

    lifeline.setNameRegion(regions.get(0));

    int cmt = rawLine().indexOf("#!");
    if (cmt >= 0 && cmt + 2 < rawLine().length() - 1) {
      String annotation = rawLine().substring(cmt + 2).trim();
      annotations.put(lifeline, annotation);
    }

    return lifeline;
  }