Sample

Schnappinger/argoUML/org.argouml.application.events.ArgoEventPump

Human rating uses the original dataset scale.

Human4
Lines534

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
23.4Δ 75.3
Scalabrino0.8450–1; higher is more readable
74.3Δ 24.4
Dorn0.9790–1; higher is more readable
99.7Δ 1.0
Mi0.6310–1; higher is more readable
68.6Δ 30.0
LLOC159Logical lines; fewer is more readable
16.5Δ 82.2
DeepSeek V4 Pro130–20; mean of three runs
21.1Δ 77.6
GPT-6.1 Sol14.330–20; mean of three runs
19.8Δ 78.9
BTTF0.4270–1; higher is more readable
36.6Δ 62.0
Human41–4; original rating
98.7

Views

Source code

/* $Id: ArgoEventPump.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: * tfmorris ******************************************************************************* * * Some portions of this file was previously release using the BSD License: */ // Copyright (c) 1996-2008 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.application.events; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.SwingUtilities; import org.argouml.application.api.ArgoEventListener; /** * ArgoEventPump is an event dispatcher which handles events that are global * in nature for the entire application. * <p> * TODO: DiagramAppearance and Notation events are not application-wide and will * be moved from here to someplace more specific in the future so that they can * be managed on a per-project or per-diagram basis. */ public final class ArgoEventPump { /** * Logger. */ private static final Logger LOG = Logger.getLogger(ArgoEventPump.class.getName()); /** * <code>listeners</code> contains the list of register listeners. * * It is a list of {@link Pair}. */ private List<Pair> listeners; /** * The singleton. */ static final ArgoEventPump SINGLETON = new ArgoEventPump(); /** * @return the singleton */ public static ArgoEventPump getInstance() { return SINGLETON; } /** * Constructor. */ private ArgoEventPump() { } /** * @param listener The listener to be added. */ public static void addListener(ArgoEventListener listener) { SINGLETON.doAddListener(ArgoEventTypes.ANY_EVENT, listener); } /** * @param event the event-type to what the listener will listen * @param listener the listener to be added */ public static void addListener(int event, ArgoEventListener listener) { SINGLETON.doAddListener(event, listener); } /** * @param listener the listener to be removed */ public static void removeListener(ArgoEventListener listener) { SINGLETON.doRemoveListener(ArgoEventTypes.ANY_EVENT, listener); } /** * @param event the event to which the listener will not listen any more * @param listener the listener to be removed */ public static void removeListener(int event, ArgoEventListener listener) { SINGLETON.doRemoveListener(event, listener); } /** * @param event the event to what the listener will listen (?) * @param listener the listener to be added */ protected void doAddListener(int event, ArgoEventListener listener) { if (listeners == null) { listeners = new ArrayList<Pair>(); } synchronized (listeners) { listeners.add(new Pair(event, listener)); } } /** * Removes a listener, eventtype pair from the listener list. * * TODO: replace the listener implementation with a EventListenerList * for better performance * * @param event the event to which the listener will not listen any more * @param listener the listener to be removed */ protected void doRemoveListener(int event, ArgoEventListener listener) { if (listeners == null) { return; } synchronized (listeners) { List<Pair> removeList = new ArrayList<Pair>(); if (event == ArgoEventTypes.ANY_EVENT) { // TODO: This is a linear search of a list that contain many // thousands of items (one for every Fig in the entire project) for (Pair p : listeners) { if (p.listener == listener) { removeList.add(p); } } } else { Pair test = new Pair(event, listener); // TODO: This is a linear search of a list that contain many // thousands of items (one for every Fig in the entire project) for (Pair p : listeners) { if (p.equals(test)) { removeList.add(p); } } } listeners.removeAll(removeList); } } /** * Handle firing a notation event. * <p> * TODO: This needs to be managed on a per-diagram or per-project basis. * * @param event The event to be fired. * @param listener The listener. */ private void handleFireNotationEvent( final ArgoNotationEvent event, final ArgoNotationEventListener listener) { // Notation events are likely to cause GEF/Swing operations, so we // dispatch them on the Swing event thread as a convenience so that // the receiving notationChanged() methods don't need to deal with it if (SwingUtilities.isEventDispatchThread()) { fireNotationEventInternal(event, listener); } else { SwingUtilities.invokeLater(new Runnable() { public void run() { fireNotationEventInternal(event, listener); } }); } } private void fireNotationEventInternal(ArgoNotationEvent event, ArgoNotationEventListener listener) { switch (event.getEventType()) { case ArgoEventTypes.NOTATION_CHANGED : listener.notationChanged(event); /* Remark: The code in * ProjectSettings.init() currently presumes * that nobody is using this event. */ break; case ArgoEventTypes.NOTATION_ADDED : listener.notationAdded(event); break; case ArgoEventTypes.NOTATION_REMOVED : listener.notationRemoved(event); break; case ArgoEventTypes.NOTATION_PROVIDER_ADDED : listener.notationProviderAdded(event); break; case ArgoEventTypes.NOTATION_PROVIDER_REMOVED : listener.notationProviderRemoved(event); break; default : LOG.log(Level.SEVERE, "Invalid event:" + event.getEventType()); break; } } /** * Handle firing a diagram appearance event. * <p> * TODO: This needs to be managed on a per-diagram or per-project basis. * * @param event The event to be fired. * @param listener The listener. */ private void handleFireDiagramAppearanceEvent( final ArgoDiagramAppearanceEvent event, final ArgoDiagramAppearanceEventListener listener) { if (SwingUtilities.isEventDispatchThread()) { fireDiagramAppearanceEventInternal(event, listener); } else { SwingUtilities.invokeLater(new Runnable() { public void run() { fireDiagramAppearanceEventInternal(event, listener); } }); } } private void fireDiagramAppearanceEventInternal( final ArgoDiagramAppearanceEvent event, final ArgoDiagramAppearanceEventListener listener) { switch (event.getEventType()) { case ArgoEventTypes.DIAGRAM_FONT_CHANGED : listener.diagramFontChanged(event); break; default : LOG.log(Level.SEVERE, "Invalid event:" + event.getEventType()); break; } } /** * Handle firing a help text event. * * @param event The event to be fired. * @param listener The listener. */ private void handleFireHelpEvent( ArgoHelpEvent event, ArgoHelpEventListener listener) { switch (event.getEventType()) { case ArgoEventTypes.HELP_CHANGED : listener.helpChanged(event); break; case ArgoEventTypes.HELP_REMOVED : listener.helpRemoved(event); break; default : LOG.log(Level.SEVERE, "Invalid event:" + event.getEventType()); break; } } /** * Handle firing a status text event. * * @param event The event to be fired. * @param listener The listener. */ private void handleFireStatusEvent( ArgoStatusEvent event, ArgoStatusEventListener listener) { switch (event.getEventType()) { case ArgoEventTypes.STATUS_TEXT : listener.statusText(event); break; case ArgoEventTypes.STATUS_CLEARED : listener.statusCleared(event); break; case ArgoEventTypes.STATUS_PROJECT_SAVED : listener.projectSaved(event); break; case ArgoEventTypes.STATUS_PROJECT_LOADED : listener.projectLoaded(event); break; case ArgoEventTypes.STATUS_PROJECT_MODIFIED : listener.projectModified(event); break; default : LOG.log(Level.SEVERE, "Invalid event:" + event.getEventType()); break; } } /** * Handle firing a profile event. * * @param event The event to be fired. * @param listener The listener. */ private void handleFireProfileEvent( ArgoProfileEvent event, ArgoProfileEventListener listener) { switch (event.getEventType()) { case ArgoEventTypes.PROFILE_ADDED: listener.profileAdded(event); break; case ArgoEventTypes.PROFILE_REMOVED: listener.profileRemoved(event); break; default: LOG.log(Level.SEVERE, "Invalid event:" + event.getEventType()); break; } } /** * Handle firing a generator event. * * @param event The event to be fired. * @param listener The listener. */ private void handleFireGeneratorEvent( ArgoGeneratorEvent event, ArgoGeneratorEventListener listener) { switch (event.getEventType()) { case ArgoEventTypes.GENERATOR_CHANGED: listener.generatorChanged(event); break; case ArgoEventTypes.GENERATOR_ADDED: listener.generatorAdded(event); break; case ArgoEventTypes.GENERATOR_REMOVED: listener.generatorRemoved(event); break; default: LOG.log(Level.SEVERE, "Invalid event:" + event.getEventType()); break; } } private void handleFireEvent(ArgoEvent event, ArgoEventListener listener) { if (event.getEventType() == ArgoEventTypes.ANY_EVENT) { if (listener instanceof ArgoNotationEventListener) { handleFireNotationEvent((ArgoNotationEvent) event, (ArgoNotationEventListener) listener); } if (listener instanceof ArgoHelpEventListener) { handleFireHelpEvent((ArgoHelpEvent) event, (ArgoHelpEventListener) listener); } if (listener instanceof ArgoStatusEventListener) { handleFireStatusEvent((ArgoStatusEvent) event, (ArgoStatusEventListener) listener); } } else { if (event.getEventType() >= ArgoEventTypes.ANY_NOTATION_EVENT && event.getEventType() < ArgoEventTypes.LAST_NOTATION_EVENT) { if (listener instanceof ArgoNotationEventListener) { handleFireNotationEvent((ArgoNotationEvent) event, (ArgoNotationEventListener) listener); } } if (event.getEventType() >= ArgoEventTypes .ANY_DIAGRAM_APPEARANCE_EVENT && event.getEventType() < ArgoEventTypes .LAST_DIAGRAM_APPEARANCE_EVENT) { if (listener instanceof ArgoDiagramAppearanceEventListener) { handleFireDiagramAppearanceEvent( (ArgoDiagramAppearanceEvent) event, (ArgoDiagramAppearanceEventListener) listener); } } if (event.getEventType() >= ArgoEventTypes.ANY_HELP_EVENT && event.getEventType() < ArgoEventTypes.LAST_HELP_EVENT) { if (listener instanceof ArgoHelpEventListener) { handleFireHelpEvent((ArgoHelpEvent) event, (ArgoHelpEventListener) listener); } } if (event.getEventType() >= ArgoEventTypes.ANY_GENERATOR_EVENT && event.getEventType() < ArgoEventTypes.LAST_GENERATOR_EVENT) { if (listener instanceof ArgoGeneratorEventListener) { handleFireGeneratorEvent((ArgoGeneratorEvent) event, (ArgoGeneratorEventListener) listener); } } if (event.getEventType() >= ArgoEventTypes.ANY_STATUS_EVENT && event.getEventType() < ArgoEventTypes .LAST_STATUS_EVENT) { if (listener instanceof ArgoStatusEventListener) { handleFireStatusEvent((ArgoStatusEvent) event, (ArgoStatusEventListener) listener); } } if (event.getEventType() >= ArgoEventTypes.ANY_PROFILE_EVENT && event.getEventType() < ArgoEventTypes .LAST_PROFILE_EVENT) { if (listener instanceof ArgoProfileEventListener) { handleFireProfileEvent((ArgoProfileEvent) event, (ArgoProfileEventListener) listener); } } } } /** * @param event the event to be fired */ public static void fireEvent(ArgoEvent event) { SINGLETON.doFireEvent(event); } /** * @param event the event to be fired */ protected void doFireEvent(ArgoEvent event) { if (listeners == null) { return; } // Make a read-only copy of the listeners list so that reentrant calls // back to add/removeListener won't mess us up. // TODO: Potential performance issue, but we need the correctness - tfm List<Pair> readOnlyListeners; synchronized (listeners) { readOnlyListeners = new ArrayList<Pair>(listeners); } for (Pair pair : readOnlyListeners) { if (pair.getEventType() == ArgoEventTypes.ANY_EVENT) { handleFireEvent(event, pair.getListener()); } else if (pair.getEventType() == event.getEventStartRange() || pair.getEventType() == event.getEventType()) { handleFireEvent(event, pair.getListener()); } } } /** * Data structure handling listener registrations. */ static class Pair { private int eventType; private ArgoEventListener listener; /** * Constructor. * * @param myEventType The event type. * @param myListener The listener. */ Pair(int myEventType, ArgoEventListener myListener) { eventType = myEventType; listener = myListener; } /** * @return The event type. */ int getEventType() { return eventType; } /** * @return The listener. */ ArgoEventListener getListener() { return listener; } @Override public String toString() { return "{Pair(" + eventType + "," + listener + ")}"; } @Override public int hashCode() { if (listener != null) { return eventType + listener.hashCode(); } return eventType; } @Override public boolean equals(Object o) { if (o instanceof Pair) { Pair p = (Pair) o; if (p.eventType == eventType && p.listener == listener) { return true; } } return false; } } }

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.12308.062−406.166
Source linesThe number of non-empty source lines.534+213.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.506−6.759

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

