├── .gitignore ├── .travis.yml ├── CHANGELOG.txt ├── LICENSE ├── README-JDBC.md ├── README-JPA.md ├── README-MEM.md ├── README.md ├── codecov.yml ├── pom.xml └── src ├── main └── java │ └── pl │ └── exsio │ └── nestedj │ ├── DelegatingNestedNodeRepository.java │ ├── NestedNodeRepository.java │ ├── config │ ├── jdbc │ │ ├── JdbcNestedNodeRepositoryConfiguration.java │ │ ├── discriminator │ │ │ └── JdbcTreeDiscriminator.java │ │ └── factory │ │ │ └── JdbcNestedNodeRepositoryFactory.java │ ├── jpa │ │ ├── JpaNestedNodeRepositoryConfiguration.java │ │ ├── discriminator │ │ │ ├── JpaTreeDiscriminator.java │ │ │ └── MapJpaTreeDiscriminator.java │ │ └── factory │ │ │ └── JpaNestedNodeRepositoryFactory.java │ └── mem │ │ ├── InMemoryNestedNodeRepositoryConfiguration.java │ │ ├── discriminator │ │ └── InMemoryTreeDiscriminator.java │ │ ├── factory │ │ └── InMemoryNestedNodeRepositoryFactory.java │ │ ├── identity │ │ └── InMemoryNestedNodeIdentityGenerator.java │ │ └── lock │ │ └── InMemoryLock.java │ ├── delegate │ ├── NestedNodeHierarchyManipulator.java │ ├── NestedNodeInserter.java │ ├── NestedNodeMover.java │ ├── NestedNodeRebuilder.java │ ├── NestedNodeRemover.java │ ├── NestedNodeRetriever.java │ ├── control │ │ ├── QueryBasedNestedNodeInserter.java │ │ ├── QueryBasedNestedNodeMover.java │ │ ├── QueryBasedNestedNodeRebuilder.java │ │ ├── QueryBasedNestedNodeRemover.java │ │ └── QueryBasedNestedNodeRetriever.java │ └── query │ │ ├── NestedNodeInsertingQueryDelegate.java │ │ ├── NestedNodeMovingQueryDelegate.java │ │ ├── NestedNodeRebuildingQueryDelegate.java │ │ ├── NestedNodeRemovingQueryDelegate.java │ │ ├── NestedNodeRetrievingQueryDelegate.java │ │ ├── jdbc │ │ ├── JdbcKeyHolder.java │ │ ├── JdbcNestedNodeInsertingQueryDelegate.java │ │ ├── JdbcNestedNodeMovingQueryDelegate.java │ │ ├── JdbcNestedNodeQueryDelegate.java │ │ ├── JdbcNestedNodeRebuildingQueryDelegate.java │ │ ├── JdbcNestedNodeRemovingQueryDelegate.java │ │ └── JdbcNestedNodeRetrievingQueryDelegate.java │ │ ├── jpa │ │ ├── JpaNestedNodeInsertingQueryDelegate.java │ │ ├── JpaNestedNodeMovingQueryDelegate.java │ │ ├── JpaNestedNodeQueryDelegate.java │ │ ├── JpaNestedNodeRebuildingQueryDelegate.java │ │ ├── JpaNestedNodeRemovingQueryDelegate.java │ │ └── JpaNestedNodeRetrievingQueryDelegate.java │ │ └── mem │ │ ├── InMemoryNestedNodeInsertingQueryDelegate.java │ │ ├── InMemoryNestedNodeMovingQueryDelegate.java │ │ ├── InMemoryNestedNodeQueryDelegate.java │ │ ├── InMemoryNestedNodeRebuildingQueryDelegate.java │ │ ├── InMemoryNestedNodeRemovingQueryDelegate.java │ │ └── InMemoryNestedNodeRetrievingQueryDelegate.java │ ├── ex │ ├── InvalidNodeException.java │ ├── InvalidNodesHierarchyException.java │ ├── InvalidParentException.java │ └── RepositoryLockedException.java │ ├── lock │ └── NoLock.java │ └── model │ ├── InMemoryTree.java │ ├── NestedNode.java │ ├── NestedNodeInfo.java │ └── Tree.java └── test ├── java └── pl │ └── exsio │ └── nestedj │ ├── TestConfiguration.java │ ├── base │ ├── FunctionalNestedjTest.java │ ├── NestedNodeRepositoryInsertingTest.java │ ├── NestedNodeRepositoryMovingTest.java │ ├── NestedNodeRepositoryRebuildingTest.java │ ├── NestedNodeRepositoryRemovingTest.java │ ├── NestedNodeRepositoryRetrievingTest.java │ ├── NestedNodeRepositoryTest.java │ └── TestHelper.java │ ├── config │ ├── jdbc │ │ └── discriminator │ │ │ └── TestJdbcTreeDiscriminator.java │ ├── jpa │ │ └── discriminator │ │ │ └── TestJpaTreeDiscriminator.java │ └── mem │ │ └── discriminator │ │ └── TestInMemoryTreeDiscriminator.java │ ├── jdbc │ ├── JdbcNestedNodeRepositoryInsertingTest.java │ ├── JdbcNestedNodeRepositoryMovingTest.java │ ├── JdbcNestedNodeRepositoryRebuildingTest.java │ ├── JdbcNestedNodeRepositoryRemovingTest.java │ ├── JdbcNestedNodeRepositoryRetrievingTest.java │ ├── JdbcNestedNodeRepositoryTest.java │ └── JdbcTestHelper.java │ ├── jpa │ ├── JpaNestedNodeRepositoryInsertingTest.java │ ├── JpaNestedNodeRepositoryMovingTest.java │ ├── JpaNestedNodeRepositoryRebuildingTest.java │ ├── JpaNestedNodeRepositoryRemovingTest.java │ ├── JpaNestedNodeRepositoryRetrievingTest.java │ ├── JpaNestedNodeRepositoryTest.java │ └── JpaTestHelper.java │ ├── mem │ ├── InMemoryNestedNodeRepositoryInsertingTest.java │ ├── InMemoryNestedNodeRepositoryMovingTest.java │ ├── InMemoryNestedNodeRepositoryRebuildingTest.java │ ├── InMemoryNestedNodeRepositoryRemovingTest.java │ ├── InMemoryNestedNodeRepositoryRetrievingTest.java │ ├── InMemoryNestedNodeRepositoryTest.java │ └── InMemoryTestHelper.java │ ├── model │ └── TestNode.java │ └── qualifier │ ├── Jdbc.java │ ├── Jpa.java │ └── Mem.java └── resources ├── fixtures └── test-import.sql └── logback-test.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *# 2 | *.iml 3 | *.ipr 4 | *.iws 5 | *.jar 6 | *.sw? 7 | *~ 8 | .#* 9 | .*.md.html 10 | .DS_Store 11 | .classpath 12 | .factorypath 13 | .gradle 14 | .idea 15 | .metadata 16 | .project 17 | .recommenders 18 | .settings 19 | .springBeans 20 | /build 21 | /code 22 | MANIFEST.MF 23 | _site/ 24 | activemq-data 25 | bin 26 | build 27 | build.log 28 | dependency-reduced-pom.xml 29 | dump.rdb 30 | interpolated*.xml 31 | lib/ 32 | manifest.yml 33 | overridedb.* 34 | target 35 | transaction-logs 36 | .flattened-pom.xml 37 | secrets.yml 38 | .gradletasknamecache 39 | .sts4-cache -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - openjdk8 4 | script: mvn test -f pom.xml 5 | sudo: false 6 | 7 | env: 8 | global: 9 | # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created 10 | # via the "travis encrypt" command using the project repo's public key 11 | - secure: "Q4knSRO6hhSZFtIkm8uoXm3SfqWfx7BREkO2zZvks87I9rg42K7SWeBkj0CST3HNf4enQvDEc2Uh613BmeNIgEggSQes9eKyYoLw33rvpLx0X0mnf2ULQljcWIG7ZaPzZo3Vz/wTJKjpBakScvefd+tt9YRt2q+Ilu8q0ZLSyls=" 12 | 13 | addons: 14 | coverity_scan: 15 | project: 16 | name: "eXsio/nestedj" 17 | description: "Build submitted via Travis CI" 18 | notification_email: noneedto@notify.me 19 | build_command_prepend: "mvn clean" 20 | build_command: "mvn -DskipTests=true compile" 21 | branch_pattern: master 22 | 23 | after_success: 24 | - bash <(curl -s https://codecov.io/bash) 25 | -------------------------------------------------------------------------------- /CHANGELOG.txt: -------------------------------------------------------------------------------- 1 | NestedJ Changelog: 2 | 3 | - 5.0.3 4 | - pass the node instance into generated JDBC key resolver 5 | 6 | - 5.0.2 7 | - parametrize retrieving of generated JDBC keys 8 | 9 | - 5.0.0 10 | - new backing storage implementation - In Memory. Operates on Java Set using Streams 11 | - ability to add pessimistic locking to all Tree operations via new Lock interface 12 | - change methods that were returning Iterable to return List 13 | - add Javadocs to public APIs 14 | - move Factory classes to config packages for better clarity 15 | - update project dependencies 16 | - rework README for better clarity 17 | 18 | - 4.1.1 19 | - don't throw exception when inserting last root as last root or first root as first root 20 | 21 | - 4.1.0 22 | - added new Repository methods: insertAsFirstRoot, insertAsLastRoot 23 | 24 | - 4.0.0 25 | - Decoupled DB Query Delegates from the actual Tree logic 26 | - Created JDBC implementation of the NestedNodeRepository 27 | - Refactored test suite - divided tests into categories and ensured that all implementations (JPA, JDBC) use the same tests and assertions 28 | - Bumped up dependencies 29 | 30 | - 3.0.0 31 | 32 | - Removed custom annotations (@LeftColumn/@RightColumn/etc) 33 | - Updated the NestedNode interface - changed method names, JavaBean standard required (getters/setters/field names) 34 | - Removed Parent JPA mapping from the NestedNode interface - replaced with parentId field - mapping had an inherent danger of a recursive Hibernate loading 35 | 36 | - 2.2.0 37 | - Parametrized ID column - no requirements for the NestedNode's ID type 38 | - updated Project dependencies 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 eXsio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README-JDBC.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | ```xml 4 | 5 | 6 | 7 | jitpack.io 8 | https://jitpack.io 9 | 10 | 11 | 12 | 13 | com.github.eXsio 14 | nestedj 15 | 5.0.4 16 | 17 | 18 | org.springframework 19 | spring-jdbc 20 | 5.3.7 21 | 22 | 23 | ``` 24 | 25 | ## JDBC Usage 26 | 27 | In order to use NestedJ, You have to configure it. In 9 our of 10 cases you will want to use the preconfigured builder methods available in the ```JdbcNestedNodeRepositoryFactory``` class: 28 | 29 | ```java 30 | 31 | //ROW MAPPER FOR CREATING INSTANCES OF THE NODE OBJECT FROM RESULT SET 32 | RowMapper mapper = (resultSet, i) -> YourNode.fromResultSet(resultSet); 33 | 34 | //TABLE NAME 35 | String tableName = "nested_nodes"; 36 | 37 | // QUERY USED FOR INSERTING NEW NODES 38 | String insertQuery = "insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(next value for SEQ,?,?,?,?,?,?)"; 39 | 40 | // INSERT QUERY VALUES PROVIDER, CONVERTS NODE OBJECT INTO AN OBJECT ARRAY 41 | Function insertValuesProvider = n -> new Object[]{n.getTreeLeft(), n.getTreeLevel(), n.getTreeRight(), n.getName(), n.getParentId(), n.getDiscriminator()}; 42 | 43 | // METHOD OF RETRIEVING GENERATED DATABASE PRIMARY KEYS 44 | BiFunction generatedKeyResolver = (node, jdbcKeyHolder) -> jdbcKeyHolder.getKeyValueAs(Long.class); 45 | 46 | //CONFIGURATION CLASS 47 | JdbcNestedNodeRepositoryConfiguration configuration = new JdbcNestedNodeRepositoryConfiguration<>( 48 | new JdbcTemplate(dataSource), tableName, mapper, insertQuery, insertValuesProvider, generatedKeyResolver, new YourJdbcTreeDiscriminator() 49 | ); 50 | 51 | //CUSTOM COLUMN NAMES 52 | configuration.setIdColumnName("id"); 53 | configuration.setParentIdColumnName("parent_id"); 54 | configuration.setLeftColumnName("tree_left"); 55 | configuration.setRighColumnName("tree_right"); 56 | configuration.setLevelColumnName("tree_level"); 57 | 58 | return JdbcNestedNodeRepositoryFactory.create(configuration); 59 | 60 | ``` 61 | 62 | The Node Class has to implement the ```NestedNode``` interface so that the logic can operage on Nested Node specific columns. 63 | -------------------------------------------------------------------------------- /README-JPA.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | ```xml 4 | 5 | 6 | 7 | jitpack.io 8 | https://jitpack.io 9 | 10 | 11 | 12 | 13 | com.github.eXsio 14 | nestedj 15 | 5.0.4 16 | 17 | 18 | org.hibernate 19 | hibernate-core 20 | 5.4.32.Final 21 | 22 | 23 | ``` 24 | 25 | 26 | ## JPA Usage 27 | 28 | In order to use NestedJ, You have to configure it. In 9 our of 10 cases you will want to use the preconfigured builder methods available in the ```JpaNestedNodeRepositoryFactory``` class: 29 | 30 | ```java 31 | //ID and Node classes 32 | JpaNestedNodeRepositoryConfiguration configuration = new JpaNestedNodeRepositoryConfiguration<>( 33 | entityManager, YourNode.class, Long.class, new YourJpaTreeDiscriminator() //Discriminator is optional, allows to create multiple trees in one table 34 | ); 35 | return JpaNestedNodeRepositoryFactory.create(configuration); 36 | 37 | ``` 38 | Here is the example entity that implements the ```NestedNode``` interface: 39 | 40 | ```java 41 | 42 | @Entity 43 | @Table(name = "nested_nodes") 44 | public class TestNode implements NestedNode { 45 | 46 | @Id 47 | @GeneratedValue(strategy = GenerationType.AUTO) 48 | protected Long id; 49 | 50 | @Column(name = "tree_left", nullable = false) 51 | protected Long treeLeft; 52 | 53 | @Column(name = "tree_right", nullable = false) 54 | protected Long treeRight; 55 | 56 | @Column(name = "tree_level", nullable = false) 57 | protected Long treeLevel; 58 | 59 | @Column(name = "parent_id") 60 | protected Long parentId; 61 | 62 | //getters, setters 63 | } 64 | ``` 65 | -------------------------------------------------------------------------------- /README-MEM.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | ```xml 4 | 5 | 6 | 7 | jitpack.io 8 | https://jitpack.io 9 | 10 | 11 | 12 | 13 | com.github.eXsio 14 | nestedj 15 | 5.0.4 16 | 17 | 18 | ``` 19 | 20 | ## In Memory Usage 21 | 22 | In order to use NestedJ, You have to configure it. In 9 our of 10 cases you will want to use the preconfigured builder methods available in the ```InMemoryNestedNodeRepositoryFactory``` class: 23 | 24 | ```java 25 | AtomicLong id = new AtomicLong(); 26 | List nodes = Lists.newArrayList(); 27 | InMemoryNestedNodeRepositoryConfiguration configuration = new InMemoryNestedNodeRepositoryConfiguration<>(id::incrementAndGet, nodes, new TestInMemoryTreeDiscriminator()); 28 | return InMemoryNestedNodeRepositoryFactory.create(configuration, new InMemoryLock<>(YourNode::getDiscriminator)); 29 | 30 | ``` 31 | 32 | or if you don't need multithreaded access to the Repository and Tree Discriminator: 33 | 34 | ```java 35 | AtomicLong id = new AtomicLong(); 36 | InMemoryNestedNodeRepositoryConfiguration configuration = new InMemoryNestedNodeRepositoryConfiguration<>(id::incrementAndGet); 37 | return InMemoryNestedNodeRepositoryFactory.create(configuration); 38 | 39 | ``` 40 | 41 | The Node Class has to implement the ```NestedNode``` interface so that the logic can operage on Nested Node specific columns. 42 | 43 | ## Using in-memory implementation with noSQL storage 44 | 45 | You can use the in-memory implementation to modify and traverse the Tree. anytime you need to persist it, you can just get your Nodes 46 | by calling InMemoryNestedNodeRepositoryConfiguration::getNodes and store the flat List of the Tree Nodes wherever you want! 47 | You can serialize them to JSON or XML and store in noSQL database or even in flat file. -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | token: 692e8d9a-e2c4-416a-bcb9-90d8d9771677 3 | branch: master 4 | comment: 5 | layout: header, changes, diff 6 | coverage: 7 | status: {} -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | pl.exsio 6 | NestedJ 7 | 5.0.4.RELEASE 8 | jar 9 | 10 | NestedJ 11 | http://maven.apache.org 12 | 13 | 14 | org.springframework.boot 15 | spring-boot-starter-parent 16 | 2.5.0 17 | 18 | 19 | 20 | 21 | UTF-8 22 | 1.8 23 | 1.8 24 | 1.8 25 | 1.2.3 26 | 1.4.200 27 | 28 | 29 | 30 | 31 | 32 | org.hibernate.javax.persistence 33 | hibernate-jpa-2.1-api 34 | 1.0.2.Final 35 | provided 36 | 37 | 38 | org.springframework 39 | spring-jdbc 40 | 5.3.7 41 | provided 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-data-jpa 47 | test 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-test 52 | test 53 | 54 | 55 | com.h2database 56 | h2 57 | ${h2.version} 58 | test 59 | 60 | 61 | ch.qos.logback 62 | logback-core 63 | ${logback.version} 64 | test 65 | 66 | 67 | ch.qos.logback 68 | logback-classic 69 | ${logback.version} 70 | test 71 | 72 | 73 | 74 | 75 | NestedJ-${project.version} 76 | 77 | 78 | org.apache.maven.plugins 79 | maven-surefire-plugin 80 | 2.22.2 81 | 82 | ${argLine} 83 | 84 | **/*Test.java 85 | 86 | 87 | 88 | 89 | org.jacoco 90 | jacoco-maven-plugin 91 | 0.8.7 92 | 93 | 94 | 95 | prepare-agent 96 | 97 | 98 | 99 | report 100 | test 101 | 102 | report 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/jdbc/discriminator/JdbcTreeDiscriminator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.jdbc.discriminator; 22 | 23 | import java.util.List; 24 | 25 | /** 26 | * Tree Discriminator for use with JDBC Repository implementation. 27 | * Allows to store multiple intependant Trees in one Repository/Collection. 28 | */ 29 | public interface JdbcTreeDiscriminator { 30 | 31 | /** 32 | * Returns String with SQL query part that narrows the scope of all SQL Queries used by JDBC implementation 33 | * 34 | * @return - String with SQL query part that narrows the scope of all SQL Queries used by JDBC implementation. 35 | */ 36 | String getQueryPart(); 37 | 38 | /** 39 | * Returns List of values that should be set in the Prepared Statement and that correspond to the parameters used in the getQueryPart() method. 40 | * 41 | * @return - List of values that should be set in the Prepared Statement and that correspond to the parameters used in the getQueryPart() method. 42 | */ 43 | List getParameters(); 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/jdbc/factory/JdbcNestedNodeRepositoryFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.jdbc.factory; 22 | 23 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 24 | import pl.exsio.nestedj.NestedNodeRepository; 25 | import pl.exsio.nestedj.config.jdbc.JdbcNestedNodeRepositoryConfiguration; 26 | import pl.exsio.nestedj.delegate.control.*; 27 | import pl.exsio.nestedj.delegate.query.jdbc.*; 28 | import pl.exsio.nestedj.lock.NoLock; 29 | import pl.exsio.nestedj.model.NestedNode; 30 | 31 | import java.io.Serializable; 32 | 33 | /** 34 | * Factory class to construct new instances of JDBC Tree Repositories. 35 | */ 36 | public final class JdbcNestedNodeRepositoryFactory { 37 | 38 | private JdbcNestedNodeRepositoryFactory() { 39 | } 40 | 41 | /** 42 | * Creates a new instance of NestedNodeRepository backed by JDBC storage without any Repository locking. 43 | * 44 | * @param configuration - JDBC Repository configuration 45 | * @param - Nested Node Identifier Class 46 | * @param - Nested Node Class 47 | * @return - a new instance of NestedNodeRepository backed by JDBC storage 48 | */ 49 | public static > NestedNodeRepository create(JdbcNestedNodeRepositoryConfiguration configuration) { 50 | return create(configuration, new NoLock<>()); 51 | } 52 | 53 | /** 54 | * Creates a new instance of NestedNodeRepository backed by JDBC storage with custom Repository locking. 55 | * 56 | * @param configuration - JDBC Repository configuration 57 | * @param lock - custom Repository Lock implementation 58 | * @param - Nested Node Identifier Class 59 | * @param - Nested Node Class 60 | * @return - a new instance of NestedNodeRepository backed by JDBC storage 61 | */ 62 | public static > NestedNodeRepository create(JdbcNestedNodeRepositoryConfiguration configuration, NestedNodeRepository.Lock lock) { 63 | QueryBasedNestedNodeInserter inserter = new QueryBasedNestedNodeInserter<>(new JdbcNestedNodeInsertingQueryDelegate<>(configuration)); 64 | QueryBasedNestedNodeRetriever retriever = new QueryBasedNestedNodeRetriever<>(new JdbcNestedNodeRetrievingQueryDelegate<>(configuration)); 65 | return new DelegatingNestedNodeRepository<>( 66 | new QueryBasedNestedNodeMover<>(new JdbcNestedNodeMovingQueryDelegate<>(configuration)), 67 | new QueryBasedNestedNodeRemover<>(new JdbcNestedNodeRemovingQueryDelegate<>(configuration)), 68 | retriever, 69 | new QueryBasedNestedNodeRebuilder<>(inserter, retriever, new JdbcNestedNodeRebuildingQueryDelegate<>(configuration)), 70 | inserter, 71 | lock 72 | ); 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/jpa/JpaNestedNodeRepositoryConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.jpa; 22 | 23 | import pl.exsio.nestedj.config.jpa.discriminator.JpaTreeDiscriminator; 24 | import pl.exsio.nestedj.config.jpa.discriminator.MapJpaTreeDiscriminator; 25 | import pl.exsio.nestedj.model.NestedNode; 26 | 27 | import javax.persistence.EntityManager; 28 | import java.io.Serializable; 29 | 30 | /** 31 | * Configuration class that serves as a base of creating new instances of JPA Repository. 32 | * 33 | * @param - Nested Node Identifier Class 34 | * @param - Nested Node Class 35 | */ 36 | public class JpaNestedNodeRepositoryConfiguration> { 37 | 38 | private final JpaTreeDiscriminator treeDiscriminator; 39 | 40 | private final EntityManager entityManager; 41 | 42 | private final Class nodeClass; 43 | 44 | private final Class idClass; 45 | 46 | /** 47 | * Creates new JPA Repository with custom Tree Discriminator. 48 | * 49 | * @param entityManager - JPA Entity Manager to be used by the Repository 50 | * @param nodeClass - Nested Node Identifier Class 51 | * @param idClass - Nested Node Class 52 | * @param treeDiscriminator - custom Tree Discriminator 53 | */ 54 | public JpaNestedNodeRepositoryConfiguration( 55 | EntityManager entityManager, Class nodeClass, Class idClass, JpaTreeDiscriminator treeDiscriminator) { 56 | this.treeDiscriminator = treeDiscriminator; 57 | this.entityManager = entityManager; 58 | this.nodeClass = nodeClass; 59 | this.idClass = idClass; 60 | } 61 | 62 | /** 63 | * Creates new JPA Repository with no Tree Discriminator. 64 | * 65 | * @param entityManager - JPA Entity Manager to be used by the Repository 66 | * @param nodeClass - Nested Node Identifier Class 67 | * @param idClass - Nested Node Class 68 | */ 69 | public JpaNestedNodeRepositoryConfiguration(EntityManager entityManager, Class nodeClass, Class idClass) { 70 | this(entityManager, nodeClass, idClass, new MapJpaTreeDiscriminator<>()); 71 | } 72 | 73 | /** 74 | * @return Tree Discriminator used by this Configuration 75 | */ 76 | public JpaTreeDiscriminator getTreeDiscriminator() { 77 | return treeDiscriminator; 78 | } 79 | 80 | /** 81 | * @return JPA Entity Manager used by this Configuration 82 | */ 83 | public EntityManager getEntityManager() { 84 | return entityManager; 85 | } 86 | 87 | /** 88 | * @return Node Class used by this Configuration 89 | */ 90 | public Class getNodeClass() { 91 | return nodeClass; 92 | } 93 | 94 | /** 95 | * @return Node Identifier Class used by this Configuration 96 | */ 97 | public Class getIdClass() { 98 | return idClass; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/jpa/discriminator/JpaTreeDiscriminator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.jpa.discriminator; 22 | 23 | import pl.exsio.nestedj.model.NestedNode; 24 | 25 | import javax.persistence.criteria.CriteriaBuilder; 26 | import javax.persistence.criteria.Predicate; 27 | import javax.persistence.criteria.Root; 28 | import java.io.Serializable; 29 | import java.util.List; 30 | 31 | /** 32 | * Tree Discriminator for use with JPA Repository implementation. 33 | * Allows to store multiple intependant Trees in one Repository/Collection. 34 | * 35 | * @param - Nested Node Identifier Class 36 | * @param - Nested Node Class 37 | */ 38 | public interface JpaTreeDiscriminator> { 39 | 40 | /** 41 | * Method that decides wich Nodes should be affected by the Criteria Query. 42 | * 43 | * @param cb - JPA Criteria Builder 44 | * @param root - JPA Criteria Root of the Query 45 | * @return - List of JPA Criteria Predicates to be added to every Criteria Query executed by the JPA implementation 46 | */ 47 | List getPredicates(CriteriaBuilder cb, Root root); 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/jpa/discriminator/MapJpaTreeDiscriminator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.jpa.discriminator; 22 | 23 | import pl.exsio.nestedj.model.NestedNode; 24 | 25 | import javax.persistence.criteria.CriteriaBuilder; 26 | import javax.persistence.criteria.Predicate; 27 | import javax.persistence.criteria.Root; 28 | import java.io.Serializable; 29 | import java.util.ArrayList; 30 | import java.util.HashMap; 31 | import java.util.List; 32 | import java.util.Map; 33 | import java.util.function.Supplier; 34 | 35 | /** 36 | * Default implementation of JPA Tree Discriminator based on Map of > 37 | * 38 | * @param - Nested Node Identifier Class 39 | * @param - Nested Node Class 40 | */ 41 | public class MapJpaTreeDiscriminator> implements JpaTreeDiscriminator { 42 | 43 | private Map> valueProviders; 44 | 45 | /** 46 | * Creates a JPA Tree Discriminator that will add Predicates to all the Criteria Queries based on the passed Map. 47 | * Keys of the Map will be added as Keys in the Criteria Predicates. 48 | * Values obtained by the Suppliers will be added as Values of corresponding Keys in the Criteria Predicates. 49 | * 50 | * @param valueProviders - Map of > 51 | */ 52 | public MapJpaTreeDiscriminator(Map> valueProviders) { 53 | this.valueProviders = valueProviders; 54 | } 55 | 56 | /** 57 | * Create no-up Tree Discriminator 58 | */ 59 | public MapJpaTreeDiscriminator() { 60 | this.valueProviders = new HashMap<>(); 61 | } 62 | 63 | /** 64 | * Creates a JPA Tree Discriminator that will add Predicates to all the Criteria Queries based on the passed Map. 65 | * Keys of the Map will be added as Keys in the Criteria Predicates. 66 | * Values obtained by the Suppliers will be added as Values of corresponding Keys in the Criteria Predicates. 67 | * 68 | * @param valueProviders - Map of > 69 | */ 70 | public void setValueProviders(Map> valueProviders) { 71 | this.valueProviders = valueProviders; 72 | } 73 | 74 | /** 75 | * {@inheritDoc} 76 | */ 77 | @Override 78 | public List getPredicates(CriteriaBuilder cb, Root root) { 79 | List predicates = new ArrayList<>(); 80 | for (Map.Entry> providerEntry : valueProviders.entrySet()) { 81 | predicates.add(cb.equal(root.get(providerEntry.getKey()), providerEntry.getValue().get())); 82 | } 83 | return predicates; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/jpa/factory/JpaNestedNodeRepositoryFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.jpa.factory; 22 | 23 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 24 | import pl.exsio.nestedj.NestedNodeRepository; 25 | import pl.exsio.nestedj.config.jpa.JpaNestedNodeRepositoryConfiguration; 26 | import pl.exsio.nestedj.delegate.control.*; 27 | import pl.exsio.nestedj.delegate.query.jpa.*; 28 | import pl.exsio.nestedj.lock.NoLock; 29 | import pl.exsio.nestedj.model.NestedNode; 30 | 31 | import java.io.Serializable; 32 | 33 | /** 34 | * Factory class to construct new instances of JPA Tree Repositories. 35 | */ 36 | public final class JpaNestedNodeRepositoryFactory { 37 | 38 | private JpaNestedNodeRepositoryFactory() { 39 | } 40 | 41 | /** 42 | * Creates a new instance of NestedNodeRepository backed by JPA storage without any Repository locking. 43 | * 44 | * @param configuration - JPA Repository configuration 45 | * @param - Nested Node Identifier Class 46 | * @param - Nested Node Class 47 | * @return - a new instance of NestedNodeRepository backed by JPA storage 48 | */ 49 | public static > NestedNodeRepository create(JpaNestedNodeRepositoryConfiguration configuration) { 50 | return create(configuration, new NoLock<>()); 51 | } 52 | 53 | /** 54 | * Creates a new instance of NestedNodeRepository backed by JPA storage with custom Repository locking. 55 | * 56 | * @param configuration - JPA Repository configuration 57 | * @param lock - custom Repository Lock implementation 58 | * @param - Nested Node Identifier Class 59 | * @param - Nested Node Class 60 | * @return - a new instance of NestedNodeRepository backed by JPA storage 61 | */ 62 | public static > NestedNodeRepository create(JpaNestedNodeRepositoryConfiguration configuration, NestedNodeRepository.Lock lock) { 63 | QueryBasedNestedNodeInserter inserter = new QueryBasedNestedNodeInserter<>(new JpaNestedNodeInsertingQueryDelegate<>(configuration)); 64 | QueryBasedNestedNodeRetriever retriever = new QueryBasedNestedNodeRetriever<>(new JpaNestedNodeRetrievingQueryDelegate<>(configuration)); 65 | return new DelegatingNestedNodeRepository<>( 66 | new QueryBasedNestedNodeMover<>(new JpaNestedNodeMovingQueryDelegate<>(configuration)), 67 | new QueryBasedNestedNodeRemover<>(new JpaNestedNodeRemovingQueryDelegate<>(configuration)), 68 | retriever, 69 | new QueryBasedNestedNodeRebuilder<>(inserter, retriever, new JpaNestedNodeRebuildingQueryDelegate<>(configuration)), 70 | inserter, 71 | lock 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/mem/InMemoryNestedNodeRepositoryConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.mem; 22 | 23 | import pl.exsio.nestedj.config.mem.discriminator.InMemoryTreeDiscriminator; 24 | import pl.exsio.nestedj.config.mem.identity.InMemoryNestedNodeIdentityGenerator; 25 | import pl.exsio.nestedj.model.NestedNode; 26 | 27 | import java.io.Serializable; 28 | import java.util.ArrayList; 29 | import java.util.Collection; 30 | import java.util.Collections; 31 | import java.util.HashSet; 32 | import java.util.Set; 33 | 34 | /** 35 | * Configuration class that serves as a base of creating new instances of InMemory Repository. 36 | * 37 | * @param - Nested Node Identifier Class 38 | * @param - Nested Node Class 39 | */ 40 | public class InMemoryNestedNodeRepositoryConfiguration> { 41 | 42 | private final InMemoryTreeDiscriminator treeDiscriminator; 43 | 44 | private final InMemoryNestedNodeIdentityGenerator identityGenerator; 45 | 46 | private final Set nodes = Collections.synchronizedSet(new HashSet<>()); 47 | 48 | /** 49 | * Creates new InMemory Repository with empty Tree and no Tree Discriminator. 50 | * 51 | * @param identityGenerator - Identity generator used for inserting new Nodes into an InMemory Repository. 52 | */ 53 | public InMemoryNestedNodeRepositoryConfiguration(InMemoryNestedNodeIdentityGenerator identityGenerator) { 54 | this(identityGenerator, new ArrayList<>(), null); 55 | } 56 | 57 | /** 58 | * Creates new InMemory Repository with a collection of Nodes and no Tree Discriminator. 59 | * If the Nodes do not have proper LEFT/RIGHT/LEVEL values, Tree can be initialized with NestedNodeRepository::rebuildTree() method. 60 | * 61 | * @param identityGenerator - Identity generator used for inserting new Nodes into an InMemory Repository. 62 | * @param nodes - initial collection of Nodes 63 | */ 64 | public InMemoryNestedNodeRepositoryConfiguration(InMemoryNestedNodeIdentityGenerator identityGenerator, Collection nodes) { 65 | this(identityGenerator, nodes, null); 66 | } 67 | 68 | /** 69 | * Creates new InMemory Repository with a collection of Nodes and custom Tree Discriminator. 70 | * If the Nodes do not have proper LEFT/RIGHT/LEVEL values, Tree can be initialized with NestedNodeRepository::rebuildTree() method. 71 | * 72 | * @param identityGenerator - Identity generator used for inserting new Nodes into an InMemory Repository. 73 | * @param nodes - initial collection of Nodes 74 | * @param treeDiscriminator - custom Tree Discriminator 75 | */ 76 | public InMemoryNestedNodeRepositoryConfiguration(InMemoryNestedNodeIdentityGenerator identityGenerator, Collection nodes, InMemoryTreeDiscriminator treeDiscriminator) { 77 | this.identityGenerator = identityGenerator; 78 | this.treeDiscriminator = treeDiscriminator; 79 | this.nodes.addAll(nodes); 80 | } 81 | 82 | /** 83 | * @return Tree Discriminator used by this Configuration 84 | */ 85 | public InMemoryTreeDiscriminator getTreeDiscriminator() { 86 | return treeDiscriminator; 87 | } 88 | 89 | /** 90 | * @return Identiy Generator used by this Configuration 91 | */ 92 | public InMemoryNestedNodeIdentityGenerator getIdentityGenerator() { 93 | return identityGenerator; 94 | } 95 | 96 | /** 97 | * This method can be used to retrieve the data structure backing the InMemory Repository. 98 | * You can store the collection to (no)SQL storage or use it for custom data retrieval logic. 99 | * It is not recommended to manually modify the LEFT/RIGHT/LEVEL values of the Nodes contained in the returned Set. 100 | * 101 | * @return flat Set of Nodes - the data structure backing the InMemory implementation. 102 | */ 103 | public Set getNodes() { 104 | return nodes; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/mem/discriminator/InMemoryTreeDiscriminator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.mem.discriminator; 22 | 23 | import pl.exsio.nestedj.model.NestedNode; 24 | 25 | import java.io.Serializable; 26 | 27 | /** 28 | * Tree Discriminator for use with InMemory Repository implementation. 29 | * Allows to store multiple intependant Trees in one Repository/Collection. 30 | * 31 | * @param - Nested Node Identifier Class 32 | * @param - Nested Node Class 33 | */ 34 | public interface InMemoryTreeDiscriminator> { 35 | 36 | /** 37 | * Method that decides whether a target Node belongs to the Tree or not. 38 | * 39 | * @param node - target Node 40 | * @return true if Node belongs to the Tree, false if Node does not belong to the Tree 41 | */ 42 | boolean applies(N node); 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/mem/factory/InMemoryNestedNodeRepositoryFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.mem.factory; 22 | 23 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 24 | import pl.exsio.nestedj.NestedNodeRepository; 25 | import pl.exsio.nestedj.config.mem.InMemoryNestedNodeRepositoryConfiguration; 26 | import pl.exsio.nestedj.delegate.control.*; 27 | import pl.exsio.nestedj.delegate.query.mem.*; 28 | import pl.exsio.nestedj.lock.NoLock; 29 | import pl.exsio.nestedj.model.NestedNode; 30 | 31 | import java.io.Serializable; 32 | 33 | /** 34 | * Factory class to construct new instances of InMemory Tree Repositories. 35 | */ 36 | public final class InMemoryNestedNodeRepositoryFactory { 37 | 38 | private InMemoryNestedNodeRepositoryFactory() { 39 | } 40 | 41 | /** 42 | * Creates a new instance of NestedNodeRepository backed by InMemory storage without any Repository locking. 43 | * 44 | * @param configuration - InMemory Repository configuration 45 | * @param - Nested Node Identifier Class 46 | * @param - Nested Node Class 47 | * @return - a new instance of NestedNodeRepository backed by InMemory storage 48 | */ 49 | public static > NestedNodeRepository create(InMemoryNestedNodeRepositoryConfiguration configuration) { 50 | return create(configuration, new NoLock<>()); 51 | } 52 | 53 | /** 54 | * Creates a new instance of NestedNodeRepository backed by InMemory storage with custom Repository locking. 55 | * 56 | * @param configuration - InMemory Repository configuration 57 | * @param lock - custom Repository Lock implementation 58 | * @param - Nested Node Identifier Class 59 | * @param - Nested Node Class 60 | * @return - a new instance of NestedNodeRepository backed by InMemory storage 61 | */ 62 | public static > NestedNodeRepository create(InMemoryNestedNodeRepositoryConfiguration configuration, NestedNodeRepository.Lock lock) { 63 | QueryBasedNestedNodeInserter inserter = new QueryBasedNestedNodeInserter<>(new InMemoryNestedNodeInsertingQueryDelegate<>(configuration)); 64 | QueryBasedNestedNodeRetriever retriever = new QueryBasedNestedNodeRetriever<>(new InMemoryNestedNodeRetrievingQueryDelegate<>(configuration)); 65 | return new DelegatingNestedNodeRepository<>( 66 | new QueryBasedNestedNodeMover<>(new InMemoryNestedNodeMovingQueryDelegate<>(configuration)), 67 | new QueryBasedNestedNodeRemover<>(new InMemoryNestedNodeRemovingQueryDelegate<>(configuration)), 68 | retriever, 69 | new QueryBasedNestedNodeRebuilder<>(inserter, retriever, new InMemoryNestedNodeRebuildingQueryDelegate<>(configuration)), 70 | inserter, 71 | lock 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/mem/identity/InMemoryNestedNodeIdentityGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.mem.identity; 22 | 23 | import java.io.Serializable; 24 | 25 | /** 26 | * Identity generator used for inserting new Nodes into an InMemory Repository. 27 | * If you want to have an interoperability between InMemory implementation and DB-based implementation, make sure that 28 | * IDs generated by implementation of ths interface are compatible with your database configuration. 29 | * 30 | * @param - Nested Node ID Class 31 | */ 32 | public interface InMemoryNestedNodeIdentityGenerator { 33 | 34 | /** 35 | * Generates a unique identity for InMemory repository Node insertion 36 | * 37 | * @return ID - newly generated unique identity 38 | */ 39 | ID generateIdentity(); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/config/mem/lock/InMemoryLock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.config.mem.lock; 22 | 23 | import pl.exsio.nestedj.NestedNodeRepository; 24 | import pl.exsio.nestedj.model.NestedNode; 25 | 26 | import java.io.Serializable; 27 | import java.util.Collections; 28 | import java.util.HashSet; 29 | import java.util.Set; 30 | import java.util.concurrent.atomic.AtomicBoolean; 31 | import java.util.function.Function; 32 | 33 | /** 34 | * In Memory Lock - stores a Set of Lock Handles to determine whether a Node can be modified or not. 35 | * It is up to the user to provide the Lock Handle Object taht fits the needs. The Handle should have a proper 36 | * equals() and hashCode() to be correctly stored and removed in/from Set. 37 | *

