Merge pull request 'Basic API Structure' (#2) from f/basics into develop
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				zdm/undo-redo/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	zdm/undo-redo/pipeline/head This commit looks good
				
			Reviewed-on: https://git.kske.dev/zdm/undo-redo/pulls/2 Reviewed-by: kske <kai@kske.dev> Reviewed-by: delvh <leon@kske.dev>
This commit is contained in:
		
							
								
								
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +1,5 @@ | ||||
| /target/ | ||||
| /.settings/ | ||||
| # Maven build directories | ||||
| target/ | ||||
|  | ||||
| # Eclipse settings directories | ||||
| .settings/ | ||||
|   | ||||
							
								
								
									
										6
									
								
								.project
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								.project
									
									
									
									
									
								
							| @@ -5,11 +5,6 @@ | ||||
| 	<projects> | ||||
| 	</projects> | ||||
| 	<buildSpec> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.jdt.core.javabuilder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.m2e.core.maven2Builder</name> | ||||
| 			<arguments> | ||||
| @@ -17,7 +12,6 @@ | ||||
| 		</buildCommand> | ||||
| 	</buildSpec> | ||||
| 	<natures> | ||||
| 		<nature>org.eclipse.jdt.core.javanature</nature> | ||||
| 		<nature>org.eclipse.m2e.core.maven2Nature</nature> | ||||
| 	</natures> | ||||
| </projectDescription> | ||||
|   | ||||
							
								
								
									
										40
									
								
								Jenkinsfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								Jenkinsfile
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| pipeline { | ||||
| 	agent any | ||||
|  | ||||
| 	options { | ||||
| 		ansiColor('xterm') | ||||
| 	} | ||||
|  | ||||
| 	stages { | ||||
| 		stage('Build') { | ||||
| 			steps { | ||||
| 				sh 'mvn -DskipTests clean package' | ||||
| 			} | ||||
| 		} | ||||
| 		stage('Test') { | ||||
| 			steps { | ||||
| 				sh 'mvn test' | ||||
| 			} | ||||
| 			post { | ||||
| 				always { | ||||
| 					junit '*/target/surefire-reports/*.xml' | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		stage('SonarQube Analysis') { | ||||
| 			when { | ||||
| 				branch 'develop' | ||||
| 			} | ||||
| 			steps { | ||||
| 				withSonarQubeEnv('KSKE SonarQube') { | ||||
| 					sh 'mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.9.1.2184:sonar' | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	post { | ||||
| 		success { | ||||
| 			archiveArtifacts artifacts: '*/target/undo-redo-*.jar' | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										23
									
								
								core/.project
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								core/.project
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <projectDescription> | ||||
| 	<name>undo-redo-core</name> | ||||
| 	<comment></comment> | ||||
| 	<projects> | ||||
| 	</projects> | ||||
| 	<buildSpec> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.jdt.core.javabuilder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.m2e.core.maven2Builder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 	</buildSpec> | ||||
| 	<natures> | ||||
| 		<nature>org.eclipse.jdt.core.javanature</nature> | ||||
| 		<nature>org.eclipse.m2e.core.maven2Nature</nature> | ||||
| 	</natures> | ||||
| </projectDescription> | ||||
							
								
								
									
										15
									
								
								core/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								core/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||||
| 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
| 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||
| 	<modelVersion>4.0.0</modelVersion> | ||||
|  | ||||
| 	<artifactId>undo-redo-core</artifactId> | ||||
| 	<name>Undo-Redo Core</name> | ||||
| 	 | ||||
| 	<parent> | ||||
| 		<groupId>dev.kske</groupId> | ||||
| 		<artifactId>undo-redo</artifactId> | ||||
| 		<version>0.0.1-SNAPSHOT</version> | ||||
| 	</parent> | ||||
|  | ||||
| </project> | ||||
							
								
								
									
										33
									
								
								core/src/main/java/dev/kske/undoredo/core/Change.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								core/src/main/java/dev/kske/undoredo/core/Change.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| package dev.kske.undoredo.core; | ||||
|  | ||||
| /** | ||||
|  * Base interface for changes to be registered in an undo manager. | ||||
|  *  | ||||
|  * @author Maximilian Käfer | ||||
|  * @since 0.0.1 | ||||
|  */ | ||||
| public interface Change { | ||||
|  | ||||
| 	/** | ||||
| 	 * Performs the action implemented by this change. | ||||
| 	 * | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	void apply(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Inverts this change. | ||||
| 	 *  | ||||
| 	 * @implSpec This method is not supposed to alter the state of this change, but rather to create | ||||
| 	 *           a new complementary change. | ||||
| 	 * @return the inverted change | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	Change invert(); | ||||
|  | ||||
| 	/** | ||||
| 	 * @return whether the application of this change would result in an identical state | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	boolean isIdentity(); | ||||
| } | ||||
							
								
								
									
										73
									
								
								core/src/main/java/dev/kske/undoredo/core/ChangeManager.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								core/src/main/java/dev/kske/undoredo/core/ChangeManager.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| package dev.kske.undoredo.core; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * A change manager keeps track of subsequent changes and allows un- and redoing them. A specific | ||||
|  * change can be marked using {@link #mark()} to keep track of a saved state in the application that | ||||
|  * uses the manager. | ||||
|  * | ||||
|  * @param <C> the change type to store in this change manager | ||||
|  * @author Maximilian Käfer | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since 0.0.1 | ||||
|  */ | ||||
| public interface ChangeManager<C extends Change> { | ||||
|  | ||||
| 	/** | ||||
| 	 * Applies the given change and appends it to the change list. | ||||
| 	 * | ||||
| 	 * @param change the change to add | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	void addChange(C change); | ||||
|  | ||||
| 	/** | ||||
| 	 * Undoes the current change. | ||||
| 	 * | ||||
| 	 * @return whether an action was performed | ||||
| 	 * @since 0.1.0 | ||||
| 	 */ | ||||
| 	boolean undo(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Applies the change that was undone before. | ||||
| 	 * | ||||
| 	 * @return whether an action was performed | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	boolean redo(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Marks the current change. | ||||
| 	 * | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	void mark(); | ||||
|  | ||||
| 	/** | ||||
| 	 * @return whether the current change is marked | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	boolean isAtMarkedIndex(); | ||||
|  | ||||
| 	/** | ||||
| 	 * @return whether a change is present that can be undone | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	boolean isUndoAvailable(); | ||||
|  | ||||
| 	/** | ||||
| 	 * @return whether a change is present that can be redone | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	boolean isRedoAvailable(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Provides an unmodifiable view of the changes stored in this change manager. | ||||
| 	 * | ||||
| 	 * @return all stored changes | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	List<C> getChanges(); | ||||
| } | ||||
| @@ -0,0 +1,69 @@ | ||||
| package dev.kske.undoredo.core; | ||||
|  | ||||
| import java.util.*; | ||||
|  | ||||
| /** | ||||
|  * @param <C> the change type to store in this change manager | ||||
|  * @author Maximilian Käfer | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since 0.0.1 | ||||
|  */ | ||||
| public final class UnlimitedChangeManager<C extends Change> implements ChangeManager<C> { | ||||
|  | ||||
| 	private final List<C> changes = new ArrayList<>(); | ||||
|  | ||||
| 	private int	index		= -1; | ||||
| 	private int	markedIndex	= -1; | ||||
|  | ||||
| 	@Override | ||||
| 	public void addChange(C change) { | ||||
| 		change.apply(); | ||||
| 		changes.add(change); | ||||
| 		++index; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean undo() { | ||||
| 		if (isUndoAvailable()) { | ||||
| 			changes.get(index).invert().apply(); | ||||
| 			--index; | ||||
| 			return true; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean redo() { | ||||
| 		if (isRedoAvailable()) { | ||||
| 			changes.get(index + 1).apply(); | ||||
| 			++index; | ||||
| 			return true; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void mark() { | ||||
| 		markedIndex = index; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean isAtMarkedIndex() { | ||||
| 		return markedIndex == index; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean isUndoAvailable() { | ||||
| 		return index > -1; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean isRedoAvailable() { | ||||
| 		return index < changes.size() - 1; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public List<C> getChanges() { | ||||
| 		return Collections.unmodifiableList(changes); | ||||
| 	} | ||||
| } | ||||
| @@ -5,4 +5,4 @@ | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since 0.0.1 | ||||
|  */ | ||||
| package dev.kske.undoredo; | ||||
| package dev.kske.undoredo.core; | ||||
| @@ -5,7 +5,7 @@ | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since 0.0.1 | ||||
|  */ | ||||
| module dev.kske.undoredo { | ||||
| module dev.kske.undoredo.core { | ||||
| 
 | ||||
| 	exports dev.kske.undoredo; | ||||
| 	exports dev.kske.undoredo.core; | ||||
| } | ||||
							
								
								
									
										104
									
								
								core/src/test/java/dev/kske/undoredo/core/ChangeManagerTest.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								core/src/test/java/dev/kske/undoredo/core/ChangeManagerTest.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| package dev.kske.undoredo.core; | ||||
|  | ||||
| import static org.junit.jupiter.api.Assertions.*; | ||||
|  | ||||
| import org.junit.jupiter.api.*; | ||||
|  | ||||
| /** | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since 0.0.1 | ||||
|  */ | ||||
| class ChangeManagerTest { | ||||
|  | ||||
| 	ChangeManager<IntChange>	manager; | ||||
| 	IntWrapper					wrapper; | ||||
| 	IntChange					change; | ||||
|  | ||||
| 	@BeforeEach | ||||
| 	void prepareChangeManager() { | ||||
| 		manager	= new UnlimitedChangeManager<>(); | ||||
| 		wrapper	= new IntWrapper(); | ||||
| 		change	= new IntChange(wrapper, 1); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Tests adding a change. | ||||
| 	 * | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	@Test | ||||
| 	@Order(1) | ||||
| 	void testAddChange() { | ||||
| 		assertSame(0, wrapper.value); | ||||
| 		manager.addChange(change); | ||||
| 		assertSame(1, wrapper.value); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Tests the consistency of the change list. | ||||
| 	 * | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	@Test | ||||
| 	@Order(2) | ||||
| 	void testGetChanges() { | ||||
| 		assertTrue(manager.getChanges().isEmpty()); | ||||
| 		manager.addChange(change); | ||||
| 		assertSame(1, manager.getChanges().size()); | ||||
| 		assertEquals(change, manager.getChanges().get(0)); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Test undoing a change. | ||||
| 	 * | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	@Test | ||||
| 	@Order(2) | ||||
| 	void testUndo() { | ||||
| 		assertFalse(manager.isUndoAvailable()); | ||||
| 		assertFalse(manager.undo()); | ||||
| 		manager.addChange(change); | ||||
| 		assertTrue(manager.isUndoAvailable()); | ||||
| 		assertTrue(manager.undo()); | ||||
| 		assertFalse(manager.isUndoAvailable()); | ||||
| 		assertFalse(manager.undo()); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Tests redoing a change. | ||||
| 	 * | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	@Test | ||||
| 	@Order(4) | ||||
| 	void testRedo() { | ||||
| 		assertFalse(manager.isRedoAvailable()); | ||||
| 		assertFalse(manager.redo()); | ||||
| 		manager.addChange(change); | ||||
| 		assertFalse(manager.isRedoAvailable()); | ||||
| 		assertFalse(manager.redo()); | ||||
| 		manager.undo(); | ||||
| 		assertTrue(manager.isRedoAvailable()); | ||||
| 		assertTrue(manager.redo()); | ||||
| 		assertFalse(manager.isRedoAvailable()); | ||||
| 		assertFalse(manager.redo()); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Tests marking a change. | ||||
| 	 * | ||||
| 	 * @since 0.0.1 | ||||
| 	 */ | ||||
| 	@Test | ||||
| 	@Order(5) | ||||
| 	void testMark() { | ||||
| 		assertTrue(manager.isAtMarkedIndex()); | ||||
| 		manager.addChange(change); | ||||
| 		assertFalse(manager.isAtMarkedIndex()); | ||||
| 		manager.mark(); | ||||
| 		assertTrue(manager.isAtMarkedIndex()); | ||||
| 		manager.undo(); | ||||
| 		assertFalse(manager.isAtMarkedIndex()); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										31
									
								
								core/src/test/java/dev/kske/undoredo/core/IntChange.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								core/src/test/java/dev/kske/undoredo/core/IntChange.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| package dev.kske.undoredo.core; | ||||
|  | ||||
| /** | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since 0.0.1 | ||||
|  */ | ||||
| class IntChange implements Change { | ||||
|  | ||||
| 	private final IntWrapper	wrapper; | ||||
| 	private final int			value; | ||||
|  | ||||
| 	IntChange(IntWrapper wrapper, int value) { | ||||
| 		this.wrapper	= wrapper; | ||||
| 		this.value		= value; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public void apply() { | ||||
| 		wrapper.value += value; | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public Change invert() { | ||||
| 		return new IntChange(wrapper, -value); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public boolean isIdentity() { | ||||
| 		return value == 0; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										10
									
								
								core/src/test/java/dev/kske/undoredo/core/IntWrapper.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								core/src/test/java/dev/kske/undoredo/core/IntWrapper.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| package dev.kske.undoredo.core; | ||||
|  | ||||
| /** | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since 0.0.1 | ||||
|  */ | ||||
| class IntWrapper { | ||||
|  | ||||
| 	int value; | ||||
| } | ||||
							
								
								
									
										9
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -6,11 +6,16 @@ | ||||
| 	<groupId>dev.kske</groupId> | ||||
| 	<artifactId>undo-redo</artifactId> | ||||
| 	<version>0.0.1-SNAPSHOT</version> | ||||
| 	<packaging>pom</packaging> | ||||
|  | ||||
| 	<name>Undo-Redo</name> | ||||
| 	<description>A Java library for managing changes in an editor history.</description> | ||||
| 	<url>https://git.kske.dev/kske/event-bus</url> | ||||
| 	 | ||||
| 	<modules> | ||||
| 		<module>core</module> | ||||
| 	</modules> | ||||
|  | ||||
| 	<licenses> | ||||
| 		<license> | ||||
| 			<name>Apache License, Version 2.0</name> | ||||
| @@ -165,8 +170,12 @@ | ||||
| 				<groupId>org.apache.maven.plugins</groupId> | ||||
| 				<artifactId>maven-surefire-plugin</artifactId> | ||||
| 				<version>3.0.0-M5</version> | ||||
| 				<configuration> | ||||
| 					<argLine>--add-opens dev.kske.undoredo.core/dev.kske.undoredo.core=ALL-UNNAMED</argLine> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
|  | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| </project> | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	