Score0.845

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.535−17.906
Indentation frequencyHow rapidly indentation changes from line to line.398+13.029
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.533.951+7.054
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.78.74+0.466
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.052+0.438
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.1+0.398
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.79.974+0.278

Intercept 0.07 + feature contributions = 3.827 (log-odds).
Score = sigmoid(3.827) = 0.979.

Score0.631
Score159
Run 1

The code has a clear class structure with a singleton pattern and logical method separation, but several factors reduce readability. The presence of extensive copyright headers and numerous TODO comments adds noise. The handleFireEvent method is deeply nested with multiple repeated if-condition patterns, making the flow hard to follow. Many methods are concise and one action per line, but the overall length is high due to repetitive switch statements for each event type. Naming is generally clear, but the heavy use of constants like ArgoEventTypes.ANY_EVENT and long conditional chains reduces clarity. Action granularity is mostly good, but duplicate listener dispatch logic could be refactored for brevity.

Run 2

The code is generally well-structured with clear separation of concerns and good Javadoc documentation, but it is unnecessarily verbose and contains significant repetition. The class has a logical organization with public static methods delegating to instance methods, and the listener management is reasonably clear. However, the overall length is excessive - the handleFireXxxEvent methods are highly repetitive and could be consolidated, and the handleFireEvent method contains long chains of nearly identical conditional blocks. The nesting level is moderate, with the switch statements inside methods but no excessive deep nesting. The action granularity is mostly good, with one action per line. The reading flow is natural, moving from public API to private implementation, but is disrupted by the repetitiveness. Some naming is unclear (e.g., Pair, ANY_EVENT) without reading docs. The code is readable but would benefit from reduced duplication and more concise logic.

