Skip to content

Commit 8b92f7c

Browse files
authored
Merge pull request #364 from SeeSharpSoft/main
Release 3.0.1
2 parents 60ba0f6 + 43a9157 commit 8b92f7c

10 files changed

+46
-68
lines changed

CHANGELOG

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
3.0.1
2-
Nov 11, 2022
2+
Nov 12, 2022
33

44
FIX: cannot init component state (componentName=CsvFileAttributes) #359
5+
FIX: cannot invoke "add(Object)" because "this.myUncommittedActions" is null #361
6+
FIX: cannot invoke "createNotification(...)" because "notificationGroup" is null #362
7+
FIX: cannot invoke "getManager()" because the return value of "getPsiFile()" is null #363
58
FIX: image in plugin description
69
FIX: plugin update restart
710

build.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ PS: The previous versions are still available on the project page.
110110
Update 3.0.1
111111
112112
FIX: cannot init component state (componentName=CsvFileAttributes) #359
113+
FIX: cannot invoke "add(Object)" because "this.myUncommittedActions" is null #361
114+
FIX: cannot invoke "createNotification(...)" because "notificationGroup" is null #362
115+
FIX: cannot invoke "getManager()" because the return value of "getPsiFile()" is null #363
113116
FIX: image in plugin description
114117
FIX: plugin update restart
115118

src/main/java/net/seesharpsoft/intellij/plugins/csv/CsvGithubIssueSubmitter.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ protected boolean submit(IdeaLoggingEvent event, String additionalInfo, Project
6363
}
6464
GithubAccount githubAccount = githubAuthManager.getSingleOrDefaultAccount(project);
6565
assert githubAccount != null;
66-
// the cast shouldn't be needed due to inheritance, but Java complains for some reason in 2022.1
67-
GithubApiRequestExecutor githubExecutor = GithubApiRequestExecutor.class.cast(GithubApiRequestExecutorManager.getInstance().getExecutor(githubAccount, project));
66+
GithubApiRequestExecutor githubExecutor = GithubApiRequestExecutorManager.getInstance().getExecutor(githubAccount, project);
6867

