Sample

Schnappinger/argoUML/org.argouml.sequence2.diagram.FigMessage

Human rating uses the original dataset scale.

Human2.72
Lines499

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
14.7Δ 2.8
Scalabrino0.7760–1; higher is more readable
57.5Δ 40.0
Dorn0.0030–1; higher is more readable
13.9Δ 3.6
Mi0.5620–1; higher is more readable
46.9Δ 29.4
LLOC187Logical lines; fewer is more readable
14.2Δ 3.3
DeepSeek V4 Pro130–20; mean of three runs
21.1Δ 3.6
GPT-6.1 Sol140–20; mean of three runs
16.2Δ 1.3
BTTF0.2810–1; higher is more readable
19.5Δ 2.0
Human2.721–4; original rating
17.5

Views

Source code

/* $Id: FigMessage.java 19907 2012-12-30 13:06:01Z closettop_nightlybuild $ ***************************************************************************** * Copyright (c) 2009-2012 Contributors - see below * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * bobtarling * Michiel van der Wulp ***************************************************************************** * * Some portions of this file was previously release using the BSD License: */ // Copyright (c) 2007-2009 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation without fee, and without a written // agreement is hereby granted, provided that the above copyright notice // and this paragraph appear in all copies. This software program and // documentation are copyrighted by The Regents of the University of // California. The software program and documentation are supplied "AS // IS", without any accompanying services from The Regents. The Regents // does not warrant that the operation of the program will be // uninterrupted or error-free. The end-user understands that the program // was developed for research purposes and is advised not to rely // exclusively on the program for any reason. IN NO EVENT SHALL THE // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, // UPDATES, ENHANCEMENTS, OR MODIFICATIONS. package org.argouml.sequence2.diagram; import java.awt.Color; import java.awt.Point; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JSeparator; import org.argouml.model.Model; import org.argouml.model.UmlChangeEvent; import org.argouml.notation.Notation; import org.argouml.notation.NotationProvider; import org.argouml.notation.NotationProviderFactory2; import org.argouml.notation.SDNotationSettings; import org.argouml.ui.ArgoJMenu; import org.argouml.uml.diagram.DiagramSettings; import org.argouml.uml.diagram.ui.FigEdgeModelElement; import org.argouml.uml.diagram.ui.FigTextGroup; import org.argouml.uml.diagram.ui.PathItemPlacement; import org.tigris.gef.base.Selection; import org.tigris.gef.presentation.ArrowHead; import org.tigris.gef.presentation.ArrowHeadGreater; import org.tigris.gef.presentation.ArrowHeadTriangle; import org.tigris.gef.presentation.Fig; import org.tigris.gef.presentation.FigNode; import org.tigris.gef.presentation.FigPoly; import org.tigris.gef.presentation.FigText; /** * The Fig that represents a message between classifier roles. * @author penyaskito */ public class FigMessage extends FigEdgeModelElement { private static final long serialVersionUID = -2961220746360335159L; private static final Logger LOG = Logger.getLogger(FigEdgeModelElement.class.getName()); private FigTextGroup textGroup; /** * The action owned by the message */ private Object action = null; private SDNotationSettings notationSettings; private boolean t[] = { false, false, false, false, false, false, false, false }; /** * Construct a fig owned by the given UML element with the provided render * settings. * @param edge owning UML element * @param settings rendering settings */ public FigMessage(Object edge, DiagramSettings settings) { super(edge, settings); textGroup = new FigTextGroup(edge, settings); initialize(); action = Model.getFacade().getAction(getOwner()); updateArrow(); if (action != null) { addElementListener(action, "isAsynchronous"); } t[1] = Model.getFacade().isASynchCallMessage(getOwner()); t[2] = Model.getFacade().isAASynchCallMessage(getOwner()); t[3] = Model.getFacade().isACreateMessage(getOwner()); t[4] = Model.getFacade().isADeleteMessage(getOwner()); t[5] = Model.getFacade().isAReplyMessage(getOwner()); t[6] = Model.getFacade().isAASynchSignalMessage(getOwner()); } private void initialize() { textGroup.addFig(getNameFig()); textGroup.addFig(getStereotypeFig()); addPathItem(textGroup, new PathItemPlacement(this, textGroup, 50, 10)); notationSettings = new SDNotationSettings(); } @Override protected int getNotationProviderType() { /* Use a different notation as Messages on a collaboration diagram: */ return NotationProviderFactory2.TYPE_SD_MESSAGE; } /* This next argument may be used to switch off * the generation of sequence numbers - this is * still to be implemented. * They are less desired in sequence diagrams, * since they do not add any information. * In collaboration diagrams they are needed, * and they are still optional in sequence diagrams. */ @Override protected void initNotationProviders(Object own) { super.initNotationProviders(own); notationSettings.setShowSequenceNumbers(false); } @Override protected void textEditStarted(FigText ft) { /* This is a temporary hack until the notation provider * for a SD Message will be able to parse successfully when the sequence * number is missing. * Remove this method completely then.*/ notationSettings.setShowSequenceNumbers(true); super.textEditStarted(ft); notationSettings.setShowSequenceNumbers(false); } protected SDNotationSettings getNotationSettings() { return notationSettings; } boolean isSynchCallMessage() { return t[1]; } boolean isASynchCallMessage() { return t[2]; } boolean isCreateMessage() { return t[3]; } boolean isDeleteMessage() { return t[4]; } boolean isReplyMessage() { return t[5]; } boolean isASynchSignalMessage() { return t[6]; } /** * Updates the arrow head and the arrow line according * to the action type.. */ private void updateArrow() { if (getOwner() == null) { return; } getFig().setDashed(isReplyMessage()); final Object act = getAction(); final ArrowHead arrowHead; if (act != null && Model.getFacade().isAsynchronous(getAction())) { arrowHead = new ArrowHeadGreater(); } else { arrowHead = new ArrowHeadTriangle(); getFig().setFillColor(getLineColor()); } setDestArrowHead(arrowHead); } /** * Gets the action attached to the message. * @return the action */ private Object getAction() { return action; } /** * @param me the MouseEvent that triggered the popup menu request * @return a Vector containing a combination of these 4 types: Action, * JMenu, JMenuItem, JSeparator. */ @Override public Vector getPopUpActions(MouseEvent me) { Vector popUpActions = super.getPopUpActions(me); // Operations ... if (Model.getFacade().isACallAction(getAction())) { ArgoJMenu opMenu = buildOperationMenu(); int index = popUpActions.size() - getPopupAddOffset() - 1; if (index < 0) { index = 0; } popUpActions.add(index, new JSeparator()); popUpActions.add(index, opMenu); } return popUpActions; } protected ArgoJMenu buildOperationMenu() { ArgoJMenu opMenu = new ArgoJMenu("Operation"); Iterator<Object> iter = getReceiverOperations().iterator(); opMenu.setEnabled(iter.hasNext()); while (iter.hasNext()) { Object op = iter.next(); NotationProvider np = null; try { String s = getNotationSettings().getNotationLanguage(); np = NotationProviderFactory2.getInstance() .getNotationProvider( NotationProviderFactory2.TYPE_OPERATION, op, Notation.findNotation(s)); } catch (Exception e) { //TODO: add logging, but this will never happen and is handled np = null; } String label = (np != null) ? np.toString(op, getNotationSettings()) : Model.getFacade().getName(op); opMenu.add(new ActionSetOperation(getAction(), op, label)); } return opMenu; } @Override public Selection makeSelection() { return new SelectionMessage(this); } /* * @see org.tigris.gef.presentation.FigEdge#setFig(org.tigris.gef.presentation.Fig) */ public void setFig(Fig f) { super.setFig(f); updateArrow(); } int getFinalY() { int finalY = 0; Point[] points = getFig().getPoints(); if (points.length > 0) { finalY = points[points.length - 1].y; } return finalY; } int getStartY() { int finalY = 0; Point[] points = getFig().getPoints(); if (points.length > 0) { finalY = points[0].y; } return finalY; } /** * Checks if the message source and dest are the same. * @return true if they are the same, otherwise false. */ boolean isSelfMessage() { // If possible we determine this by checking the destination // and source Figs are the same. If this is not possible // because the edge is not yet connected then we check the // model. if (getDestPortFig() == null || getSourcePortFig() == null) { return getDestination().equals(getSource()); } else { return (getDestPortFig().equals(getSourcePortFig())); } } /** * Converts the message into a spline. * This is needed for self-referencing messages. */ public void convertToArc() { if (getPoints().length > 0) { FigMessageSpline spline = new FigMessageSpline(getPoint(0)); spline.setDashed(isReplyMessage()); super.setFig(spline); computeRoute(); } } @Override public void computeRouteImpl() { super.computeRouteImpl(); updateActivations(); } public void calcBounds() { final FigPoly fp = (FigPoly) getFig(); final FigNode node = getSourceFigNode(); if (node != null && isSelfMessage() && fp.isComplete()) { // TODO: calcBounds is called by SelectionManager when the Fig is // dragged. This code is needed to reposition any self message // as they are become detached from their classifier role // (see issue 5562). The cause of the detachment is not yet // understood. // Unfortunately calcBounds is called from several other places // so the code here is not optimal but is the best workaround until // ArgoUML can provide its own replacement SelectionManager for // sequence diagram requirements // See - http://gef.tigris.org/issues/show_bug.cgi?id=344 final int x = node.getX() + (node.getWidth() + FigActivation.DEFAULT_WIDTH) / 2; final Point startPoint = new Point(x, getYs()[0]); final FigMessageSpline spline = new FigMessageSpline(startPoint); spline.setComplete(true); spline.setDashed(isReplyMessage()); super.setFig(spline); } super.calcBounds(); } private synchronized void updateActivations() { // we update the activations... FigClassifierRole source = (FigClassifierRole) getSourceFigNode(); if (source != null) { source.createActivations(); } // for performance, we check if this is a selfmessage // if it is, we have just updated the activations if (!isSelfMessage()) { FigClassifierRole dest = (FigClassifierRole) getDestFigNode(); if (dest != null) { dest.createActivations(); } } } @Override public void setLineColor(Color c) { super.setLineColor(c); getDestArrowHead().setFillColor(c); } @Override public void deleteFromModel() { ((FigClassifierRole) getSourceFigNode()).createActivations(); if (!isSelfMessage()) { ((FigClassifierRole) getDestFigNode()).createActivations(); } super.deleteFromModel(); } /** * The default behaviour from FigEdgeModelElement is not correct * here. See issue 5005. TODO: We must determine what to do here but for * now doing nothing is better. I'm not sure why the super method would * not work as I would expect that to do nothing if the ends are already * correct. * @return true at all times for now */ @Override protected boolean determineFigNodes() { return true; } @Override public void translate(int dx, int dy) { if (isSelfMessage()) { ((FigMessageSpline) getFig()).translateFig(dx, dy); } super.translate(dx, dy); } /** * {@inheritDoc} * @see org.argouml.uml.diagram.ui.FigEdgeModelElement#updateLayout(org.argouml.model.UmlChangeEvent) */ @Override public void updateLayout(UmlChangeEvent event) { if ("isAsynchronous".equals(event.getPropertyName())) { updateArrow(); } super.updateLayout(event); } /* * Overridden purely to keep our superclass from removing the listener * that we just added. * * @see org.argouml.uml.diagram.ui.FigEdgeModelElement#updateListeners(java.lang.Object, java.lang.Object) */ @Override protected void updateListeners(Object oldOwner, Object newOwner ) { action = Model.getFacade().getAction(newOwner); Set<Object[]> listeners = new HashSet<Object[]>(); Object action = getAction(); listeners.add(new Object[] {getOwner(), "remove"}); if (action != null) { listeners.add(new Object[] {action, "isAsynchronous"}); } try { updateElementListeners(listeners); } catch (Exception e) { // This call seems not very robust. Yet to determine cause. LOG.log(Level.SEVERE, "Exception caught", e); } } private Collection<Object> getReceiverOperations() { ArrayList<Object> opList = new ArrayList<Object>(); Object action = getAction(); Object receiver = Model.getFacade().getReceiver(getOwner()); if (action != null && receiver != null) { //TODO: What can we do with other kind of actions? if (Model.getFacade().isACallAction(action)) { Iterator bases = Model.getFacade().getBases(receiver).iterator(); while (bases.hasNext()) { Object base = bases.next(); opList.addAll(Model.getFacade().getOperations(base)); } } } return opList; } /** * Determines the activator of this message based on the message position * in relation to other messages. * <p>Currently this only manages return messages. Any other message type * returns with no action taking place. * <p>The activator is set to the first call or create message found above * this message. * @return the activator that has been applied to the message. */ public Object determineActivator() { final FigClassifierRole fcr = (FigClassifierRole) getSourceFigNode(); final List<FigMessage> messageFigs = fcr.getFigMessages(); final Iterator<FigMessage> it = messageFigs.iterator(); Object activator = null; while (it.hasNext()) { FigMessage messageFig = it.next(); if ((messageFig.isCreateMessage() || messageFig.isSynchCallMessage()) && messageFig.getDestFigNode() == fcr) { activator = messageFig.getOwner(); } else if (messageFig == this) { Model.getCollaborationsHelper().setActivator( getOwner(), activator); return activator; } else if (messageFig.isReplyMessage()) { activator = null; } } return null; } }