Run 3

The code is generally organized with clear method separation and documentation, but readability is hampered by several issues. The handleFireEvent method has deep nesting and repetitive conditional blocks that could be refactored into a dispatch table or strategy pattern. Many switch statements contain similar structures with repetitive logging, increasing length. Some lines are awkwardly broken (e.g., 'ArgoEventTypes .LAST_DIAGRAM_APPEARANCE_EVENT'), and indentation is inconsistent in places. There are also method names that suggest multiple actions per line, like fireNotationEventInternal, but overall one action per line is mostly followed. The listener removal uses linear searches with repeated TODO comments, indicating a known inefficiency but not solved. The use of static methods delegating to a singleton adds layers of indirection that can obscure intent. While comments explain many complex parts, the code would benefit from clearer abstractions and removal of duplicated dispatch logic.

Run 1

1. Code Structure: Listener registration, dispatch, and event-specific handling are separated into focused methods, though central routing is repetitive. 2. Nesting: Most handlers are shallow switches; removal and routing contain moderately deep conditional nesting. 3. Clarity of intent: Descriptive method names, event constants, and threading comments explain the dispatcher well. Generic Pair naming and ANY_EVENT routing make some behavior harder to interpret. 4. Code length: Repeated switches, type checks, threading wrappers, and boilerplate documentation make the class longer than necessary. 5. Action granularity: Statements generally perform one action per line, with clearly separated callbacks and control flow. 6. Reading flow: Organization is mostly predictable, but inconsistent indentation, awkward line wrapping, and repetitive branching interrupt scanning. Overall, readable and reasonably structured, but verbose dispatch logic and formatting inconsistencies prevent a higher score.

