Skip to content

Commit 6ba82f7

Browse files
committed
Implement MoveElementToOtherNamespaceNewFile
1 parent 4284690 commit 6ba82f7

File tree

6 files changed

+341
-57
lines changed

6 files changed

+341
-57
lines changed

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

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,17 @@
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;
2016
import java.util.ArrayDeque;
2117
import java.util.Deque;
2218
import java.util.HashMap;
2319
import java.util.List;
2420
import java.util.Map;
21+
import java.util.Optional;
2522
import java.util.stream.Stream;
2623

27-
import org.eclipse.esmf.aspectmodel.AspectModelBuilder;
2824
import org.eclipse.esmf.aspectmodel.AspectModelFile;
25+
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
26+
import org.eclipse.esmf.aspectmodel.resolver.modelfile.RawAspectModelFile;
2927
import org.eclipse.esmf.metamodel.AspectModel;
3028
import org.eclipse.esmf.metamodel.impl.DefaultAspectModel;
3129

@@ -94,10 +92,31 @@ public synchronized void redoChange() {
9492
}
9593

9694
private void updateAspectModelAfterChange() {
97-
final AspectModel updatedModel = AspectModelBuilder.buildAspectModelFromFiles( aspectModel.files() );
95+
final AspectModel updatedModel = AspectModelLoader.buildAspectModelFromFiles( aspectModel.files() );
9896
aspectModel.setMergedModel( updatedModel.mergedModel() );
9997
aspectModel.setElements( updatedModel.elements() );
10098
aspectModel.setFiles( updatedModel.files() );
99+
100+
final Map<AspectModelFile, FileState> updatedFileState = new HashMap<>();
101+
for ( final Map.Entry<AspectModelFile, FileState> stateEntry : fileState.entrySet() ) {
102+
final AspectModelFile file = stateEntry.getKey();
103+
final FileState state = stateEntry.getValue();
104+
105+
if ( file instanceof final RawAspectModelFile rawFile ) {
106+
final Optional<AspectModelFile> updatedAspectModelFile = aspectModel.files().stream()
107+
.filter( f -> f.sourceLocation().isPresent() )
108+
.filter( f -> f.sourceLocation().equals( file.sourceLocation() ) )
109+
.findFirst();
110+
if ( updatedAspectModelFile.isEmpty() ) {
111+
continue;
112+
}
113+
updatedFileState.put( updatedAspectModelFile.get(), state );
114+
} else {
115+
updatedFileState.put( file, state );
116+
}
117+
}
118+
fileState.clear();
119+
fileState.putAll( updatedFileState );
101120
}
102121

