diff --git a/ide/git/src/org/netbeans/modules/git/HistoryProvider.java b/ide/git/src/org/netbeans/modules/git/HistoryProvider.java index 07a26555752d..fc0601a2ec1f 100644 --- a/ide/git/src/org/netbeans/modules/git/HistoryProvider.java +++ b/ide/git/src/org/netbeans/modules/git/HistoryProvider.java @@ -53,7 +53,7 @@ */ public class HistoryProvider implements VCSHistoryProvider { - private final List listeners = new LinkedList(); + private final List listeners = new LinkedList<>(); private static final Logger LOG = Logger.getLogger(HistoryProvider.class.getName()); private Action[] actions; @@ -80,9 +80,9 @@ public synchronized HistoryEntry[] getHistory(File[] files, Date fromDate) { return null; } - List ret = new LinkedList(); - Map> rev2FileMap = new HashMap>(); - Map rev2LMMap = new LinkedHashMap(); + List ret = new LinkedList<>(); + Map> rev2FileMap = new HashMap<>(); + Map rev2LMMap = new LinkedHashMap<>(); File repositoryRoot = repositories.iterator().next(); for (File file : files) { @@ -96,12 +96,8 @@ public synchronized HistoryEntry[] getHistory(File[] files, Date fromDate) { for (GitRevisionInfo h : history) { String r = h.getRevision(); rev2LMMap.put(r, h); - Set s = rev2FileMap.get(r); - if(s == null) { - s = new HashSet(); - rev2FileMap.put(r, s); - } - s.add(file); + rev2FileMap.computeIfAbsent(r, k -> new HashSet()) + .add(file); } } catch (GitException ex) { LOG.log(Level.INFO, null, ex); @@ -110,12 +106,12 @@ public synchronized HistoryEntry[] getHistory(File[] files, Date fromDate) { for (GitRevisionInfo h : rev2LMMap.values()) { Set s = rev2FileMap.get(h.getRevision()); - File[] involvedFiles = s.toArray(new File[0]); + File[] involvedFiles = s.toArray(File[]::new); HistoryEntry e = createHistoryEntry(h, involvedFiles, repositoryRoot); ret.add(e); } - return ret.toArray(new HistoryEntry[0]); + return ret.toArray(HistoryEntry[]::new); } private HistoryEntry createHistoryEntry (GitRevisionInfo h, File[] involvedFiles, File repositoryRoot) { @@ -150,20 +146,17 @@ public Action createShowHistoryAction(File[] files) { public void fireHistoryChange (final File[] files) { final HistoryChangeListener[] la; synchronized(listeners) { - la = listeners.toArray(new HistoryChangeListener[0]); + la = listeners.toArray(HistoryChangeListener[]::new); } - Git.getInstance().getRequestProcessor().post(new Runnable() { - @Override - public void run() { - for (HistoryChangeListener l : la) { - l.fireHistoryChanged(new HistoryEvent(HistoryProvider.this, files)); - } + Git.getInstance().getRequestProcessor().post(() -> { + for (HistoryChangeListener l : la) { + l.fireHistoryChanged(new HistoryEvent(HistoryProvider.this, files)); } }); } private class RevisionProviderImpl implements RevisionProvider { - private String revision; + private final String revision; public RevisionProviderImpl(String revision) { this.revision = revision; @@ -230,7 +223,7 @@ private void openHistory(File[] files) { if(repositories == null || repositories.isEmpty()) { return; } - List nodes = new ArrayList(files.length); + List nodes = new ArrayList<>(files.length); for (File f : files) { nodes.add(new AbstractNode(Children.LEAF, Lookups.fixed(f)) { @Override @@ -239,7 +232,7 @@ public String getDisplayName() { } }); } - SearchHistoryAction.openSearch(repositories.iterator().next(), files, Utils.getContextDisplayName(VCSContext.forNodes(nodes.toArray(new Node[0])))); + SearchHistoryAction.openSearch(repositories.iterator().next(), files, Utils.getContextDisplayName(VCSContext.forNodes(nodes.toArray(Node[]::new)))); } } @@ -267,8 +260,9 @@ protected void perform(HistoryEntry entry, Set files) { @Override protected void perform(final HistoryEntry entry, final Set files) { File root = Git.getInstance().getRepositoryRoot(files.iterator().next()); - SystemAction.get(RevertChangesAction.class).revertFiles(root, files.toArray(new File[0]), - getRevisionShort(), Bundle.HistoryProvider_action_RevertTo_progress()); + SystemAction.get(RevertChangesAction.class).revertFiles( + root, files.toArray(File[]::new), getRevisionShort(), Bundle.HistoryProvider_action_RevertTo_progress() + ); } @Override protected boolean isMultipleHistory() { @@ -315,7 +309,7 @@ protected void perform () { } private static Set getRepositoryRoots(File... files) { - Set repositories = GitUtils.getRepositoryRoots(new HashSet(Arrays.asList(files))); + Set repositories = GitUtils.getRepositoryRoots(new HashSet<>(Arrays.asList(files))); if (repositories.size() != 1) { LOG.log(Level.WARNING, "History requested for {0} repositories", repositories.size()); // NOI18N return null; @@ -324,16 +318,16 @@ private static Set getRepositoryRoots(File... files) { } private class ParentProviderImpl implements ParentProvider { - private GitRevisionInfo info; - private File[] files; - private File repository; - private Map commonAncestors; + private final GitRevisionInfo info; + private final File[] files; + private final File repository; + private final Map commonAncestors; public ParentProviderImpl (GitRevisionInfo info, File[] files, File repository) { this.info = info; this.files = files; this.repository = repository; - this.commonAncestors = new HashMap(files.length); + this.commonAncestors = new HashMap<>((int) Math.ceil(files.length / 0.75)); } @Override diff --git a/ide/libs.git/src/org/netbeans/libs/git/GitRevisionInfo.java b/ide/libs.git/src/org/netbeans/libs/git/GitRevisionInfo.java index d5196895ce8b..ef6beba1dea5 100644 --- a/ide/libs.git/src/org/netbeans/libs/git/GitRevisionInfo.java +++ b/ide/libs.git/src/org/netbeans/libs/git/GitRevisionInfo.java @@ -25,10 +25,8 @@ import java.util.Collections; import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.logging.Logger; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Repository; @@ -53,7 +51,6 @@ public final class GitRevisionInfo { private final Repository repository; private final Map branches; private GitFileInfo[] modifiedFiles; - private static final Logger LOG = Logger.getLogger(GitRevisionInfo.class.getName()); private String shortMessage; GitRevisionInfo (RevCommit commit, Repository repository) { @@ -146,7 +143,7 @@ public java.util.Map getModifiedFiles () throws GitEx listFiles(); } } - Map files = new HashMap<>(modifiedFiles.length); + Map files = new HashMap<>((int) Math.ceil(modifiedFiles.length / 0.75)); for (GitFileInfo info : modifiedFiles) { files.put(info.getFile(), info); } @@ -202,17 +199,11 @@ private void listFiles() throws GitException { result.add(new GitFileInfo(new File(repository.getWorkTree(), walk.getPathString()), walk.getPathString(), GitFileInfo.Status.ADDED, null, null)); } } - this.modifiedFiles = result.toArray(new GitFileInfo[0]); + this.modifiedFiles = result.toArray(GitFileInfo[]::new); } catch (IOException ex) { throw new GitException(ex); } } - - private static Map buildBranches (RevCommit commit, Map branches) { - Map retval = new LinkedHashMap<>(branches.size()); - - return retval; - } /** * Provides information about what happened to a file between two different commits. diff --git a/ide/versioning.core/src/org/netbeans/modules/versioning/core/spi/VCSHistoryProvider.java b/ide/versioning.core/src/org/netbeans/modules/versioning/core/spi/VCSHistoryProvider.java index 8b6aba0bc5d0..a939367e678f 100644 --- a/ide/versioning.core/src/org/netbeans/modules/versioning/core/spi/VCSHistoryProvider.java +++ b/ide/versioning.core/src/org/netbeans/modules/versioning/core/spi/VCSHistoryProvider.java @@ -83,17 +83,18 @@ public interface VCSHistoryProvider { * */ public static final class HistoryEntry { - private Date dateTime; + + private final Date dateTime; private String message; - private VCSFileProxy[] files; - private String usernameShort; - private String username; - private String revisionShort; - private String revision; - private Action[] actions; - private RevisionProvider revisionProvider; - private MessageEditProvider mep; - private ParentProvider parentProvider; + private final VCSFileProxy[] files; + private final String usernameShort; + private final String username; + private final String revisionShort; + private final String revision; + private final Action[] actions; + private final RevisionProvider revisionProvider; + private final MessageEditProvider mep; + private final ParentProvider parentProvider; /** * Creates a new HistoryEntry instance. @@ -107,8 +108,9 @@ public static final class HistoryEntry { * @param revisionShort short description of the versioning revision * @param actions actions which might be called in regard with this revision * @param revisionProvider a RevisionProvider to get access to a files contents in this revision - * - * @since 1.26 + * @param messageEditProvider a MessageEditProvider to change a revisions message + * @param parentProvider a ParentProvider to provide this entries parent entry. Not necessary for VCS + * where a revisions parent always is the time nearest previous revision. */ public HistoryEntry( VCSFileProxy[] files, @@ -119,7 +121,9 @@ public HistoryEntry( String revision, String revisionShort, Action[] actions, - RevisionProvider revisionProvider) + RevisionProvider revisionProvider, + MessageEditProvider messageEditProvider, + ParentProvider parentProvider) { assert files != null && files.length > 0 : "a history entry must have at least one file"; // NOI18N assert revision != null && revision != null : "a history entry must have a revision"; // NOI18N @@ -135,6 +139,8 @@ public HistoryEntry( this.revisionShort = revisionShort; this.actions = actions; this.revisionProvider = revisionProvider; + this.mep = messageEditProvider; + this.parentProvider = parentProvider; } /** @@ -163,8 +169,7 @@ public HistoryEntry( RevisionProvider revisionProvider, MessageEditProvider messageEditProvider) { - this(files, dateTime, message, username, usernameShort, revision, revisionShort, actions, revisionProvider); - this.mep = messageEditProvider; + this(files, dateTime, message, username, usernameShort, revision, revisionShort, actions, revisionProvider, messageEditProvider, null); } /** @@ -179,10 +184,8 @@ public HistoryEntry( * @param revisionShort short description of the versioning revision * @param actions actions which might be called in regard with this revision * @param revisionProvider a RevisionProvider to get access to a files contents in this revision - * @param messageEditProvider a MessageEditProvider to change a revisions message - * @param parentProvider a ParentProvider to provide this entries parent entry. Not necessary for VCS - * where a revisions parent always is the time nearest previous revision. - * + * + * @since 1.26 */ public HistoryEntry( VCSFileProxy[] files, @@ -193,12 +196,9 @@ public HistoryEntry( String revision, String revisionShort, Action[] actions, - RevisionProvider revisionProvider, - MessageEditProvider messageEditProvider, - ParentProvider parentProvider) + RevisionProvider revisionProvider) { - this(files, dateTime, message, username, usernameShort, revision, revisionShort, actions, revisionProvider, messageEditProvider); - this.parentProvider = parentProvider; + this(files, dateTime, message, username, usernameShort, revision, revisionShort, actions, revisionProvider, null, null); } /** diff --git a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/History.java b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/History.java index 9cb44a4f7d34..a48899177c06 100644 --- a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/History.java +++ b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/History.java @@ -64,15 +64,13 @@ public RequestProcessor getRequestProcessor() { */ public List getHyperlinkProviders() { if (hpResult == null) { - hpResult = (Lookup.Result) Lookup.getDefault().lookupResult(VCSHyperlinkProvider.class); + hpResult = Lookup.getDefault().lookupResult(VCSHyperlinkProvider.class); } if (hpResult == null) { return Collections.emptyList(); } Collection providersCol = hpResult.allInstances(); - List providersList = new ArrayList(providersCol.size()); - providersList.addAll(providersCol); - return Collections.unmodifiableList(providersList); + return Collections.unmodifiableList(new ArrayList<>(providersCol)); } VersioningSystem getLocalHistory(FileObject fo) { @@ -94,14 +92,14 @@ static VCSFileProxy[] toProxies(FileObject[] files) { if(files == null) { return new VCSFileProxy[0]; } - List l = new ArrayList(files.length); + List l = new ArrayList<>(files.length); for (FileObject f : files) { VCSFileProxy proxy = VCSFileProxy.createFileProxy(f); if(proxy != null) { l.add(proxy); } } - return l.toArray(new VCSFileProxy[0]); + return l.toArray(VCSFileProxy[]::new); } } diff --git a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryComponent.java b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryComponent.java index d6ab127bd625..5233b22a72f6 100644 --- a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryComponent.java +++ b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryComponent.java @@ -22,7 +22,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; @@ -84,6 +83,7 @@ mimeType="", position=1000000 // lets leave some space in case somebody really wants to be the last ) +@SuppressWarnings("AccessingNonPublicFieldOfAnotherObject") public final class HistoryComponent extends JPanel implements MultiViewElement, HelpCtx.Provider, PropertyChangeListener { private HistoryFileView masterView; @@ -155,16 +155,16 @@ private synchronized void initFromContext() { if(context == null) return; synchronized(FILE_LOCK) { DataObject dataObject = context.lookup(DataObject.class); - List filesList = new LinkedList(); - if (dataObject instanceof DataShadow) { - dataObject = ((DataShadow) dataObject).getOriginal(); + List filesList = new LinkedList<>(); + if (dataObject instanceof DataShadow dataShadow) { + dataObject = dataShadow.getOriginal(); } if (dataObject != null) { Set daoFiles = dataObject.files(); Collection doFiles = toFileCollection(daoFiles); if(files != null && files.length > 0) { // check for possible changes - Set s = new HashSet(Arrays.asList(files)); + Set s = new HashSet<>(Arrays.asList(files)); boolean changed = false; for (FileObject fo : daoFiles) { if(!s.contains(fo)) { @@ -179,24 +179,19 @@ private synchronized void initFromContext() { } filesList.addAll(doFiles); } - initFiles(filesList.toArray(new VCSFileProxy[0])); + initFiles(filesList.toArray(VCSFileProxy[]::new)); } - Runnable r = new Runnable() { - @Override - public void run() { - resetUI(); - } - }; + Runnable reset = this::resetUI; if(EventQueue.isDispatchThread()) { - r.run(); + reset.run(); } else { - SwingUtilities.invokeLater(r); + SwingUtilities.invokeLater(reset); } } private synchronized void initFiles(VCSFileProxy[] files) { synchronized(FILE_LOCK) { - List l = new ArrayList(files.length); + List l = new ArrayList<>(files.length); unregisterFileListeners(); for (VCSFileProxy proxy : files) { final FileObject fo = proxy.toFileObject(); @@ -204,12 +199,12 @@ private synchronized void initFiles(VCSFileProxy[] files) { l.add(fo); } } - this.files = l.toArray(new FileObject[0]); + this.files = l.toArray(FileObject[]::new); registerFileListeners(); } } - private final Map listeners = new HashMap(1); + private final Map listeners = new HashMap<>(1); private void unregisterFileListeners() { synchronized(listeners) { if(!listeners.isEmpty()) { @@ -255,7 +250,7 @@ public void fileAttributeChanged(FileAttributeEvent fe) { } } private Collection toFileCollection(Collection fileObjects) { - Set ret = new HashSet(fileObjects.size()); + Set ret = new HashSet<>((int) Math.ceil(fileObjects.size() / 0.75)); for (FileObject fo : fileObjects) { ret.add(VCSFileProxy.createFileProxy(fo)); } @@ -344,12 +339,7 @@ public void propertyChange(PropertyChangeEvent evt) { hasLocalHistory != (History.getHistoryProvider(History.getInstance().getLocalHistory(fo)) != null)) { versioningSystem = vs; - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - resetUI(); - } - }); + SwingUtilities.invokeLater(this::resetUI); } } } @@ -590,12 +580,9 @@ private Toolbar(VersioningSystem vs) { modeLabel = new JLabel(NbBundle.getMessage(HistoryComponent.class, "LBL_CompareMode")); // NOI18N modeCombo = new ValueSizedCombo(); modeCombo.setModel(new DefaultComboBoxModel(new Object[] {CompareMode.TOCURRENT, CompareMode.TOPARENT})); - modeCombo.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if(e.getStateChange() == ItemEvent.SELECTED) { - onModeChange(); - } + modeCombo.addItemListener(e -> { + if(e.getStateChange() == ItemEvent.SELECTED) { + onModeChange(); } }); @@ -604,18 +591,15 @@ public void itemStateChanged(ItemEvent e) { filterCombo.setRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - if(value instanceof Filter) { - return super.getListCellRendererComponent(list, ((Filter) value).getDisplayName(), index, isSelected, cellHasFocus); + if (value instanceof Filter filter) { + return super.getListCellRendererComponent(list, filter.getDisplayName(), index, isSelected, cellHasFocus); } return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); } }); - filterCombo.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent e) { - if(e.getStateChange() == ItemEvent.SELECTED) { - onFilterChange(); - } + filterCombo.addItemListener(e -> { + if(e.getStateChange() == ItemEvent.SELECTED) { + onFilterChange(); } }); @@ -763,7 +747,7 @@ private void setMode(Filter filter) { private class ShowHistoryAction extends AbstractAction { private VersioningSystem vs; - private final Set forPaths = new HashSet(1); + private final Set forPaths = new HashSet<>(1); private Action delegate; public ShowHistoryAction(VersioningSystem vs) { @@ -786,20 +770,17 @@ private synchronized void init() { @Override public void actionPerformed(final ActionEvent e) { - History.getInstance().getRequestProcessor().post(new Runnable() { - @Override - public void run() { - for (FileObject fo : getFiles()) { - if(!forPaths.contains(fo.getPath())) { - init(); - break; - } - } - assert delegate != null; - if(delegate != null) { - delegate.actionPerformed(e); + History.getInstance().getRequestProcessor().post(() -> { + for (FileObject fo : getFiles()) { + if(!forPaths.contains(fo.getPath())) { + init(); + break; } } + assert delegate != null; + if(delegate != null) { + delegate.actionPerformed(e); + } }); } } @@ -900,10 +881,7 @@ public boolean filtersProperty(Property property) { } public abstract String getDisplayName(); protected HistoryEntry getEntry(Object value) { - if(value instanceof Node) { - return getHistoryEntry((Node)value); - } - return null; + return value instanceof Node node ? getHistoryEntry(node) : null; } private HistoryEntry getHistoryEntry(Node node) { diff --git a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryDiffView.java b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryDiffView.java index e1a5ba62c6ed..18ca5b4bb97f 100644 --- a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryDiffView.java +++ b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryDiffView.java @@ -99,16 +99,15 @@ private void refresh(Node[] newSelection) { CompareMode mode = tc.getMode(); switch(mode) { - case TOCURRENT: + case TOCURRENT -> { refreshCurrentDiffPanel(entry1, file1); return; - - case TOPARENT: + } + case TOPARENT -> { refreshRevisionDiffPanel(null, entry1, null, file1); return; - - default: - throw new IllegalStateException("Wrong mode selected: " + mode); // NOI18N + } + default -> throw new IllegalStateException("Wrong mode selected: " + mode); // NOI18N } } @@ -338,11 +337,8 @@ public void run() { } file1 = file2; if (entry1 == null) { - EventQueue.invokeLater(new Runnable() { - @Override - public void run () { - showNoContent(NbBundle.getMessage(HistoryDiffView.class, "MSG_DiffPanel_NoVersionToCompare")); // NOI18N - } + EventQueue.invokeLater(() -> { + showNoContent(NbBundle.getMessage(HistoryDiffView.class, "MSG_DiffPanel_NoVersionToCompare")); // NOI18N }); return; } @@ -655,7 +651,7 @@ public synchronized boolean cancel() { synchronized void schedule() { task = History.getInstance().getRequestProcessor().create(this); - task.schedule(500); + task.schedule(200); } protected synchronized boolean isCancelled() { diff --git a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryEntry.java b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryEntry.java index 1ec0771721a4..956b1dc292b8 100644 --- a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryEntry.java +++ b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryEntry.java @@ -33,14 +33,26 @@ */ class HistoryEntry { private final VCSHistoryProvider.HistoryEntry entry; + + /// Position within the log used for UI sorting. "Oldest" has position 0. + private int pos; private final boolean local; private Map parents; - HistoryEntry(VCSHistoryProvider.HistoryEntry entry, boolean local) { + private HistoryEntry(VCSHistoryProvider.HistoryEntry entry, int pos, boolean local) { this.entry = entry; + this.pos = pos; this.local = local; } + static HistoryEntry createLocalEntry(VCSHistoryProvider.HistoryEntry entry) { + return new HistoryEntry(entry, 0, true); + } + + static HistoryEntry createVCSEntry(VCSHistoryProvider.HistoryEntry entry, int pos) { + return new HistoryEntry(entry, pos, false); + } + public Object[] getLookupObjects() { Object[] delegates = Utils.getDelegateEntry(entry); if(delegates == null) { @@ -52,6 +64,14 @@ public Object[] getLookupObjects() { return ret; } } + + public int getPos() { + return pos; + } + + public void setPos(int pos) { + this.pos = pos; + } public String getUsernameShort() { return entry.getUsernameShort(); @@ -99,18 +119,13 @@ public boolean canEdit() { } public synchronized HistoryEntry getParent(VCSFileProxy file) { - HistoryEntry parent = null; - if(parents == null) { - parents = new HashMap(); - } else { - parent = parents.get(file); - } - if(parent == null) { - VCSHistoryProvider.HistoryEntry vcsParent = entry.getParentEntry(file); - parent = vcsParent != null ? new HistoryEntry(vcsParent, local) : null; - parents.put(file, parent); + if (parents == null) { + parents = new HashMap<>(); } - return parent; + return parents.computeIfAbsent(file, k -> { + VCSHistoryProvider.HistoryEntry vcsParent = entry.getParentEntry(k); + return vcsParent != null ? new HistoryEntry(vcsParent, 0, local) : null; + }); } public boolean isLocalHistory() { diff --git a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryFileView.java b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryFileView.java index 9a48aa80f213..65f9e03a3d9e 100644 --- a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryFileView.java +++ b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryFileView.java @@ -23,7 +23,6 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; -import java.beans.PropertyVetoException; import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.List; @@ -66,11 +65,12 @@ * * @author Tomas Stupka */ +@SuppressWarnings({"AccessingNonPublicFieldOfAnotherObject", "ValueOfIncrementOrDecrementUsed"}) class HistoryFileView implements PreferenceChangeListener, VCSHistoryProvider.HistoryChangeListener { - private FileTablePanel tablePanel; + private final FileTablePanel tablePanel; - private RequestProcessor rp = new RequestProcessor("HistoryView", 1, true); // NOI18N + private final RequestProcessor rp = new RequestProcessor("HistoryView", 1, true); // NOI18N private final HistoryComponent tc; private Filter filter; private Task refreshTask; @@ -79,7 +79,7 @@ class HistoryFileView implements PreferenceChangeListener, VCSHistoryProvider.Hi private final VersioningSystem lh; private Date currentDateFrom; - private LoadNextAction loadNextAction; + private final LoadNextAction loadNextAction; private boolean visible; private VCSHistoryProvider pendingProviderToRefresh; @@ -171,12 +171,9 @@ void requestActive() { visible = true; if(getRootNode() == null) { // invoked for the first time -> refresh - History.getInstance().getRequestProcessor().post(new Runnable() { - @Override - public void run() { - refresh(); - tablePanel.requestActivate(); - } + History.getInstance().getRequestProcessor().post(() -> { + refresh(); + tablePanel.requestActivate(); }); } else { tablePanel.requestActivate(); @@ -226,7 +223,7 @@ public void run() { VCSHistoryProvider.HistoryEntry[] vcsHistory; if(forceLoadAll || HistorySettings.getInstance().getLoadAll()) { - vcsHistory = hp.getHistory(files, (Date) null); // get all + vcsHistory = hp.getHistory(files, null); // get all // XXX need different text for "Showing Subversion revisions..." } else { int increment = HistorySettings.getInstance().getIncrements(); @@ -241,120 +238,29 @@ public void run() { if(vcsHistory == null || vcsHistory.length == 0) { return; } - List entries = new ArrayList(vcsHistory.length); + List entries = new ArrayList<>(vcsHistory.length); + + int pos = vcsHistory.length - 1; for (VCSHistoryProvider.HistoryEntry he : vcsHistory) { - entries.add(new HistoryEntry(he, false)); + entries.add(HistoryEntry.createVCSEntry(he, pos--)); } - rootNode.addVCSEntries(entries.toArray(new HistoryEntry[0]), 0); + rootNode.addVCSEntries(entries.toArray(HistoryEntry[]::new), 0); } finally { rootNode.loadingVCSFinished(currentDateFrom); - EventQueue.invokeLater(new Runnable() { - - @Override - public void run () { - tablePanel.repaint(); - } - }); + EventQueue.invokeLater(tablePanel::repaint); // XXX yet select the first node on } } }); } - - private void restoreSelection(final HistoryRootNode root, Node[] oldSelection) { - tablePanel.getExplorerManager().setRootContext(root); - if(root.getChildren().getNodesCount() > 0) { - if (oldSelection != null && oldSelection.length > 0) { - Node[] newSelection = getEqualNodes(root, oldSelection); - if(newSelection.length > 0) { - setSelection(newSelection); - } else { - Node[] newExploredContext = getEqualNodes(root, new Node[] { oldSelection[0].getParentNode() }); - if(newExploredContext.length > 0) { - selectFirstNeighborNode(newExploredContext[0], oldSelection[0]); - } - } - } else { - selectFirstNode(root); - } - } else { - setSelection(new Node[]{}); - } - } - - private Node[] getEqualNodes(Node root, Node[] oldNodes) { - List ret = new ArrayList(); - for(Node on : oldNodes) { - Node node = findEqualInChildren(root, on); - if(node != null) { - ret.add(node); - } - if(root.getName().equals(on.getName())) { - ret.add(root); - } - } - return ret.toArray(new Node[0]); - } - - private Node findEqualInChildren(Node node, Node toFind) { - Node[] children = node.getChildren().getNodes(); - for(Node child : children) { - if(toFind.getName().equals(child.getName())) { - return child; - } - Node n = findEqualInChildren(child, toFind); - if(n != null) { - return n; - } - } - return null; - } - - private void selectFirstNode(final Node root) { - Node[] dateFolders = root.getChildren().getNodes(); - if (dateFolders != null && dateFolders.length > 0) { - final Node[] nodes = dateFolders[0].getChildren().getNodes(); - if (nodes != null && nodes.length > 0) { - setSelection(new Node[]{ nodes[0] }); - } - } - } - - private void selectFirstNeighborNode(Node context, Node oldSelection) { - Node[] children = context.getChildren().getNodes(); - if(children.length > 0 && children[0] instanceof Comparable) { - Node[] newSelection = new Node[] { children[0] } ; - for(int i = 1; i < children.length; i++) { - Comparable c = (Comparable) children[i]; - if( c.compareTo(oldSelection) < 0 ) { - newSelection[0] = children[i]; - } - } - setSelection(newSelection); - tablePanel.getExplorerManager().setExploredContext(context); - } - } - - private void setSelection(final Node[] nodes) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - try { - tablePanel.getExplorerManager().setSelectedNodes(nodes); - } catch (PropertyVetoException ex) { - // ignore - } - } - }); - } - + @Override public void fireHistoryChanged(HistoryEvent evt) { FileObject[] files = tc.getFiles(); if(files == null) { return; } - Set fileSet = new HashSet(); + Set fileSet = new HashSet<>(); for (VCSFileProxy f : evt.getFiles()) { FileObject fo = f != null ? f.toFileObject() : null; if(fo != null) { @@ -523,9 +429,8 @@ private class RefreshTable implements Runnable { public void run() { HistoryRootNode root = getRootNode(); if(root == null) { - final String vcsName = (String) (History.getHistoryProvider(versioningSystem) != null ? - versioningSystem.getDisplayName() : - null); + String vcsName = History.getHistoryProvider(versioningSystem) != null + ? versioningSystem.getDisplayName() : null; root = new HistoryRootNode(vcsName, loadNextAction, createActions()); tablePanel.getExplorerManager().setRootContext(root); } @@ -551,17 +456,13 @@ public void run() { loadVCSEntries(proxies, false); } refreshTask = null; - EventQueue.invokeLater(new Runnable() { - - @Override - public void run () { - tablePanel.revalidate(); - tablePanel.repaint(); - - int row = tablePanel.treeView.getOutline().getSelectedRow(); - if(row > -1) { - scrollToVisible(row, 2); - } + EventQueue.invokeLater(() -> { + tablePanel.revalidate(); + tablePanel.repaint(); + + int row = tablePanel.treeView.getOutline().getSelectedRow(); + if(row > -1) { + scrollToVisible(row, 2); } }); } @@ -579,13 +480,13 @@ private HistoryEntry[] loadLHEntries(VCSFileProxy[] files) { VCSHistoryProvider.HistoryEntry[] vcsHistory = hp.getHistory(files, null); HistoryEntry[] history = new HistoryEntry[vcsHistory.length]; for (int i = 0; i < vcsHistory.length; i++) { - history[i] = new HistoryEntry(vcsHistory[i], true); + history[i] = HistoryEntry.createLocalEntry(vcsHistory[i]); } return history; } private Action[] createActions() { - List actions = new LinkedList(); + List actions = new LinkedList<>(); actions.add(loadNextAction); actions.add(new AbstractAction(NbBundle.getMessage(HistoryFileView.class, "LBL_LoadAll")) { // NOI18N @Override @@ -601,7 +502,7 @@ public void actionPerformed(ActionEvent e) { loadVCSEntries(History.toProxies(tc.getFiles()), true); } }); - return actions.toArray(new Action[0]); + return actions.toArray(Action[]::new); } private class FileTablePanel extends JPanel implements ExplorerManager.Provider, TreeExpansionListener { private final BrowserTreeTableView treeView; @@ -808,11 +709,11 @@ public int compare(Node n1, Node n2) { } else if(HistoryRootNode.isLoadNext(n2) || HistoryRootNode.isWait(n2)) { return etc.isAscending() ? -1 : 1; } - if(n1 instanceof Comparable) { - return ((Comparable)n1).compareTo(n2); + if (n1 instanceof Comparable c1) { + return c1.compareTo(n2); } - if(n2 instanceof Comparable) { - return -((Comparable)n2).compareTo(n1); + if (n2 instanceof Comparable c2) { + return -c2.compareTo(n1); } return n1.getName().compareTo(n2.getName()); } @@ -845,7 +746,7 @@ public int compare(TableEntry e1, TableEntry e2) { } private class NoLeafIconRenderDataProvider implements RenderDataProvider { - private RenderDataProvider delegate; + private final RenderDataProvider delegate; public NoLeafIconRenderDataProvider( RenderDataProvider delegate ) { this.delegate = delegate; } @@ -972,8 +873,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole valueString = sb.toString(); renderer = super.getTableCellRendererComponent(table, valueString, isSelected, hasFocus, row, column); - if(renderer instanceof JComponent) { - JComponent comp = (JComponent)renderer; + if(renderer instanceof JComponent comp) { comp.setToolTipText(getTooltip((Node.Property) value)); } } catch (Exception ex) { @@ -994,8 +894,8 @@ String getDisplayValue(Node.Property p) throws IllegalAccessException, Invocatio String getTooltip(Node.Property p) throws IllegalAccessException, InvocationTargetException { Object value = p.getValue(); - if(value instanceof TableEntry) { - return ((TableEntry) value).getTooltip(); + if(value instanceof TableEntry tableEntry) { + return tableEntry.getTooltip(); } String tooltip = p.toString(); if(tooltip != null && tooltip.contains("\n")) { // NOI18N @@ -1054,9 +954,8 @@ public void mouseDragged(MouseEvent e) {} public void mouseMoved(MouseEvent e) { try { Object value = getValue(e); - if(value instanceof MessageProperty) { - MessageProperty msg = (MessageProperty) value; - if(msg == null || !containsHyperlink(msg.getValue().getDisplayValue())) { + if(value instanceof MessageProperty msg) { + if(!containsHyperlink(msg.getValue().getDisplayValue())) { outline.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } else { outline.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); @@ -1146,14 +1045,11 @@ private void refreshName() { } else { name = NbBundle.getMessage(HistoryRootNode.class, "LBL_LoadNext", HistorySettings.getInstance().getIncrements()); // NOI18N } - final Runnable r = new Runnable() { - @Override - public void run() { - putValue(Action.NAME, name); - HistoryRootNode rootNode = getRootNode(); - if(rootNode != null) { - rootNode.refreshLoadNextName(); - } + Runnable r = () -> { + putValue(Action.NAME, name); + HistoryRootNode rootNode = getRootNode(); + if(rootNode != null) { + rootNode.refreshLoadNextName(); } }; if(EventQueue.isDispatchThread()) { diff --git a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryRootNode.java b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryRootNode.java index c11c61d7a320..6010326333d5 100644 --- a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryRootNode.java +++ b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryRootNode.java @@ -45,7 +45,7 @@ public class HistoryRootNode extends AbstractNode { private static DateFormat dateFormat = DateFormat.getDateInstance(); - private Map revisionEntries = new HashMap(); + private Map revisionEntries = new HashMap<>(); private LoadNextNode loadNextNode; private WaitNode waitNode; @@ -106,29 +106,37 @@ synchronized HistoryEntry getPreviousEntry(HistoryEntry entry) { private void addEntries (HistoryEntry[] entries, boolean vcs, long removeThreshold) { // add new - List nodes = new LinkedList(); + List nodes = new LinkedList<>(); removeOldEntries(entries, !vcs, removeThreshold); for (HistoryEntry e : entries) { - if(!revisionEntries.containsKey(e.getDateTime().getTime())) { - revisionEntries.put(e.getDateTime().getTime(), e); + String key = key(e); + if (!revisionEntries.containsKey(key)) { + revisionEntries.put(key, e); if(vcs) { vcsCount++; } nodes.add(RevisionNode.create(e)); - } + } else { + revisionEntries.get(key).setPos(e.getPos()); + } } if(loadNextNode != null) { loadNextNode.refreshMessage(); } - getChildren().add(nodes.toArray(new Node[0])); + getChildren().add(nodes.toArray(Node[]::new)); + } + + // note: uses rev+time since local history entries return "Local" as revision + private String key(HistoryEntry entry) { + return entry.getRevision() + "-" + entry.getDateTime().getTime(); } private void removeOldEntries (HistoryEntry[] entries, boolean isLocal, long removeThreshold) { - Set timestamps = new HashSet(entries.length); + Set timestamps = new HashSet<>(entries.length); for (HistoryEntry e : entries) { timestamps.add(e.getDateTime().getTime()); } - List toRemove = new ArrayList(); + List toRemove = new ArrayList<>(); for (Node n : getChildren().getNodes()) { HistoryEntry e = n.getLookup().lookup(HistoryEntry.class); if (e != null && isLocal == e.isLocalHistory()) { @@ -139,14 +147,14 @@ private void removeOldEntries (HistoryEntry[] entries, boolean isLocal, long rem History.LOG.log(Level.FINE, "Removing obsolete history entry: {0} {1}", //NOI18N new Object[] { e.getRevisionShort(), e.getMessage() }); toRemove.add(n); - revisionEntries.remove(time); + revisionEntries.remove(key(e)); if (!isLocal) { vcsCount--; } } } } - getChildren().remove(toRemove.toArray(new Node[0])); + getChildren().remove(toRemove.toArray(Node[]::new)); } public synchronized void addWaitNode() { diff --git a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryUtils.java b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryUtils.java index efde2ea2071a..0d9125c43e84 100644 --- a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryUtils.java +++ b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/HistoryUtils.java @@ -39,9 +39,9 @@ public static String escapeForHTMLLabel(String text) { for (int i=0; i': sb.append(">"); break; // NOI18N - default: sb.append(c); + case '<' -> sb.append("<"); // NOI18N + case '>' -> sb.append(">"); // NOI18N + default -> sb.append(c); } } return sb.toString(); diff --git a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/MsgTooltipWindow.java b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/MsgTooltipWindow.java index ce546de2f81a..e2226e6f640f 100644 --- a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/MsgTooltipWindow.java +++ b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/MsgTooltipWindow.java @@ -77,7 +77,7 @@ class MsgTooltipWindow implements AWTEventListener, MouseMotionListener, MouseLi */ private int messageOffset; - private VCSHyperlinkSupport linkerSupport = new VCSHyperlinkSupport(); + private final VCSHyperlinkSupport linkerSupport = new VCSHyperlinkSupport(); /** * Currently showing popup @@ -137,11 +137,8 @@ void show(Point location) { contentWindow.setLocation(location.x, location.y + 1); // slight visual adjustment contentWindow.setVisible(true); - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - cp.scrollRectToVisible(new Rectangle(1, 1)); - } + SwingUtilities.invokeLater(() -> { + cp.scrollRectToVisible(new Rectangle(1, 1)); }); Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.KEY_EVENT_MASK); w.addWindowFocusListener(this); diff --git a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/RevisionNode.java b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/RevisionNode.java index f59238477640..923c4005bf3a 100644 --- a/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/RevisionNode.java +++ b/ide/versioning.ui/src/org/netbeans/modules/versioning/ui/history/RevisionNode.java @@ -41,15 +41,16 @@ * @author Tomas Stupka * */ +@SuppressWarnings("AccessingNonPublicFieldOfAnotherObject") class RevisionNode extends AbstractNode implements Comparable { static final String PROPERTY_NAME_LABEL = "label"; // NOI18N static final String PROPERTY_NAME_USER = "user"; // NOI18N static final String PROPERTY_NAME_VERSION = "version"; // NOI18N - private HistoryEntry entry; - private static DateFormat dateFormat = DateFormat.getDateTimeInstance(); - private static DateFormat timeFormat = DateFormat.getTimeInstance(); + private final HistoryEntry entry; + private static final DateFormat dateFormat = DateFormat.getDateTimeInstance(); + private static final DateFormat timeFormat = DateFormat.getTimeInstance(); private RevisionNode(HistoryEntry entry, Lookup l) { super(createChildren(entry), l); @@ -58,7 +59,7 @@ private RevisionNode(HistoryEntry entry, Lookup l) { } static RevisionNode create(HistoryEntry entry) { - List lookup = new LinkedList(); + List lookup = new LinkedList<>(); VCSFileProxy[] proxies = entry.getFiles(); for (VCSFileProxy proxy : proxies) { lookup.add(proxy); @@ -69,7 +70,7 @@ static RevisionNode create(HistoryEntry entry) { } lookup.addAll(Arrays.asList(entry.getLookupObjects())); lookup.add(entry); - return new RevisionNode(entry, Lookups.fixed(lookup.toArray(new Object[0]))); + return new RevisionNode(entry, Lookups.fixed(lookup.toArray(Object[]::new))); } private static Children createChildren(HistoryEntry entry) { @@ -116,11 +117,11 @@ public String toString() { static String getFormatedDate(HistoryEntry se) { int day = getDay(se.getDateTime().getTime()); - switch(day) { - case 0: return NbBundle.getMessage(RevisionNode.class, "LBL_Today", new Object[] {timeFormat.format(se.getDateTime())}); - case 1: return NbBundle.getMessage(RevisionNode.class, "LBL_Yesterday", new Object[] {timeFormat.format(se.getDateTime())}); - default: return dateFormat.format(se.getDateTime()); - } + return switch (day) { + case 0 -> NbBundle.getMessage(RevisionNode.class, "LBL_Today", new Object[] {timeFormat.format(se.getDateTime())}); + case 1 -> NbBundle.getMessage(RevisionNode.class, "LBL_Yesterday", new Object[] {timeFormat.format(se.getDateTime())}); + default -> dateFormat.format(se.getDateTime()); + }; } private static int getDay(long ts) { @@ -154,11 +155,16 @@ public int compareTo(Object obj) { return -1; } RevisionNode node = (RevisionNode) obj; - return entry.getDateTime().compareTo(node.entry.getDateTime()); + + if (entry.isLocalHistory() || node.entry.isLocalHistory()) { + return entry.getDateTime().compareTo(node.entry.getDateTime()); + } else { + return Integer.compare(entry.getPos(), node.entry.getPos()); + } } class MessageProperty extends PropertySupport.ReadOnly { - private TableEntry te; + private final TableEntry te; public MessageProperty() { super(PROPERTY_NAME_LABEL, TableEntry.class, NbBundle.getMessage(RevisionNode.class, "LBL_LabelProperty_Name"), NbBundle.getMessage(RevisionNode.class, "LBL_LabelProperty_Desc")); te = new TableEntry() { @@ -237,7 +243,7 @@ public String getDisplayValue() { @Override public String getTooltip() { String tooltip = entry.getMessage(); - if(tooltip == null || "".equals(tooltip.trim())) { // NOI18N + if(tooltip == null || tooltip.isBlank()) { tooltip = NbBundle.getMessage(RevisionNode.class, "LBL_SetTooltip"); // NOI18N } return tooltip; @@ -275,7 +281,7 @@ public boolean equals(Object obj) { } class UserProperty extends PropertySupport.ReadOnly { - private TableEntry te; + private final TableEntry te; public UserProperty() { super(PROPERTY_NAME_USER, TableEntry.class, NbBundle.getMessage(RevisionNode.class, "LBL_UserProperty_Name"), NbBundle.getMessage(RevisionNode.class, "LBL_UserProperty_Desc")); te = new UserEntry(entry); @@ -369,8 +375,8 @@ public int compareTo(TableEntry e) { Integer i1; Integer i2; try { - i1 = Integer.parseInt(getDisplayValue()); - i2 = Integer.parseInt(e.getDisplayValue()); + i1 = Integer.valueOf(getDisplayValue()); + i2 = Integer.valueOf(e.getDisplayValue()); return i1.compareTo(i2); } catch (NumberFormatException ex) {} return super.compareTo(e); @@ -413,7 +419,7 @@ static class FileNode extends AbstractNode implements Comparable { } private static Lookup createLookup(VCSFileProxy proxy, HistoryEntry entry) { - List lookup = new LinkedList(); + List lookup = new LinkedList<>(); lookup.add(proxy); File f = proxy.toFile(); if(f != null) { @@ -421,7 +427,7 @@ private static Lookup createLookup(VCSFileProxy proxy, HistoryEntry entry) { } lookup.add(entry); lookup.addAll(Arrays.asList(entry.getLookupObjects())); - return Lookups.fixed(lookup.toArray(new Object[0])); + return Lookups.fixed(lookup.toArray(Object[]::new)); } @Override diff --git a/ide/versioning.ui/test/unit/src/org/netbeans/modules/versioning/ui/history/HistoryTestKit.java b/ide/versioning.ui/test/unit/src/org/netbeans/modules/versioning/ui/history/HistoryTestKit.java index 65345c803256..a89a5868b89e 100644 --- a/ide/versioning.ui/test/unit/src/org/netbeans/modules/versioning/ui/history/HistoryTestKit.java +++ b/ide/versioning.ui/test/unit/src/org/netbeans/modules/versioning/ui/history/HistoryTestKit.java @@ -26,6 +26,6 @@ */ public class HistoryTestKit { public static Node createHistoryNode(org.netbeans.modules.versioning.core.spi.VCSHistoryProvider.HistoryEntry entry) { - return RevisionNode.create(new HistoryEntry(entry, false)); + return RevisionNode.create(HistoryEntry.createVCSEntry(entry, 42)); } }