Skip to content

Commit e38ae46

Browse files
authored
Merge pull request #897 from th37rose/feature/bundle
Create Bundle Object, Bundle API, Permission API
2 parents 47300c1 + 9a7f0c8 commit e38ae46

36 files changed

+2392
-14
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.lowcoder.domain.bundle.model;
2+
3+
4+
import jakarta.annotation.Nullable;
5+
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
7+
import lombok.Setter;
8+
import lombok.experimental.SuperBuilder;
9+
import org.lowcoder.sdk.models.HasIdAndAuditing;
10+
import org.springframework.data.mongodb.core.mapping.Document;
11+
12+
@Getter
13+
@Setter
14+
@Document
15+
@NoArgsConstructor
16+
@SuperBuilder
17+
public class Bundle extends HasIdAndAuditing {
18+
private String organizationId;
19+
@Nullable
20+
private String name;
21+
private String title;
22+
private String description;
23+
private String category;
24+
private String image;
25+
private BundleStatus bundleStatus;
26+
private Boolean publicToAll;
27+
private Boolean publicToMarketplace;
28+
private Boolean agencyProfile;
29+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package org.lowcoder.domain.bundle.model;
2+
3+
public record BundleElement(String bundleId, String elementId, int position) {
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.lowcoder.domain.bundle.model;
2+
3+
public enum BundleRequestType {
4+
PUBLIC_TO_ALL,
5+
PUBLIC_TO_MARKETPLACE,
6+
AGENCY_PROFILE,
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.lowcoder.domain.bundle.model;
2+
3+
public enum BundleStatus {
4+
5+
NORMAL, // default
6+
RECYCLED,
7+
DELETED,
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.lowcoder.domain.bundle.repository;
2+
3+
import org.lowcoder.domain.application.model.Application;
4+
import org.lowcoder.domain.bundle.model.Bundle;
5+
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
6+
import org.springframework.stereotype.Repository;
7+
import reactor.core.publisher.Flux;
8+
9+
import java.util.Collection;
10+
11+
@Repository
12+
public interface BundleRepository extends ReactiveMongoRepository<Bundle, String> {
13+
14+
Flux<Bundle> findByUserId(String userId);
15+
/**
16+
* Filter marketplace bundles from list of supplied IDs
17+
*/
18+
Flux<Bundle> findByPublicToAllIsTrueAndPublicToMarketplaceIsTrueAndIdIn(Collection<String> ids);
19+
/**
20+
* Filter public bundles from list of supplied IDs
21+
*/
22+
Flux<Bundle> findByPublicToAllIsTrueAndIdIn(Collection<String> ids);
23+
Flux<Bundle> findByCreatedByAndIdIn(String userId, Collection<String> ids);
24+
/**
25+
* Filter agency bundles from list of supplied IDs
26+
*/
27+
Flux<Bundle> findByPublicToAllIsTrueAndAgencyProfileIsTrueAndIdIn(Collection<String> ids);
28+
29+
Flux<Bundle> findByPublicToAllIsTrueAndPublicToMarketplaceIsTrue();
30+
31+
Flux<Bundle> findByPublicToAllIsTrueAndAgencyProfileIsTrue();
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.lowcoder.domain.bundle.service;
2+
3+
import org.lowcoder.domain.bundle.model.BundleElement;
4+
import org.reactivestreams.Publisher;
5+
import reactor.core.publisher.Flux;
6+
import reactor.core.publisher.Mono;
7+
8+
import java.util.List;
9+
10+
public interface BundleElementRelationService {
11+
Mono<Boolean> deleteByBundleIds(List<String> bundleIds);
12+
13+
Mono<Boolean> deleteByElementId(String elementId);
14+
15+
Mono<Void> create(String bundleId, String elementId);
16+
17+
Flux<BundleElement> getByElementIds(List<String> elementIds);
18+
19+
Mono<Void> updateElementPos(String bundleId, String elementId, long position);
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package org.lowcoder.domain.bundle.service;
2+
3+
import lombok.RequiredArgsConstructor;
4+
import org.lowcoder.domain.bundle.model.BundleElement;
5+
import org.lowcoder.infra.birelation.BiRelationService;
6+
import org.springframework.stereotype.Service;
7+
import reactor.core.publisher.Flux;
8+
import reactor.core.publisher.Mono;
9+
10+
import java.util.List;
11+
import java.util.Objects;
12+
13+
import static org.lowcoder.infra.birelation.BiRelationBizType.BUNDLE_ELEMENT;
14+
15+
@RequiredArgsConstructor
16+
@Service
17+
public class BundleElementRelationServiceImpl implements BundleElementRelationService {
18+
19+
private final BiRelationService biRelationService;
20+
21+
@Override
22+
public Mono<Boolean> deleteByBundleIds(List<String> bundleIds) {
23+
return biRelationService.removeAllBiRelations(BUNDLE_ELEMENT, bundleIds);
24+
}
25+
26+
@Override
27+
public Mono<Boolean> deleteByElementId(String elementId) {
28+
return biRelationService.removeAllBiRelationsByTargetId(BUNDLE_ELEMENT, elementId);
29+
}
30+
31+
@Override
32+
public Mono<Void> create(String bundleId, String elementId) {
33+
return biRelationService.getBySourceId(BUNDLE_ELEMENT, bundleId)
34+
.mapNotNull(rel -> {
35+
try {
36+
return Integer.parseInt(rel.getExtParam1());
37+
} catch (NumberFormatException e) {
38+
return null;
39+
}
40+
})
41+
.reduce(Integer::max)
42+
.switchIfEmpty(Mono.just(0))
43+
.flatMap(maxVal -> biRelationService.addBiRelation(BUNDLE_ELEMENT, bundleId, elementId, null, null, String.valueOf(maxVal + 1)))
44+
.then();
45+
}
46+
47+
@Override
48+
public Flux<BundleElement> getByElementIds(List<String> elementIds) {
49+
return biRelationService.getByTargetIds(BUNDLE_ELEMENT, elementIds)
50+
.map(biRelation -> new BundleElement(biRelation.getSourceId(), biRelation.getTargetId(), Integer.parseInt(biRelation.getExtParam1())));
51+
}
52+
53+
@Override
54+
public Mono<Void> updateElementPos(String bundleId, String elementId, long position) {
55+
return biRelationService.getBiRelation(BUNDLE_ELEMENT, bundleId, elementId)
56+
.doOnNext(biRelation -> biRelation.setExtParam1(String.valueOf(position)))
57+
.then();
58+
}
59+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package org.lowcoder.domain.bundle.service;
2+
3+
import jakarta.annotation.Nonnull;
4+
import jakarta.annotation.Nullable;
5+
import lombok.Getter;
6+
import lombok.Setter;
7+
8+
import java.util.*;
9+
import java.util.function.Consumer;
10+
import java.util.function.Function;
11+
12+
@Getter
13+
@Setter
14+
public class BundleNode<T, F> implements Node<T, F> {
15+
16+
private final F self;
17+
private BundleNode<T, F> parent;
18+
protected final Collection<Node<T, F>> children;
19+
@Nonnull
20+
private final Function<F, String> idExtractor;
21+
@Nonnull
22+
private final Function<F, String> parentIdExtractor;
23+
24+
BundleNode(F self, @Nonnull Function<F, String> idExtractor, @Nonnull Function<F, String> parentIdExtractor,
25+
@Nullable Comparator<Node<T, F>> comparator) {
26+
this.self = self;
27+
this.idExtractor = idExtractor;
28+
this.parentIdExtractor = parentIdExtractor;
29+
this.children = comparator == null ? new ArrayList<>() : new PriorityQueue<>(comparator);
30+
}
31+
32+
public String id() {
33+
return idExtractor.apply(self);
34+
}
35+
36+
@Override
37+
public String parentId() {
38+
return parentIdExtractor.apply(self);
39+
}
40+
41+
public final List<F> getBundleChildren() {
42+
return children.stream()
43+
.filter(node -> node instanceof BundleNode<T, F>)
44+
.map(node -> ((BundleNode<T, F>) node).getSelf())
45+
.toList();
46+
}
47+
48+
public final List<T> getElementChildren() {
49+
return children.stream()
50+
.filter(node -> node instanceof ElementNode<T, F>)
51+
.map(node -> ((ElementNode<T, F>) node).getSelf())
52+
.toList();
53+
}
54+
55+
public final List<F> getAllBundleChildren() {
56+
return this.children.stream()
57+
.map(node -> {
58+
if (node instanceof BundleNode<T, F> bundleNode) {
59+
F self = bundleNode.getSelf();
60+
List<F> bundleChildren = bundleNode.getAllBundleChildren();
61+
List<F> all = new ArrayList<>(bundleChildren);
62+
if (self != null) {
63+
all.add(self);
64+
}
65+
return all;
66+
}
67+
return new ArrayList<F>();
68+
})
69+
.flatMap(List::stream)
70+
.toList();
71+
}
72+
73+
74+
/**
75+
* @param consumer will be called for children node first, then by parent node
76+
*/
77+
public void postOrderIterate(Consumer<Node<T, F>> consumer) {
78+
children.forEach(node -> {
79+
if (node instanceof BundleNode<T, F> bundleNode) {
80+
bundleNode.postOrderIterate(consumer);
81+
return;
82+
}
83+
consumer.accept(node);
84+
});
85+
consumer.accept(this);
86+
}
87+
88+
public final int depth() {
89+
if (parent == null) {
90+
return 1;
91+
}
92+
return parent.depth() + 1;
93+
}
94+
95+
@Override
96+
public String toString() {
97+
return "BundleNode{" +
98+
"self=" + self +
99+
", children=" + children +
100+
'}';
101+
}
102+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package org.lowcoder.domain.bundle.service;
2+
3+
import org.lowcoder.domain.application.model.Application;
4+
import org.lowcoder.domain.application.model.ApplicationRequestType;
5+
import org.lowcoder.domain.bundle.model.Bundle;
6+
import org.lowcoder.domain.bundle.model.BundleRequestType;
7+
import org.lowcoder.infra.annotation.NonEmptyMono;
8+
import reactor.core.publisher.Flux;
9+
import reactor.core.publisher.Mono;
10+
11+
import java.util.Collection;
12+
import java.util.Set;
13+
14+
public interface BundleService {
15+
Mono<Boolean> updateById(String id, Bundle resource);
16+
17+
Mono<Bundle> findById(String id);
18+
19+
Mono<Bundle> create(Bundle bundle);
20+
21+
Flux<Bundle> findByUserId(String bundleId);
22+
23+
Mono<Void> deleteAllById(Collection<String> ids);
24+
25+
Mono<Boolean> exist(String id);
26+
27+
@NonEmptyMono
28+
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
29+
Mono<Set<String>> getFilteredPublicBundleIds(BundleRequestType requestType, Collection<String> bundleIds, String userId, Boolean isPrivateMarketplace);
30+
@NonEmptyMono
31+
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
32+
Mono<Set<String>> getPublicBundleIds(Collection<String> bundleIds);
33+
34+
@NonEmptyMono
35+
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
36+
Mono<Set<String>> getPrivateBundleIds(Collection<String> bundleIds, String userId);
37+
38+
@NonEmptyMono
39+
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
40+
Mono<Set<String>> getPublicMarketplaceBundleIds(Collection<String> bundleIds, boolean isAnonymous, boolean isPrivateMarketplace);
41+
42+
@NonEmptyMono
43+
@SuppressWarnings("ReactiveStreamsNullableInLambdaInTransform")
44+
Mono<Set<String>> getPublicAgencyBundleIds(Collection<String> bundleIds);
45+
46+
Mono<Boolean> setBundlePublicToAll(String bundleId, boolean publicToAll);
47+
48+
Mono<Boolean> setBundlePublicToMarketplace(String bundleId, Boolean publicToMarketplace);
49+
50+
Mono<Boolean> setBundleAsAgencyProfile(String bundleId, boolean agencyProfile);
51+
52+
Flux<Bundle> findAllMarketplaceBundles();
53+
54+
Flux<Bundle> findAllAgencyProfileBundles();
55+
}

0 commit comments

Comments
 (0)