Loading feature diagnosis…

Source regions

Feature contributions

Feature contributions

FeatureValueContribution
(log-odds)
Halstead volumeHow much symbolic information the code contains. It combines the total number of operators and values with the number of distinct ones.17135.715−565.479
Source linesThe number of non-empty source lines.499+199.6
Byte entropyHow varied the bytes in the source text are. Repeated bytes give a lower value; a more even mixture gives a higher value.4.767−7.15

Intercept 8.87 + feature contributions = -364.158 (log-odds).
Score = sigmoid(-364.158) = 0.

Score0.776

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.500−16.667
Indentation frequencyHow rapidly indentation changes from line to line.382+12.476
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.382−8.345
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.498.901+6.564
Identifier layout (horizontal)How rapidly the visual pattern of identifier characters changes from left to right. It measures spatial frequency, not the meaning of the names.109.974−0.993
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.109.978+0.97
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.073+0.235

Intercept 0.07 + feature contributions = -5.69 (log-odds).
Score = sigmoid(-5.69) = 0.003.

Score0.562
Score187
Run 1

The code has a clear overall structure and logical organization, with methods that are generally short and focused. However, several readability issues detract from the score. The use of a boolean array 't[]' with numeric indices for message type flags is cryptic and makes intent unclear. Nested conditionals appear in a few methods, though they are not excessively deep. Some methods mix concerns or have unclear names (e.g., 'getFinalY', 'determineActivator'). There is inconsistent indentation and formatting throughout, which disrupts reading flow. Comments are helpful in places, but large portions of logic require domain knowledge to understand. The code is not overly lengthy, but some methods contain multiple actions per line. Overall, it is functional and reasonably organized but lacks clarity in several areas, preventing a higher readability rating.

