121 lines
6.7 KiB
Java
121 lines
6.7 KiB
Java
package gr.cite.annotation.model.builder;
|
|
|
|
import gr.cite.annotation.authorization.AffiliatedResource;
|
|
import gr.cite.annotation.authorization.AuthorizationFlags;
|
|
import gr.cite.annotation.authorization.authorizationcontentresolver.AuthorizationContentResolver;
|
|
import gr.cite.annotation.convention.ConventionService;
|
|
import gr.cite.annotation.data.AnnotationEntity;
|
|
import gr.cite.annotation.model.Annotation;
|
|
import gr.cite.annotation.model.AnnotationAuthor;
|
|
import gr.cite.annotation.model.User;
|
|
import gr.cite.annotation.query.UserQuery;
|
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
|
import gr.cite.tools.data.builder.BuilderFactory;
|
|
import gr.cite.tools.data.query.QueryFactory;
|
|
import gr.cite.tools.exception.MyApplicationException;
|
|
import gr.cite.tools.fieldset.BaseFieldSet;
|
|
import gr.cite.tools.fieldset.FieldSet;
|
|
import gr.cite.tools.logging.DataLogEntry;
|
|
import gr.cite.tools.logging.LoggerService;
|
|
import org.slf4j.LoggerFactory;
|
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
|
import org.springframework.context.annotation.Scope;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import java.util.*;
|
|
import java.util.stream.Collectors;
|
|
|
|
@Component
|
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
|
public class AnnotationBuilder extends BaseBuilder<Annotation, AnnotationEntity> {
|
|
|
|
private final QueryFactory queryFactory;
|
|
|
|
private final BuilderFactory builderFactory;
|
|
private final AuthorizationContentResolver authorizationContentResolver;
|
|
private final AuthorizationService authorizationService;
|
|
|
|
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
|
|
|
public AnnotationBuilder(ConventionService conventionService, QueryFactory queryFactory, BuilderFactory builderFactory, AuthorizationContentResolver authorizationContentResolver, AuthorizationService authorizationService) {
|
|
super(conventionService, new LoggerService(LoggerFactory.getLogger(AnnotationBuilder.class)));
|
|
this.queryFactory = queryFactory;
|
|
this.builderFactory = builderFactory;
|
|
this.authorizationContentResolver = authorizationContentResolver;
|
|
this.authorizationService = authorizationService;
|
|
}
|
|
|
|
public AnnotationBuilder authorize(EnumSet<AuthorizationFlags> values) {
|
|
this.authorize = values;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public List<Annotation> build(FieldSet fields, List<AnnotationEntity> data) throws MyApplicationException {
|
|
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0));
|
|
this.logger.trace(new DataLogEntry("requested fields", fields));
|
|
if (fields == null || fields.isEmpty())
|
|
return new ArrayList<>();
|
|
|
|
List<Annotation> models = new ArrayList<>();
|
|
if (data == null) return models;
|
|
|
|
FieldSet authorFields = fields.extractPrefixed(this.asPrefix(Annotation._author));
|
|
Map<UUID, AnnotationAuthor> authorsMap = this.collectAuthors(authorFields, data);
|
|
Set<String> authorizationFlags = this.extractAuthorizationFlags(fields, Annotation._authorizationFlags, this.authorizationContentResolver.getPermissionNames());
|
|
Map<UUID, AffiliatedResource> affiliatedResourceMap = authorizationFlags == null || authorizationFlags.isEmpty() ? null : this.authorizationContentResolver.annotationsAffiliation(data.stream().map(AnnotationEntity::getId).toList());
|
|
|
|
|
|
for (AnnotationEntity d : data) {
|
|
Annotation m = new Annotation();
|
|
if (fields.hasField(this.asIndexer(Annotation._id))) m.setId(d.getId());
|
|
if (fields.hasField(this.asIndexer(Annotation._entityId))) m.setEntityId(d.getEntityId());
|
|
if (fields.hasField(this.asIndexer(Annotation._entityType))) m.setEntityType(d.getEntityType());
|
|
if (fields.hasField(this.asIndexer(Annotation._anchor))) m.setAnchor(d.getAnchor());
|
|
if (fields.hasField(this.asIndexer(Annotation._payload))) m.setPayload(d.getPayload());
|
|
if (fields.hasField(this.asIndexer(Annotation._subjectId))) m.setSubjectId(d.getSubjectId());
|
|
if (fields.hasField(this.asIndexer(Annotation._threadId))) m.setThreadId(d.getThreadId());
|
|
if (fields.hasField(this.asIndexer(Annotation._parentId))) m.setParentId(d.getParentId());
|
|
if (fields.hasField(this.asIndexer(Annotation._protectionType))) m.setProtectionType(d.getProtectionType());
|
|
if (fields.hasField(this.asIndexer(Annotation._timeStamp))) m.setTimeStamp(d.getTimeStamp());
|
|
if (fields.hasField(this.asIndexer(Annotation._createdAt))) m.setCreatedAt(d.getCreatedAt());
|
|
if (fields.hasField(this.asIndexer(Annotation._updatedAt))) m.setUpdatedAt(d.getUpdatedAt());
|
|
if (fields.hasField(this.asIndexer(Annotation._isActive))) m.setIsActive(d.getIsActive());
|
|
if (fields.hasField(this.asIndexer(Annotation._hash))) m.setHash(this.hashValue(d.getUpdatedAt()));
|
|
if (!authorFields.isEmpty() && authorsMap != null && authorsMap.containsKey(d.getSubjectId())) m.setAuthor(authorsMap.get(d.getSubjectId()));
|
|
if (affiliatedResourceMap != null && !authorizationFlags.isEmpty()) m.setAuthorizationFlags(this.evaluateAuthorizationFlags(this.authorizationService, authorizationFlags, affiliatedResourceMap.getOrDefault(d.getId(), null)));
|
|
models.add(m);
|
|
}
|
|
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
|
|
return models;
|
|
}
|
|
|
|
private Map<UUID, AnnotationAuthor> collectAuthors(FieldSet fields, List<AnnotationEntity> data) {
|
|
if (fields.isEmpty() || data.isEmpty()) return null;
|
|
this.logger.debug("checking related - {}", User.class.getSimpleName());
|
|
|
|
Map<UUID, AnnotationAuthor> itemMap = new HashMap<>();
|
|
FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(this.asIndexer(User._id), this.asIndexer(User._name));
|
|
List<UUID> userIds = data.stream()
|
|
.map(AnnotationEntity::getSubjectId)
|
|
.distinct()
|
|
.collect(Collectors.toList());
|
|
UserQuery query = this.queryFactory.query(UserQuery.class).ids(userIds);
|
|
Map<UUID, List<User>> users = this.builderFactory.builder(UserBuilder.class).authorize(this.authorize).asMasterKey(query, clone, User::getId);
|
|
|
|
users.forEach((key, val) -> {
|
|
itemMap.put(key, this.authorFromUser(val.getFirst()));
|
|
});
|
|
|
|
return itemMap;
|
|
}
|
|
|
|
private AnnotationAuthor authorFromUser(User user) {
|
|
AnnotationAuthor author = new AnnotationAuthor();
|
|
author.setId(user.getId());
|
|
author.setName(user.getName());
|
|
return author;
|
|
}
|
|
|
|
}
|