103122
@Override

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ protected record ModelChanges( Model add, Model remove, String description ) {
3333
@Override
3434
public ChangeReport fire( final ChangeContext changeContext ) {
3535
final Map<AspectModelFile, ModelChanges> changesPerFile = changeContext.aspectModelFiles()
36-
.map( file -> new AbstractMap.SimpleEntry<>( file, calculateChangesForFile( file ) ) )
36+
.map( file -> Map.entry( file, calculateChangesForFile( file ) ) )
3737
.filter( entry -> entry.getValue() != ModelChanges.NONE )
38-
.collect( Collectors.toMap( AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue ) );
38+
.collect( Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue ) );
3939

4040
changesPerFile.forEach( ( file, modelChanges ) -> {
4141
if ( changeContext.aspectModelFiles().anyMatch( file::equals ) ) {

tools/samm-cli/src/main/java/org/eclipse/esmf/AbstractCommand.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,9 @@ protected File getInputFile( final String modelFileName ) {
6161
: Path.of( System.getProperty( "user.dir" ) ).resolve( inputFile.toPath() ).toFile().getAbsoluteFile();
6262
}
6363

64-
protected AspectModel loadAspectModelOrFail( final String modelFileName, final ExternalResolverMixin resolverConfig,
64+
protected AspectModel loadAspectModelOrFail( final File modelFile, final ExternalResolverMixin resolverConfig,
6565
final boolean details ) {
66-
final File absoluteFile = getInputFile( modelFileName );
67-
66+
final File absoluteFile = modelFile.getAbsoluteFile();
6867
final ResolutionStrategy resolveFromWorkspace = new FileSystemStrategy( modelsRootForFile( absoluteFile ) );
6968
final ResolutionStrategy resolveFromCurrentDirectory = AspectModelLoader.DEFAULT_STRATEGY.get();
7069
final ResolutionStrategy resolutionStrategy = resolverConfig.commandLine.isBlank()
@@ -87,6 +86,11 @@ protected AspectModel loadAspectModelOrFail( final String modelFileName, final E
8786
return validModelOrViolations.get();
8887
}
8988

89+
protected AspectModel loadAspectModelOrFail( final String modelFileName, final ExternalResolverMixin resolverConfig,
90+
final boolean details ) {
91+
return loadAspectModelOrFail( getInputFile( modelFileName ), resolverConfig, details );
92+
}
93+
9094
protected Aspect loadAspectOrFail( final String modelFileName, final ExternalResolverMixin resolverConfig ) {
9195
final File inputFile = new File( modelFileName );
9296
final AspectModel aspectModel = loadAspectModelOrFail( modelFileName, resolverConfig );

tools/samm-cli/src/main/java/org/eclipse/esmf/SammCli.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,7 @@ public SammCli() {
105105
commandLine = initialCommandLine.setExecutionExceptionHandler( new CommandLine.IExecutionExceptionHandler() {
106106
@Override
107107
public int handleExecutionException( final Exception exception, final CommandLine commandLine,
108-
final CommandLine.ParseResult parseResult )
109-
throws Exception {
108+
final CommandLine.ParseResult parseResult ) throws Exception {
110109
if ( exception.getClass().getName()
111110
.equals( String.format( "%s.MainClassProcessLauncher$SystemExitCaptured", SammCli.class.getPackageName() ) ) ) {
112111
// If the exception we encounter is a SystemExitCaptured, this is part of the security manager in the test suite that

tools/samm-cli/src/main/java/org/eclipse/esmf/aspect/edit/AspectEditMoveCommand.java

Lines changed: 92 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.eclipse.esmf.ExternalResolverMixin;
2727
import org.eclipse.esmf.LoggingMixin;
2828
import org.eclipse.esmf.aspect.AspectEditCommand;
29-
import org.eclipse.esmf.aspectmodel.AspectModelBuilder;
3029
import org.eclipse.esmf.aspectmodel.AspectModelFile;
3130
import org.eclipse.esmf.aspectmodel.edit.AspectChangeContext;
3231
import org.eclipse.esmf.aspectmodel.edit.AspectChangeContextConfig;
@@ -36,11 +35,16 @@
3635
import org.eclipse.esmf.aspectmodel.edit.ChangeReportFormatter;
3736
import org.eclipse.esmf.aspectmodel.edit.change.MoveElementToExistingFile;
3837
import org.eclipse.esmf.aspectmodel.edit.change.MoveElementToNewFile;
38+
import org.eclipse.esmf.aspectmodel.edit.change.MoveElementToOtherNamespaceExistingFile;
39+
import org.eclipse.esmf.aspectmodel.edit.change.MoveElementToOtherNamespaceNewFile;
40+
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
3941
import org.eclipse.esmf.aspectmodel.serializer.AspectSerializer;
4042
import org.eclipse.esmf.aspectmodel.urn.AspectModelUrn;
4143
import org.eclipse.esmf.exception.CommandException;
4244
import org.eclipse.esmf.metamodel.AspectModel;
4345
import org.eclipse.esmf.metamodel.ModelElement;
46+
import org.eclipse.esmf.metamodel.Namespace;
47+
import org.eclipse.esmf.metamodel.impl.DefaultNamespace;
4448

4549
import picocli.CommandLine;
4650

@@ -116,93 +120,137 @@ public class AspectEditMoveCommand extends AbstractCommand {
116120
public void run() {
117121
final String input = parentCommand.parentCommand.getInput();
118122

123+
// Move to other/new file in same namespace
119124
if ( targetNamespace == null ) {
120125
final File targetFileRelativeToInput = getInputFile( input ).toPath().getParent().resolve( targetFile ).toFile();
121126
if ( targetFileRelativeToInput.exists() ) {
122-
moveElementToExistingFile();
127+
moveElementToExistingFile( targetFileRelativeToInput );
123128
} else {
124129
moveElementToNewFile();
125130
}
131+
return;
132+
}
133+
134+
// Move to other/new file in other namespace
135+
final File inputFile = getInputFile( input );
136+
final AspectModelUrn targetNamespaceUrn = AspectModelUrn.from( targetNamespace )
137+
.getOrElseThrow( () -> new CommandException( "Target namespace is invalid: " + targetNamespace ) );
138+
final File targetFileInOtherNamespace = modelsRootForFile( inputFile )
139+
.resolve( targetNamespaceUrn.getNamespaceMainPart() )
140+
.resolve( targetNamespaceUrn.getVersion() )
141+
.resolve( targetFile )
142+
.toFile();
143+
if ( targetFileInOtherNamespace.exists() ) {
144+
moveElementToOtherNamespaceExistingFile( targetNamespaceUrn, targetFileInOtherNamespace );
126145
} else {
127-
final File inputFile = getInputFile( input );
128-
final AspectModelUrn targetNamespaceUrn = AspectModelUrn.from( targetNamespace )
129-
.getOrElseThrow( () -> new CommandException( "Target namespace is invalid: " + targetNamespace ) );
130-
final File targetFileInNewNamespace = modelsRootForFile( inputFile )
131-
.resolve( targetNamespaceUrn.getNamespaceMainPart() )
132-
.resolve( targetNamespaceUrn.getVersion() )
133-
.resolve( targetFile )
134-
.toFile();
135-
if ( targetFileInNewNamespace.exists() ) {
136-
moveElementToOtherNamespaceExistingFile();
137-
} else {
138-
moveElementToOtherNamespaceNewFile();
139-
}
146+
moveElementToOtherNamespaceNewFile( targetNamespaceUrn, targetFileInOtherNamespace );
140147
}
141148
}
142149

143150
/**
144-
* Supports the case {@code samm aspect Aspect.ttl edit move :MyAspect newFile.ttl}
151+
* Supports the case {@code samm aspect Aspect.ttl edit move MyAspect newFile.ttl}
145152
*/
146153
private void moveElementToNewFile() {
147154
final String input = parentCommand.parentCommand.getInput();
148155
final AspectModel aspectModel = loadAspectModelOrFail( input, customResolver );
149156

150157
// Do refactoring
151158
final ModelElement modelElement = determineModelElementToMove( aspectModel );
159+
if ( targetFile.contains( File.separator ) ) {
160+
throw new CommandException( "The target file name should not contain a path; only a file name." );
161+
}
152162
final URI targetFileUri = getInputFile( input ).toPath().getParent().resolve( targetFile ).toUri();
153163
final List<String> headerCommentForNewFile = copyHeader
154164
? modelElement.getSourceFile().headerComment()
155165
: List.of();
156166
final Change move = new MoveElementToNewFile( modelElement, headerCommentForNewFile, Optional.of( targetFileUri ) );
157-
final AspectChangeContext changeContext = performRefactoring( aspectModel, move );
158-
159-
// Check & write changes to file system
160-
checkFilesystemConsistency( changeContext );
161-
performFileSystemWrite( changeContext );
167+
performRefactoring( aspectModel, move ).ifPresent( changeContext -> {
168+
// Check & write changes to file system
169+
checkFilesystemConsistency( changeContext );
170+
performFileSystemWrite( changeContext );
171+
} );
162172
}
163173

164174
/**
165-
* Supports the case {@code samm aspect Aspect.ttl edit move :MyAspect existingFile.ttl urn:samm:com.example.othernamespace:1.0.0}
175+
* Supports the case {@code samm aspect Aspect.ttl edit move MyAspect newFile.ttl urn:samm:com.example.othernamespace:1.0.0}
166176
*/
167-
private void moveElementToOtherNamespaceExistingFile() {
168-
// TODO
177+
private void moveElementToOtherNamespaceNewFile( final AspectModelUrn targetNamespaceUrn, final File targetFileInNewNamespace ) {
178+
final String input = parentCommand.parentCommand.getInput();
179+
final AspectModel aspectModel = loadAspectModelOrFail( input, customResolver );
180+
181+
// Do refactoring
182+
final ModelElement modelElement = determineModelElementToMove( aspectModel );
183+
if ( targetFile.contains( File.separator ) ) {
184+
throw new CommandException( "The target file name should not contain a path; only a file name: " + targetFile );
185+
}
186+
187+
final Namespace namespace = new DefaultNamespace( targetNamespaceUrn, List.of(), Optional.empty() );
188+
final List<String> headerCommentForNewFile = copyHeader
189+
? modelElement.getSourceFile().headerComment()
190+
: List.of();
191+
192+
final Change move = new MoveElementToOtherNamespaceNewFile( modelElement, namespace, headerCommentForNewFile,
193+
Optional.of( targetFileInNewNamespace.toURI() ) );
194+
performRefactoring( aspectModel, move ).ifPresent( changeContext -> {
195+
// Check & write changes to file system
196+
checkFilesystemConsistency( changeContext );
197+
performFileSystemWrite( changeContext );
198+
} );
169199
}
170200

171201
/**
172-
* Supports the case {@code samm aspect Aspect.ttl edit move :MyAspect newFile.ttl urn:samm:com.example.othernamespace:1.0.0}
202+
* Support the case {@code samm aspect Aspect.ttl edit move MyAspect existingFile.ttl}
173203
*/
174-
private void moveElementToOtherNamespaceNewFile() {
175-
// TODO
204+
private void moveElementToExistingFile( final File targetFileRelativeToInput ) {
205+
final AspectModel sourceAspectModel = loadAspectModelOrFail( parentCommand.parentCommand.getInput(), customResolver );
206+
final AspectModel targetAspectModel = loadAspectModelOrFail( targetFileRelativeToInput, customResolver, false );
207+
208+
// Create a consistent in-memory representation of both the source and target models.
209+
// On this Aspect Model we can perform the refactoring operation
210+
final AspectModel aspectModel = AspectModelLoader.merge( sourceAspectModel, targetAspectModel );
211+
212+
// Find the loaded AspectModelFile that corresponds to the input targetFile
213+
final ModelElement modelElement = determineModelElementToMove( aspectModel );
214+
final AspectModelFile targetAspectModelFile = determineTargetAspectModelFile( aspectModel, modelElement.getSourceFile().namespace() );
215+
216+
// Do refactoring
217+
final Change move = new MoveElementToExistingFile( modelElement, targetAspectModelFile );
218+
performRefactoring( aspectModel, move ).ifPresent( changeContext -> {
219+
// Check & write changes to file system
220+
checkFilesystemConsistency( changeContext );
221+
performFileSystemWrite( changeContext );
222+
} );
176223
}
177224

178225
/**
179-
* Support the case {@code samm aspect Aspect.ttl edit move MyAspect existingFile.ttl}
226+
* Supports the case {@code samm aspect Aspect.ttl edit move MyAspect existingFile.ttl urn:samm:com.example.othernamespace:1.0.0}
180227
*/
181-
private void moveElementToExistingFile() {
228+
private void moveElementToOtherNamespaceExistingFile( final AspectModelUrn targetNamespaceUrn, final File targetFileInOtherNamespace ) {
182229
final AspectModel sourceAspectModel = loadAspectModelOrFail( parentCommand.parentCommand.getInput(), customResolver );
183-
final AspectModel targetAspectModel = loadAspectModelOrFail( targetFile, customResolver );
230+
final AspectModel targetAspectModel = loadAspectModelOrFail( targetFileInOtherNamespace, customResolver, false );
184231

185232
// Create a consistent in-memory representation of both the source and target models.
186233
// On this Aspect Model we can perform the refactoring operation
187-
final AspectModel aspectModel = AspectModelBuilder.merge( sourceAspectModel, targetAspectModel );
234+
final AspectModel aspectModel = AspectModelLoader.merge( sourceAspectModel, targetAspectModel );
188235

189236
// Find the loaded AspectModelFile that corresponds to the input targetFile
190-
final AspectModelFile targetAspectModelFile = determineTargetAspectModelFile( aspectModel );
237+
final Namespace namespace = new DefaultNamespace( targetNamespaceUrn, List.of(), Optional.empty() );
238+
final AspectModelFile targetAspectModelFile = determineTargetAspectModelFile( aspectModel, namespace );
191239

192240
// Do refactoring
193241
final ModelElement modelElement = determineModelElementToMove( aspectModel );
194-
final Change move = new MoveElementToExistingFile( modelElement, targetAspectModelFile );
195-
final AspectChangeContext changeContext = performRefactoring( aspectModel, move );
196-
197-
// Check & write changes to file system
198-
checkFilesystemConsistency( changeContext );
199-
performFileSystemWrite( changeContext );
242+
final Change move = new MoveElementToOtherNamespaceExistingFile( modelElement, targetAspectModelFile, namespace );
243+
performRefactoring( aspectModel, move ).ifPresent( changeContext -> {
244+
// Check & write changes to file system
245+
checkFilesystemConsistency( changeContext );
246+
performFileSystemWrite( changeContext );
247+
} );
200248
}
201249

202-
private AspectModelFile determineTargetAspectModelFile( final AspectModel aspectModel ) {
203-
final URI targetFileUri = getInputFile( targetFile ).toURI();
250+
private AspectModelFile determineTargetAspectModelFile( final AspectModel aspectModel, final Namespace targetNamespace ) {
204251
return aspectModel.files().stream()
205-
.filter( file -> file.sourceLocation().map( uri -> uri.equals( targetFileUri ) ).orElse( false ) )
252+
.filter( file -> file.namespace().urn().equals( targetNamespace.urn() )
253+
&& file.sourceLocation().map( uri -> Paths.get( uri ).toFile().getName().equals( targetFile ) ).orElse( false ) )
206254
.findFirst()
207255
.orElseThrow( () -> new CommandException( "Could not determine target file" ) );
208256
}
@@ -227,7 +275,7 @@ private ModelElement determineModelElementToMove( final AspectModel aspectModel
227275
return potentialElements.get( 0 );
228276
}
229277

230-
private AspectChangeContext performRefactoring( final AspectModel aspectModel, final Change change ) {
278+
private Optional<AspectChangeContext> performRefactoring( final AspectModel aspectModel, final Change change ) {
231279
final AspectChangeContextConfig config = AspectChangeContextConfigBuilder.builder()
232280
.detailedChangeReport( details )
233281
.build();
@@ -237,9 +285,9 @@ private AspectChangeContext performRefactoring( final AspectModel aspectModel, f
237285
System.out.println( "Changes to be performed" );
238286
System.out.println( "=======================" );
239287
System.out.println( ChangeReportFormatter.INSTANCE.apply( changeReport, config ) );
240-
System.exit( 0 );
288+
return Optional.empty();
241289
}
242-
return changeContext;
290+
return Optional.of( changeContext );
243291
}
244292

245293
private void performFileSystemWrite( final AspectChangeContext changeContext ) {

0 commit comments

Comments
 (0)