Run 2

The code has clear structure with separated methods and logical organization, but suffers from several readability issues. It contains excessive copyright headers that clutter the top of the file. Temporary hacks are present (textEditStarted, updateActivations, determineFigNodes) with comments explaining workarounds but adding confusion. The boolean array 't[]' uses cryptic indices (t[1] through t[6]) instead of meaningful variable names, making intent unclear. Method names like getStartY and getFinalY are misleading — both use a variable named 'finalY'. Inconsistent indentation (tabs vs spaces) appears throughout. Some methods like buildOperationMenu have complex nested logic and exception handling that reduces clarity. Magic numbers appear (e.g., 50, 10 in PathItemPlacement). Comments are helpful in some areas (explaining workarounds and TODOs) but the overall code length is high for the functionality provided. The reading flow is disrupted by long methods and unclear boolean state tracking.

Run 3

The code has some organizational strengths but also notable readability issues. Structure is adequate with clear package/import organization and method separation, but several methods are cluttered with explanatory comments that add length without clarifying well. Nesting is generally flat, which is good, though a few methods like getReceiverOperations() and determineActivator() contain nested conditionals. Intent clarity is mixed - method names are mostly descriptive, but the use of the boolean array 't[]' without named indices is ambiguous and error-prone. Code length is excessive in places due to verbose comments interspersed with logic. Action granularity is inconsistent: most lines perform one action, but spacing and tabbing are erratic (tabs vs spaces), reducing readability. Reading flow suffers because related functionality is scattered (e.g., isXMessage methods return array values rather than using meaningful fields). The updateArrow() and updateListeners() methods are reasonably clear, but commented-out pseudo-explanations throughout interrupt logical flow. Overall, this is functional but would benefit from named message-type fields and consistent formatting.

