Skip to content

Commit

Permalink
Merge pull request #263 from kbss-cvut/development
Browse files Browse the repository at this point in the history
[3.0.4] Release
  • Loading branch information
ledsoft authored Apr 15, 2024
2 parents e427b5d + 6b53d4d commit 6be4c40
Show file tree
Hide file tree
Showing 17 changed files with 131 additions and 73 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</parent>

<artifactId>termit</artifactId>
<version>3.0.3</version>
<version>3.0.4</version>
<name>TermIt</name>
<description>Terminology manager based on Semantic Web technologies.</description>
<packaging>${packaging}</packaging>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public void persist(AccessControlList acl) {
*/
public void update(AccessControlList acl) {
Objects.requireNonNull(acl);
final AccessControlList original = em.find(AccessControlList.class, acl.getUri());
final AccessControlList original = em.find(AccessControlList.class, acl.getUri(), descriptor());
assert original != null;
removeOrphanRecords(original, acl);
em.merge(acl, descriptor());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,19 @@ public class RestExceptionHandler {

private static final Logger LOG = LoggerFactory.getLogger(RestExceptionHandler.class);

private static void logException(TermItException ex) {
private static void logException(TermItException ex, HttpServletRequest request) {
if (shouldSuppressLogging(ex)) {
return;
}
logException("Exception caught.", ex);
logException("Exception caught when processing request to '" + request.getRequestURI() + "'.", ex);
}

private static boolean shouldSuppressLogging(TermItException ex) {
return ex.getClass().getAnnotation(SuppressibleLogging.class) != null;
}

private static void logException(Throwable ex) {
logException("Exception caught.", ex);
private static void logException(Throwable ex, HttpServletRequest request) {
logException("Exception caught when processing request to '" + request.getRequestURI() + "'.", ex);
}

private static void logException(String message, Throwable ex) {
Expand All @@ -85,7 +85,7 @@ private static ErrorInfo errorInfo(HttpServletRequest request, Throwable e) {

@ExceptionHandler(PersistenceException.class)
public ResponseEntity<ErrorInfo> persistenceException(HttpServletRequest request, PersistenceException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e.getCause()), HttpStatus.INTERNAL_SERVER_ERROR);
}

Expand All @@ -97,7 +97,7 @@ public ResponseEntity<ErrorInfo> jopaException(HttpServletRequest request, OWLPe

@ExceptionHandler(ResourceExistsException.class)
public ResponseEntity<ErrorInfo> resourceExistsException(HttpServletRequest request, ResourceExistsException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.CONFLICT);
}

Expand All @@ -115,40 +115,40 @@ public ResponseEntity<ErrorInfo> usernameNotFound(HttpServletRequest request, Us

@ExceptionHandler(AuthorizationException.class)
public ResponseEntity<ErrorInfo> authorizationException(HttpServletRequest request, AuthorizationException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.FORBIDDEN);
}

@ExceptionHandler(ValidationException.class)
public ResponseEntity<ErrorInfo> validationException(HttpServletRequest request, ValidationException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.CONFLICT);
}

@ExceptionHandler(WebServiceIntegrationException.class)
public ResponseEntity<ErrorInfo> webServiceIntegrationException(HttpServletRequest request,
WebServiceIntegrationException e) {
logException(e.getCause());
logException(e.getCause(), request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(AnnotationGenerationException.class)
public ResponseEntity<ErrorInfo> annotationGenerationException(HttpServletRequest request,
AnnotationGenerationException e) {
logException(e.getCause());
logException(e.getCause(), request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(TermItException.class)
public ResponseEntity<ErrorInfo> termItException(HttpServletRequest request,
TermItException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(JsonLdException.class)
public ResponseEntity<ErrorInfo> jsonLdException(HttpServletRequest request, JsonLdException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(
ErrorInfo.createWithMessage("Error when processing JSON-LD.", request.getRequestURI()),
HttpStatus.INTERNAL_SERVER_ERROR);
Expand All @@ -157,14 +157,14 @@ public ResponseEntity<ErrorInfo> jsonLdException(HttpServletRequest request, Jso
@ExceptionHandler(UnsupportedOperationException.class)
public ResponseEntity<ErrorInfo> unsupportedAssetOperationException(HttpServletRequest request,
UnsupportedOperationException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.CONFLICT);
}

@ExceptionHandler(VocabularyImportException.class)
public ResponseEntity<ErrorInfo> vocabularyImportException(HttpServletRequest request,
VocabularyImportException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(
ErrorInfo.createWithMessageAndMessageId(e.getMessage(), e.getMessageId(), request.getRequestURI()),
HttpStatus.CONFLICT);
Expand All @@ -173,26 +173,26 @@ public ResponseEntity<ErrorInfo> vocabularyImportException(HttpServletRequest re
@ExceptionHandler
public ResponseEntity<ErrorInfo> unsupportedImportMediaTypeException(HttpServletRequest request,
UnsupportedImportMediaTypeException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.UNSUPPORTED_MEDIA_TYPE);
}

@ExceptionHandler
public ResponseEntity<ErrorInfo> assetRemovalException(HttpServletRequest request, AssetRemovalException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.CONFLICT);
}

@ExceptionHandler
public ResponseEntity<ErrorInfo> invalidParameter(HttpServletRequest request, InvalidParameterException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.UNPROCESSABLE_ENTITY);
}

@ExceptionHandler
public ResponseEntity<ErrorInfo> maxUploadSizeExceededException(HttpServletRequest request,
MaxUploadSizeExceededException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(ErrorInfo.createWithMessageAndMessageId(
e.getMessage(),
"error.file.maxUploadSizeExceeded", request.getRequestURI()), HttpStatus.BAD_REQUEST);
Expand All @@ -201,29 +201,29 @@ public ResponseEntity<ErrorInfo> maxUploadSizeExceededException(HttpServletReque
@ExceptionHandler
public ResponseEntity<ErrorInfo> snapshotNotEditableException(HttpServletRequest request,
SnapshotNotEditableException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(ErrorInfo.createWithMessage(e.getMessage(), request.getRequestURI()),
HttpStatus.CONFLICT);
HttpStatus.CONFLICT);
}

@ExceptionHandler
public ResponseEntity<ErrorInfo> unsupportedSearchFacetException(HttpServletRequest request,
UnsupportedSearchFacetException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.BAD_REQUEST);
}

@ExceptionHandler
public ResponseEntity<ErrorInfo> invalidLanguageConstantException(HttpServletRequest request,
InvalidLanguageConstantException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(errorInfo(request, e), HttpStatus.BAD_REQUEST);
}

@ExceptionHandler
public ResponseEntity<ErrorInfo> vocabularyImportException(HttpServletRequest request,
InvalidTermStateException e) {
logException(e);
logException(e, request);
return new ResponseEntity<>(
ErrorInfo.createWithMessageAndMessageId(e.getMessage(), e.getMessageId(), request.getRequestURI()),
HttpStatus.CONFLICT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public static String normalize(String value) {
return value.toLowerCase()
.trim()
.replaceAll("[\\s/\\\\]", Character.toString(REPLACEMENT_CHARACTER))
.replaceAll("[(?&),]", "");
.replaceAll("[(?&$#),]", "");
}

/**
Expand Down Expand Up @@ -169,7 +169,7 @@ public URI generateDerivedIdentifier(URI baseUri, String namespaceSeparator, Str

/**
* Generates a synthetic identifier using the specified base URL.
*
* <p>
* This particular implementation uses the current system time in millis to generate the locally unique part of the identifier.
*
* @param base URL base
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,20 @@ private ReadOnlyTerm create(final Term term) {

public List<ReadOnlyTerm> findSubTerms(ReadOnlyTerm parent) {
Objects.requireNonNull(parent);
final Term arg = new Term(parent.getUri());
final Term arg = toTerm(parent);
if (parent.getSubTerms() != null) {
arg.setSubTerms(parent.getSubTerms());
}
return termService.findSubTerms(arg).stream().map(this::create).collect(Collectors.toList());
}

private static Term toTerm(ReadOnlyTerm roTerm) {
final Term t = new Term(roTerm.getUri());
// Ensure vocabulary is set on the Term instance as it may be referenced later
t.setVocabulary(roTerm.getVocabulary());
return t;
}

/**
* Gets comments related to the specified term created in the specified time interval.
*
Expand Down Expand Up @@ -132,13 +139,13 @@ public List<TermOccurrence> getDefinitionallyRelatedTargeting(Term instance) {

public List<Snapshot> findSnapshots(ReadOnlyTerm asset) {
Objects.requireNonNull(asset);
final Term arg = new Term(asset.getUri());
final Term arg = toTerm(asset);
return termService.findSnapshots(arg);
}

public ReadOnlyTerm findVersionValidAt(ReadOnlyTerm asset, Instant at) {
Objects.requireNonNull(asset);
final Term arg = new Term(asset.getUri());
final Term arg = toTerm(asset);
return create(termService.findVersionValidAt(arg, at));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ public Collection<UpdateChangeRecord> calculateChanges(Asset<?> changed, Asset<?
final Object updateValue = EntityPropertiesUtils.getAttributeValue(att, changed);
if (att.isAssociation()) {
final Optional<UpdateChangeRecord> change = resolveAssociationChange(originalValue, updateValue, att,
original.getUri());
original.getUri());
change.ifPresent(records::add);

} else if (!Objects.equals(originalValue, updateValue)) {
} else if (!areEqual(att, originalValue, updateValue)) {
final UpdateChangeRecord record = createChangeRecord(original.getUri(), att.getIRI().toURI());
recordValues(record, att, originalValue, updateValue);
records.add(record);
Expand All @@ -78,6 +78,11 @@ private boolean shouldIgnoreChanges(Attribute<?, ?> att) {
return att.getJavaField().isAnnotationPresent(IgnoreChanges.class);
}

private boolean areEqual(Attribute<?, ?> att, Object originalValue, Object newValue) {
return att.isCollection() ? areCollectionsEqual((Collection<?>) originalValue, (Collection<?>) newValue) :
Objects.equals(originalValue, newValue);
}

private void recordValues(UpdateChangeRecord record, Attribute<?, ?> att, Object originalValue, Object newValue) {
if (!att.isCollection()) {
if (originalValue != null) {
Expand Down Expand Up @@ -120,7 +125,7 @@ private Optional<UpdateChangeRecord> resolveAssociationChange(Object originalVal
updateToCompare = updateValue != null ? getIdentifier(updateValue, metamodel) : null;
}

if (Objects.equals(originalToCompare, updateToCompare)) {
if (areEqual(att, originalToCompare, updateToCompare)) {
return Optional.empty();
} else {
final UpdateChangeRecord record = createChangeRecord(assetId, att.getIRI().toURI());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ private Class<T> resolveGenericType() {
// Adapted from https://gist.github.com/yunspace/930d4d40a787a1f6a7d1
final List<ResolvedType> typeParameters =
new TypeResolver().resolve(this.getClass()).typeParametersFor(BaseRepositoryService.class);
assert typeParameters.size() >= 1;
assert !typeParameters.isEmpty();
return (Class<T>) typeParameters.get(0).getErasedType();
}

Expand Down Expand Up @@ -230,10 +230,9 @@ protected void preUpdate(@NonNull T instance) {
}

/**
* Override this method to plug custom behavior into the transactional cycle of {@link #update(HasIdentifier)} )}.
* Override this method to plug custom behavior into the transactional cycle of {@link #update(HasIdentifier)}.
*
* @param instance The updated instance which will be returned by {@link #update(HasIdentifier)} )}, not {@code
* null}
* @param instance The updated instance which will be returned by {@link #update(HasIdentifier)}, not {@code null}
*/
protected void postUpdate(@NonNull T instance) {
// Do nothing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import cz.cvut.kbss.termit.persistence.dao.TermOccurrenceDao;
import cz.cvut.kbss.termit.service.IdentifierResolver;
import cz.cvut.kbss.termit.util.Configuration;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -72,7 +73,7 @@ protected Resource mapToDto(Resource entity) {
}

@Override
protected void prePersist(Resource instance) {
protected void prePersist(@NotNull Resource instance) {
super.prePersist(instance);
if (instance.getUri() == null) {
instance.setUri(idResolver.generateIdentifier(cfgNamespace.getResource(), instance.getLabel()));
Expand All @@ -97,17 +98,16 @@ public void persist(Resource resource, Vocabulary vocabulary) {
}

@Override
protected void preRemove(Resource instance) {
protected void preRemove(@NotNull Resource instance) {
LOG.trace("Removing term occurrences in resource {} which is about to be removed.", instance);
termOccurrenceDao.removeAll(instance);
removeFromParentDocumentIfFile(instance);
}

private void removeFromParentDocumentIfFile(Resource instance) {
if (!(instance instanceof File)) {
if (!(instance instanceof File file)) {
return;
}
final File file = (File) instance;
final Document parent = file.getDocument();
if (parent != null) {
LOG.trace("Removing file {} from its parent document {}.", instance, parent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ private void pruneEmptyTranslations(Term instance) {
}

@Override
protected void postUpdate(Term instance) {
protected void postUpdate(@NotNull Term instance) {
final Vocabulary vocabulary = vocabularyService.getRequiredReference(instance.getVocabulary());
if (instance.hasParentInSameVocabulary()) {
vocabulary.getGlossary().removeRootTerm(instance);
Expand Down Expand Up @@ -427,7 +427,7 @@ protected void preRemove(@NotNull Term instance) {
}

@Override
protected void postRemove(Term instance) {
protected void postRemove(@NotNull Term instance) {
super.postRemove(instance);
if (!instance.hasParentInSameVocabulary()) {
final Vocabulary v = vocabularyService.findRequired(instance.getVocabulary());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import cz.cvut.kbss.termit.persistence.dao.UserAccountDao;
import cz.cvut.kbss.termit.service.IdentifierResolver;
import cz.cvut.kbss.termit.util.Configuration;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -72,13 +73,13 @@ protected UserAccount mapToDto(UserAccount entity) {
}

@Override
protected UserAccount postLoad(UserAccount instance) {
protected UserAccount postLoad(@NotNull UserAccount instance) {
instance.erasePassword();
return instance;
}

@Override
protected void prePersist(UserAccount instance) {
protected void prePersist(@NotNull UserAccount instance) {
super.prePersist(instance);
if (instance.getUri() == null) {
instance.setUri(idResolver
Expand All @@ -90,7 +91,7 @@ protected void prePersist(UserAccount instance) {
}

@Override
protected void preUpdate(UserAccount instance) {
protected void preUpdate(@NotNull UserAccount instance) {
final UserAccount original = userAccountDao.find(instance.getUri()).orElseThrow(
() -> new NotFoundException("User " + instance + " does not exist."));
if (instance.getPassword() != null) {
Expand Down
Loading

0 comments on commit 6be4c40

Please sign in to comment.