// Copyright (c) 2006 - 2008, Markus Strauch.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package net.sf.sdedit.diagram;
import java.awt.Point;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import net.sf.sdedit.drawable.Note;
import net.sf.sdedit.error.SyntaxError;
import net.sf.sdedit.message.Message;
import net.sf.sdedit.util.Pair;
public class NoteManager {
private final LinkedList<Note> notes;
private final Map<Integer, List<Message>> messageAssociation;
private final Map<Integer, List<Pair<Lifeline, Integer>>> eventAssociation;
private final Map<String, Note> pendingNotes;
private int freeNoteNumber;
private final Diagram diagram;
public NoteManager(Diagram diagram) {
this.diagram = diagram;
notes = new LinkedList<Note>();
messageAssociation = new HashMap<Integer, List<Message>>();
eventAssociation = new HashMap<Integer, List<Pair<Lifeline, Integer>>>();
freeNoteNumber = 0;
pendingNotes = new HashMap<String, Note>();
}
public void associateMessage(int number, Message msg) {
List<Message> msgs = messageAssociation.get(number);
if (msgs == null) {
msgs = new LinkedList<Message>();
messageAssociation.put(number, msgs);
}
msgs.add(msg);
}
public void computeArrowAssociations() {
for (Note description : notes) {
List<Message> msgs = messageAssociation
.get(description.getNumber());
if (msgs != null) {
for (Message msg : msgs) {
// This can be a pseudo-message ("_") that returns
// the control flow to an object.
// We just ignore the attempt to uselessly associate a
// note to this.
if (msg.getArrow() != null) {
description.addTarget(msg.getArrow().getAnchor());
}
}
}
List<Pair<Lifeline, Integer>> pairs = eventAssociation
.get(description.getNumber());
if (pairs != null) {
for (Pair<Lifeline, Integer> pair : pairs) {
int x = pair.getFirst().getView().getLeft()
+ pair.getFirst().getView().getWidth() / 2;
Point p = new Point(x, pair.getSecond());
description.addTarget(p);
}
}
}
}
public int getNextFreeNoteNumber() {
return freeNoteNumber;
}
private void associateEvent(Lifeline line, int descriptionNumber) {
List<Pair<Lifeline, Integer>> pairs = eventAssociation
.get(descriptionNumber);
if (pairs == null) {
pairs = new LinkedList<Pair<Lifeline, Integer>>();
eventAssociation.put(descriptionNumber, pairs);
}
pairs.add(new Pair<Lifeline, Integer>(line, diagram
.getVerticalPosition()));
}
/**
*
* @param lifeline
* the name of a lifeline that may have a non-consuming note box
* associated to it
*/
void closeNote(String lifeline) {
Note note = pendingNotes.get(lifeline);
if (note != null) {
int diff = note.getTop() + note.getHeight()
- diagram.getVerticalPosition();
if (diff > 0) {
diagram.extendLifelines(diff);
}
pendingNotes.remove(lifeline);
}
}
public boolean step() throws SyntaxError {
Note note = diagram.getDataProvider().getNote();
if (note != null) {
freeNoteNumber = Math.max(freeNoteNumber, note.getNumber() + 1);
diagram.getPaintDevice().addSequenceElement(note);
notes.add(note);
closeNote(note.getLocation().getName());
diagram.getFragmentManager().openFragments();
diagram.getPaintDevice().announce(note.getHeight());
note.setTop(diagram.getVerticalPosition());
if (note.isConsuming()) {
diagram.extendLifelines(note.getHeight());
} else {
pendingNotes.put(note.getLocation().getName(), note);
}
if (diagram.getDataProvider().getState() != null) {
diagram.addToStateMap(note, diagram.getDataProvider()
.getState());
}
diagram.getFragmentManager().clearLabels();
return true;
}
Pair<Lifeline, Integer> eventAssoc = diagram.getDataProvider()
.getEventAssociation();
if (eventAssoc != null) {
associateEvent(eventAssoc.getFirst(), eventAssoc.getSecond());
return true;
}
return false;
}
}