Run 1

Code Structure: Mostly well-organized into focused methods, though rendering, model listeners, menus, and activation logic share one large class. Nesting: Generally shallow; getReceiverOperations has a moderately nested conditional/loop structure. Clarity of intent: Descriptive method names and explanatory comments help, but the opaque boolean array t with numeric indices, generic Object types, variable shadowing, and workaround-heavy behavior obscure intent. Code length: Most methods are concise, but repetitive flag accessors, lengthy comments, and duplicated activation handling add bulk. Action granularity: Statements generally perform one action per line, with few readability concerns beyond chained calls and inline casts. Reading flow: Methods are locally easy to follow, but inconsistent indentation, scattered related responsibilities, and reliance on superclass lifecycle behavior make the overall flow harder to trace.

Run 2

Code Structure: Responsibilities are separated into focused methods, although rendering, notation, menus, and model listeners share one large class. Nesting: Mostly shallow conditionals and early returns; operation discovery and menu construction introduce moderate nesting. Clarity of intent: Descriptive method names and explanatory comments help, but the boolean array t with unexplained numeric indices, abbreviated variables, and shadowed action variable obscure meaning. Code length: Most methods are concise, but extensive boilerplate, workaround commentary, and repeated model-access expressions increase reading effort. Action granularity: Statements generally perform one action per line, with clear separation of updates. Reading flow: Method-level flow is natural, but inconsistent indentation, legacy raw collection types, and dependencies on superclass behavior interrupt comprehension. Overall, the code is reasonably readable but would benefit from named message-type fields, consistent formatting, and clearer grouping of related methods.

Run 3

Code Structure: Mostly well-organized into focused methods, although rendering, model listeners, menus, and activation logic share one class. Nesting: Generally shallow, with moderate nesting in operation retrieval and menu construction. Clarity of intent: Descriptive method names and explanatory comments help, but the boolean array t and numeric indices obscure message types; abbreviated variables and action shadowing add friction. Code length: Most methods are concise, but lengthy workaround comments, boilerplate, and repeated geometry and activation logic increase reading effort. Action granularity: Statements generally perform one action per line, making execution easy to follow. Reading flow: Method-level flow is natural, but inconsistent indentation, scattered related responsibilities, and reliance on superclass behavior interrupt comprehension. Overall, readable legacy code with notable naming and consistency weaknesses.