Run 2

1. Code Structure: Listener registration, dispatch, event-specific handlers, and registration data are separated into focused methods, though dispatch remains centralized and repetitive. 2. Nesting: Most handlers are flat switches; listener removal and general dispatch introduce several nested conditions that require more attention. 3. Clarity of intent: Descriptive method names, event constants, and comments make the purpose clear. The generic Pair name and numeric event-range routing are less expressive. 4. Code length: Repeated switches, type checks, wrapper methods, and boilerplate documentation make the class longer than necessary, although individual methods are mostly manageable. 5. Action granularity: Statements generally perform one action each, and callbacks are easy to identify; multiline conditions and casts add visual complexity without combining unrelated actions. 6. Reading flow: Registration methods followed by handlers and dispatch provide reasonable organization, but inconsistent indentation, awkward line wrapping, and placing the public firing entry point after detailed handlers interrupt the flow.

Run 3

Code Structure: Listener registration, removal, and event-specific dispatch are separated into focused methods, but centralized routing contains repetitive type checks and casts. Nesting: Most handlers are shallow switches; removal and general dispatch introduce moderately deep nesting. Clarity of intent: Descriptive method names, event constants, and threading comments explain the purpose well, although the generic Pair name and special ANY_EVENT handling require interpretation. Code length: Repeated dispatch patterns, boilerplate documentation, and duplicated removal loops make the class longer than necessary. Action granularity: Statements generally perform one action per line, with clear separation of conditions and callbacks. Reading flow: Consistent handler patterns help scanning, but inconsistent indentation, awkward line wrapping, and placing the public fireEvent entry point after internal handlers interrupt the flow.