Skip to content

Commit c1e05b8

Browse files
committed
Track adding/removing/changing files in AspectChangeContext
1 parent 50fb68b commit c1e05b8

File tree

9 files changed

+190
-50
lines changed

9 files changed

+190
-50
lines changed

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/edit/AspectChangeContext.java

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,42 @@
1313

1414
package org.eclipse.esmf.aspectmodel.edit;
1515

16+
import java.io.IOException;
17+
import java.nio.file.Files;
18+
import java.nio.file.Path;
19+
import java.nio.file.Paths;
1620
import java.util.ArrayDeque;
1721
import java.util.Deque;
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.stream.Stream;
1826

1927
import org.eclipse.esmf.aspectmodel.AspectModelBuilder;
28+
import org.eclipse.esmf.aspectmodel.AspectModelFile;
2029
import org.eclipse.esmf.metamodel.AspectModel;
2130
import org.eclipse.esmf.metamodel.impl.DefaultAspectModel;
2231

23-
public class AspectChangeContext {
32+
import org.slf4j.Logger;
33+
import org.slf4j.LoggerFactory;
34+
35+
public class AspectChangeContext implements ChangeContext {
36+
private static final Logger LOG = LoggerFactory.getLogger( AspectChangeContext.class );
37+
2438
private final Deque<Change> undoStack = new ArrayDeque<>();
2539
private final Deque<Change> redoStack = new ArrayDeque<>();
2640
private final DefaultAspectModel aspectModel;
2741
private final AspectChangeContextConfig config;
42+
private final Map<AspectModelFile, FileState> fileState = new HashMap<>();
43+
private boolean isUndoOperation = false;
44+
45+
private enum FileState {
46+
CREATED, CHANGED, REMOVED
47+
}
2848

2949
public AspectChangeContext( final AspectChangeContextConfig config, final AspectModel aspectModel ) {
3050
this.config = config;
51+
resetFileStates();
3152
if ( aspectModel instanceof final DefaultAspectModel defaultAspectModel ) {
3253
this.aspectModel = defaultAspectModel;
3354
} else {
@@ -40,7 +61,9 @@ public AspectChangeContext( final AspectModel aspectModel ) {
4061
}
4162

4263
public synchronized ChangeReport applyChange( final Change change ) {
43-
final ChangeReport result = change.fire( new ChangeContext( aspectModel.files(), config ) );
64+
resetFileStates();
65+
isUndoOperation = false;
66+
final ChangeReport result = change.fire( this );
4467
updateAspectModelAfterChange();
4568
undoStack.offerLast( change.reverse() );
4669
return result;
@@ -50,8 +73,10 @@ public synchronized void undoChange() {
5073
if ( undoStack.isEmpty() ) {
5174
return;
5275
}
76+
isUndoOperation = true;
77+
resetFileStates();
5378
final Change change = undoStack.pollLast();
54-
change.fire( new ChangeContext( aspectModel.files(), config ) );
79+
change.fire( this );
5580
updateAspectModelAfterChange();
5681
redoStack.offerLast( change.reverse() );
5782
}
@@ -60,8 +85,10 @@ public synchronized void redoChange() {
6085
if ( redoStack.isEmpty() ) {
6186
return;
6287
}
88+
resetFileStates();
6389
final Change change = redoStack.pollLast();
64-
change.fire( new ChangeContext( aspectModel.files(), config ) );
90+
isUndoOperation = false;
91+
change.fire( this );
6592
updateAspectModelAfterChange();
6693
undoStack.offerLast( change.reverse() );
6794
}
@@ -72,4 +99,63 @@ private void updateAspectModelAfterChange() {
7299
aspectModel.setElements( updatedModel.elements() );
73100
aspectModel.setFiles( updatedModel.files() );
74101
}
102+
103+
@Override
104+
public Stream<AspectModelFile> aspectModelFiles() {
105+
return aspectModel.files().stream();
106+
}
107+
108+
@Override
109+
public AspectChangeContextConfig config() {
110+
return config;
111+
}
112+
113+
@Override
114+
public List<AspectModelFile> createdFiles() {
115+
return fileState.entrySet().stream()
116+
.filter( entry -> entry.getValue() == FileState.CREATED )
117+
.map( Map.Entry::getKey )
118+
.toList();
119+
}
120+
121+
@Override
122+
public List<AspectModelFile> modifiedFiles() {
123+
return fileState.entrySet().stream()
124+
.filter( entry -> entry.getValue() == FileState.CHANGED )
125+
.map( Map.Entry::getKey )
126+
.toList();
127+
}
128+
129+
@Override
130+
public List<AspectModelFile> removedFiles() {
131+
return fileState.entrySet().stream()
132+
.filter( entry -> entry.getValue() == FileState.REMOVED )
133+
.map( Map.Entry::getKey )
134+
.toList();
135+
}
136+
137+
@Override
138+
public void resetFileStates() {
139+
fileState.clear();
140+
}
141+
142+
@Override
143+
public void indicateFileIsAdded( final AspectModelFile file ) {
144+
fileState.put( file, FileState.CREATED );
145+
aspectModel.files().add( file );
146+
}
147+
148+
@Override
149+
public void indicateFileIsRemoved( final AspectModelFile file ) {
150+
fileState.put( file, FileState.REMOVED );
151+
aspectModel.files().remove( file );
152+
}
153+
154+
@Override
155+
public void indicateFileHasChanged( final AspectModelFile file ) {
156+
// If the file was newly created, keep this state even if we now change the file content
157+
if ( fileState.get( file ) != FileState.CREATED ) {
158+
fileState.put( file, FileState.CHANGED );
159+
}
160+
}
75161
}

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/edit/ChangeContext.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,26 @@
1414
package org.eclipse.esmf.aspectmodel.edit;
1515

1616
import java.util.List;
17+
import java.util.stream.Stream;
1718

1819
import org.eclipse.esmf.aspectmodel.AspectModelFile;
1920

20-
public record ChangeContext(
21-
List<AspectModelFile> aspectModelFiles,
22-
AspectChangeContextConfig config ) {
21+
public interface ChangeContext {
22+
Stream<AspectModelFile> aspectModelFiles();
23+
24+
AspectChangeContextConfig config();
25+
26+
List<AspectModelFile> createdFiles();
27+
28+
List<AspectModelFile> modifiedFiles();
29+
30+
List<AspectModelFile> removedFiles();
31+
32+
void indicateFileIsAdded( AspectModelFile file );
33+
34+
void indicateFileIsRemoved( AspectModelFile file );
35+
36+
void indicateFileHasChanged( AspectModelFile file );
37+
38+
void resetFileStates();
2339
}

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/edit/change/AddAspectModelFile.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public AddAspectModelFile( final AspectModelFile newFile ) {
3333

3434
@Override
3535
public ChangeReport fire( final ChangeContext changeContext ) {
36-
changeContext.aspectModelFiles().add( newFile );
36+
changeContext.indicateFileIsAdded( newFile );
3737
final Model contentToAdd = ModelFactory.createDefaultModel();
3838
contentToAdd.add( newFile.sourceModel() );
3939
return new ChangeReport.EntryWithDetails( "Add file " + show( newFile ),
@@ -46,7 +46,7 @@ public Change reverse() {
4646
@Override
4747
public ChangeReport fire( final ChangeContext changeContext ) {
4848
final AspectModelFile file = fileToRemove( changeContext );
49-
changeContext.aspectModelFiles().remove( file );
49+
changeContext.indicateFileIsRemoved( file );
5050
return new ChangeReport.EntryWithDetails( "Remove file " + show( file ),
5151
Map.of( "model content to remove", file.sourceModel() ) );
5252
}
@@ -57,7 +57,7 @@ public Change reverse() {
5757
}
5858

5959
private AspectModelFile fileToRemove( final ChangeContext changeContext ) {
60-
return changeContext.aspectModelFiles().stream()
60+
return changeContext.aspectModelFiles()
6161
.filter( file -> file.sourceLocation().equals( newFile.sourceLocation() ) )
6262
.findFirst()
6363
.orElseThrow( () -> new ModelChangeException( "Unable to remove Aspect Model File" ) );

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/edit/change/EditAspectModel.java

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -28,41 +28,37 @@ protected record ModelChanges( Model add, Model remove, String description ) {
2828
public static final ModelChanges NONE = new ModelChanges( null, null, "" );
2929
}
3030

31-
protected Map<AspectModelFile, ModelChanges> changesPerFile = null;
32-
33-
synchronized protected void prepare( final ChangeContext changeContext ) {
34-
if ( changesPerFile == null ) {
35-
changesPerFile = changeContext.aspectModelFiles().stream()
36-
.map( file -> new AbstractMap.SimpleEntry<>( file, calculateChangesForFile( file ) ) )
37-
.filter( entry -> entry.getValue() != ModelChanges.NONE )
38-
.collect( Collectors.toMap( AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue ) );
39-
}
40-
}
41-
4231
abstract protected ModelChanges calculateChangesForFile( AspectModelFile aspectModelFile );
4332

4433
@Override
4534
public ChangeReport fire( final ChangeContext changeContext ) {
46-
prepare( changeContext );
35+
final Map<AspectModelFile, ModelChanges> changesPerFile = changeContext.aspectModelFiles()
36+
.map( file -> new AbstractMap.SimpleEntry<>( file, calculateChangesForFile( file ) ) )
37+
.filter( entry -> entry.getValue() != ModelChanges.NONE )
38+
.collect( Collectors.toMap( AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue ) );
39+
4740
changesPerFile.forEach( ( file, modelChanges ) -> {
48-
if ( changeContext.aspectModelFiles().contains( file ) ) {
41+
if ( changeContext.aspectModelFiles().anyMatch( file::equals ) ) {
4942
file.sourceModel().add( modelChanges.add() );
5043
file.sourceModel().remove( modelChanges.remove() );
44+
45+
if ( !modelChanges.add().isEmpty() || !modelChanges.remove().isEmpty() ) {
46+
changeContext.indicateFileHasChanged( file );
47+
}
5148
}
5249
} );
5350

5451
return new ChangeReport.MultipleEntries(
5552
changesPerFile.entrySet().stream().<ChangeReport> map( entry -> {
56-
final AspectModelFile file = entry.getKey();
57-
final ModelChanges modelChanges = entry.getValue();
58-
return new ChangeReport.EntryWithDetails( modelChanges.description(), Map.of(
59-
"Add content in " + show( file ), modelChanges.add(),
60-
"Remove content from " + show( file ), modelChanges.remove() )
61-
.entrySet().stream()
62-
.filter( descriptionEntry -> !descriptionEntry.getValue().isEmpty() )
63-
.collect( Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue ) ) );
64-
}
65-
).toList()
53+
final AspectModelFile file = entry.getKey();
54+
final ModelChanges modelChanges = entry.getValue();
55+
return new ChangeReport.EntryWithDetails( modelChanges.description(), Map.of(
56+
"Add content in " + show( file ), modelChanges.add(),
57+
"Remove content from " + show( file ), modelChanges.remove() )
58+
.entrySet().stream()
59+
.filter( descriptionEntry -> !descriptionEntry.getValue().isEmpty() )
60+
.collect( Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue ) ) );
61+
} ).toList()
6662
);
6763
}
6864
}

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/edit/change/MoveElementToExistingFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public MoveElementToExistingFile( final AspectModelUrn elementUrn, final AspectM
4848

4949
@Override
5050
public ChangeReport fire( final ChangeContext changeContext ) {
51-
final AspectModelFile targetFile = changeContext.aspectModelFiles().stream()
51+
final AspectModelFile targetFile = changeContext.aspectModelFiles()
5252
.filter( file -> file.sourceLocation().equals( targetFileLocation ) )
5353
.findFirst()
5454
.orElseThrow( () -> new ModelChangeException( "Can not determine target file to move element" ) );

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/edit/change/MoveRenameAspectModelFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public MoveRenameAspectModelFile( final AspectModelFile file, final Optional<URI
4040

4141
@Override
4242
public ChangeReport fire( final ChangeContext changeContext ) {
43-
final AspectModelFile targetFile = changeContext.aspectModelFiles().stream()
43+
final AspectModelFile targetFile = changeContext.aspectModelFiles()
4444
.filter( file -> file.sourceLocation().equals( file.sourceLocation() ) )
4545
.findFirst()
4646
.orElseThrow( () -> new ModelChangeException( "Can not find file to move/rename" ) );

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/edit/change/RemoveAspectModelFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public RemoveAspectModelFile( final AspectModelFile fileToRemove ) {
2929

3030
@Override
3131
public ChangeReport fire( final ChangeContext changeContext ) {
32-
changeContext.aspectModelFiles().remove( fileToRemove );
32+
changeContext.indicateFileIsRemoved( fileToRemove );
3333
return new ChangeReport.EntryWithDetails( "Remove file " + show( fileToRemove ),
3434
Map.of( "model content", fileToRemove.sourceModel() ) );
3535
}

core/esmf-aspect-meta-model-java/src/main/java/org/eclipse/esmf/aspectmodel/edit/change/StructuralChange.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
public abstract class StructuralChange extends AbstractChange {
2727
protected AspectModelFile sourceFile( final ChangeContext changeContext, final AspectModelUrn elementUrn ) {
28-
return changeContext.aspectModelFiles().stream().filter( aspectModelFile -> {
28+
return changeContext.aspectModelFiles().filter( aspectModelFile -> {
2929
final Resource elementResource = aspectModelFile.sourceModel().createResource( elementUrn.toString() );
3030
return Streams.stream( aspectModelFile.sourceModel().listStatements( elementResource, RDF.type, (RDFNode) null ) )
3131
.count() == 1;

0 commit comments

Comments
 (0)