diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/.classpath b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/.classpath
new file mode 100644
index 0000000..3195ced
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/.classpath
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/.project b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/.project
new file mode 100644
index 0000000..e31a4db
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/.project
@@ -0,0 +1,17 @@
+
+
+ VioletPlugin.ObjectDiagrams
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/.settings/org.eclipse.jdt.core.prefs b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..838bd9d
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/horstmann.eclipse.code.formatter.xml b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/horstmann.eclipse.code.formatter.xml
new file mode 100644
index 0000000..bef0923
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/horstmann.eclipse.code.formatter.xml
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/pom.xml b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/pom.xml
new file mode 100644
index 0000000..95fec3d
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/pom.xml
@@ -0,0 +1,62 @@
+
+
+ 4.0.0
+ com.horstmann.violet.plugin
+ com.horstmann.violet.plugin.objectdiagram
+ Violet UML Editor Object Diagram Plugin
+ 2.0.0-SNAPSHOT
+
+ jar
+
+
+ com.horstmann.violet.framework
+ com.horstmann.violet.framework
+ 2.0.0-SNAPSHOT
+
+
+
+
+
+ src/main/resources
+
+
+ src/main/java
+
+ **/*.gif
+ **/*.jpg
+ **/*.properties
+ **/*.xml
+
+
+
+
+
+ maven-compiler-plugin
+ 2.0.2
+
+
+ 1.6
+
+
+
+
+
+
+ web.sourceforge.net
+ Violet's Maven Repository
+
+ sftp://web.sourceforge.net/home/groups/v/vi/violet/htdocs/maven2/repo
+
+
+
+
+
+ violet.repo
+ Violet's Maven repository (public access)
+ http://violet.sourceforge.net/maven2/repo/
+
+
+
\ No newline at end of file
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/FieldNode.java b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/FieldNode.java
new file mode 100644
index 0000000..accbd80
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/FieldNode.java
@@ -0,0 +1,324 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.product.diagram.object;
+
+import java.awt.Graphics2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.List;
+
+import com.horstmann.violet.product.diagram.abstracts.edge.IEdge;
+import com.horstmann.violet.product.diagram.abstracts.node.INode;
+import com.horstmann.violet.product.diagram.abstracts.node.RectangularNode;
+import com.horstmann.violet.product.diagram.abstracts.property.MultiLineString;
+
+/**
+ * A field node in an object diagram.
+ */
+public class FieldNode extends RectangularNode
+{
+ /**
+ * Default constructor
+ */
+ public FieldNode()
+ {
+ name = new MultiLineString();
+ name.setJustification(MultiLineString.RIGHT);
+ value = new MultiLineString();
+ equalSeparator = new MultiLineString();
+ equalSeparator.setText(" = ");
+ setZ(1);
+ }
+
+ @Override
+ public Point2D getLocation()
+ {
+ Point2D location = new Point2D.Double(this.horizontalLocation, this.verticalLocation);
+ Point2D snappedLocation = getGraph().getGrid().snap(location);
+ return snappedLocation;
+ }
+
+
+
+ private void adjustVerticalLocation() {
+ this.verticalLocation = 0;
+ INode parent = getParent();
+ if (parent == null) {
+ return;
+ }
+ List children = parent.getChildren();
+ ObjectNode parentNode = (ObjectNode) parent;
+ Rectangle2D topRectangle = parentNode.getTopRectangle();
+ this.verticalLocation = topRectangle.getHeight();
+ for (INode node : children) {
+ if (node == this) {
+ return;
+ }
+ Rectangle2D bounds = node.getBounds();
+ double nodeHeight = bounds.getHeight();
+ this.verticalLocation = this.verticalLocation + nodeHeight + YGAP;
+ }
+ }
+
+ private void adjustHorizontalLocation() {
+ this.horizontalLocation = 0;
+ double maxWidth = 0;
+ INode parent = getParent();
+ if (parent == null) {
+ return;
+ }
+ for (INode node : parent.getChildren()) {
+ if (node == this) {
+ continue;
+ }
+ if (!node.getClass().isAssignableFrom(FieldNode.class)) {
+ continue;
+ }
+ Rectangle2D bounds = node.getBounds();
+ double nodeWidth = bounds.getWidth();
+ maxWidth = Math.max(maxWidth, nodeWidth);
+ }
+ Rectangle2D currentBounds = getBounds();
+ double currentWidth = currentBounds.getWidth();
+ if (currentWidth < maxWidth) {
+ this.horizontalLocation = (maxWidth - currentWidth) / 2;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.horstmann.violet.framework.INode#draw(java.awt.Graphics2D)
+ */
+ public void draw(Graphics2D g2)
+ {
+ adjustHorizontalLocation();
+ adjustVerticalLocation();
+ // Translate g2 if node has parent
+ Point2D nodeLocationOnGraph = getLocationOnGraph();
+ Point2D nodeLocation = getLocation();
+ Point2D g2Location = new Point2D.Double(nodeLocationOnGraph.getX() - nodeLocation.getX(), nodeLocationOnGraph.getY() - nodeLocation.getY());
+ g2.translate(g2Location.getX(), g2Location.getY());
+ // Perform drawing
+ Rectangle2D b = getBounds();
+ name.draw(g2, getNameBounds());
+ equalSeparator.draw(g2, getEqualSeparatorBounds());
+ value.draw(g2, getValueBounds());
+ // Restore g2 original location
+ g2.translate(-g2Location.getX(), -g2Location.getY());
+ }
+
+ @Override
+ public boolean addConnection(IEdge e)
+ {
+ INode endingINode = e.getEnd();
+ if (e.getClass().isAssignableFrom(ObjectReferenceEdge.class) && endingINode.getClass().isAssignableFrom(ObjectNode.class))
+ {
+ value.setText("");
+ return true;
+ }
+ // Hack to allow drawing relationship edge over fields
+ if (e.getClass().isAssignableFrom(ObjectRelationshipEdge.class)) {
+ INode startingNode = e.getStart();
+ INode endingNode = e.getEnd();
+ if (startingNode.getClass().isAssignableFrom(FieldNode.class)) {
+ startingNode = startingNode.getParent();
+ }
+ if (endingNode.getClass().isAssignableFrom(FieldNode.class)) {
+ endingNode = endingNode.getParent();
+ }
+ e.setStart(startingNode);
+ e.setEnd(endingNode);
+ return getParent().addConnection(e);
+ }
+ return false;
+ }
+
+ /**
+ * Hack to be able to add fields on object when we do a single click on another field
+ * READ THIS : due to this hack, when you dble click to edit this field, the first click
+ * triggers this methods (which is a correct framework behavior). The workaround for end users
+ * is to use right click instead of dble click to edit fields. It is so simple to find it
+ * so we accept to deal with this bug.
+ */
+ @Override
+ public boolean addChild(INode n, Point2D p)
+ {
+ if (!n.getClass().isAssignableFrom(FieldNode.class)) {
+ return false;
+ }
+ INode parent = getParent();
+ List parentChildren = parent.getChildren();
+ int currentPosition = parentChildren.indexOf(this);
+ parent.addChild(n, currentPosition + 1);
+ return true;
+ }
+
+
+ @Override
+ public Point2D getConnectionPoint(IEdge edge)
+ {
+ Rectangle2D b = getBounds();
+ double parentX = 0;
+ double parentY = 0;
+ // This node has a location relative to its parent
+ // So, we need to take the parent's location in the connection point we return
+ INode parentNode = getParent();
+ if (parentNode != null) {
+ Point2D parentLocation = parentNode.getLocation();
+ parentX = parentLocation.getX();
+ parentY = parentLocation.getY();
+ }
+ return new Point2D.Double(parentX + (b.getMaxX() + b.getX() + getAxisX()) / 2, parentY + b.getCenterY());
+ }
+
+ private Rectangle2D getNameBounds() {
+ Rectangle2D nameBounds = name.getBounds();
+ Point2D currentLocation = getLocation();
+ double x = currentLocation.getX();
+ double y = currentLocation.getY();
+ double w = nameBounds.getWidth();
+ double h = nameBounds.getHeight();
+ nameBounds = new Rectangle2D.Double(x, y, w, h);
+ Rectangle2D snappedBounds = getGraph().getGrid().snap(nameBounds);
+ return snappedBounds;
+ }
+
+ private Rectangle2D getEqualSeparatorBounds() {
+ Rectangle2D equalsSeparatorBounds = equalSeparator.getBounds();
+ Rectangle2D nameBounds = getNameBounds();
+ double x = nameBounds.getMaxX();
+ double y = nameBounds.getY();
+ double w = equalsSeparatorBounds.getWidth();
+ double h = equalsSeparatorBounds.getHeight();
+ equalsSeparatorBounds = new Rectangle2D.Double(x, y, w, h);
+ Rectangle2D snappedBounds = getGraph().getGrid().snap(equalsSeparatorBounds);
+ return snappedBounds;
+ }
+
+ private Rectangle2D getValueBounds() {
+ Rectangle2D valueBounds = value.getBounds();
+ Rectangle2D equalSeparatorBounds = getEqualSeparatorBounds();
+ double x = equalSeparatorBounds.getMaxX();
+ double y = equalSeparatorBounds.getY();
+ double w = valueBounds.getWidth();
+ double h = valueBounds.getHeight();
+ valueBounds = new Rectangle2D.Double(x, y, w, h);
+ Rectangle2D snappedBounds = getGraph().getGrid().snap(valueBounds);
+ return snappedBounds;
+ }
+
+ @Override
+ public Rectangle2D getBounds()
+ {
+ Rectangle2D nameBounds = getNameBounds();
+ Rectangle2D valueBounds = getValueBounds();
+ Rectangle2D equalSeparatorBounds = getEqualSeparatorBounds();
+ nameBounds.add(equalSeparatorBounds);
+ nameBounds.add(valueBounds);
+ double x = nameBounds.getX();
+ double y = nameBounds.getY();
+ double w = Math.max(nameBounds.getWidth(), DEFAULT_WIDTH);
+ double h = Math.max(nameBounds.getHeight(), DEFAULT_HEIGHT);
+ Rectangle2D globalBounds = new Rectangle2D.Double(x, y, w, h);
+ Rectangle2D snappedBounds = getGraph().getGrid().snap(globalBounds);
+ return snappedBounds;
+ }
+
+
+ /**
+ * Sets the name property value.
+ *
+ * @param newValue the field name
+ */
+ public void setName(MultiLineString newValue)
+ {
+ name = newValue;
+ }
+
+ /**
+ * Gets the name property value.
+ *
+ * @return the field name
+ */
+ public MultiLineString getName()
+ {
+ return name;
+ }
+
+ /**
+ * Sets the value property value.
+ *
+ * @param newValue the field value
+ */
+ public void setValue(MultiLineString newValue)
+ {
+ value = newValue;
+ }
+
+ /**
+ * Gets the value property value.
+ *
+ * @return the field value
+ */
+ public MultiLineString getValue()
+ {
+ return value;
+ }
+
+ /**
+ * Gets the x-offset of the axis (the location of the = sign) from the left corner of the bounding rectangle.
+ *
+ * @return the x-offset of the axis
+ */
+ public double getAxisX()
+ {
+ Rectangle2D nameBounds = getNameBounds();
+ Rectangle2D equalSeparatorBounds = getEqualSeparatorBounds();
+ double leftWidth = nameBounds.getWidth();
+ double middleWidth = equalSeparatorBounds.getWidth();
+ return leftWidth + middleWidth / 2;
+ }
+
+ @Override
+ public FieldNode clone()
+ {
+ FieldNode cloned = (FieldNode) super.clone();
+ cloned.name = (MultiLineString) name.clone();
+ cloned.value = (MultiLineString) value.clone();
+ return cloned;
+ }
+
+ private MultiLineString name;
+ private MultiLineString value;
+ private MultiLineString equalSeparator;
+
+ private static int DEFAULT_WIDTH = 60;
+ private static int DEFAULT_HEIGHT = 20;
+ private static int XGAP = 5;
+ private static int YGAP = 5;
+
+ private transient double verticalLocation = 0;
+ private transient double horizontalLocation = 0;
+
+
+}
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectDiagramConstant.java b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectDiagramConstant.java
new file mode 100644
index 0000000..2b6e0d9
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectDiagramConstant.java
@@ -0,0 +1,8 @@
+package com.horstmann.violet.product.diagram.object;
+
+public interface ObjectDiagramConstant
+{
+
+ public static final String OBJECT_DIAGRAM_STRINGS = "properties.ObjectDiagramGraphStrings";
+
+}
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectDiagramGraph.java b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectDiagramGraph.java
new file mode 100644
index 0000000..8a788a9
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectDiagramGraph.java
@@ -0,0 +1,95 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.product.diagram.object;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import com.horstmann.violet.product.diagram.abstracts.AbstractGraph;
+import com.horstmann.violet.product.diagram.abstracts.edge.IEdge;
+import com.horstmann.violet.product.diagram.abstracts.node.INode;
+import com.horstmann.violet.product.diagram.abstracts.property.MultiLineString;
+import com.horstmann.violet.product.diagram.common.DiagramLinkNode;
+import com.horstmann.violet.product.diagram.common.NoteEdge;
+import com.horstmann.violet.product.diagram.common.NoteNode;
+
+/**
+ * An UML-style object diagram that shows object references.
+ */
+public class ObjectDiagramGraph extends AbstractGraph
+{
+ public List getNodePrototypes()
+ {
+ return NODE_PROTOTYPES;
+ }
+
+ public List getEdgePrototypes()
+ {
+ return EDGE_PROTOTYPES;
+ }
+
+ private static final List NODE_PROTOTYPES = new ArrayList();
+
+ private static final List EDGE_PROTOTYPES = new ArrayList();
+
+ static
+ {
+ ResourceBundle rs = ResourceBundle.getBundle(ObjectDiagramConstant.OBJECT_DIAGRAM_STRINGS, Locale.getDefault());
+
+ ObjectNode node0 = new ObjectNode();
+ node0.setToolTip(rs.getString("node0.tooltip"));
+ NODE_PROTOTYPES.add(node0);
+
+ FieldNode node1 = new FieldNode();
+ node1.setToolTip(rs.getString("node1.tooltip"));
+ MultiLineString fn = new MultiLineString();
+ fn.setText("name");
+ node1.setName(fn);
+ MultiLineString fv = new MultiLineString();
+ fv.setText("value");
+ node1.setValue(fv);
+ NODE_PROTOTYPES.add(node1);
+
+ NoteNode node2 = new NoteNode();
+ node2.setToolTip(rs.getString("node2.tooltip"));
+ NODE_PROTOTYPES.add(node2);
+
+ DiagramLinkNode node3 = new DiagramLinkNode();
+ node3.setToolTip(rs.getString("node3.tooltip"));
+ NODE_PROTOTYPES.add(node3);
+
+ ObjectReferenceEdge reference = new ObjectReferenceEdge();
+ reference.setToolTip(rs.getString("edge0.tooltip"));
+ EDGE_PROTOTYPES.add(reference);
+
+ ObjectRelationshipEdge association = new ObjectRelationshipEdge();
+ association.setToolTip(rs.getString("edge1.tooltip"));
+ EDGE_PROTOTYPES.add(association);
+
+ NoteEdge noteEdge = new NoteEdge();
+ noteEdge.setToolTip(rs.getString("edge2.tooltip"));
+ EDGE_PROTOTYPES.add(noteEdge);
+ }
+
+}
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectDiagramPlugin.java b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectDiagramPlugin.java
new file mode 100644
index 0000000..884127c
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectDiagramPlugin.java
@@ -0,0 +1,105 @@
+package com.horstmann.violet.product.diagram.object;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import com.horstmann.violet.framework.plugin.IDiagramPlugin;
+import com.horstmann.violet.framework.plugin.extensionpoint.Violet016FileFilterExtensionPoint;
+import com.horstmann.violet.product.diagram.abstracts.IGraph;
+
+/**
+ * Describes object diagram graph type
+ *
+ * @author Alexandre de Pellegrin
+ *
+ */
+public class ObjectDiagramPlugin implements IDiagramPlugin, Violet016FileFilterExtensionPoint
+{
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.horstmann.violet.framework.plugin.AbstractPlugin#getDescription()
+ */
+ public String getDescription()
+ {
+ return "Object UML diagram";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.horstmann.violet.framework.plugin.AbstractPlugin#getProvider()
+ */
+ public String getProvider()
+ {
+ return "Alexandre de Pellegrin / Cays S. Horstmann";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.horstmann.violet.framework.plugin.AbstractPlugin#getVersion()
+ */
+ public String getVersion()
+ {
+ return "1.0.0";
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.horstmann.violet.product.diagram.abstracts.GraphType#getName()
+ */
+ public String getName()
+ {
+ return this.rs.getString("menu.object_diagram.text");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.horstmann.violet.product.diagram.abstracts.GraphType#getFileExtension()
+ */
+ public String getFileExtension()
+ {
+ return this.rs.getString("files.object.extension");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.horstmann.violet.product.diagram.abstracts.GraphType#getFileExtensionName()
+ */
+ public String getFileExtensionName()
+ {
+ return this.rs.getString("files.object.name");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.horstmann.violet.product.diagram.abstracts.GraphType#getGraphClass()
+ */
+ public Class extends IGraph> getGraphClass()
+ {
+ return ObjectDiagramGraph.class;
+ }
+
+ public Map getMappingToKeepViolet016Compatibility()
+ {
+ Map replaceMap = new HashMap();
+ replaceMap.put("com.horstmann.violet.ObjectDiagramGraph", ObjectDiagramGraph.class.getName());
+ replaceMap.put("com.horstmann.violet.FieldNode", FieldNode.class.getName());
+ replaceMap.put("com.horstmann.violet.ObjectNode", ObjectNode.class.getName());
+ replaceMap.put("com.horstmann.violet.ObjectReferenceEdge", ObjectReferenceEdge.class.getName());
+ replaceMap.put("com.horstmann.violet.ObjectRelationshipEdge", ObjectRelationshipEdge.class.getName());
+ return replaceMap;
+ }
+
+ ResourceBundle rs = ResourceBundle.getBundle(ObjectDiagramConstant.OBJECT_DIAGRAM_STRINGS, Locale.getDefault());
+
+
+}
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectNode.java b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectNode.java
new file mode 100644
index 0000000..5645a72
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectNode.java
@@ -0,0 +1,192 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.product.diagram.object;
+
+import java.awt.Graphics2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.List;
+
+import com.horstmann.violet.product.diagram.abstracts.Direction;
+import com.horstmann.violet.product.diagram.abstracts.edge.IEdge;
+import com.horstmann.violet.product.diagram.abstracts.node.INode;
+import com.horstmann.violet.product.diagram.abstracts.node.RectangularNode;
+import com.horstmann.violet.product.diagram.abstracts.property.MultiLineString;
+import com.horstmann.violet.product.diagram.common.PointNode;
+
+/**
+ * An object node in an object diagram.
+ */
+public class ObjectNode extends RectangularNode
+{
+ /**
+ * Construct an object node with a default size
+ */
+ public ObjectNode()
+ {
+ name = new MultiLineString();
+ name.setUnderlined(true);
+ name.setSize(MultiLineString.LARGE);
+ }
+
+ public void draw(Graphics2D g2)
+ {
+ super.draw(g2);
+ Rectangle2D globalBounds = getBounds();
+ Rectangle2D topBounds = getTopRectangle();
+ g2.draw(globalBounds);
+ name.draw(g2, topBounds);
+ g2.drawLine((int) globalBounds.getX(),(int) topBounds.getMaxY(),(int) globalBounds.getMaxX(),(int) topBounds.getMaxY());
+ for (INode n : getChildren()) {
+ n.draw(g2); // make sure they get drawn on top
+ }
+ }
+
+
+ /**
+ * Returns the rectangle at the top of the object node.
+ *
+ * @return the top rectangle
+ */
+ public Rectangle2D getTopRectangle()
+ {
+ Rectangle2D b = name.getBounds();
+ double defaultHeight = DEFAULT_HEIGHT;
+ boolean hasChildren = (getChildren().size() > 0);
+ if (hasChildren) {
+ defaultHeight = defaultHeight - YGAP;
+ }
+ Point2D currentLocation = getLocation();
+ double x = currentLocation.getX();
+ double y = currentLocation.getY();
+ double w = Math.max(b.getWidth(), DEFAULT_WIDTH);
+ double h = Math.max(b.getHeight(), DEFAULT_HEIGHT);
+ Rectangle2D topBounds = new Rectangle2D.Double(x, y, w, h);
+ topBounds = getGraph().getGrid().snap(topBounds);
+ return topBounds;
+ }
+
+ private Rectangle2D getBottomRectangle() {
+ Rectangle2D topBounds = getTopRectangle();
+ double topHeight = topBounds.getHeight();
+ Rectangle2D bottomBounds = new Rectangle2D.Double(0, topHeight, 0, 0);
+ for (INode node : getChildren()) {
+ Rectangle2D nodeBounds = node.getBounds();
+ bottomBounds.add(nodeBounds);
+ }
+ double x = topBounds.getX();
+ double y = topBounds.getMaxY();
+ double w = bottomBounds.getWidth();
+ double h = bottomBounds.getHeight();
+ bottomBounds.setFrame(x, y, w, h);
+ bottomBounds = getGraph().getGrid().snap(bottomBounds);
+ return bottomBounds;
+ }
+
+ @Override
+ public Rectangle2D getBounds()
+ {
+ Rectangle2D topBounds = getTopRectangle();
+ Rectangle2D bottomBounds = getBottomRectangle();
+ topBounds.add(bottomBounds);
+ topBounds = getGraph().getGrid().snap(topBounds);
+ return topBounds;
+ }
+
+ public boolean addConnection(IEdge e)
+ {
+ if (!e.getClass().isAssignableFrom(ObjectRelationshipEdge.class)) {
+ return false;
+ }
+ INode startingNode = e.getStart();
+ INode endingNode = e.getEnd();
+ if (startingNode.getClass().isAssignableFrom(FieldNode.class)) {
+ startingNode = startingNode.getParent();
+ }
+ if (endingNode.getClass().isAssignableFrom(FieldNode.class)) {
+ endingNode = endingNode.getParent();
+ }
+ e.setStart(startingNode);
+ e.setEnd(endingNode);
+ return true;
+ }
+
+ public Point2D getConnectionPoint(Direction d)
+ {
+ Rectangle2D topBounds = getTopRectangle();
+ double topHeight = topBounds.getHeight();
+ if (d.getX() > 0) {
+ return new Point2D.Double(getBounds().getMaxX(), getBounds().getMinY() + topHeight / 2);
+ }
+ return new Point2D.Double(getBounds().getX(), getBounds().getMinY() + topHeight / 2);
+ }
+
+
+ /**
+ * Sets the name property value.
+ *
+ * @param newValue the new object name
+ */
+ public void setName(MultiLineString n)
+ {
+ name = n;
+ }
+
+ /**
+ * Gets the name property value.
+ *
+ * @param the object name
+ */
+ public MultiLineString getName()
+ {
+ return name;
+ }
+
+ @Override
+ public boolean addChild(INode n, Point2D p)
+ {
+ List fields = getChildren();
+ if (!(n instanceof FieldNode)) return false;
+ if (fields.contains(n)) return true;
+ int i = 0;
+ while (i < fields.size() && fields.get(i).getLocation().getY() < p.getY())
+ i++;
+ addChild(n, i);
+ n.setGraph(getGraph());
+ n.setParent(this);
+ return true;
+ }
+
+
+ public ObjectNode clone()
+ {
+ ObjectNode cloned = (ObjectNode) super.clone();
+ cloned.name = name.clone();
+ return cloned;
+ }
+
+ private MultiLineString name;
+
+ private static int DEFAULT_WIDTH = 80;
+ private static int DEFAULT_HEIGHT = 60;
+ private static int YGAP = 5;
+}
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectReferenceEdge.java b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectReferenceEdge.java
new file mode 100644
index 0000000..db47119
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectReferenceEdge.java
@@ -0,0 +1,115 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.product.diagram.object;
+
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Line2D;
+import java.awt.geom.Point2D;
+
+import com.horstmann.violet.product.diagram.abstracts.Direction;
+import com.horstmann.violet.product.diagram.abstracts.edge.ShapeEdge;
+import com.horstmann.violet.product.diagram.abstracts.node.INode;
+import com.horstmann.violet.product.diagram.abstracts.property.ArrowHead;
+
+/**
+ * An S- or C-shaped edge with an arrowhead.
+ */
+public class ObjectReferenceEdge extends ShapeEdge
+{
+ public void draw(Graphics2D g2)
+ {
+ g2.draw(getShape());
+ Line2D line = getConnectionPoints();
+ double x1;
+ double x2 = line.getX2();
+ double y = line.getY2();
+ if (isSShaped()) x1 = x2 - ENDSIZE;
+ else x1 = x2 + ENDSIZE;
+ ArrowHead.BLACK_TRIANGLE.draw(g2, new Point2D.Double(x1, y), new Point2D.Double(x2, y));
+ }
+
+ public Shape getShape()
+ {
+ Line2D line = getConnectionPoints();
+
+ double y1 = line.getY1();
+ double y2 = line.getY2();
+ double xmid = (line.getX1() + line.getX2()) / 2;
+ double ymid = (line.getY1() + line.getY2()) / 2;
+ GeneralPath p = new GeneralPath();
+ if (isSShaped())
+ {
+ double x1 = line.getX1() + ENDSIZE;
+ double x2 = line.getX2() - ENDSIZE;
+
+ p.moveTo((float) line.getX1(), (float) y1);
+ p.lineTo((float) x1, (float) y1);
+ p.quadTo((float) ((x1 + xmid) / 2), (float) y1, (float) xmid, (float) ymid);
+ p.quadTo((float) ((x2 + xmid) / 2), (float) y2, (float) x2, (float) y2);
+ p.lineTo((float) line.getX2(), (float) y2);
+ }
+ else
+ // reverse C shaped
+ {
+ double x1 = Math.max(line.getX1(), line.getX2()) + ENDSIZE;
+ double x2 = x1 + ENDSIZE;
+ p.moveTo((float) line.getX1(), (float) y1);
+ p.lineTo((float) x1, (float) y1);
+ p.quadTo((float) x2, (float) y1, (float) x2, (float) ymid);
+ p.quadTo((float) x2, (float) y2, (float) x1, (float) y2);
+ p.lineTo((float) line.getX2(), (float) y2);
+ }
+ return p;
+ }
+
+
+ @Override
+ public Direction getDirection(INode node) {
+ // Case 1 : start node
+ if (node.equals(getStart())) {
+ return Direction.EAST;
+ }
+ // Case 2 : end node
+ if (isSShaped()) {
+ return Direction.WEST;
+ }
+ return Direction.EAST;
+ }
+
+ /**
+ * Tests whether the node should be S- or C-shaped.
+ *
+ * @return true if the node should be S-shaped
+ */
+ private boolean isSShaped()
+ {
+ // FIXME
+ return false;
+// Rectangle2D b = getEnd().getBounds();
+// Point2D p = getStart().getConnectionPoint(Direction.EAST);
+// return b.getX() >= p.getX() + 2 * ENDSIZE;
+ }
+
+ private static final int ENDSIZE = 10;
+}
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectRelationshipEdge.java b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectRelationshipEdge.java
new file mode 100644
index 0000000..e1f0d17
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectRelationshipEdge.java
@@ -0,0 +1,56 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.product.diagram.object;
+
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+
+import com.horstmann.violet.product.diagram.abstracts.edge.SegmentedLineEdge;
+import com.horstmann.violet.product.diagram.abstracts.property.BentStyle;
+
+
+/**
+ * An edge that is shaped like a line with up to three segments with an arrowhead
+ */
+public class ObjectRelationshipEdge extends SegmentedLineEdge
+{
+ /**
+ * Constructs a straight edge.
+ */
+ public ObjectRelationshipEdge()
+ {
+ setBentStyle(BentStyle.STRAIGHT);
+ }
+
+ private void setBentStyle(BentStyle straight) {
+ // TODO Auto-generated method stub tms
+
+ }
+
+ @Override
+ public ArrayList getPoints() {
+ // TODO Auto-generated method stub tms
+ return null;
+ }
+
+
+}
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectRelationshipEdgeBeanInfo.java b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectRelationshipEdgeBeanInfo.java
new file mode 100644
index 0000000..1d80196
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/com/horstmann/violet/product/diagram/object/ObjectRelationshipEdgeBeanInfo.java
@@ -0,0 +1,59 @@
+/*
+ Violet - A program for editing UML diagrams.
+
+ Copyright (C) 2007 Cay S. Horstmann (http://horstmann.com)
+ Alexandre de Pellegrin (http://alexdp.free.fr);
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package com.horstmann.violet.product.diagram.object;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.beans.SimpleBeanInfo;
+
+/**
+ * The bean info for the ClassRelationshipEdge type.
+ */
+public class ObjectRelationshipEdgeBeanInfo extends SimpleBeanInfo
+{
+
+ @Override
+ public PropertyDescriptor[] getPropertyDescriptors()
+ {
+ try
+ {
+ PropertyDescriptor[] descriptors = new PropertyDescriptor[]
+ {
+ new PropertyDescriptor("startLabel", ObjectRelationshipEdge.class),
+ new PropertyDescriptor("middleLabel", ObjectRelationshipEdge.class),
+ new PropertyDescriptor("endLabel", ObjectRelationshipEdge.class),
+ new PropertyDescriptor("bentStyle", ObjectRelationshipEdge.class),
+ };
+ for (int i = 0; i < descriptors.length; i++)
+ {
+ descriptors[i].setValue("priority", new Integer(i));
+ }
+ return descriptors;
+ }
+ catch (IntrospectionException exception)
+ {
+ exception.printStackTrace();
+ return null;
+ }
+ }
+
+}
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/main/resources/META-INF/services/com.horstmann.violet.framework.plugin.IDiagramPlugin b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/main/resources/META-INF/services/com.horstmann.violet.framework.plugin.IDiagramPlugin
new file mode 100644
index 0000000..e6844e7
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/main/resources/META-INF/services/com.horstmann.violet.framework.plugin.IDiagramPlugin
@@ -0,0 +1 @@
+com.horstmann.violet.product.diagram.object.ObjectDiagramPlugin
\ No newline at end of file
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/main/resources/properties/ObjectDiagramGraphStrings.properties b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/main/resources/properties/ObjectDiagramGraphStrings.properties
new file mode 100644
index 0000000..dd68f0d
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/main/resources/properties/ObjectDiagramGraphStrings.properties
@@ -0,0 +1,10 @@
+node0.tooltip=Object
+node1.tooltip=Field
+node2.tooltip=Note
+node3.tooltip=Linked diagram
+edge0.tooltip=Object reference (from field)
+edge1.tooltip=Association between objects
+edge2.tooltip=Note connector
+menu.object_diagram.text=Object diagram
+files.object.name=Object Diagram Files
+files.object.extension=.object.violet
\ No newline at end of file
diff --git a/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/main/resources/properties/ObjectDiagramGraphStrings_fr.properties b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/main/resources/properties/ObjectDiagramGraphStrings_fr.properties
new file mode 100644
index 0000000..35d0c56
--- /dev/null
+++ b/VioletPluginObjectDiagrams/VioletPlugin.ObjectDiagrams/src/main/resources/properties/ObjectDiagramGraphStrings_fr.properties
@@ -0,0 +1,10 @@
+node0.tooltip=Objet
+node1.tooltip=Champ
+node2.tooltip=Note
+node3.tooltip=Diagramme li\u00E9
+edge0.tooltip=R\u00E9f\u00E9rence \u00E0 l'objet (depuis un champ)
+edge1.tooltip=Association entre objets
+edge2.tooltip=Connection \u00E0 la note
+menu.object_diagram.text=Diagramme d'objet
+files.object.name=Diagramme d'objet
+files.object.extension=.object.violet