Skip to content

Commit

Permalink
Merge pull request #37 from softleader/add-bag-to-context
Browse files Browse the repository at this point in the history
feat: add bag to conetxt
  • Loading branch information
shihyuho authored Mar 24, 2022
2 parents f8b6bca + 624cee4 commit 7c7945c
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,37 @@
*/
package tw.com.softleader.data.jpa.spec;

import static java.util.Optional.ofNullable;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
import lombok.Synchronized;
import lombok.val;
import org.springframework.data.util.Pair;
import java.util.Optional;
import lombok.NonNull;
import tw.com.softleader.data.jpa.spec.domain.Context;
import tw.com.softleader.data.jpa.spec.domain.JoinContext;

class SpecContext implements Context {

private final Map<Pair<String, Root<?>>, javax.persistence.criteria.Join<?, ?>> joins = new HashMap<>();
private final Map<String, Function<Root<?>, Join<?, ?>>> lazyJoins = new HashMap<>();
private final Map<String, Object> bag = new HashMap<>();
private final JoinContext join = new SpecJoinContext();

@Override
public JoinContext join() {
return join;
}

@Override
public Optional<Object> get(@NonNull String key) {
return ofNullable(bag.get(key));
}

@Override
@Synchronized
public Join<?, ?> getJoin(String key, Root<?> root) {
val lazyJoin = lazyJoins.get(key);
if (lazyJoin == null) {
return null;
}
Pair<String, Root<?>> rootKey = Pair.of(key, root);
joins.computeIfAbsent(rootKey, k -> lazyJoin.apply(root));
return joins.get(rootKey);
public Object put(@NonNull String key, @NonNull Object value) {
return bag.put(key, value);
}

public void putLazyJoin(String key, Function<Root<?>, Join<?, ?>> lazyJoin) {
lazyJoins.put(key, lazyJoin);
@Override
public Object remove(@NonNull String key) {
return bag.remove(key);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright © 2022 SoftLeader
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package tw.com.softleader.data.jpa.spec;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
import lombok.Synchronized;
import lombok.val;
import org.springframework.data.util.Pair;
import tw.com.softleader.data.jpa.spec.domain.JoinContext;

class SpecJoinContext implements JoinContext {

private final Map<Pair<String, Root<?>>, Join<?, ?>> joins = new HashMap<>();
private final Map<String, Function<Root<?>, Join<?, ?>>> lazyJoins = new HashMap<>();

@Override
@Synchronized
public Join<?, ?> get(String key, Root<?> root) {
val lazyJoin = lazyJoins.get(key);
if (lazyJoin == null) {
return null;
}
Pair<String, Root<?>> rootKey = Pair.of(key, root);
joins.computeIfAbsent(rootKey, k -> lazyJoin.apply(root));
return joins.get(rootKey);
}

public void putLazy(String key, Function<Root<?>, Join<?, ?>> lazyJoin) {
lazyJoins.put(key, lazyJoin);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/
package tw.com.softleader.data.jpa.spec.domain;

import java.util.Optional;
import java.util.function.Function;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
Expand All @@ -31,8 +32,11 @@
*/
public interface Context {

@SuppressWarnings({ "rawtypes" })
Join getJoin(String key, Root<?> root);
JoinContext join();

void putLazyJoin(String key, Function<Root<?>, Join<?, ?>> function);
Optional<Object> get(String key);

Object put(String key, Object value);

Object remove(String key);
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuild

private void join(Root<T> root) {
if (!pathToJoinOn.contains(".")) {
context.putLazyJoin(alias, r -> r.join(pathToJoinOn, joinType));
context.join().putLazy(alias, r -> r.join(pathToJoinOn, joinType));
return;
}
val byDot = pathToJoinOn.split("\\.");

val extractedAlias = byDot[0];
val joined = context.getJoin(extractedAlias, root);
val joined = context.join().get(extractedAlias, root);
if (joined == null) {
throw new IllegalArgumentException(
"Join definition with alias: '" + extractedAlias + "' not found! " +
Expand All @@ -74,6 +74,6 @@ private void join(Root<T> root) {
}

val extractedPathToJoin = byDot[1];
context.putLazyJoin(alias, r -> joined.join(extractedPathToJoin, joinType));
context.join().putLazy(alias, r -> joined.join(extractedPathToJoin, joinType));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright © 2022 SoftLeader
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package tw.com.softleader.data.jpa.spec.domain;

import java.util.function.Function;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;

/**
* Share data between specifications
*
* @author Matt Ho
*/
public interface JoinContext {

@SuppressWarnings({ "rawtypes" })
Join get(String key, Root<?> root);

void putLazy(String key, Function<Root<?>, Join<?, ?>> function);
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ protected <F> Path<F> getPath(Root<T> root) {
Path<?> expr = null;
for (String field : split) {
if (expr == null) {
expr = ofNullable(context.getJoin(field, root))
expr = ofNullable(context.join().get(field, root))
.map(joined -> (Path<T>) joined)
.orElseGet(() -> root.get(field));
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ static class GeneralCodingRules {
static final ArchRule noClassesShouldThrowGenericExceptions = NO_CLASSES_SHOULD_THROW_GENERIC_EXCEPTIONS;

@ArchTest
static final ArchRule noClassesShouldUseJodatime = NO_CLASSES_SHOULD_USE_JODATIME;
static final ArchRule noClassesShouldUseJodaTime = NO_CLASSES_SHOULD_USE_JODATIME;

@ArchTest
static final ArchRule noClassesShouldUseFieldInjection = NO_CLASSES_SHOULD_USE_FIELD_INJECTION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,12 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.function.Function;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
import java.util.Optional;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import tw.com.softleader.data.jpa.spec.domain.Context;
import tw.com.softleader.data.jpa.spec.domain.JoinContext;

/**
* Integration test with Spring Boot Data JPA
Expand All @@ -57,12 +56,22 @@ class TestApplication {
public static Context noopContext() {
return new Context() {
@Override
public Join<?, ?> getJoin(String key, Root<?> root) {
public JoinContext join() {
throw new UnsupportedOperationException();
}

@Override
public void putLazyJoin(String key, Function<Root<?>, Join<?, ?>> function) {
public Optional<Object> get(String key) {
throw new UnsupportedOperationException();
}

@Override
public Object put(String key, Object value) {
throw new UnsupportedOperationException();
}

@Override
public Object remove(String key) {
throw new UnsupportedOperationException();
}
};
Expand Down

0 comments on commit 7c7945c

Please sign in to comment.