22
33import java .io .IOException ;
44import java .nio .file .Path ;
5+ import java .util .List ;
56import java .util .Optional ;
67
78import org .jabref .gui .DialogService ;
89import org .jabref .gui .StateManager ;
10+ import org .jabref .gui .actions .ActionHelper ;
911import org .jabref .gui .actions .SimpleCommand ;
1012import org .jabref .gui .preferences .GuiPreferences ;
1113import org .jabref .logic .JabRefException ;
1416import org .jabref .logic .git .conflicts .GitConflictResolverStrategy ;
1517import org .jabref .logic .git .merge .GitSemanticMergeExecutor ;
1618import org .jabref .logic .git .merge .GitSemanticMergeExecutorImpl ;
19+ import org .jabref .logic .git .model .PullResult ;
1720import org .jabref .logic .git .util .GitHandlerRegistry ;
1821import org .jabref .logic .l10n .Localization ;
1922import org .jabref .logic .util .BackgroundTask ;
2023import org .jabref .logic .util .TaskExecutor ;
2124import org .jabref .model .database .BibDatabaseContext ;
25+ import org .jabref .model .entry .BibEntry ;
2226
27+ import com .airhacks .afterburner .injection .Injector ;
2328import org .eclipse .jgit .api .errors .GitAPIException ;
2429
2530public class GitPullAction extends SimpleCommand {
@@ -28,18 +33,17 @@ public class GitPullAction extends SimpleCommand {
2833 private final StateManager stateManager ;
2934 private final GuiPreferences guiPreferences ;
3035 private final TaskExecutor taskExecutor ;
31- private final GitHandlerRegistry handlerRegistry ;
3236
3337 public GitPullAction (DialogService dialogService ,
3438 StateManager stateManager ,
3539 GuiPreferences guiPreferences ,
36- TaskExecutor taskExecutor ,
37- GitHandlerRegistry handlerRegistry ) {
40+ TaskExecutor taskExecutor ) {
3841 this .dialogService = dialogService ;
3942 this .stateManager = stateManager ;
4043 this .guiPreferences = guiPreferences ;
4144 this .taskExecutor = taskExecutor ;
42- this .handlerRegistry = handlerRegistry ;
45+
46+ this .executable .bind (ActionHelper .needsDatabase (stateManager ).and (ActionHelper .needsGitRemoteConfigured (stateManager )));
4347 }
4448
4549 @ Override
@@ -64,57 +68,87 @@ public void execute() {
6468 }
6569
6670 Path bibFilePath = bibFilePathOpt .get ();
67- GitHandler handler = new GitHandler (bibFilePath .getParent ());
68- GitConflictResolverDialog dialog = new GitConflictResolverDialog (dialogService , guiPreferences );
69- GitConflictResolverStrategy resolver = new GuiGitConflictResolverStrategy (dialog );
70- GitSemanticMergeExecutor mergeExecutor = new GitSemanticMergeExecutorImpl (guiPreferences .getImportFormatPreferences ());
7171
72- GitSyncService syncService = new GitSyncService (guiPreferences .getImportFormatPreferences (), handlerRegistry , resolver , mergeExecutor );
73- GitStatusViewModel statusViewModel = new GitStatusViewModel (stateManager , bibFilePath );
74- GitPullViewModel viewModel = new GitPullViewModel (syncService , statusViewModel );
72+ GitHandlerRegistry registry = Injector .instantiateModelOrService (GitHandlerRegistry .class );
73+ GitStatusViewModel gitStatusViewModel = GitStatusViewModel .fromPathAndContext (stateManager , taskExecutor , registry , bibFilePath );
7574
7675 BackgroundTask
77- .wrap (() -> viewModel . pull ( ))
76+ .wrap (() -> doPull ( activeDatabase , bibFilePath , stateManager , registry ))
7877 .onSuccess (result -> {
79- if (result .isSuccessful ()) {
78+ if (result .noop ()) {
8079 dialogService .showInformationDialogAndWait (
8180 Localization .lang ("Git Pull" ),
82- Localization .lang ("Successfully merged and updated." )
83- );
84- } else {
85- dialogService .showWarningDialogAndWait (
86- Localization .lang ("Git Pull" ),
87- Localization .lang ("Merge completed with conflicts." )
88- );
89- }
90- })
91- .onFailure (ex -> {
92- if (ex instanceof JabRefException e ) {
93- dialogService .showErrorDialogAndWait (
94- Localization .lang ("Git Pull Failed" ),
95- e .getLocalizedMessage (),
96- e
97- );
98- } else if (ex instanceof GitAPIException e ) {
99- dialogService .showErrorDialogAndWait (
100- Localization .lang ("Git Pull Failed" ),
101- Localization .lang ("An unexpected Git error occurred: %0" , e .getLocalizedMessage ()),
102- e
103- );
104- } else if (ex instanceof IOException e ) {
105- dialogService .showErrorDialogAndWait (
106- Localization .lang ("Git Pull Failed" ),
107- Localization .lang ("I/O error: %0" , e .getLocalizedMessage ()),
108- e
109- );
110- } else {
111- dialogService .showErrorDialogAndWait (
112- Localization .lang ("Git Pull Failed" ),
113- Localization .lang ("Unexpected error: %0" , ex .getLocalizedMessage ()),
114- ex
81+ Localization .lang ("Already up to date." )
11582 );
83+ } else if (result .isSuccessful ()) {
84+ try {
85+ replaceWithMergedEntries (result .getMergedEntries (), activeDatabase );
86+ gitStatusViewModel .refresh (bibFilePath );
87+ dialogService .showInformationDialogAndWait (
88+ Localization .lang ("Git Pull" ),
89+ Localization .lang ("Merged and updated." ));
90+ } catch (IOException | JabRefException ex ) {
91+ showPullError (ex );
92+ }
11693 }
11794 })
95+ .onFailure (exception -> showPullError (exception ))
11896 .executeWith (taskExecutor );
11997 }
98+
99+ private PullResult doPull (BibDatabaseContext databaseContext , Path bibPath , StateManager stateManager , GitHandlerRegistry registry ) throws IOException , GitAPIException , JabRefException {
100+ GitSyncService syncService = buildSyncService (bibPath , registry );
101+ GitHandler handler = registry .get (bibPath .getParent ());
102+ String user = guiPreferences .getGitPreferences ().getUsername ();
103+ String pat = guiPreferences .getGitPreferences ().getPat ();
104+ handler .setCredentials (user , pat );
105+ return syncService .fetchAndMerge (databaseContext , bibPath );
106+ }
107+
108+ private GitSyncService buildSyncService (Path bibPath , GitHandlerRegistry handlerRegistry ) throws JabRefException {
109+ GitConflictResolverDialog dialog = new GitConflictResolverDialog (dialogService , guiPreferences );
110+ GitConflictResolverStrategy resolver = new GuiGitConflictResolverStrategy (dialog );
111+ GitSemanticMergeExecutor mergeExecutor = new GitSemanticMergeExecutorImpl (guiPreferences .getImportFormatPreferences ());
112+
113+ return new GitSyncService (guiPreferences .getImportFormatPreferences (), handlerRegistry , resolver , mergeExecutor );
114+ }
115+
116+ private void showPullError (Throwable exception ) {
117+ if (exception instanceof JabRefException e ) {
118+ dialogService .showErrorDialogAndWait (
119+ Localization .lang ("Git Pull Failed" ),
120+ e .getLocalizedMessage (),
121+ e
122+ );
123+ } else if (exception instanceof GitAPIException e ) {
124+ dialogService .showErrorDialogAndWait (
125+ Localization .lang ("Git Pull Failed" ),
126+ Localization .lang ("An unexpected Git error occurred: %0" , e .getLocalizedMessage ()),
127+ e
128+ );
129+ } else if (exception instanceof IOException e ) {
130+ dialogService .showErrorDialogAndWait (
131+ Localization .lang ("Git Pull Failed" ),
132+ Localization .lang ("I/O error: %0" , e .getLocalizedMessage ()),
133+ e
134+ );
135+ } else {
136+ dialogService .showErrorDialogAndWait (
137+ Localization .lang ("Git Pull Failed" ),
138+ Localization .lang ("Unexpected error: %0" , exception .getLocalizedMessage ()),
139+ exception
140+ );
141+ }
142+ }
143+
144+ private void replaceWithMergedEntries (List <BibEntry > mergedEntries , BibDatabaseContext databaseContext ) throws IOException , JabRefException {
145+ List <BibEntry > currentEntries = List .copyOf (databaseContext .getDatabase ().getEntries ());
146+ for (BibEntry entry : currentEntries ) {
147+ databaseContext .getDatabase ().removeEntry (entry );
148+ }
149+
150+ for (BibEntry entry : mergedEntries ) {
151+ databaseContext .getDatabase ().insertEntry (new BibEntry (entry ));
152+ }
153+ }
120154}
0 commit comments