38 | * Additionally the Lock check whether the whole Repository is locked or not. Locked repository takes precedence before 39 | * locking single Node. 40 | * 41 | * @param - Nested Node Identifier Class 42 | * @param - Nested Node Class 43 | */ 44 | public class InMemoryLock> implements NestedNodeRepository.Lock { 45 | 46 | private final AtomicBoolean repositoryLocked = new AtomicBoolean(false); 47 | 48 | private final Set lockHandles = Collections.synchronizedSet(new HashSet<>()); 49 | 50 | private final Function lockHandleProvider; 51 | 52 | public InMemoryLock() { 53 | this.lockHandleProvider = null; 54 | } 55 | 56 | public InMemoryLock(Function lockHandleProvider) { 57 | if (lockHandleProvider == null) { 58 | throw new NullPointerException("lockHandleProvider cannot be null"); 59 | } 60 | this.lockHandleProvider = lockHandleProvider; 61 | } 62 | 63 | /** 64 | * {@inheritDoc} 65 | */ 66 | @Override 67 | public synchronized boolean lockNode(N node) { 68 | if (repositoryLocked.get()) { 69 | return false; 70 | } 71 | if (lockHandleProvider == null) { 72 | return lockRepository(); 73 | } 74 | 75 | Object handle = lockHandleProvider.apply(node); 76 | if (lockHandles.contains(handle)) { 77 | return false; 78 | } 79 | lockHandles.add(handle); 80 | return true; 81 | } 82 | 83 | /** 84 | * {@inheritDoc} 85 | */ 86 | @Override 87 | public synchronized void unlockNode(N node) { 88 | if (lockHandleProvider == null) { 89 | unlockRepository(); 90 | } else { 91 | lockHandles.remove(lockHandleProvider.apply(node)); 92 | } 93 | } 94 | 95 | /** 96 | * {@inheritDoc} 97 | */ 98 | @Override 99 | public synchronized boolean lockRepository() { 100 | if (repositoryLocked.get()) { 101 | return false; 102 | } 103 | repositoryLocked.set(true); 104 | return true; 105 | } 106 | 107 | /** 108 | * {@inheritDoc} 109 | */ 110 | @Override 111 | public synchronized void unlockRepository() { 112 | repositoryLocked.set(false); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/NestedNodeHierarchyManipulator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.delegate; 21 | 22 | public interface NestedNodeHierarchyManipulator { 23 | 24 | enum Mode { 25 | FIRST_CHILD, 26 | LAST_CHILD, 27 | NEXT_SIBLING, 28 | PREV_SIBLING 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/NestedNodeInserter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.delegate; 21 | 22 | import pl.exsio.nestedj.model.NestedNode; 23 | import pl.exsio.nestedj.model.NestedNodeInfo; 24 | 25 | import java.io.Serializable; 26 | 27 | public interface NestedNodeInserter> extends NestedNodeHierarchyManipulator { 28 | 29 | void insert(N node, NestedNodeInfo parentInfo, Mode mode); 30 | 31 | void insertAsFirstNode(N node); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/NestedNodeMover.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.delegate; 21 | 22 | import pl.exsio.nestedj.model.NestedNode; 23 | import pl.exsio.nestedj.model.NestedNodeInfo; 24 | 25 | import java.io.Serializable; 26 | 27 | public interface NestedNodeMover> extends NestedNodeHierarchyManipulator { 28 | 29 | void move(NestedNodeInfo nodeInfo, NestedNodeInfo parentInfo, Mode mode); 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/NestedNodeRebuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.delegate; 21 | 22 | import pl.exsio.nestedj.model.NestedNode; 23 | 24 | import java.io.Serializable; 25 | 26 | public interface NestedNodeRebuilder> { 27 | 28 | void rebuildTree(); 29 | 30 | void destroyTree(); 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/NestedNodeRemover.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.delegate; 21 | 22 | import pl.exsio.nestedj.model.NestedNode; 23 | import pl.exsio.nestedj.model.NestedNodeInfo; 24 | 25 | import java.io.Serializable; 26 | 27 | public interface NestedNodeRemover> { 28 | 29 | void removeSingle(NestedNodeInfo node); 30 | 31 | void removeSubtree(NestedNodeInfo node); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/NestedNodeRetriever.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.delegate; 21 | 22 | import pl.exsio.nestedj.model.NestedNode; 23 | import pl.exsio.nestedj.model.NestedNodeInfo; 24 | import pl.exsio.nestedj.model.Tree; 25 | 26 | import java.io.Serializable; 27 | import java.util.List; 28 | import java.util.Optional; 29 | 30 | public interface NestedNodeRetriever> { 31 | 32 | List getTreeAsList(N node); 33 | 34 | List getChildren(N node); 35 | 36 | Optional getParent(N nodes); 37 | 38 | Optional getPrevSibling(N node); 39 | 40 | Optional getNextSibling(N node); 41 | 42 | Tree getTree(N node); 43 | 44 | List getParents(N node); 45 | 46 | Optional> getNodeInfo(ID nodeIds); 47 | 48 | Optional findFirstRoot(); 49 | 50 | Optional findLastRoot(); 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/control/QueryBasedNestedNodeRebuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.delegate.control; 21 | 22 | import pl.exsio.nestedj.delegate.NestedNodeInserter; 23 | import pl.exsio.nestedj.delegate.NestedNodeMover; 24 | import pl.exsio.nestedj.delegate.NestedNodeRebuilder; 25 | import pl.exsio.nestedj.delegate.NestedNodeRetriever; 26 | import pl.exsio.nestedj.delegate.query.NestedNodeRebuildingQueryDelegate; 27 | import pl.exsio.nestedj.ex.InvalidNodeException; 28 | import pl.exsio.nestedj.model.NestedNode; 29 | import pl.exsio.nestedj.model.NestedNodeInfo; 30 | 31 | import java.io.Serializable; 32 | import java.util.Optional; 33 | 34 | public class QueryBasedNestedNodeRebuilder> implements NestedNodeRebuilder { 35 | 36 | private final NestedNodeInserter inserter; 37 | 38 | private final NestedNodeRetriever retriever; 39 | 40 | private final NestedNodeRebuildingQueryDelegate queryDelegate; 41 | 42 | public QueryBasedNestedNodeRebuilder(NestedNodeInserter inserter, NestedNodeRetriever retriever, 43 | NestedNodeRebuildingQueryDelegate queryDelegate) { 44 | this.inserter = inserter; 45 | this.retriever = retriever; 46 | this.queryDelegate = queryDelegate; 47 | } 48 | 49 | @Override 50 | public void rebuildTree() { 51 | N first = queryDelegate.findFirst(); 52 | queryDelegate.resetFirst(first); 53 | restoreSiblings(first); 54 | rebuildRecursively(first); 55 | for (N node : queryDelegate.getSiblings(first.getId())) { 56 | rebuildRecursively(node); 57 | } 58 | } 59 | 60 | @Override 61 | public void destroyTree() { 62 | queryDelegate.destroyTree(); 63 | } 64 | 65 | private void rebuildRecursively(N parent) { 66 | for (N child : queryDelegate.getChildren(parent)) { 67 | inserter.insert(child, getNodeInfo(parent.getId()), NestedNodeMover.Mode.LAST_CHILD); 68 | rebuildRecursively(child); 69 | } 70 | } 71 | 72 | private void restoreSiblings(N first) { 73 | for (N node : queryDelegate.getSiblings(first.getId())) { 74 | inserter.insert(node, getNodeInfo(first.getId()), NestedNodeMover.Mode.NEXT_SIBLING); 75 | } 76 | } 77 | 78 | private NestedNodeInfo getNodeInfo(ID nodeId) { 79 | if (nodeId == null) { 80 | throw new NullPointerException("nodeId cannot be null"); 81 | } 82 | Optional> nodeInfo = retriever.getNodeInfo(nodeId); 83 | if (!nodeInfo.isPresent()) { 84 | throw new InvalidNodeException(String.format("Couldn't find node with Id %s", nodeId)); 85 | } 86 | return nodeInfo.get(); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/control/QueryBasedNestedNodeRemover.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.delegate.control; 21 | 22 | import pl.exsio.nestedj.delegate.NestedNodeRemover; 23 | import pl.exsio.nestedj.delegate.query.NestedNodeRemovingQueryDelegate; 24 | import pl.exsio.nestedj.model.NestedNode; 25 | import pl.exsio.nestedj.model.NestedNodeInfo; 26 | 27 | import java.io.Serializable; 28 | 29 | import static pl.exsio.nestedj.model.NestedNode.LEFT; 30 | import static pl.exsio.nestedj.model.NestedNode.RIGHT; 31 | 32 | public class QueryBasedNestedNodeRemover> implements NestedNodeRemover { 33 | 34 | private final NestedNodeRemovingQueryDelegate queryDelegate; 35 | 36 | public QueryBasedNestedNodeRemover(NestedNodeRemovingQueryDelegate queryDelegate) { 37 | this.queryDelegate = queryDelegate; 38 | } 39 | 40 | @Override 41 | public void removeSingle(NestedNodeInfo nodeInfo) { 42 | Long from = nodeInfo.getRight(); 43 | queryDelegate.setNewParentForDeletedNodesChildren(nodeInfo); 44 | queryDelegate.decrementSideFieldsBeforeSingleNodeRemoval(from, RIGHT); 45 | queryDelegate.decrementSideFieldsBeforeSingleNodeRemoval(from, LEFT); 46 | queryDelegate.pushUpDeletedNodesChildren(nodeInfo); 47 | queryDelegate.performSingleDeletion(nodeInfo); 48 | } 49 | 50 | @Override 51 | public void removeSubtree(NestedNodeInfo nodeInfo) { 52 | Long delta = nodeInfo.getRight() - nodeInfo.getLeft() + 1; 53 | Long from = nodeInfo.getRight(); 54 | queryDelegate.performBatchDeletion(nodeInfo); 55 | queryDelegate.decrementSideFieldsAfterSubtreeRemoval(from, delta, RIGHT); 56 | queryDelegate.decrementSideFieldsAfterSubtreeRemoval(from, delta, LEFT); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/control/QueryBasedNestedNodeRetriever.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.delegate.control; 21 | 22 | import pl.exsio.nestedj.delegate.NestedNodeRetriever; 23 | import pl.exsio.nestedj.delegate.query.NestedNodeRetrievingQueryDelegate; 24 | import pl.exsio.nestedj.model.InMemoryTree; 25 | import pl.exsio.nestedj.model.NestedNode; 26 | import pl.exsio.nestedj.model.NestedNodeInfo; 27 | import pl.exsio.nestedj.model.Tree; 28 | 29 | import java.io.Serializable; 30 | import java.util.List; 31 | import java.util.Optional; 32 | 33 | public class QueryBasedNestedNodeRetriever> implements NestedNodeRetriever { 34 | 35 | private final NestedNodeRetrievingQueryDelegate queryDelegate; 36 | 37 | public QueryBasedNestedNodeRetriever(NestedNodeRetrievingQueryDelegate queryDelegate) { 38 | this.queryDelegate = queryDelegate; 39 | } 40 | 41 | @Override 42 | public Tree getTree(N node) { 43 | Tree tree = new InMemoryTree<>(node); 44 | for (N n : queryDelegate.getChildren(node)) { 45 | Tree subtree = this.getTree(n); 46 | tree.addChild(subtree); 47 | } 48 | return tree; 49 | } 50 | 51 | @Override 52 | public List getTreeAsList(N node) { 53 | return queryDelegate.getTreeAsList(node); 54 | } 55 | 56 | @Override 57 | public List getChildren(N node) { 58 | return queryDelegate.getChildren(node); 59 | } 60 | 61 | @Override 62 | public Optional getParent(N node) { 63 | return queryDelegate.getParent(node); 64 | } 65 | 66 | @Override 67 | public List getParents(N node) { 68 | return queryDelegate.getParents(node); 69 | } 70 | 71 | @Override 72 | public Optional getPrevSibling(N node) { 73 | return queryDelegate.getPrevSibling(node); 74 | } 75 | 76 | @Override 77 | public Optional getNextSibling(N node) { 78 | return queryDelegate.getNextSibling(node); 79 | } 80 | 81 | @Override 82 | public Optional> getNodeInfo(ID nodeId) { 83 | return queryDelegate.getNodeInfo(nodeId); 84 | } 85 | 86 | @Override 87 | public Optional findFirstRoot() { 88 | return queryDelegate.findFirstRoot(); 89 | } 90 | 91 | @Override 92 | public Optional findLastRoot() { 93 | return queryDelegate.findLastRoot(); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/NestedNodeInsertingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query; 22 | 23 | import pl.exsio.nestedj.model.NestedNode; 24 | 25 | import java.io.Serializable; 26 | 27 | public interface NestedNodeInsertingQueryDelegate> { 28 | 29 | Long INCREMENT_BY = 2L; 30 | 31 | void insert(N node); 32 | 33 | void incrementSideFieldsGreaterThan(Long from, String fieldName); 34 | 35 | void incermentSideFieldsGreaterThanOrEqualTo(Long from, String fieldName); 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/NestedNodeMovingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query; 22 | 23 | import pl.exsio.nestedj.model.NestedNode; 24 | import pl.exsio.nestedj.model.NestedNodeInfo; 25 | 26 | import java.io.Serializable; 27 | 28 | public interface NestedNodeMovingQueryDelegate> { 29 | 30 | Integer markNodeIds(NestedNodeInfo node); 31 | 32 | void updateSideFieldsUp(Long delta, Long start, Long stop, String field); 33 | 34 | void updateSideFieldsDown(Long delta, Long start, Long stop, String field); 35 | 36 | void performMoveUp(Long nodeDelta, Long levelModificator); 37 | 38 | void performMoveDown(Long nodeDelta, Long levelModificator); 39 | 40 | void updateParentField(ID newParentId, NestedNodeInfo node); 41 | 42 | void clearParentField(NestedNodeInfo node); 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/NestedNodeRebuildingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query; 22 | 23 | import pl.exsio.nestedj.model.NestedNode; 24 | 25 | import java.io.Serializable; 26 | import java.util.List; 27 | 28 | public interface NestedNodeRebuildingQueryDelegate> { 29 | 30 | void destroyTree(); 31 | 32 | N findFirst(); 33 | 34 | void resetFirst(N first); 35 | 36 | List getSiblings(ID first); 37 | 38 | List getChildren(N parent); 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/NestedNodeRemovingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query; 22 | 23 | import pl.exsio.nestedj.model.NestedNode; 24 | import pl.exsio.nestedj.model.NestedNodeInfo; 25 | 26 | import java.io.Serializable; 27 | 28 | public interface NestedNodeRemovingQueryDelegate> { 29 | 30 | Long DECREMENT_BY = 2L; 31 | 32 | void setNewParentForDeletedNodesChildren(NestedNodeInfo node); 33 | 34 | void performSingleDeletion(NestedNodeInfo node); 35 | 36 | void decrementSideFieldsBeforeSingleNodeRemoval(Long from, String field); 37 | 38 | void pushUpDeletedNodesChildren(NestedNodeInfo node); 39 | 40 | void decrementSideFieldsAfterSubtreeRemoval(Long from, Long delta, String field); 41 | 42 | void performBatchDeletion(NestedNodeInfo node); 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/NestedNodeRetrievingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query; 22 | 23 | import pl.exsio.nestedj.model.NestedNode; 24 | import pl.exsio.nestedj.model.NestedNodeInfo; 25 | 26 | import java.io.Serializable; 27 | import java.util.List; 28 | import java.util.Optional; 29 | 30 | public interface NestedNodeRetrievingQueryDelegate> { 31 | 32 | List getTreeAsList(N node); 33 | 34 | List getChildren(N node); 35 | 36 | Optional getParent(N node); 37 | 38 | List getParents(N node); 39 | 40 | Optional getPrevSibling(N node); 41 | 42 | Optional getNextSibling(N node); 43 | 44 | Optional> getNodeInfo(ID nodeId); 45 | 46 | Optional findFirstRoot(); 47 | 48 | Optional findLastRoot(); 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/jdbc/JdbcKeyHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query.jdbc; 22 | 23 | import org.springframework.dao.DataRetrievalFailureException; 24 | import org.springframework.dao.InvalidDataAccessApiUsageException; 25 | import org.springframework.jdbc.support.GeneratedKeyHolder; 26 | 27 | import java.io.Serializable; 28 | import java.util.Iterator; 29 | import java.util.Map; 30 | 31 | public class JdbcKeyHolder extends GeneratedKeyHolder implements Serializable { 32 | 33 | @SuppressWarnings("unchecked") 34 | public T getKeyValueAs(Class keyClass) { 35 | if (this.getKeyList().isEmpty()) { 36 | return null; 37 | } else if (this.getKeyList().size() <= 1 && this.getKeyList().get(0).size() <= 1) { 38 | Iterator keyIter = ((Map)this.getKeyList().get(0)).values().iterator(); 39 | if (keyIter.hasNext()) { 40 | Object key = keyIter.next(); 41 | if (!(keyClass.isAssignableFrom(key.getClass()))) { 42 | throw new DataRetrievalFailureException("The generated key is not of a supported type. Unable to cast [" + key.getClass().getName() + "] to [" + keyClass.getName() + "]"); 43 | } else { 44 | return keyClass.cast(key); 45 | } 46 | } else { 47 | throw new DataRetrievalFailureException("Unable to retrieve the generated key. Check that the table has an identity column enabled."); 48 | } 49 | } else { 50 | throw new InvalidDataAccessApiUsageException("The getKey method should only be used when a single key is returned. The current key entry contains multiple keys: " + this.getKeyList()); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/jdbc/JdbcNestedNodeInsertingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query.jdbc; 22 | 23 | import pl.exsio.nestedj.config.jdbc.JdbcNestedNodeRepositoryConfiguration; 24 | import pl.exsio.nestedj.delegate.query.NestedNodeInsertingQueryDelegate; 25 | import pl.exsio.nestedj.model.NestedNode; 26 | 27 | import java.io.Serializable; 28 | import java.sql.PreparedStatement; 29 | import java.sql.Types; 30 | 31 | public class JdbcNestedNodeInsertingQueryDelegate> 32 | extends JdbcNestedNodeQueryDelegate 33 | implements NestedNodeInsertingQueryDelegate { 34 | 35 | public JdbcNestedNodeInsertingQueryDelegate(JdbcNestedNodeRepositoryConfiguration configuration) { 36 | super(configuration); 37 | } 38 | 39 | @Override 40 | 41 | public void insert(N node) { 42 | if (node.getId() == null) { 43 | doInsert(node); 44 | } else { 45 | update(node); 46 | } 47 | 48 | } 49 | 50 | private void update(N node) { 51 | jdbcTemplate.update( 52 | getDiscriminatedQuery( 53 | new Query("update :tableName set :left = ?, :right = ?, :level = ?, :parentId = ? where :id = ?").build() 54 | ), 55 | preparedStatement -> { 56 | preparedStatement.setObject(1, node.getTreeLeft()); 57 | preparedStatement.setObject(2, node.getTreeRight()); 58 | preparedStatement.setObject(3, node.getTreeLevel()); 59 | if (node.getParentId() == null) { 60 | preparedStatement.setNull(4, Types.OTHER); 61 | } else { 62 | preparedStatement.setObject(4, node.getParentId()); 63 | } 64 | preparedStatement.setObject(5, node.getId()); 65 | setDiscriminatorParams(preparedStatement, 6); 66 | } 67 | ); 68 | } 69 | 70 | private void doInsert(N node) { 71 | JdbcKeyHolder keyHolder = new JdbcKeyHolder(); 72 | jdbcTemplate.update(con -> { 73 | PreparedStatement ps = con.prepareStatement(insertQuery, new String[]{id}); 74 | Object[] params = insertValuesProvider.apply(node); 75 | for (int i = 0; i < params.length; i++) { 76 | ps.setObject(i + 1, params[i]); 77 | } 78 | return ps; 79 | }, keyHolder); 80 | node.setId(generatedKeyResolver.apply(node, keyHolder)); 81 | } 82 | 83 | @Override 84 | public void incrementSideFieldsGreaterThan(Long from, String fieldName) { 85 | updateFields(from, fieldName, false); 86 | } 87 | 88 | @Override 89 | public void incermentSideFieldsGreaterThanOrEqualTo(Long from, String fieldName) { 90 | updateFields(from, fieldName, true); 91 | } 92 | 93 | private void updateFields(Long from, String fieldName, boolean gte) { 94 | String columnName = treeColumnNames.get(fieldName); 95 | String sign = gte ? ">=" : ">"; 96 | jdbcTemplate.update( 97 | getDiscriminatedQuery( 98 | new Query("update :tableName set :columnName = (:columnName + ?) where :columnName :sign ?") 99 | .set("columnName", columnName) 100 | .set("sign", sign) 101 | .build() 102 | ), 103 | preparedStatement -> { 104 | preparedStatement.setLong(1, INCREMENT_BY); 105 | preparedStatement.setLong(2, from); 106 | setDiscriminatorParams(preparedStatement, 3); 107 | } 108 | ); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/jdbc/JdbcNestedNodeRebuildingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query.jdbc; 22 | 23 | import pl.exsio.nestedj.config.jdbc.JdbcNestedNodeRepositoryConfiguration; 24 | import pl.exsio.nestedj.delegate.query.NestedNodeRebuildingQueryDelegate; 25 | import pl.exsio.nestedj.model.NestedNode; 26 | 27 | import java.io.Serializable; 28 | import java.util.List; 29 | 30 | public class JdbcNestedNodeRebuildingQueryDelegate> 31 | extends JdbcNestedNodeQueryDelegate 32 | implements NestedNodeRebuildingQueryDelegate { 33 | 34 | public JdbcNestedNodeRebuildingQueryDelegate(JdbcNestedNodeRepositoryConfiguration configuration) { 35 | super(configuration); 36 | } 37 | 38 | 39 | @Override 40 | public void destroyTree() { 41 | jdbcTemplate.update( 42 | getDiscriminatedQuery( 43 | new Query("update :tableName set :left = 0, :right = 0, :level = 0").build() 44 | ), 45 | preparedStatement -> setDiscriminatorParams(preparedStatement, 1) 46 | ); 47 | } 48 | 49 | @Override 50 | public N findFirst() { 51 | List result = jdbcTemplate.query( 52 | getDiscriminatedQuery( 53 | new Query("select * from :tableName where :parentId is null order by :id desc").build() 54 | ), 55 | preparedStatement -> { 56 | setDiscriminatorParams(preparedStatement, 1); 57 | }, 58 | rowMapper 59 | ); 60 | return result.stream().findFirst().orElse(null); 61 | } 62 | 63 | @Override 64 | public void resetFirst(N first) { 65 | jdbcTemplate.update( 66 | getDiscriminatedQuery( 67 | new Query("update :tableName set :left = 1, :right = 2, :level = 0 where :id = ?").build() 68 | ), 69 | preparedStatement -> { 70 | preparedStatement.setObject(1, first.getId()); 71 | setDiscriminatorParams(preparedStatement, 2); 72 | } 73 | ); 74 | } 75 | 76 | @Override 77 | public List getSiblings(ID first) { 78 | return jdbcTemplate.query( 79 | getDiscriminatedQuery( 80 | new Query("select * from :tableName where :parentId is null and :id <> ? order by :id asc").build() 81 | ), 82 | preparedStatement -> { 83 | preparedStatement.setObject(1, first); 84 | setDiscriminatorParams(preparedStatement, 2); 85 | }, 86 | rowMapper 87 | ); 88 | } 89 | 90 | @Override 91 | public List getChildren(N parent) { 92 | return jdbcTemplate.query( 93 | getDiscriminatedQuery( 94 | new Query("select * from :tableName where :parentId = ? order by :id asc").build() 95 | ), 96 | preparedStatement -> { 97 | preparedStatement.setObject(1, parent.getId()); 98 | setDiscriminatorParams(preparedStatement, 2); 99 | }, 100 | rowMapper 101 | ); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/jpa/JpaNestedNodeInsertingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query.jpa; 22 | 23 | import pl.exsio.nestedj.config.jpa.JpaNestedNodeRepositoryConfiguration; 24 | import pl.exsio.nestedj.delegate.query.NestedNodeInsertingQueryDelegate; 25 | import pl.exsio.nestedj.model.NestedNode; 26 | 27 | import javax.persistence.criteria.CriteriaBuilder; 28 | import javax.persistence.criteria.CriteriaUpdate; 29 | import javax.persistence.criteria.Root; 30 | import java.io.Serializable; 31 | 32 | public class JpaNestedNodeInsertingQueryDelegate> 33 | extends JpaNestedNodeQueryDelegate 34 | implements NestedNodeInsertingQueryDelegate { 35 | 36 | public JpaNestedNodeInsertingQueryDelegate(JpaNestedNodeRepositoryConfiguration configuration) { 37 | super(configuration); 38 | } 39 | 40 | @Override 41 | public void insert(N node) { 42 | entityManager.persist(node); 43 | } 44 | 45 | @Override 46 | public void incrementSideFieldsGreaterThan(Long from, String fieldName) { 47 | updateFields(from, fieldName, false); 48 | } 49 | 50 | @Override 51 | public void incermentSideFieldsGreaterThanOrEqualTo(Long from, String fieldName) { 52 | updateFields(from, fieldName, true); 53 | } 54 | 55 | private void updateFields(Long from, String fieldName, boolean gte) { 56 | CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 57 | CriteriaUpdate update = cb.createCriteriaUpdate(nodeClass); 58 | Root root = update.from(nodeClass); 59 | update.set(root.get(fieldName), cb.sum(root.get(fieldName), INCREMENT_BY)); 60 | if(gte) { 61 | update.where(getPredicates(cb, root, cb.greaterThanOrEqualTo(root.get(fieldName), from))); 62 | } else { 63 | update.where(getPredicates(cb, root, cb.greaterThan(root.get(fieldName), from))); 64 | } 65 | entityManager.createQuery(update).executeUpdate(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/jpa/JpaNestedNodeQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query.jpa; 22 | 23 | import pl.exsio.nestedj.config.jpa.JpaNestedNodeRepositoryConfiguration; 24 | import pl.exsio.nestedj.config.jpa.discriminator.JpaTreeDiscriminator; 25 | import pl.exsio.nestedj.model.NestedNode; 26 | 27 | import javax.persistence.EntityManager; 28 | import javax.persistence.criteria.CriteriaBuilder; 29 | import javax.persistence.criteria.Predicate; 30 | import javax.persistence.criteria.Root; 31 | import java.io.Serializable; 32 | import java.util.ArrayList; 33 | import java.util.Collections; 34 | import java.util.List; 35 | 36 | public abstract class JpaNestedNodeQueryDelegate> { 37 | 38 | private final JpaTreeDiscriminator treeDiscriminator; 39 | 40 | protected final EntityManager entityManager; 41 | 42 | protected final Class nodeClass; 43 | 44 | protected final Class idClass; 45 | 46 | public JpaNestedNodeQueryDelegate(JpaNestedNodeRepositoryConfiguration configuration) { 47 | this.entityManager = configuration.getEntityManager(); 48 | this.treeDiscriminator = configuration.getTreeDiscriminator(); 49 | this.nodeClass = configuration.getNodeClass(); 50 | this.idClass = configuration.getIdClass(); 51 | } 52 | 53 | protected Predicate[] getPredicates(CriteriaBuilder cb, Root root, Predicate... predicates) { 54 | List predicateList = new ArrayList<>(treeDiscriminator.getPredicates(cb, root)); 55 | Collections.addAll(predicateList, predicates); 56 | return predicateList.toArray(new Predicate[0]); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/jpa/JpaNestedNodeRebuildingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query.jpa; 22 | 23 | import pl.exsio.nestedj.config.jpa.JpaNestedNodeRepositoryConfiguration; 24 | import pl.exsio.nestedj.delegate.query.NestedNodeRebuildingQueryDelegate; 25 | import pl.exsio.nestedj.model.NestedNode; 26 | 27 | import javax.persistence.criteria.CriteriaBuilder; 28 | import javax.persistence.criteria.CriteriaQuery; 29 | import javax.persistence.criteria.CriteriaUpdate; 30 | import javax.persistence.criteria.Root; 31 | import java.io.Serializable; 32 | import java.util.List; 33 | 34 | import static pl.exsio.nestedj.model.NestedNode.*; 35 | 36 | public class JpaNestedNodeRebuildingQueryDelegate> 37 | extends JpaNestedNodeQueryDelegate 38 | implements NestedNodeRebuildingQueryDelegate { 39 | 40 | private final static Long UPDATE_INCREMENT_BY = 2L; 41 | 42 | public JpaNestedNodeRebuildingQueryDelegate(JpaNestedNodeRepositoryConfiguration configuration) { 43 | super(configuration); 44 | } 45 | 46 | @Override 47 | public void destroyTree() { 48 | CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 49 | CriteriaUpdate update = cb.createCriteriaUpdate(nodeClass); 50 | Root root = update.from(nodeClass); 51 | update 52 | .set(root.get(LEFT), 0L) 53 | .set(root.get(RIGHT), 0L) 54 | .set(root.get(LEVEL), 0L) 55 | .where(getPredicates(cb, root)); 56 | 57 | entityManager.createQuery(update).executeUpdate(); 58 | } 59 | 60 | @Override 61 | public N findFirst() { 62 | CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 63 | CriteriaQuery select = cb.createQuery(nodeClass); 64 | Root root = select.from(nodeClass); 65 | select.where(getPredicates(cb, root, cb.isNull(root.get(PARENT_ID)))) 66 | .orderBy(cb.desc(root.get(ID))); 67 | return entityManager.createQuery(select).setMaxResults(1).getSingleResult(); 68 | } 69 | 70 | @Override 71 | public void resetFirst(N first) { 72 | CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 73 | CriteriaUpdate update = cb.createCriteriaUpdate(nodeClass); 74 | Root root = update.from(nodeClass); 75 | update 76 | .set(root.get(LEVEL), 0L) 77 | .set(root.get(LEFT), 1L) 78 | .set(root.get(RIGHT), 2L) 79 | .where(getPredicates(cb, root, cb.equal(update.getRoot().get(ID), first.getId()))); 80 | entityManager.createQuery(update).executeUpdate(); 81 | } 82 | 83 | @Override 84 | public List getSiblings(ID first) { 85 | CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 86 | CriteriaQuery select = cb.createQuery(nodeClass); 87 | Root root = select.from(nodeClass); 88 | select.where(getPredicates(cb, root, 89 | cb.isNull(root.get(PARENT_ID)), 90 | cb.notEqual(root.get(ID), first) 91 | )).orderBy(cb.asc(root.get(ID))); 92 | return entityManager.createQuery(select).getResultList(); 93 | } 94 | 95 | @Override 96 | public List getChildren(N parent) { 97 | CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 98 | CriteriaQuery select = cb.createQuery(nodeClass); 99 | Root root = select.from(nodeClass); 100 | select.where(getPredicates(cb, root, cb.equal(root.get(PARENT_ID), parent.getId()))).orderBy(cb.asc(root.get(ID))); 101 | return entityManager.createQuery(select).getResultList(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/mem/InMemoryNestedNodeInsertingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query.mem; 22 | 23 | import pl.exsio.nestedj.config.mem.InMemoryNestedNodeRepositoryConfiguration; 24 | import pl.exsio.nestedj.delegate.query.NestedNodeInsertingQueryDelegate; 25 | import pl.exsio.nestedj.model.NestedNode; 26 | 27 | import java.io.Serializable; 28 | 29 | 30 | public class InMemoryNestedNodeInsertingQueryDelegate> 31 | extends InMemoryNestedNodeQueryDelegate 32 | implements NestedNodeInsertingQueryDelegate { 33 | 34 | 35 | public InMemoryNestedNodeInsertingQueryDelegate(InMemoryNestedNodeRepositoryConfiguration configuration) { 36 | super(configuration); 37 | } 38 | 39 | @Override 40 | public void insert(N node) { 41 | if (node.getId() == null) { 42 | doInsert(node); 43 | } else { 44 | update(node); 45 | } 46 | } 47 | 48 | private void update(N node) { 49 | nodesStream() 50 | .filter(n -> getSerializable(NestedNode.ID, n).equals(node.getId())) 51 | .forEach(n -> { 52 | n.setTreeLevel(node.getTreeLevel()); 53 | n.setTreeLeft(node.getTreeLeft()); 54 | n.setTreeRight(node.getTreeRight()); 55 | n.setParentId(node.getParentId()); 56 | }); 57 | } 58 | 59 | private void doInsert(N node) { 60 | ID newId = generateIdentity(); 61 | node.setId(newId); 62 | nodes.add(node); 63 | } 64 | 65 | @Override 66 | public void incrementSideFieldsGreaterThan(Long from, String fieldName) { 67 | nodesStream() 68 | .filter(n -> getLong(fieldName, n) > from) 69 | .forEach(n -> setLong(fieldName, n, getLong(fieldName, n) + INCREMENT_BY)); 70 | } 71 | 72 | @Override 73 | public void incermentSideFieldsGreaterThanOrEqualTo(Long from, String fieldName) { 74 | nodesStream() 75 | .filter(n -> getLong(fieldName, n) >= from) 76 | .forEach(n -> setLong(fieldName, n, getLong(fieldName, n) + INCREMENT_BY)); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/mem/InMemoryNestedNodeQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query.mem; 22 | 23 | import pl.exsio.nestedj.config.mem.InMemoryNestedNodeRepositoryConfiguration; 24 | import pl.exsio.nestedj.config.mem.discriminator.InMemoryTreeDiscriminator; 25 | import pl.exsio.nestedj.config.mem.identity.InMemoryNestedNodeIdentityGenerator; 26 | import pl.exsio.nestedj.model.NestedNode; 27 | 28 | import java.io.Serializable; 29 | import java.util.HashMap; 30 | import java.util.Map; 31 | import java.util.Set; 32 | import java.util.stream.Stream; 33 | 34 | import static pl.exsio.nestedj.model.NestedNode.ID; 35 | import static pl.exsio.nestedj.model.NestedNode.LEFT; 36 | import static pl.exsio.nestedj.model.NestedNode.LEVEL; 37 | import static pl.exsio.nestedj.model.NestedNode.PARENT_ID; 38 | import static pl.exsio.nestedj.model.NestedNode.RIGHT; 39 | 40 | @SuppressWarnings("unchecked") 41 | public abstract class InMemoryNestedNodeQueryDelegate> { 42 | 43 | private final InMemoryTreeDiscriminator treeDiscriminator; 44 | 45 | private final InMemoryNestedNodeIdentityGenerator identityGenerator; 46 | 47 | protected final Set nodes; 48 | 49 | protected final static Map SETTERS = new HashMap<>(); 50 | 51 | protected final static Map GETTERS = new HashMap<>(); 52 | 53 | static { 54 | SETTERS.put(RIGHT, (node, value) -> node.setTreeRight((Long) value)); 55 | SETTERS.put(LEFT, (node, value) -> node.setTreeLeft((Long) value)); 56 | SETTERS.put(LEVEL, (node, value) -> node.setTreeLevel((Long) value)); 57 | SETTERS.put(ID, (node, value) -> node.setId((Serializable) value)); 58 | SETTERS.put(PARENT_ID, (node, value) -> node.setParentId((Serializable) value)); 59 | 60 | GETTERS.put(RIGHT, NestedNode::getTreeRight); 61 | GETTERS.put(LEFT, NestedNode::getTreeLeft); 62 | GETTERS.put(LEVEL, NestedNode::getTreeLevel); 63 | GETTERS.put(ID, NestedNode::getId); 64 | GETTERS.put(PARENT_ID, NestedNode::getParentId); 65 | } 66 | 67 | public InMemoryNestedNodeQueryDelegate(InMemoryNestedNodeRepositoryConfiguration configuration) { 68 | this.treeDiscriminator = configuration.getTreeDiscriminator(); 69 | this.identityGenerator = configuration.getIdentityGenerator(); 70 | this.nodes = configuration.getNodes(); 71 | } 72 | 73 | protected Stream nodesStream() { 74 | return treeDiscriminator != null ? nodes.stream().filter(treeDiscriminator::applies) : nodes.stream(); 75 | } 76 | 77 | protected ID generateIdentity() { 78 | return identityGenerator.generateIdentity(); 79 | } 80 | 81 | 82 | protected interface Setter> { 83 | void set(N node, Object value); 84 | } 85 | 86 | protected interface Getter> { 87 | Object get(N node); 88 | } 89 | 90 | protected Long getLong(String fieldname, N node) { 91 | return (Long) GETTERS.get(fieldname).get(node); 92 | } 93 | 94 | protected Serializable getSerializable(String fieldname, N node) { 95 | return (Serializable) GETTERS.get(fieldname).get(node); 96 | } 97 | 98 | protected void setLong(String fieldname, N node, Long value) { 99 | SETTERS.get(fieldname).set(node, value); 100 | } 101 | 102 | protected void setSerializable(String fieldname, N node, Serializable value) { 103 | SETTERS.get(fieldname).set(node, value); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/mem/InMemoryNestedNodeRebuildingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query.mem; 22 | 23 | import pl.exsio.nestedj.config.mem.InMemoryNestedNodeRepositoryConfiguration; 24 | import pl.exsio.nestedj.delegate.query.NestedNodeRebuildingQueryDelegate; 25 | import pl.exsio.nestedj.ex.InvalidNodeException; 26 | import pl.exsio.nestedj.model.NestedNode; 27 | 28 | import java.io.Serializable; 29 | import java.util.Comparator; 30 | import java.util.List; 31 | import java.util.stream.Collectors; 32 | 33 | import static pl.exsio.nestedj.model.NestedNode.ID; 34 | import static pl.exsio.nestedj.model.NestedNode.PARENT_ID; 35 | 36 | public class InMemoryNestedNodeRebuildingQueryDelegate> 37 | extends InMemoryNestedNodeQueryDelegate 38 | implements NestedNodeRebuildingQueryDelegate { 39 | 40 | public InMemoryNestedNodeRebuildingQueryDelegate(InMemoryNestedNodeRepositoryConfiguration configuration) { 41 | super(configuration); 42 | } 43 | 44 | 45 | @Override 46 | public void destroyTree() { 47 | nodesStream() 48 | .forEach(n -> { 49 | n.setTreeLeft(0L); 50 | n.setTreeRight(0L); 51 | n.setTreeLevel(0L); 52 | }); 53 | } 54 | 55 | @Override 56 | 57 | public N findFirst() { 58 | return nodesStream() 59 | .filter(n -> n.getParentId() == null) 60 | .max(getIdComparator()).orElseThrow(() -> new InvalidNodeException("There are no Root Nodes in the Tree")); 61 | } 62 | 63 | @Override 64 | public void resetFirst(N first) { 65 | nodesStream() 66 | .filter(n -> n.getId().equals(first.getId())) 67 | .forEach(n -> { 68 | n.setTreeLeft(1L); 69 | n.setTreeRight(2L); 70 | n.setTreeLevel(0L); 71 | }); 72 | } 73 | 74 | @Override 75 | public List getSiblings(ID first) { 76 | if (first == null) { 77 | throw new NullPointerException("first cannot be null"); 78 | } 79 | return nodesStream() 80 | .filter(n -> getSerializable(PARENT_ID, n) == null) 81 | .filter(n -> !getSerializable(ID, n).equals(first)) 82 | .sorted(getIdComparator()) 83 | .collect(Collectors.toList()); 84 | } 85 | 86 | @Override 87 | public List getChildren(N parent) { 88 | return nodesStream() 89 | .filter(n -> parent.getId().equals(getSerializable(PARENT_ID, n))) 90 | .sorted(getIdComparator()) 91 | .collect(Collectors.toList()); 92 | } 93 | 94 | @SuppressWarnings("unchecked") 95 | private Comparator getIdComparator() { 96 | return (o1, o2) -> { 97 | if (o1.getId() instanceof Comparable) { 98 | return ((Comparable) o1.getId()).compareTo(o2.getId()); 99 | } else { 100 | return Integer.compare(o1.getId().hashCode(), o2.getId().hashCode()); 101 | } 102 | }; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/delegate/query/mem/InMemoryNestedNodeRemovingQueryDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.delegate.query.mem; 22 | 23 | import pl.exsio.nestedj.config.mem.InMemoryNestedNodeRepositoryConfiguration; 24 | import pl.exsio.nestedj.delegate.query.NestedNodeRemovingQueryDelegate; 25 | import pl.exsio.nestedj.ex.InvalidNodeException; 26 | import pl.exsio.nestedj.model.NestedNode; 27 | import pl.exsio.nestedj.model.NestedNodeInfo; 28 | 29 | import java.io.Serializable; 30 | import java.util.List; 31 | import java.util.Optional; 32 | import java.util.stream.Collectors; 33 | 34 | import static pl.exsio.nestedj.model.NestedNode.ID; 35 | import static pl.exsio.nestedj.model.NestedNode.LEFT; 36 | import static pl.exsio.nestedj.model.NestedNode.LEVEL; 37 | import static pl.exsio.nestedj.model.NestedNode.PARENT_ID; 38 | import static pl.exsio.nestedj.model.NestedNode.RIGHT; 39 | 40 | public class InMemoryNestedNodeRemovingQueryDelegate> 41 | extends InMemoryNestedNodeQueryDelegate 42 | implements NestedNodeRemovingQueryDelegate { 43 | 44 | public InMemoryNestedNodeRemovingQueryDelegate(InMemoryNestedNodeRepositoryConfiguration configuration) { 45 | super(configuration); 46 | } 47 | 48 | 49 | @Override 50 | public void setNewParentForDeletedNodesChildren(NestedNodeInfo node) { 51 | nodesStream() 52 | .filter(n -> getLong(LEFT, n) >= node.getLeft()) 53 | .filter(n -> getLong(RIGHT, n) <= node.getRight()) 54 | .filter(n -> getLong(LEVEL, n).equals(node.getLevel() + 1)) 55 | .forEach(n -> setSerializable(PARENT_ID, n, findNodeParentId(node).orElse(null))); 56 | } 57 | 58 | @Override 59 | public void performSingleDeletion(NestedNodeInfo node) { 60 | List nodesToDelete = nodesStream() 61 | .filter(n -> getSerializable(ID, n).equals(node.getId())) 62 | .collect(Collectors.toList()); 63 | nodes.removeAll(nodesToDelete); 64 | } 65 | 66 | @Override 67 | public void decrementSideFieldsBeforeSingleNodeRemoval(Long from, String field) { 68 | decrementSideFields(from, DECREMENT_BY, field); 69 | } 70 | 71 | @Override 72 | public void pushUpDeletedNodesChildren(NestedNodeInfo node) { 73 | nodesStream() 74 | .filter(n -> getLong(LEFT, n) > node.getLeft()) 75 | .filter(n -> getLong(RIGHT, n) < node.getRight()) 76 | .forEach(n -> { 77 | setLong(RIGHT, n, getLong(RIGHT, n) - 1); 78 | setLong(LEFT, n, getLong(LEFT, n) - 1); 79 | setLong(LEVEL, n, getLong(LEVEL, n) - 1); 80 | }); 81 | } 82 | 83 | @Override 84 | public void decrementSideFieldsAfterSubtreeRemoval(Long from, Long delta, String field) { 85 | decrementSideFields(from, delta, field); 86 | } 87 | 88 | @Override 89 | public void performBatchDeletion(NestedNodeInfo node) { 90 | List nodesToDelete = nodesStream() 91 | .filter(n -> getLong(LEFT, n) >= node.getLeft()) 92 | .filter(n -> getLong(RIGHT, n) <= node.getRight()) 93 | .collect(Collectors.toList()); 94 | nodes.removeAll(nodesToDelete); 95 | } 96 | 97 | private void decrementSideFields(Long from, Long delta, String field) { 98 | nodesStream() 99 | .filter(n -> getLong(field, n) > from) 100 | .forEach(n -> setLong(field, n, getLong(field, n) - delta)); 101 | } 102 | 103 | private Optional findNodeParentId(NestedNodeInfo node) { 104 | if (node.getLevel() > 0) { 105 | return Optional.of(nodesStream() 106 | .filter(n -> getLong(LEFT, n) < node.getLeft()) 107 | .filter(n -> getLong(RIGHT, n) > node.getRight()) 108 | .filter(n -> getLong(LEVEL, n).equals(node.getLevel() - 1)) 109 | .map(NestedNode::getId) 110 | .findFirst() 111 | .orElseThrow(() -> new InvalidNodeException(String.format("Couldn't find node's parent, although its level is greater than 0. It seems the tree is malformed: %s", node)))); 112 | } 113 | return Optional.empty(); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/ex/InvalidNodeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.ex; 21 | 22 | public class InvalidNodeException extends RuntimeException { 23 | 24 | public InvalidNodeException(String msg) { 25 | super(msg); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/ex/InvalidNodesHierarchyException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.ex; 21 | 22 | public class InvalidNodesHierarchyException extends RuntimeException { 23 | 24 | public InvalidNodesHierarchyException(String msg) { 25 | super(msg); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/ex/InvalidParentException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.ex; 21 | 22 | public class InvalidParentException extends RuntimeException { 23 | 24 | public InvalidParentException(String msg) { 25 | super(msg); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/ex/RepositoryLockedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.ex; 21 | 22 | public class RepositoryLockedException extends RuntimeException { 23 | 24 | public RepositoryLockedException(String msg) { 25 | super(msg); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/lock/NoLock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.lock; 22 | 23 | import pl.exsio.nestedj.NestedNodeRepository; 24 | import pl.exsio.nestedj.model.NestedNode; 25 | 26 | import java.io.Serializable; 27 | 28 | /** 29 | * Default no-op Lock implementation 30 | * 31 | * @param - Nested Node Identifier Class 32 | * @param - Nested Node Class 33 | */ 34 | public class NoLock> implements NestedNodeRepository.Lock { 35 | /** 36 | * {@inheritDoc} 37 | */ 38 | @Override 39 | public boolean lockNode(N node) { 40 | return true; 41 | } 42 | 43 | /** 44 | * {@inheritDoc} 45 | */ 46 | @Override 47 | public void unlockNode(N node) { 48 | } 49 | 50 | /** 51 | * {@inheritDoc} 52 | */ 53 | @Override 54 | public boolean lockRepository() { 55 | return true; 56 | } 57 | 58 | /** 59 | * {@inheritDoc} 60 | */ 61 | @Override 62 | public void unlockRepository() { 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/model/InMemoryTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.model; 21 | 22 | import java.io.Serializable; 23 | import java.util.LinkedList; 24 | import java.util.List; 25 | 26 | /** 27 | * {@inheritDoc} 28 | */ 29 | public class InMemoryTree> implements Tree { 30 | 31 | private List> children; 32 | 33 | private Tree parent; 34 | 35 | private N node; 36 | 37 | private InMemoryTree() { 38 | this.children = new LinkedList<>(); 39 | } 40 | 41 | public InMemoryTree(N node) { 42 | this(); 43 | this.node = node; 44 | } 45 | 46 | public InMemoryTree(N node, Tree parent) { 47 | this(); 48 | this.parent = parent; 49 | this.node = node; 50 | } 51 | 52 | @Override 53 | public void addChild(Tree child) { 54 | this.children.add(child); 55 | child.setParent(this); 56 | } 57 | 58 | @Override 59 | public void setChildren(List> children) { 60 | this.children = children; 61 | } 62 | 63 | @Override 64 | public List> getChildren() { 65 | return this.children; 66 | } 67 | 68 | @Override 69 | public Tree getParent() { 70 | return this.parent; 71 | } 72 | 73 | @Override 74 | public void setParent(Tree parent) { 75 | this.parent = parent; 76 | } 77 | 78 | @Override 79 | public N getNode() { 80 | return this.node; 81 | } 82 | 83 | @Override 84 | public void setNode(N node) { 85 | this.node = node; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/model/NestedNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.model; 21 | 22 | import java.io.Serializable; 23 | 24 | /** 25 | * Base Interface that has to be implemented by any Entity/Object to be used by NestedNodeRepository. 26 | * 27 | * It is strongly recommented to follow Java-bean naming standards. It is important expecially for JPA implementation. 28 | * JPA Criteria Queries are constructed using the constants defined in this interface. In order for NestedJ to work corerctly 29 | * you have to follow this rule. It is not required by other implementations, but still it is recommended. 30 | * 31 | * Although Nested Set model doesn't require the presence of PARENT_ID mapping, it is required by NestedJ. 32 | * Nested Set Model is a very fragile construct. One manual upadte can destroy the tree beyond repair. 33 | * NestedJ uses PARENT_ID mapping to srenghten the Tree Structure and to be able to repair the Nested Set Model if needed. 34 | * 35 | * @param - Nested Node Identifier Class 36 | */ 37 | public interface NestedNode { 38 | 39 | /** 40 | * Standarized Field Names used internally by NestedJ. 41 | * Any Java class that implements the NestedNode interface should have fields with names matching the below constants. 42 | */ 43 | String LEFT = "treeLeft"; 44 | String RIGHT = "treeRight"; 45 | String LEVEL = "treeLevel"; 46 | String PARENT_ID = "parentId"; 47 | String ID = "id"; 48 | 49 | /** 50 | * Should be PK if using Database. 51 | * 52 | * @return unique Identifier of the Entity/Object. 53 | */ 54 | ID getId(); 55 | 56 | /** 57 | * @return Nested Set Model LEFT value 58 | */ 59 | Long getTreeLeft(); 60 | 61 | /** 62 | * @return Nested Set Model RIGHT value 63 | */ 64 | Long getTreeRight(); 65 | 66 | /** 67 | * @return Nested Set Model LEVEL value 68 | */ 69 | Long getTreeLevel(); 70 | 71 | /** 72 | * Should be a FK if using Database. 73 | * 74 | * @return Parent Idendifier 75 | */ 76 | ID getParentId(); 77 | 78 | /** 79 | * Sets the unique Identifier of the Entity/Object. 80 | * 81 | * @param id - unique Identifier of the Entity/Object. 82 | */ 83 | void setId(ID id); 84 | 85 | /** 86 | * Sets the Nested Set Model LEFT value 87 | * 88 | * @param treeLeft - Nested Set Model LEFT value 89 | */ 90 | void setTreeLeft(Long treeLeft); 91 | 92 | /** 93 | * Sets the Nested Set Model RIGHT value 94 | * 95 | * @param treeRight - Nested Set Model RIGHT value 96 | */ 97 | void setTreeRight(Long treeRight); 98 | 99 | /** 100 | * Sets the Nested Set Model LEVEL value 101 | * 102 | * @param treeLevel - Nested Set Model LEVEL value 103 | */ 104 | void setTreeLevel(Long treeLevel); 105 | 106 | /** 107 | * Sets the Parent Idendifier 108 | * 109 | * @param parent - Parent Idendifier 110 | */ 111 | void setParentId(ID parent); 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/model/NestedNodeInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | 21 | package pl.exsio.nestedj.model; 22 | 23 | import java.io.Serializable; 24 | 25 | /** 26 | * Internal representation of Nested Node, not intended for use outside of NestedJ implementation. 27 | * 28 | * @param - Nested Node Identifier Class 29 | */ 30 | public class NestedNodeInfo { 31 | 32 | private final ID id; 33 | 34 | private final ID parentId; 35 | 36 | private final Long left; 37 | 38 | private final Long right; 39 | 40 | private final Long level; 41 | 42 | public NestedNodeInfo(ID id, ID parentId, Long left, Long right, Long level) { 43 | this.id = id; 44 | this.parentId = parentId; 45 | this.left = left; 46 | this.right = right; 47 | this.level = level; 48 | } 49 | 50 | public ID getId() { 51 | return id; 52 | } 53 | 54 | public ID getParentId() { 55 | return parentId; 56 | } 57 | 58 | public Long getLeft() { 59 | return left; 60 | } 61 | 62 | public Long getRight() { 63 | return right; 64 | } 65 | 66 | public Long getLevel() { 67 | return level; 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "NestedNodeInfo{" + 73 | "id=" + id + 74 | ", parentId=" + parentId + 75 | ", left=" + left + 76 | ", right=" + right + 77 | ", level=" + level + 78 | '}'; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/pl/exsio/nestedj/model/Tree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright (c) 2019 eXsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of 11 | * the Software. 12 | * 13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 16 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 17 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 | * SOFTWARE. 19 | */ 20 | package pl.exsio.nestedj.model; 21 | 22 | import java.io.Serializable; 23 | import java.util.List; 24 | 25 | /** 26 | * Recursive Data Structure used for Nested Tree branches retrieval 27 | * 28 | * @param - Nested Node Identifier Class 29 | * @param - Nested Node Class 30 | */ 31 | public interface Tree> { 32 | 33 | void setChildren(List> children); 34 | 35 | void addChild(Tree child); 36 | 37 | List> getChildren(); 38 | 39 | Tree getParent(); 40 | 41 | void setParent(Tree parent); 42 | 43 | N getNode(); 44 | 45 | void setNode(N node); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/base/NestedNodeRepositoryRemovingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.base; 25 | 26 | import org.junit.jupiter.api.Test; 27 | import org.springframework.transaction.annotation.Transactional; 28 | import pl.exsio.nestedj.model.TestNode; 29 | 30 | import static org.junit.jupiter.api.Assertions.assertEquals; 31 | 32 | 33 | @Transactional 34 | public abstract class NestedNodeRepositoryRemovingTest extends FunctionalNestedjTest { 35 | 36 | @Test 37 | public void testRemoveSubtreeWithoutChildren() { 38 | 39 | TestNode d = this.findNode("d"); 40 | this.repository.removeSubtree(d); 41 | TestNode a = this.findNode("a"); 42 | TestNode e = this.findNode("e"); 43 | TestNode b = this.findNode("b"); 44 | TestNode g = this.findNode("g"); 45 | TestNode c = this.findNode("c"); 46 | TestNode h = this.findNode("h"); 47 | TestNode f = this.findNode("f"); 48 | 49 | assertEquals(3, (long) e.getTreeLeft()); 50 | assertEquals(4, (long) e.getTreeRight()); 51 | assertEquals(5, (long) b.getTreeRight()); 52 | assertEquals(10, (long) h.getTreeLeft()); 53 | assertEquals(11, (long) h.getTreeRight()); 54 | assertEquals(14, (long) a.getTreeRight()); 55 | assertEquals(6, (long) c.getTreeLeft()); 56 | assertEquals(13, (long) c.getTreeRight()); 57 | assertEquals(9, (long) g.getTreeLeft()); 58 | assertEquals(12, (long) g.getTreeRight()); 59 | assertSecondTreeIntact(); 60 | 61 | } 62 | 63 | @Test 64 | public void testRemoveSubtree() { 65 | 66 | TestNode b = this.findNode("b"); 67 | this.repository.removeSubtree(b); 68 | TestNode a = this.findNode("a"); 69 | TestNode g = this.findNode("g"); 70 | TestNode c = this.findNode("c"); 71 | TestNode h = this.findNode("h"); 72 | TestNode f = this.findNode("f"); 73 | 74 | assertEquals(6, (long) h.getTreeLeft()); 75 | assertEquals(7, (long) h.getTreeRight()); 76 | assertEquals(10, (long) a.getTreeRight()); 77 | assertEquals(2, (long) c.getTreeLeft()); 78 | assertEquals(9, (long) c.getTreeRight()); 79 | assertEquals(5, (long) g.getTreeLeft()); 80 | assertEquals(8, (long) g.getTreeRight()); 81 | assertSecondTreeIntact(); 82 | 83 | } 84 | 85 | @Test 86 | public void testRemoveSingleNodeThatHasChildren() { 87 | 88 | TestNode b = this.findNode("b"); 89 | this.repository.removeSingle(b); 90 | TestNode a = this.findNode("a"); 91 | TestNode e = this.findNode("e"); 92 | TestNode d = this.findNode("d"); 93 | TestNode g = this.findNode("g"); 94 | TestNode c = this.findNode("c"); 95 | TestNode h = this.findNode("h"); 96 | 97 | assertEquals(2, (long) d.getTreeLeft()); 98 | assertEquals(3, (long) d.getTreeRight()); 99 | assertEquals(4, (long) e.getTreeLeft()); 100 | assertEquals(5, (long) e.getTreeRight()); 101 | assertEquals(10, (long) h.getTreeLeft()); 102 | assertEquals(11, (long) h.getTreeRight()); 103 | assertEquals(14, (long) a.getTreeRight()); 104 | assertEquals(6, (long) c.getTreeLeft()); 105 | assertEquals(13, (long) c.getTreeRight()); 106 | assertEquals(9, (long) g.getTreeLeft()); 107 | assertEquals(12, (long) g.getTreeRight()); 108 | assertEquals(1, (long) d.getTreeLevel()); 109 | assertEquals(1, (long) e.getTreeLevel()); 110 | assertSecondTreeIntact(); 111 | } 112 | 113 | @Test 114 | public void testRemoveSingleNode() { 115 | 116 | TestNode d = this.findNode("d"); 117 | this.repository.removeSingle(d); 118 | TestNode a = this.findNode("a"); 119 | TestNode g = this.findNode("g"); 120 | TestNode c = this.findNode("c"); 121 | TestNode e = this.findNode("e"); 122 | 123 | assertEquals(3, (long) e.getTreeLeft()); 124 | assertEquals(4, (long) e.getTreeRight()); 125 | assertEquals(14, (long) a.getTreeRight()); 126 | assertEquals(6, (long) c.getTreeLeft()); 127 | assertEquals(13, (long) c.getTreeRight()); 128 | assertEquals(9, (long) g.getTreeLeft()); 129 | assertEquals(12, (long) g.getTreeRight()); 130 | assertSecondTreeIntact(); 131 | 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/base/TestHelper.java: -------------------------------------------------------------------------------- 1 | package pl.exsio.nestedj.base; 2 | 3 | import pl.exsio.nestedj.model.TestNode; 4 | 5 | public interface TestHelper { 6 | 7 | TestNode findNode(String symbol); 8 | 9 | TestNode getParent(TestNode f); 10 | 11 | void breakTree(); 12 | 13 | void resetParent(String symbol); 14 | 15 | void removeTree(); 16 | 17 | static void printNode(String symbol, TestNode n) { 18 | if(n != null) { 19 | System.out.println(String.format("Node %s: %d/%d/%d", symbol, n.getTreeLeft(), n.getTreeRight(), n.getTreeLevel())); 20 | } 21 | } 22 | 23 | default void flushAndClear() { 24 | 25 | } 26 | 27 | default void flush() { 28 | 29 | } 30 | 31 | default void refresh(TestNode node) { 32 | 33 | } 34 | 35 | void save(TestNode node); 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/config/jdbc/discriminator/TestJdbcTreeDiscriminator.java: -------------------------------------------------------------------------------- 1 | package pl.exsio.nestedj.config.jdbc.discriminator; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class TestJdbcTreeDiscriminator implements JdbcTreeDiscriminator { 7 | 8 | @Override 9 | public String getQueryPart() { 10 | return "discriminator = ?"; 11 | } 12 | 13 | @Override 14 | public List getParameters() { 15 | ArrayList result = new ArrayList<>(); 16 | result.add("tree_1"); 17 | return result; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/config/jpa/discriminator/TestJpaTreeDiscriminator.java: -------------------------------------------------------------------------------- 1 | package pl.exsio.nestedj.config.jpa.discriminator; 2 | 3 | import pl.exsio.nestedj.model.TestNode; 4 | 5 | import java.util.Collections; 6 | 7 | public class TestJpaTreeDiscriminator extends MapJpaTreeDiscriminator { 8 | 9 | public TestJpaTreeDiscriminator() { 10 | super(Collections.singletonMap("discriminator", () -> "tree_1")); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/config/mem/discriminator/TestInMemoryTreeDiscriminator.java: -------------------------------------------------------------------------------- 1 | package pl.exsio.nestedj.config.mem.discriminator; 2 | 3 | import pl.exsio.nestedj.model.TestNode; 4 | 5 | public class TestInMemoryTreeDiscriminator implements InMemoryTreeDiscriminator { 6 | @Override 7 | public boolean applies(TestNode node) { 8 | return "tree_1".equals(node.getDiscriminator()); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jdbc/JdbcNestedNodeRepositoryInsertingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jdbc; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryInsertingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jdbc; 33 | 34 | import javax.sql.DataSource; 35 | 36 | @Transactional 37 | public class JdbcNestedNodeRepositoryInsertingTest extends NestedNodeRepositoryInsertingTest { 38 | 39 | private JdbcTestHelper helper; 40 | 41 | @Autowired 42 | private DataSource dataSource; 43 | 44 | @Autowired 45 | @Jdbc 46 | private DelegatingNestedNodeRepository jdbcRepository; 47 | 48 | @BeforeEach 49 | public void setup() { 50 | helper = new JdbcTestHelper(dataSource); 51 | this.repository = this.jdbcRepository; 52 | } 53 | 54 | @Override 55 | protected TestNode findNode(String symbol) { 56 | return helper.findNode(symbol); 57 | } 58 | 59 | @Override 60 | protected TestNode getParent(TestNode f) { 61 | return helper.getParent(f); 62 | } 63 | 64 | @Override 65 | protected void breakTree() { 66 | helper.breakTree(); 67 | } 68 | 69 | @Override 70 | protected void resetParent(String symbol) { 71 | helper.resetParent(symbol); 72 | } 73 | 74 | @Override 75 | protected void removeTree() { 76 | helper.removeTree(); 77 | } 78 | 79 | @Override 80 | protected void flushAndClear() { 81 | helper.flushAndClear(); 82 | } 83 | 84 | @Override 85 | protected void flush() { 86 | helper.flush(); 87 | } 88 | 89 | @Override 90 | protected void refresh(TestNode node) { 91 | helper.refresh(node); 92 | } 93 | 94 | @Override 95 | protected void save(TestNode node){ 96 | helper.save(node); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jdbc/JdbcNestedNodeRepositoryMovingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jdbc; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryMovingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jdbc; 33 | 34 | import javax.sql.DataSource; 35 | 36 | @Transactional 37 | public class JdbcNestedNodeRepositoryMovingTest extends NestedNodeRepositoryMovingTest { 38 | 39 | private JdbcTestHelper helper; 40 | 41 | @Autowired 42 | private DataSource dataSource; 43 | 44 | @Autowired 45 | @Jdbc 46 | private DelegatingNestedNodeRepository jdbcRepository; 47 | 48 | @BeforeEach 49 | public void setup() { 50 | helper = new JdbcTestHelper(dataSource); 51 | this.repository = this.jdbcRepository; 52 | } 53 | 54 | @Override 55 | protected TestNode findNode(String symbol) { 56 | return helper.findNode(symbol); 57 | } 58 | 59 | @Override 60 | protected TestNode getParent(TestNode f) { 61 | return helper.getParent(f); 62 | } 63 | 64 | @Override 65 | protected void breakTree() { 66 | helper.breakTree(); 67 | } 68 | 69 | @Override 70 | protected void resetParent(String symbol) { 71 | helper.resetParent(symbol); 72 | } 73 | 74 | @Override 75 | protected void removeTree() { 76 | helper.removeTree(); 77 | } 78 | 79 | @Override 80 | protected void flushAndClear() { 81 | helper.flushAndClear(); 82 | } 83 | 84 | @Override 85 | protected void flush() { 86 | helper.flush(); 87 | } 88 | 89 | @Override 90 | protected void refresh(TestNode node) { 91 | helper.refresh(node); 92 | } 93 | 94 | @Override 95 | protected void save(TestNode node) { 96 | helper.save(node); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jdbc/JdbcNestedNodeRepositoryRebuildingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jdbc; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryRebuildingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jdbc; 33 | 34 | import javax.sql.DataSource; 35 | 36 | @Transactional 37 | public class JdbcNestedNodeRepositoryRebuildingTest extends NestedNodeRepositoryRebuildingTest { 38 | 39 | private JdbcTestHelper helper; 40 | 41 | @Autowired 42 | private DataSource dataSource; 43 | 44 | @Autowired 45 | @Jdbc 46 | private DelegatingNestedNodeRepository jdbcRepository; 47 | 48 | @BeforeEach 49 | public void setup() { 50 | helper = new JdbcTestHelper(dataSource); 51 | this.repository = this.jdbcRepository; 52 | } 53 | 54 | @Override 55 | protected TestNode findNode(String symbol) { 56 | return helper.findNode(symbol); 57 | } 58 | 59 | @Override 60 | protected TestNode getParent(TestNode f) { 61 | return helper.getParent(f); 62 | } 63 | 64 | @Override 65 | protected void breakTree() { 66 | helper.breakTree(); 67 | } 68 | 69 | @Override 70 | protected void resetParent(String symbol) { 71 | helper.resetParent(symbol); 72 | } 73 | 74 | @Override 75 | protected void removeTree() { 76 | helper.removeTree(); 77 | } 78 | 79 | @Override 80 | protected void flushAndClear() { 81 | helper.flushAndClear(); 82 | } 83 | 84 | @Override 85 | protected void flush() { 86 | helper.flush(); 87 | } 88 | 89 | @Override 90 | protected void refresh(TestNode node) { 91 | helper.refresh(node); 92 | } 93 | 94 | @Override 95 | protected void save(TestNode node) { 96 | helper.save(node); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jdbc/JdbcNestedNodeRepositoryRemovingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jdbc; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryRemovingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jdbc; 33 | 34 | import javax.sql.DataSource; 35 | 36 | @Transactional 37 | public class JdbcNestedNodeRepositoryRemovingTest extends NestedNodeRepositoryRemovingTest { 38 | 39 | private JdbcTestHelper helper; 40 | 41 | @Autowired 42 | private DataSource dataSource; 43 | 44 | @Autowired 45 | @Jdbc 46 | private DelegatingNestedNodeRepository jdbcRepository; 47 | 48 | @BeforeEach 49 | public void setup() { 50 | helper = new JdbcTestHelper(dataSource); 51 | this.repository = this.jdbcRepository; 52 | } 53 | 54 | @Override 55 | protected TestNode findNode(String symbol) { 56 | return helper.findNode(symbol); 57 | } 58 | 59 | @Override 60 | protected TestNode getParent(TestNode f) { 61 | return helper.getParent(f); 62 | } 63 | 64 | @Override 65 | protected void breakTree() { 66 | helper.breakTree(); 67 | } 68 | 69 | @Override 70 | protected void resetParent(String symbol) { 71 | helper.resetParent(symbol); 72 | } 73 | 74 | @Override 75 | protected void removeTree() { 76 | helper.removeTree(); 77 | } 78 | 79 | @Override 80 | protected void flushAndClear() { 81 | helper.flushAndClear(); 82 | } 83 | 84 | @Override 85 | protected void flush() { 86 | helper.flush(); 87 | } 88 | 89 | @Override 90 | protected void refresh(TestNode node) { 91 | helper.refresh(node); 92 | } 93 | 94 | @Override 95 | protected void save(TestNode node) { 96 | helper.save(node); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jdbc/JdbcNestedNodeRepositoryRetrievingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jdbc; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryRetrievingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jdbc; 33 | 34 | import javax.sql.DataSource; 35 | 36 | @Transactional 37 | public class JdbcNestedNodeRepositoryRetrievingTest extends NestedNodeRepositoryRetrievingTest { 38 | 39 | private JdbcTestHelper helper; 40 | 41 | @Autowired 42 | private DataSource dataSource; 43 | 44 | @Autowired 45 | @Jdbc 46 | private DelegatingNestedNodeRepository jdbcRepository; 47 | 48 | @BeforeEach 49 | public void setup() { 50 | helper = new JdbcTestHelper(dataSource); 51 | this.repository = this.jdbcRepository; 52 | } 53 | 54 | @Override 55 | protected TestNode findNode(String symbol) { 56 | return helper.findNode(symbol); 57 | } 58 | 59 | @Override 60 | protected TestNode getParent(TestNode f) { 61 | return helper.getParent(f); 62 | } 63 | 64 | @Override 65 | protected void breakTree() { 66 | helper.breakTree(); 67 | } 68 | 69 | @Override 70 | protected void resetParent(String symbol) { 71 | helper.resetParent(symbol); 72 | } 73 | 74 | @Override 75 | protected void removeTree() { 76 | helper.removeTree(); 77 | } 78 | 79 | @Override 80 | protected void flushAndClear() { 81 | helper.flushAndClear(); 82 | } 83 | 84 | @Override 85 | protected void flush() { 86 | helper.flush(); 87 | } 88 | 89 | @Override 90 | protected void refresh(TestNode node) { 91 | helper.refresh(node); 92 | } 93 | 94 | @Override 95 | protected void save(TestNode node) { 96 | helper.save(node); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jdbc/JdbcNestedNodeRepositoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jdbc; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jdbc; 33 | 34 | import javax.sql.DataSource; 35 | 36 | @Transactional 37 | public class JdbcNestedNodeRepositoryTest extends NestedNodeRepositoryTest { 38 | 39 | private JdbcTestHelper helper; 40 | 41 | @Autowired 42 | private DataSource dataSource; 43 | 44 | @Autowired 45 | @Jdbc 46 | private DelegatingNestedNodeRepository jdbcRepository; 47 | 48 | @BeforeEach 49 | public void setup() { 50 | helper = new JdbcTestHelper(dataSource); 51 | this.repository = this.jdbcRepository; 52 | } 53 | 54 | @Override 55 | protected TestNode findNode(String symbol) { 56 | return helper.findNode(symbol); 57 | } 58 | 59 | @Override 60 | protected TestNode getParent(TestNode f) { 61 | return helper.getParent(f); 62 | } 63 | 64 | @Override 65 | protected void breakTree() { 66 | helper.breakTree(); 67 | } 68 | 69 | @Override 70 | protected void resetParent(String symbol) { 71 | helper.resetParent(symbol); 72 | } 73 | 74 | @Override 75 | protected void removeTree() { 76 | helper.removeTree(); 77 | } 78 | 79 | @Override 80 | protected void flushAndClear() { 81 | helper.flushAndClear(); 82 | } 83 | 84 | @Override 85 | protected void flush() { 86 | helper.flush(); 87 | } 88 | 89 | @Override 90 | protected void refresh(TestNode node) { 91 | helper.refresh(node); 92 | } 93 | 94 | @Override 95 | protected void save(TestNode node) { 96 | helper.save(node); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jdbc/JdbcTestHelper.java: -------------------------------------------------------------------------------- 1 | package pl.exsio.nestedj.jdbc; 2 | 3 | import org.springframework.jdbc.core.JdbcTemplate; 4 | import org.springframework.jdbc.support.KeyHolder; 5 | import pl.exsio.nestedj.base.TestHelper; 6 | import pl.exsio.nestedj.delegate.query.jdbc.JdbcKeyHolder; 7 | import pl.exsio.nestedj.model.TestNode; 8 | 9 | import javax.sql.DataSource; 10 | 11 | public class JdbcTestHelper implements TestHelper { 12 | 13 | private final JdbcTemplate jdbcTemplate; 14 | 15 | JdbcTestHelper(DataSource dataSource) { 16 | this.jdbcTemplate = new JdbcTemplate(dataSource); 17 | } 18 | 19 | @Override 20 | public TestNode findNode(String symbol) { 21 | return jdbcTemplate.query("select id, node_name, tree_left, tree_right, tree_level, parent_id, discriminator from nested_nodes where node_name = '" + symbol + "'", 22 | (resultSet, i) -> TestNode.fromResultSet(resultSet)).stream().findFirst().orElse(null); 23 | } 24 | 25 | @Override 26 | public TestNode getParent(TestNode f) { 27 | refresh(f); 28 | TestNode parent = null; 29 | Long parentId = f.getParentId(); 30 | if (parentId != null) { 31 | parent = findNode(parentId); 32 | } 33 | System.out.println(String.format("Parent of %s is %s", f.getName(), parent != null ? parent.getName() : "null")); 34 | return parent; 35 | } 36 | 37 | public TestNode findNode(Long id) { 38 | return jdbcTemplate.query("select id, node_name, tree_left, tree_right, tree_level, parent_id, discriminator from nested_nodes where id = '" + id + "'", 39 | (resultSet, i) -> TestNode.fromResultSet(resultSet)).stream().findFirst().orElse(null); 40 | } 41 | 42 | @Override 43 | public void breakTree() { 44 | jdbcTemplate.execute("update nested_nodes set tree_left = 0, tree_right = 0, tree_level = 0 where discriminator = 'tree_1'"); 45 | } 46 | 47 | @Override 48 | public void resetParent(String symbol) { 49 | jdbcTemplate.execute("update nested_nodes set parent_id = null where node_name='"+symbol+"' and discriminator = 'tree_1'"); 50 | } 51 | 52 | @Override 53 | public void removeTree() { 54 | jdbcTemplate.execute("delete from nested_nodes where discriminator = 'tree_1'"); 55 | } 56 | 57 | public void flushAndClear() { 58 | } 59 | 60 | public void flush() { 61 | } 62 | 63 | public void refresh(TestNode node) { 64 | if(node.getId() == null) { 65 | return; 66 | } 67 | TestNode refreshed = findNode(node.getId()); 68 | node.setParentId(refreshed.getParentId()); 69 | node.setName(refreshed.getName()); 70 | node.setTreeRight(refreshed.getTreeRight()); 71 | node.setTreeLeft(refreshed.getTreeLeft()); 72 | node.setTreeLevel(refreshed.getTreeLevel()); 73 | node.setDiscriminator(refreshed.getDiscriminator()); 74 | } 75 | 76 | public void save(TestNode node) { 77 | KeyHolder keyHolder = new JdbcKeyHolder(); 78 | jdbcTemplate.update(con -> { 79 | String insertQuery = String.format("insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(next value for SEQ,%s,%s,%s,'%s',%s,'%s')", 80 | node.getTreeLeft(), node.getTreeLevel(), node.getTreeRight(), node.getName(), node.getParentId(), node.getDiscriminator() 81 | ); 82 | return con.prepareStatement(insertQuery, new String[]{"id"}); 83 | }, keyHolder); 84 | node.setId((Long) keyHolder.getKey()); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jpa/JpaNestedNodeRepositoryInsertingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jpa; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryInsertingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jpa; 33 | 34 | import javax.persistence.EntityManager; 35 | import javax.persistence.PersistenceContext; 36 | 37 | @Transactional 38 | public class JpaNestedNodeRepositoryInsertingTest extends NestedNodeRepositoryInsertingTest { 39 | 40 | private JpaTestHelper helper; 41 | 42 | @PersistenceContext 43 | private EntityManager em; 44 | 45 | @Autowired 46 | @Jpa 47 | private DelegatingNestedNodeRepository jpaRepository; 48 | 49 | @BeforeEach 50 | public void setup() { 51 | helper = new JpaTestHelper(em); 52 | this.repository = this.jpaRepository; 53 | } 54 | 55 | @Override 56 | protected TestNode findNode(String symbol) { 57 | return helper.findNode(symbol); 58 | } 59 | 60 | @Override 61 | protected TestNode getParent(TestNode f) { 62 | return helper.getParent(f); 63 | } 64 | 65 | @Override 66 | protected void breakTree() { 67 | helper.breakTree(); 68 | } 69 | 70 | @Override 71 | protected void resetParent(String symbol) { 72 | helper.resetParent(symbol); 73 | } 74 | 75 | @Override 76 | protected void removeTree() { 77 | helper.removeTree(); 78 | } 79 | 80 | @Override 81 | protected void flushAndClear() { 82 | helper.flushAndClear(); 83 | } 84 | 85 | @Override 86 | protected void flush() { 87 | helper.flush(); 88 | } 89 | 90 | @Override 91 | protected void refresh(TestNode node) { 92 | helper.refresh(node); 93 | } 94 | 95 | @Override 96 | protected void save(TestNode node) { 97 | helper.save(node); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jpa/JpaNestedNodeRepositoryMovingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jpa; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryMovingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jpa; 33 | 34 | import javax.persistence.EntityManager; 35 | import javax.persistence.PersistenceContext; 36 | 37 | @Transactional 38 | public class JpaNestedNodeRepositoryMovingTest extends NestedNodeRepositoryMovingTest { 39 | 40 | private JpaTestHelper helper; 41 | 42 | @PersistenceContext 43 | private EntityManager em; 44 | 45 | @Autowired 46 | @Jpa 47 | private DelegatingNestedNodeRepository jpaRepository; 48 | 49 | @BeforeEach 50 | public void setup() { 51 | helper = new JpaTestHelper(em); 52 | this.repository = this.jpaRepository; 53 | } 54 | 55 | @Override 56 | protected TestNode findNode(String symbol) { 57 | return helper.findNode(symbol); 58 | } 59 | 60 | @Override 61 | protected TestNode getParent(TestNode f) { 62 | return helper.getParent(f); 63 | } 64 | 65 | @Override 66 | protected void breakTree() { 67 | helper.breakTree(); 68 | } 69 | 70 | @Override 71 | protected void removeTree() { 72 | helper.removeTree(); 73 | } 74 | 75 | @Override 76 | protected void flushAndClear() { 77 | helper.flushAndClear(); 78 | } 79 | 80 | @Override 81 | protected void flush() { 82 | helper.flush(); 83 | } 84 | 85 | @Override 86 | protected void refresh(TestNode node) { 87 | helper.refresh(node); 88 | } 89 | 90 | @Override 91 | protected void resetParent(String symbol) { 92 | helper.resetParent(symbol); 93 | } 94 | 95 | @Override 96 | protected void save(TestNode node) { 97 | helper.save(node); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jpa/JpaNestedNodeRepositoryRebuildingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jpa; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryRebuildingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jpa; 33 | 34 | import javax.persistence.EntityManager; 35 | import javax.persistence.PersistenceContext; 36 | 37 | @Transactional 38 | public class JpaNestedNodeRepositoryRebuildingTest extends NestedNodeRepositoryRebuildingTest { 39 | 40 | private JpaTestHelper helper; 41 | 42 | @PersistenceContext 43 | private EntityManager em; 44 | 45 | @Autowired 46 | @Jpa 47 | private DelegatingNestedNodeRepository jpaRepository; 48 | 49 | @BeforeEach 50 | public void setup() { 51 | helper = new JpaTestHelper(em); 52 | this.repository = this.jpaRepository; 53 | } 54 | 55 | @Override 56 | protected TestNode findNode(String symbol) { 57 | return helper.findNode(symbol); 58 | } 59 | 60 | @Override 61 | protected TestNode getParent(TestNode f) { 62 | return helper.getParent(f); 63 | } 64 | 65 | @Override 66 | protected void breakTree() { 67 | helper.breakTree(); 68 | } 69 | 70 | @Override 71 | protected void removeTree() { 72 | helper.removeTree(); 73 | } 74 | 75 | @Override 76 | protected void flushAndClear() { 77 | helper.flushAndClear(); 78 | } 79 | 80 | @Override 81 | protected void flush() { 82 | helper.flush(); 83 | } 84 | 85 | @Override 86 | protected void resetParent(String symbol) { 87 | helper.resetParent(symbol); 88 | } 89 | 90 | @Override 91 | protected void refresh(TestNode node) { 92 | helper.refresh(node); 93 | } 94 | 95 | @Override 96 | protected void save(TestNode node) { 97 | helper.save(node); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jpa/JpaNestedNodeRepositoryRemovingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jpa; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryRemovingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jpa; 33 | 34 | import javax.persistence.EntityManager; 35 | import javax.persistence.PersistenceContext; 36 | 37 | @Transactional 38 | public class JpaNestedNodeRepositoryRemovingTest extends NestedNodeRepositoryRemovingTest { 39 | private JpaTestHelper helper; 40 | 41 | @PersistenceContext 42 | private EntityManager em; 43 | 44 | @Autowired 45 | @Jpa 46 | private DelegatingNestedNodeRepository jpaRepository; 47 | 48 | @BeforeEach 49 | public void setup() { 50 | helper = new JpaTestHelper(em); 51 | this.repository = this.jpaRepository; 52 | } 53 | 54 | @Override 55 | protected TestNode findNode(String symbol) { 56 | return helper.findNode(symbol); 57 | } 58 | 59 | @Override 60 | protected TestNode getParent(TestNode f) { 61 | return helper.getParent(f); 62 | } 63 | 64 | @Override 65 | protected void breakTree() { 66 | helper.breakTree(); 67 | } 68 | 69 | @Override 70 | protected void removeTree() { 71 | helper.removeTree(); 72 | } 73 | 74 | @Override 75 | protected void flushAndClear() { 76 | helper.flushAndClear(); 77 | } 78 | 79 | @Override 80 | protected void flush() { 81 | helper.flush(); 82 | } 83 | 84 | @Override 85 | protected void resetParent(String symbol) { 86 | helper.resetParent(symbol); 87 | } 88 | 89 | @Override 90 | protected void refresh(TestNode node) { 91 | helper.refresh(node); 92 | } 93 | 94 | @Override 95 | protected void save(TestNode node) { 96 | helper.save(node); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jpa/JpaNestedNodeRepositoryRetrievingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jpa; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryRetrievingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jpa; 33 | 34 | import javax.persistence.EntityManager; 35 | import javax.persistence.PersistenceContext; 36 | 37 | @Transactional 38 | public class JpaNestedNodeRepositoryRetrievingTest extends NestedNodeRepositoryRetrievingTest { 39 | private JpaTestHelper helper; 40 | 41 | @PersistenceContext 42 | private EntityManager em; 43 | 44 | @Autowired 45 | @Jpa 46 | private DelegatingNestedNodeRepository jpaRepository; 47 | 48 | @BeforeEach 49 | public void setup() { 50 | helper = new JpaTestHelper(em); 51 | this.repository = this.jpaRepository; 52 | } 53 | 54 | @Override 55 | protected TestNode findNode(String symbol) { 56 | return helper.findNode(symbol); 57 | } 58 | 59 | @Override 60 | protected TestNode getParent(TestNode f) { 61 | return helper.getParent(f); 62 | } 63 | 64 | @Override 65 | protected void breakTree() { 66 | helper.breakTree(); 67 | } 68 | 69 | @Override 70 | protected void removeTree() { 71 | helper.removeTree(); 72 | } 73 | 74 | @Override 75 | protected void flushAndClear() { 76 | helper.flushAndClear(); 77 | } 78 | 79 | @Override 80 | protected void flush() { 81 | helper.flush(); 82 | } 83 | 84 | @Override 85 | protected void resetParent(String symbol) { 86 | helper.resetParent(symbol); 87 | } 88 | 89 | @Override 90 | protected void refresh(TestNode node) { 91 | helper.refresh(node); 92 | } 93 | 94 | @Override 95 | protected void save(TestNode node) { 96 | helper.save(node); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jpa/JpaNestedNodeRepositoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.jpa; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Jpa; 33 | 34 | import javax.persistence.EntityManager; 35 | import javax.persistence.PersistenceContext; 36 | 37 | @Transactional 38 | public class JpaNestedNodeRepositoryTest extends NestedNodeRepositoryTest { 39 | 40 | private JpaTestHelper helper; 41 | 42 | @PersistenceContext 43 | private EntityManager em; 44 | 45 | @Autowired 46 | @Jpa 47 | private DelegatingNestedNodeRepository jpaRepository; 48 | 49 | @BeforeEach 50 | public void setup() { 51 | helper = new JpaTestHelper(em); 52 | this.repository = this.jpaRepository; 53 | } 54 | 55 | @Override 56 | protected TestNode findNode(String symbol) { 57 | return helper.findNode(symbol); 58 | } 59 | 60 | @Override 61 | protected TestNode getParent(TestNode f) { 62 | return helper.getParent(f); 63 | } 64 | 65 | @Override 66 | protected void breakTree() { 67 | helper.breakTree(); 68 | } 69 | 70 | @Override 71 | protected void removeTree() { 72 | helper.removeTree(); 73 | } 74 | 75 | @Override 76 | protected void flushAndClear() { 77 | helper.flushAndClear(); 78 | } 79 | 80 | @Override 81 | protected void flush() { 82 | helper.flush(); 83 | } 84 | 85 | @Override 86 | protected void resetParent(String symbol) { 87 | helper.resetParent(symbol); 88 | } 89 | 90 | @Override 91 | protected void refresh(TestNode node) { 92 | helper.refresh(node); 93 | } 94 | 95 | @Override 96 | protected void save(TestNode node) { 97 | helper.save(node); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/jpa/JpaTestHelper.java: -------------------------------------------------------------------------------- 1 | package pl.exsio.nestedj.jpa; 2 | 3 | import pl.exsio.nestedj.base.TestHelper; 4 | import pl.exsio.nestedj.model.TestNode; 5 | 6 | import javax.persistence.EntityManager; 7 | import javax.persistence.criteria.CriteriaBuilder; 8 | import javax.persistence.criteria.CriteriaQuery; 9 | import javax.persistence.criteria.Root; 10 | 11 | public class JpaTestHelper implements TestHelper { 12 | 13 | private final EntityManager em; 14 | 15 | JpaTestHelper(EntityManager em) { 16 | this.em = em; 17 | } 18 | 19 | @Override 20 | public TestNode findNode(String symbol) { 21 | CriteriaBuilder cb = em.getCriteriaBuilder(); 22 | CriteriaQuery select = cb.createQuery(TestNode.class); 23 | Root root = select.from(TestNode.class); 24 | select.where(cb.equal(root.get("name"), symbol)); 25 | TestNode n = em.createQuery(select).getSingleResult(); 26 | TestHelper.printNode(symbol, n); 27 | this.em.refresh(n); 28 | return n; 29 | } 30 | 31 | @Override 32 | public TestNode getParent(TestNode f) { 33 | this.em.refresh(f); 34 | TestNode parent = null; 35 | Long parentId = f.getParentId(); 36 | if (parentId != null) { 37 | parent = em.find(TestNode.class, parentId); 38 | } 39 | System.out.println(String.format("Parent of %s is %s", f.getName(), parent != null ? parent.getName() : "null")); 40 | return parent; 41 | } 42 | 43 | @Override 44 | public void breakTree() { 45 | this.em.createQuery("update TestNode set treeLeft = 0, treeRight = 0, treeLevel = 0 where discriminator = 'tree_1'").executeUpdate(); 46 | } 47 | 48 | @Override 49 | public void resetParent(String symbol) { 50 | this.em.createQuery("update TestNode set parentId = null where name='"+symbol+"' and discriminator = 'tree_1'").executeUpdate(); 51 | } 52 | 53 | @Override 54 | public void removeTree() { 55 | this.em.createQuery("delete from TestNode where discriminator = 'tree_1'").executeUpdate(); 56 | } 57 | 58 | public void flushAndClear() { 59 | em.flush(); 60 | em.clear(); 61 | } 62 | 63 | public void flush() { 64 | em.flush(); 65 | } 66 | 67 | public void refresh(TestNode node) { 68 | em.refresh(node); 69 | } 70 | 71 | public void save(TestNode node) { 72 | em.persist(node); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/mem/InMemoryNestedNodeRepositoryInsertingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.mem; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryInsertingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Mem; 33 | 34 | @Transactional 35 | public class InMemoryNestedNodeRepositoryInsertingTest extends NestedNodeRepositoryInsertingTest { 36 | 37 | private InMemoryTestHelper helper; 38 | 39 | @Autowired 40 | @Mem 41 | private DelegatingNestedNodeRepository inMemoryRepository; 42 | 43 | @BeforeEach 44 | public void setup() { 45 | helper = new InMemoryTestHelper(); 46 | helper.rollback(); 47 | this.repository = this.inMemoryRepository; 48 | } 49 | 50 | @Override 51 | protected TestNode findNode(String symbol) { 52 | return helper.findNode(symbol); 53 | } 54 | 55 | @Override 56 | protected TestNode getParent(TestNode f) { 57 | return helper.getParent(f); 58 | } 59 | 60 | @Override 61 | protected void breakTree() { 62 | helper.breakTree(); 63 | } 64 | 65 | @Override 66 | protected void resetParent(String symbol) { 67 | helper.resetParent(symbol); 68 | } 69 | 70 | @Override 71 | protected void removeTree() { 72 | helper.removeTree(); 73 | } 74 | 75 | @Override 76 | protected void flushAndClear() { 77 | helper.flushAndClear(); 78 | } 79 | 80 | @Override 81 | protected void flush() { 82 | helper.flush(); 83 | } 84 | 85 | @Override 86 | protected void refresh(TestNode node) { 87 | helper.refresh(node); 88 | } 89 | 90 | @Override 91 | protected void save(TestNode node) { 92 | helper.save(node); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/mem/InMemoryNestedNodeRepositoryMovingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.mem; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryMovingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Mem; 33 | 34 | @Transactional 35 | public class InMemoryNestedNodeRepositoryMovingTest extends NestedNodeRepositoryMovingTest { 36 | 37 | private InMemoryTestHelper helper; 38 | 39 | @Autowired 40 | @Mem 41 | private DelegatingNestedNodeRepository inMemoryRepository; 42 | 43 | @BeforeEach 44 | public void setup() { 45 | helper = new InMemoryTestHelper(); 46 | helper.rollback(); 47 | this.repository = this.inMemoryRepository; 48 | } 49 | 50 | @Override 51 | protected TestNode findNode(String symbol) { 52 | return helper.findNode(symbol); 53 | } 54 | 55 | @Override 56 | protected TestNode getParent(TestNode f) { 57 | return helper.getParent(f); 58 | } 59 | 60 | @Override 61 | protected void breakTree() { 62 | helper.breakTree(); 63 | } 64 | 65 | @Override 66 | protected void resetParent(String symbol) { 67 | helper.resetParent(symbol); 68 | } 69 | 70 | @Override 71 | protected void removeTree() { 72 | helper.removeTree(); 73 | } 74 | 75 | @Override 76 | protected void flushAndClear() { 77 | helper.flushAndClear(); 78 | } 79 | 80 | @Override 81 | protected void flush() { 82 | helper.flush(); 83 | } 84 | 85 | @Override 86 | protected void refresh(TestNode node) { 87 | helper.refresh(node); 88 | } 89 | 90 | @Override 91 | protected void save(TestNode node) { 92 | helper.save(node); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/mem/InMemoryNestedNodeRepositoryRebuildingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.mem; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryRebuildingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Mem; 33 | 34 | @Transactional 35 | public class InMemoryNestedNodeRepositoryRebuildingTest extends NestedNodeRepositoryRebuildingTest { 36 | 37 | 38 | private InMemoryTestHelper helper; 39 | 40 | @Autowired 41 | @Mem 42 | private DelegatingNestedNodeRepository inMemoryRepository; 43 | 44 | @BeforeEach 45 | public void setup() { 46 | helper = new InMemoryTestHelper(); 47 | helper.rollback(); 48 | this.repository = this.inMemoryRepository; 49 | } 50 | 51 | @Override 52 | protected TestNode findNode(String symbol) { 53 | return helper.findNode(symbol); 54 | } 55 | 56 | @Override 57 | protected TestNode getParent(TestNode f) { 58 | return helper.getParent(f); 59 | } 60 | 61 | @Override 62 | protected void breakTree() { 63 | helper.breakTree(); 64 | } 65 | 66 | @Override 67 | protected void resetParent(String symbol) { 68 | helper.resetParent(symbol); 69 | } 70 | 71 | @Override 72 | protected void removeTree() { 73 | helper.removeTree(); 74 | } 75 | 76 | @Override 77 | protected void flushAndClear() { 78 | helper.flushAndClear(); 79 | } 80 | 81 | @Override 82 | protected void flush() { 83 | helper.flush(); 84 | } 85 | 86 | @Override 87 | protected void refresh(TestNode node) { 88 | helper.refresh(node); 89 | } 90 | 91 | @Override 92 | protected void save(TestNode node) { 93 | helper.save(node); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/mem/InMemoryNestedNodeRepositoryRemovingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.mem; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryRemovingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Mem; 33 | 34 | @Transactional 35 | public class InMemoryNestedNodeRepositoryRemovingTest extends NestedNodeRepositoryRemovingTest { 36 | 37 | private InMemoryTestHelper helper; 38 | 39 | @Autowired 40 | @Mem 41 | private DelegatingNestedNodeRepository inMemoryRepository; 42 | 43 | @BeforeEach 44 | public void setup() { 45 | helper = new InMemoryTestHelper(); 46 | helper.rollback(); 47 | this.repository = this.inMemoryRepository; 48 | } 49 | 50 | @Override 51 | protected TestNode findNode(String symbol) { 52 | return helper.findNode(symbol); 53 | } 54 | 55 | @Override 56 | protected TestNode getParent(TestNode f) { 57 | return helper.getParent(f); 58 | } 59 | 60 | @Override 61 | protected void breakTree() { 62 | helper.breakTree(); 63 | } 64 | 65 | @Override 66 | protected void resetParent(String symbol) { 67 | helper.resetParent(symbol); 68 | } 69 | 70 | @Override 71 | protected void removeTree() { 72 | helper.removeTree(); 73 | } 74 | 75 | @Override 76 | protected void flushAndClear() { 77 | helper.flushAndClear(); 78 | } 79 | 80 | @Override 81 | protected void flush() { 82 | helper.flush(); 83 | } 84 | 85 | @Override 86 | protected void refresh(TestNode node) { 87 | helper.refresh(node); 88 | } 89 | 90 | @Override 91 | protected void save(TestNode node) { 92 | helper.save(node); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/mem/InMemoryNestedNodeRepositoryRetrievingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.mem; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryRetrievingTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Mem; 33 | 34 | @Transactional 35 | public class InMemoryNestedNodeRepositoryRetrievingTest extends NestedNodeRepositoryRetrievingTest { 36 | 37 | private InMemoryTestHelper helper; 38 | 39 | @Autowired 40 | @Mem 41 | private DelegatingNestedNodeRepository inMemoryRepository; 42 | 43 | @BeforeEach 44 | public void setup() { 45 | helper = new InMemoryTestHelper(); 46 | helper.rollback(); 47 | this.repository = this.inMemoryRepository; 48 | } 49 | 50 | @Override 51 | protected TestNode findNode(String symbol) { 52 | return helper.findNode(symbol); 53 | } 54 | 55 | @Override 56 | protected TestNode getParent(TestNode f) { 57 | return helper.getParent(f); 58 | } 59 | 60 | @Override 61 | protected void breakTree() { 62 | helper.breakTree(); 63 | } 64 | 65 | @Override 66 | protected void resetParent(String symbol) { 67 | helper.resetParent(symbol); 68 | } 69 | 70 | @Override 71 | protected void removeTree() { 72 | helper.removeTree(); 73 | } 74 | 75 | @Override 76 | protected void flushAndClear() { 77 | helper.flushAndClear(); 78 | } 79 | 80 | @Override 81 | protected void flush() { 82 | helper.flush(); 83 | } 84 | 85 | @Override 86 | protected void refresh(TestNode node) { 87 | helper.refresh(node); 88 | } 89 | 90 | @Override 91 | protected void save(TestNode node) { 92 | helper.save(node); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/mem/InMemoryNestedNodeRepositoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2015 exsio. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package pl.exsio.nestedj.mem; 25 | 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.springframework.beans.factory.annotation.Autowired; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import pl.exsio.nestedj.DelegatingNestedNodeRepository; 30 | import pl.exsio.nestedj.base.NestedNodeRepositoryTest; 31 | import pl.exsio.nestedj.model.TestNode; 32 | import pl.exsio.nestedj.qualifier.Mem; 33 | 34 | @Transactional 35 | public class InMemoryNestedNodeRepositoryTest extends NestedNodeRepositoryTest { 36 | 37 | private InMemoryTestHelper helper; 38 | 39 | @Autowired 40 | @Mem 41 | private DelegatingNestedNodeRepository inMemoryRepository; 42 | 43 | @BeforeEach 44 | public void setup() { 45 | helper = new InMemoryTestHelper(); 46 | helper.rollback(); 47 | this.repository = this.inMemoryRepository; 48 | } 49 | 50 | @Override 51 | protected TestNode findNode(String symbol) { 52 | return helper.findNode(symbol); 53 | } 54 | 55 | @Override 56 | protected TestNode getParent(TestNode f) { 57 | return helper.getParent(f); 58 | } 59 | 60 | @Override 61 | protected void breakTree() { 62 | helper.breakTree(); 63 | } 64 | 65 | @Override 66 | protected void resetParent(String symbol) { 67 | helper.resetParent(symbol); 68 | } 69 | 70 | @Override 71 | protected void removeTree() { 72 | helper.removeTree(); 73 | } 74 | 75 | @Override 76 | protected void flushAndClear() { 77 | helper.flushAndClear(); 78 | } 79 | 80 | @Override 81 | protected void flush() { 82 | helper.flush(); 83 | } 84 | 85 | @Override 86 | protected void refresh(TestNode node) { 87 | helper.refresh(node); 88 | } 89 | 90 | @Override 91 | protected void save(TestNode node) { 92 | helper.save(node); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/mem/InMemoryTestHelper.java: -------------------------------------------------------------------------------- 1 | package pl.exsio.nestedj.mem; 2 | 3 | import pl.exsio.nestedj.TestConfiguration; 4 | import pl.exsio.nestedj.base.TestHelper; 5 | import pl.exsio.nestedj.config.mem.InMemoryNestedNodeRepositoryConfiguration; 6 | import pl.exsio.nestedj.model.TestNode; 7 | 8 | import java.util.List; 9 | import java.util.stream.Collectors; 10 | 11 | public class InMemoryTestHelper implements TestHelper { 12 | 13 | private final InMemoryNestedNodeRepositoryConfiguration config = TestConfiguration.IN_MEM_CONFIG; 14 | 15 | @Override 16 | public TestNode findNode(String symbol) { 17 | System.out.println(config.getNodes()); 18 | return config.getNodes().stream().filter(n -> n.getName().equals(symbol)).findFirst().orElse(null); 19 | } 20 | 21 | @Override 22 | public TestNode getParent(TestNode f) { 23 | if (f.getParentId() == null) { 24 | return null; 25 | } 26 | TestNode parent = config.getNodes().stream().filter(n -> n.getId().equals(f.getParentId())).findFirst().orElse(null); 27 | System.out.println(String.format("Parent of %s is %s", f.getName(), parent != null ? parent.getName() : "null")); 28 | return parent; 29 | } 30 | 31 | @Override 32 | public void breakTree() { 33 | config.getNodes().stream() 34 | .filter(n -> n.getDiscriminator() 35 | .equals("tree_1")).forEach(n -> { 36 | n.setTreeLevel(0L); 37 | n.setTreeLeft(0L); 38 | n.setTreeRight(0L); 39 | }); 40 | } 41 | 42 | @Override 43 | public void resetParent(String symbol) { 44 | findNode(symbol).setParentId(null); 45 | } 46 | 47 | @Override 48 | public void removeTree() { 49 | List nodes = config.getNodes().stream().filter(n -> n.getDiscriminator().equals("tree_1")) 50 | .collect(Collectors.toList()); 51 | config.getNodes().removeAll(nodes); 52 | } 53 | 54 | @Override 55 | public void save(TestNode node) { 56 | node.setId(config.getIdentityGenerator().generateIdentity()); 57 | config.getNodes().add(node); 58 | } 59 | 60 | public void rollback() { 61 | config.getNodes().clear(); 62 | config.getNodes().addAll(TestConfiguration.IN_MEM_NODES.stream().map(TestNode::copy).collect(Collectors.toList())); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/qualifier/Jdbc.java: -------------------------------------------------------------------------------- 1 | package pl.exsio.nestedj.qualifier; 2 | 3 | import org.springframework.beans.factory.annotation.Qualifier; 4 | 5 | @Qualifier 6 | public @interface Jdbc { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/qualifier/Jpa.java: -------------------------------------------------------------------------------- 1 | package pl.exsio.nestedj.qualifier; 2 | 3 | import org.springframework.beans.factory.annotation.Qualifier; 4 | 5 | @Qualifier 6 | public @interface Jpa { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/pl/exsio/nestedj/qualifier/Mem.java: -------------------------------------------------------------------------------- 1 | package pl.exsio.nestedj.qualifier; 2 | 3 | import org.springframework.beans.factory.annotation.Qualifier; 4 | 5 | @Qualifier 6 | public @interface Mem { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/resources/fixtures/test-import.sql: -------------------------------------------------------------------------------- 1 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(1000,1,0,16,'a',null, 'tree_1'); 2 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(2000,2,1,7,'b',1000, 'tree_1'); 3 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(3000,8,1,15,'c',1000, 'tree_1'); 4 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(4000,3,2,4,'d',2000, 'tree_1'); 5 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(5000,5,2,6,'e',2000, 'tree_1'); 6 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(6000,9,2,10,'f',3000, 'tree_1'); 7 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(7000,11,2,14,'g',3000, 'tree_1'); 8 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(8000,12,3,13,'h',7000, 'tree_1'); 9 | 10 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(9000,1,0,16,'a2',null, 'tree_2'); 11 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(10000,2,1,7,'b2',9000, 'tree_2'); 12 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(11000,8,1,15,'c2',9000, 'tree_2'); 13 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(12000,3,2,4,'d2',10000, 'tree_2'); 14 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(13000,5,2,6,'e2',10000, 'tree_2'); 15 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(14000,9,2,10,'f2',11000, 'tree_2'); 16 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(15000,11,2,14,'g2',11000, 'tree_2'); 17 | insert into nested_nodes(id, tree_left, tree_level, tree_right, node_name, parent_id, discriminator) values(16000,12,3,13,'h2',15000, 'tree_2'); 18 | -------------------------------------------------------------------------------- /src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UTF-8 6 | %date %-5level [%thread] %logger{36} - %message%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | --------------------------------------------------------------------------------