6968
Task submitTask = new Task.Backgroundable(project, getReportActionText()) {
7069
@Override

src/main/java/net/seesharpsoft/intellij/plugins/csv/CsvPlugin.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ public void run(@NotNull ProgressIndicator progressIndicator) {
6666
public void runActivity(@NotNull Project project) {
6767
doAsyncProjectMaintenance(project);
6868

69-
if (CsvEditorSettings.getInstance().checkCurrentPluginVersion(getVersion())) {
69+
NotificationGroup notificationGroup = NotificationGroupManager.getInstance().getNotificationGroup("net.seesharpsoft.intellij.plugins.csv");
70+
if (notificationGroup == null || CsvEditorSettings.getInstance().checkCurrentPluginVersion(getVersion())) {
7071
return;
7172
}
7273

73-
NotificationGroup notificationGroup = NotificationGroupManager.getInstance().getNotificationGroup("net.seesharpsoft.intellij.plugins.csv");
7474
Notification notification = notificationGroup.createNotification(
7575
"CSV Editor " + getVersion() + " - Change Notes",
7676
getChangeNotes() +

src/main/java/net/seesharpsoft/intellij/plugins/csv/components/CsvFileAttributes.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ public CsvFileAttributes getState() {
5151
}
5252

5353
@Override
54-
public void loadState(@NotNull CsvFileAttributes state) {
54+
public synchronized void loadState(@NotNull CsvFileAttributes state) {
5555
XmlSerializerUtil.copyBean(state, this);
5656
}
5757

58-
public void cleanupAttributeMap(@NotNull Project project) {
58+
public synchronized void cleanupAttributeMap(@NotNull Project project) {
5959
List<String> faultyFiles = new ArrayList<>();
6060
attributeMap.forEach((fileName, attribute) -> {
6161
if (!CsvStorageHelper.csvFileExists(project, fileName)) {
@@ -153,7 +153,7 @@ private CsvValueSeparator autoDetectSeparator(Project project, VirtualFile virtu
153153
// ignore non-matched separators
154154
.filter(p -> p.getSecond() > 0)
155155
// get the one with most hits
156-
.max((p1, p2) -> p1.getSecond() - p2.getSecond())
156+
.max(Comparator.comparingInt(Pair::getSecond))
157157
// failsafe (e.g. empty document)
158158
.orElse(null);
159159

src/main/java/net/seesharpsoft/intellij/plugins/csv/editor/table/CsvTableModelBase.java

+22-13
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package net.seesharpsoft.intellij.plugins.csv.editor.table;
22

3-
import com.intellij.psi.PsiElement;
4-
import com.intellij.psi.PsiFile;
5-
import com.intellij.psi.PsiTreeAnyChangeAbstractAdapter;
6-
import com.intellij.psi.PsiTreeChangeListener;
3+
import com.intellij.psi.*;
74
import com.intellij.psi.util.PsiTreeUtil;
85
import net.seesharpsoft.intellij.plugins.csv.CsvEscapeCharacter;
96
import net.seesharpsoft.intellij.plugins.csv.CsvHelper;
@@ -25,10 +22,8 @@ public class CsvTableModelBase<T extends PsiFileHolder> implements CsvTableModel
2522
private int myCachedColumnCount = -1;
2623
private CsvEscapeCharacter myCachedEscapeCharacter;
2724
private Boolean myCachedHasErrors = null;
28-
2925
private int myPointedRow = -1;
3026
private PsiElement myPointedRecord = null;
31-
3227
private final CsvPsiTreeUpdater myPsiTreeUpdater;
3328

3429
private final PsiTreeChangeListener myPsiTreeChangeListener = new PsiTreeAnyChangeAbstractAdapter() {
@@ -42,18 +37,34 @@ public CsvTableModelBase(@NotNull T psiFileHolder) {
4237
myPsiFileHolder = psiFileHolder;
4338
myPsiTreeUpdater = new CsvPsiTreeUpdater(psiFileHolder);
4439
myPsiTreeUpdater.addCommitListener(() -> onPsiTreeChanged(getPsiFile()));
45-
getPsiFile().getManager().addPsiTreeChangeListener(myPsiTreeChangeListener, myPsiFileHolder);
40+
addPsiTreeChangeListener();
4641
}
4742

4843
public T getPsiFileHolder() {
4944
return myPsiFileHolder;
5045
}
5146

47+
protected void addPsiTreeChangeListener() {
48+
PsiFile psiFile = getPsiFile();
49+
if (psiFile == null) return;
50+
PsiManager manager = psiFile.getManager();
51+
if (manager == null) return;
52+
manager.addPsiTreeChangeListener(myPsiTreeChangeListener, myPsiFileHolder);
53+
}
54+
55+
protected void removePsiTreeChangeListener() {
56+
PsiFile psiFile = getPsiFile();
57+
if (psiFile == null) return;
58+
PsiManager manager = psiFile.getManager();
59+
if (manager == null) return;
60+
manager.removePsiTreeChangeListener(myPsiTreeChangeListener);
61+
}
62+
5263
@Override
5364
public void dispose() {
5465
CsvTableModel.super.dispose();
55-
getPsiFile().getManager().removePsiTreeChangeListener(myPsiTreeChangeListener);
5666
myPsiTreeUpdater.dispose();
67+
removePsiTreeChangeListener();
5768
}
5869

5970
private void onPsiTreeChanged(@Nullable PsiFile file) {
@@ -80,10 +91,9 @@ private void resetCachedValues() {
8091
myCachedEscapeCharacter = null;
8192
}
8293

83-
private PsiElement resetPointer() {
94+
private void resetPointer() {
8495
myPointedRecord = PsiTreeUtil.findChildOfType(getPsiFile(), CsvRecord.class);
8596
myPointedRow = 0;
86-
return myPointedRecord;
8797
}
8898

8999
protected CsvPsiTreeUpdater getPsiTreeUpdater() {
@@ -104,9 +114,7 @@ public PsiElement getFieldAt(int row, int column) {
104114
resetPointer();
105115
diffToCurrent = row;
106116
}
107-
// fail gracefully or not?!
108117
if (myPointedRecord == null) return null;
109-
assert myPointedRecord != null;
110118

111119
CsvRecord record = PsiHelper.getNthSiblingOfType(myPointedRecord, diffToCurrent, CsvRecord.class, myPointedRow > row);
112120
if (record == null) return null;
@@ -176,14 +184,15 @@ public void setValueAt(String value, int rowIndex, int columnIndex, boolean comm
176184
}
177185

178186
@Override
179-
public String getValue(int rowIndex, int columnIndex) {
187+
public @NotNull String getValue(int rowIndex, int columnIndex) {
180188
PsiElement field = getFieldAt(rowIndex, columnIndex);
181189
return CsvHelper.getFieldValue(field, getEscapeCharacter());
182190
}
183191

184192
@Override
185193
public void addRow(int anchorRowIndex, boolean before) {
186194
CsvRecord row = PsiHelper.getNthChildOfType(getPsiFile(), anchorRowIndex, CsvRecord.class);
195+
if (row == null) return;
187196
getPsiTreeUpdater().addRow(row, before);
188197
getPsiTreeUpdater().commit();
189198
}

src/main/java/net/seesharpsoft/intellij/plugins/csv/editor/table/swing/CsvTableEditorSwing.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ public class CsvTableEditorSwing extends CsvTableEditor {
3434
private JComponent panelInfo;
3535
private JScrollPane tableScrollPane;
3636
private JPanel panelTop;
37-
3837
private JTable rowHeadersTable;
3938

4039
private int baseFontHeight;
@@ -44,7 +43,6 @@ public class CsvTableEditorSwing extends CsvTableEditor {
4443
protected final CsvTableEditorMouseListener tableEditorMouseListener;
4544
protected final CsvTableEditorKeyListener tableEditorKeyListener;
4645
protected final CsvTableEditorMouseWheelListener tableEditorMouseWheelListener;
47-
4846
private boolean listenerApplied = false;
4947

5048

@@ -236,7 +234,7 @@ public void selectColumn(int currentColumn, boolean append) {
236234

237235
@NotNull
238236
@Override
239-
public CsvTableActions getActions() {
237+
public CsvTableActions<CsvTableEditorSwing> getActions() {
240238
return this.tableEditorActions;
241239
}
242240

src/main/java/net/seesharpsoft/intellij/plugins/csv/psi/CsvPsiTreeUpdater.java

+5-7
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class CsvPsiTreeUpdater implements PsiFileHolder, Suspendable {
3030

3131
private final CsvPsiParserFileType myFileType;
3232

33-
protected final EventListenerList listenerList = new EventListenerList();
33+
protected final EventListenerList myEventListenerList = new EventListenerList();
3434

3535
private List<PsiAction> myUncommittedActions = new ArrayList<>();
3636

@@ -83,7 +83,6 @@ public PsiFile getPsiFile() {
8383
@Override
8484
public void dispose() {
8585
Suspendable.super.dispose();
86-
myUncommittedActions = null;
8786
}
8887

8988
public @Nullable PsiElement createValueSeparator() {
@@ -95,7 +94,7 @@ public void dispose() {
9594
}
9695

9796
public void doAction(PsiAction action) {
98-
myUncommittedActions.add(action);
97+
if (myUncommittedActions != null) myUncommittedActions.add(action);
9998
}
10099

101100
public void appendEmptyFields(@NotNull PsiElement anchor, int no) {
@@ -325,7 +324,6 @@ public synchronized void commit() {
325324
try {
326325
actionsToCommit.forEach(PsiAction::execute);
327326
} finally {
328-
PsiDocumentManager.getInstance(getPsiFile().getProject()).doPostponedOperationsAndUnblockDocument(getDocument());
329327
resume();
330328
fireCommitted();
331329
}
@@ -354,16 +352,16 @@ private boolean doCommit(@NotNull Runnable runnable) {
354352
}
355353

356354
public void addCommitListener(CommitListener l) {
357-
listenerList.add(CommitListener.class, l);
355+
myEventListenerList.add(CommitListener.class, l);
358356
}
359357

360358
public void removeCommitListener(CommitListener l) {
361-
listenerList.remove(CommitListener.class, l);
359+
myEventListenerList.remove(CommitListener.class, l);
362360
}
363361

364362
protected void fireCommitted() {
365363
// Guaranteed to return a non-null array
366-
Object[] listeners = listenerList.getListenerList();
364+
Object[] listeners = myEventListenerList.getListenerList();
367365
// Process the listeners last to first, notifying
368366
// those that are interested in this event
369367
for (int i = listeners.length - 2; i >= 0; i -= 2) {

src/main/java/net/seesharpsoft/intellij/util/CheckedDisposableAwareRunnable.java

-33
This file was deleted.

src/main/java/net/seesharpsoft/intellij/util/Suspendable.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import java.util.HashMap;
66
import java.util.Map;
7+
import java.util.concurrent.ConcurrentHashMap;
78

89
public interface Suspendable extends Disposable {
910
SuspensionMonitor MONITOR = new SuspensionMonitor();
@@ -25,14 +26,14 @@ default void dispose() {
2526
}
2627

2728
class SuspensionMonitor {
28-
private final Map<Suspendable, Integer> suspendableCounterMap = new HashMap<>();
29+
private final Map<Suspendable, Integer> suspendableCounterMap = new ConcurrentHashMap<>();
2930

3031
private Integer getSuspendableCounter(Suspendable suspendable) {
3132
if (suspendableCounterMap.containsKey(suspendable)) return suspendableCounterMap.get(suspendable);
3233
return null;
3334
}
3435

35-
void suspend(Suspendable suspendable) {
36+
synchronized void suspend(Suspendable suspendable) {
3637
Integer suspendableCounter = getSuspendableCounter(suspendable);
3738
if (suspendableCounter == null) {
3839
suspendableCounterMap.put(suspendable, 1);
@@ -41,7 +42,7 @@ void suspend(Suspendable suspendable) {
4142
}
4243
}
4344

44-
void resume(Suspendable suspendable) {
45+
synchronized void resume(Suspendable suspendable) {
4546
Integer suspendableCounter = getSuspendableCounter(suspendable);
4647
// this usually shouldn't happen but doesn't hurt, so fail gracefully
4748
if (suspendableCounter == null) return;
@@ -55,7 +56,7 @@ boolean isSuspended(Suspendable suspendable) {
5556
return suspendableCounter != null;
5657
}
5758

58-
void unwatch(Suspendable suspendable) {
59+
synchronized void unwatch(Suspendable suspendable) {
5960
suspendableCounterMap.remove(suspendable);
6061
}
6162
}

0 commit comments

Comments
 (0)