Add parsed text to publication entities.
This commit is contained in:
@@ -8,6 +8,7 @@ public record Publication(
|
|||||||
String key,
|
String key,
|
||||||
String title,
|
String title,
|
||||||
String text,
|
String text,
|
||||||
|
String parsedText,
|
||||||
String description,
|
String description,
|
||||||
ZonedDateTime creationDate,
|
ZonedDateTime creationDate,
|
||||||
UUID illustrationId,
|
UUID illustrationId,
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package org.codiki.domain.publication.model.builder;
|
package org.codiki.domain.publication.model.builder;
|
||||||
|
|
||||||
|
import org.codiki.domain.publication.model.Author;
|
||||||
|
import org.codiki.domain.publication.model.Publication;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.codiki.domain.category.model.Category;
|
|
||||||
import org.codiki.domain.publication.model.Author;
|
|
||||||
import org.codiki.domain.publication.model.Publication;
|
|
||||||
|
|
||||||
public class PublicationBuilder {
|
public class PublicationBuilder {
|
||||||
private UUID id;
|
private UUID id;
|
||||||
private String key;
|
private String key;
|
||||||
private String title;
|
private String title;
|
||||||
private String text;
|
private String text;
|
||||||
|
private String parsedText;
|
||||||
private String description;
|
private String description;
|
||||||
private ZonedDateTime creationDate;
|
private ZonedDateTime creationDate;
|
||||||
private UUID illustrationId;
|
private UUID illustrationId;
|
||||||
@@ -30,6 +30,7 @@ public class PublicationBuilder {
|
|||||||
.withKey(publication.key())
|
.withKey(publication.key())
|
||||||
.withTitle(publication.title())
|
.withTitle(publication.title())
|
||||||
.withText(publication.text())
|
.withText(publication.text())
|
||||||
|
.withParsedText(publication.parsedText())
|
||||||
.withDescription(publication.description())
|
.withDescription(publication.description())
|
||||||
.withCreationDate(publication.creationDate())
|
.withCreationDate(publication.creationDate())
|
||||||
.withIllustrationId(publication.illustrationId())
|
.withIllustrationId(publication.illustrationId())
|
||||||
@@ -57,6 +58,11 @@ public class PublicationBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PublicationBuilder withParsedText(String parsedText) {
|
||||||
|
this.parsedText = parsedText;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public PublicationBuilder withDescription(String description) {
|
public PublicationBuilder withDescription(String description) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
return this;
|
return this;
|
||||||
@@ -88,6 +94,7 @@ public class PublicationBuilder {
|
|||||||
key,
|
key,
|
||||||
title,
|
title,
|
||||||
text,
|
text,
|
||||||
|
parsedText,
|
||||||
description,
|
description,
|
||||||
creationDate,
|
creationDate,
|
||||||
illustrationId,
|
illustrationId,
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package org.codiki.exposition.publication.model;
|
package org.codiki.exposition.publication.model;
|
||||||
|
|
||||||
|
import org.codiki.domain.publication.model.Publication;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.codiki.domain.publication.model.Publication;
|
|
||||||
import org.codiki.exposition.category.model.CategoryDto;
|
|
||||||
|
|
||||||
public record PublicationDto(
|
public record PublicationDto(
|
||||||
UUID id,
|
UUID id,
|
||||||
String key,
|
String key,
|
||||||
String title,
|
String title,
|
||||||
String text,
|
String text,
|
||||||
|
String parsedText,
|
||||||
String description,
|
String description,
|
||||||
ZonedDateTime creationDate,
|
ZonedDateTime creationDate,
|
||||||
UUID illustrationId,
|
UUID illustrationId,
|
||||||
@@ -23,6 +23,7 @@ public record PublicationDto(
|
|||||||
publication.key(),
|
publication.key(),
|
||||||
publication.title(),
|
publication.title(),
|
||||||
publication.text(),
|
publication.text(),
|
||||||
|
publication.parsedText(),
|
||||||
publication.description(),
|
publication.description(),
|
||||||
publication.creationDate(),
|
publication.creationDate(),
|
||||||
publication.illustrationId(),
|
publication.illustrationId(),
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
package org.codiki.infrastructure.publication;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ParserService {
|
||||||
|
private static final String REG_CODE = "\\[code lg="([a-z]+)"\\](.*)\\[\\/code\\]\\n";
|
||||||
|
private static final String REG_IMAGES = "\\[img src="([^\"| ]+)"( alt="([^\"| ]+)")? \\/\\]";
|
||||||
|
private static final String REG_LINKS = "\\[link href="([^\"| ]+)" txt="([^\"| ]+)" \\/\\]";
|
||||||
|
|
||||||
|
private static final Pattern PATTERN_CODE;
|
||||||
|
private static final Pattern PATTERN_IMAGES;
|
||||||
|
private static final Pattern PATTERN_LINKS;
|
||||||
|
|
||||||
|
static {
|
||||||
|
PATTERN_CODE = Pattern.compile(REG_CODE);
|
||||||
|
PATTERN_IMAGES = Pattern.compile(REG_IMAGES);
|
||||||
|
PATTERN_LINKS = Pattern.compile(REG_LINKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String parse(String pSource) {
|
||||||
|
return unParseDolars(parseCode(parseHeaders(parseImages(parseLinks(parseBackSpaces(escapeHtml4(parseDolars(pSource))))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String parseDolars(final String pSource) {
|
||||||
|
return pSource.replace("$", "£ø");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String unParseDolars(final String pSource) {
|
||||||
|
return pSource.replace("£ø", "$");
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseHeaders(final String pSource) {
|
||||||
|
String result = pSource;
|
||||||
|
for(int i = 1 ; i <= 3 ; i++) {
|
||||||
|
result = parseHeadersHX(result, i);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseHeadersHX(final String pSource, final int pNumHeader) {
|
||||||
|
String result = pSource;
|
||||||
|
|
||||||
|
// (.*)(\[hX\](.*)\[\/hX\])+(.*)
|
||||||
|
final String regex = concat("(.*)(\\[h", pNumHeader, "\\](.*)\\[\\/h", pNumHeader, "\\])+(.*)");
|
||||||
|
|
||||||
|
final Pattern pattern = Pattern.compile(regex);
|
||||||
|
|
||||||
|
Matcher matcher = pattern.matcher(result);
|
||||||
|
|
||||||
|
while(matcher.find()) {
|
||||||
|
// \1<hX>\3</hX>\4
|
||||||
|
result = matcher.replaceFirst(concat(matcher.group(1),
|
||||||
|
"<h", pNumHeader, ">", matcher.group(3), "</h", pNumHeader, ">", matcher.group(4)));
|
||||||
|
matcher = pattern.matcher(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseBackSpaces(final String pSource) {
|
||||||
|
return pSource.replaceAll("\r?\n", "<br/>").replaceAll("\\[\\/code\\]<br\\/><br\\/>", "[/code]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseImages(final String pSource) {
|
||||||
|
String result = pSource;
|
||||||
|
|
||||||
|
Matcher matcher = PATTERN_IMAGES.matcher(result);
|
||||||
|
|
||||||
|
while(matcher.find()) {
|
||||||
|
String altStr = matcher.group(3);
|
||||||
|
|
||||||
|
if(altStr == null) {
|
||||||
|
altStr = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
result = matcher.replaceFirst(concat("<img src=\"", matcher.group(1), "\" alt=\"", altStr, "\" />"));
|
||||||
|
matcher = PATTERN_IMAGES.matcher(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
String parseLinks(final String pSource) {
|
||||||
|
String result = pSource;
|
||||||
|
|
||||||
|
Matcher matcher = PATTERN_LINKS.matcher(result);
|
||||||
|
|
||||||
|
while(matcher.find()) {
|
||||||
|
result = matcher.replaceFirst(concat("<a href=\"", matcher.group(1), "\">", matcher.group(2), "</a>"));
|
||||||
|
matcher = PATTERN_LINKS.matcher(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String parseCode(final String pSource) {
|
||||||
|
String result = pSource;
|
||||||
|
|
||||||
|
Matcher matcher = PATTERN_CODE.matcher(result);
|
||||||
|
|
||||||
|
while(matcher.find()) {
|
||||||
|
// replace the '<br/>' in group by '\n'
|
||||||
|
String codeContent = matcher.group(2).replaceAll("<br\\/>", "\n");
|
||||||
|
if(codeContent.startsWith("\n")) {
|
||||||
|
codeContent = codeContent.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = matcher.replaceFirst(
|
||||||
|
concat(
|
||||||
|
"<pre class=\"line-numbers\"><code class=\"language-",
|
||||||
|
matcher.group(1),
|
||||||
|
"\">",
|
||||||
|
codeContent,
|
||||||
|
"</code></pre>"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
matcher = PATTERN_CODE.matcher(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Concatenate the parameters to form just one single string.
|
||||||
|
*
|
||||||
|
* @param pArgs
|
||||||
|
* The strings to concatenate.
|
||||||
|
* @return The parameters concatenated.
|
||||||
|
*/
|
||||||
|
private static String concat(final Object... pArgs) {
|
||||||
|
final StringBuilder result = new StringBuilder();
|
||||||
|
for (final Object arg : pArgs) {
|
||||||
|
result.append(arg);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,5 @@
|
|||||||
package org.codiki.infrastructure.publication;
|
package org.codiki.infrastructure.publication;
|
||||||
|
|
||||||
import static java.util.Collections.reverseOrder;
|
|
||||||
import static java.util.Comparator.comparingInt;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.codiki.domain.publication.model.Publication;
|
import org.codiki.domain.publication.model.Publication;
|
||||||
import org.codiki.domain.publication.model.search.PublicationSearchCriterion;
|
import org.codiki.domain.publication.model.search.PublicationSearchCriterion;
|
||||||
import org.codiki.domain.publication.port.PublicationPort;
|
import org.codiki.domain.publication.port.PublicationPort;
|
||||||
@@ -14,17 +8,29 @@ import org.codiki.infrastructure.publication.model.PublicationSearchResult;
|
|||||||
import org.codiki.infrastructure.publication.repository.PublicationRepository;
|
import org.codiki.infrastructure.publication.repository.PublicationRepository;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static java.util.Collections.reverseOrder;
|
||||||
|
import static java.util.Comparator.comparingInt;
|
||||||
|
import static org.codiki.domain.publication.model.builder.PublicationBuilder.aPublication;
|
||||||
|
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class PublicationJpaAdapter implements PublicationPort {
|
public class PublicationJpaAdapter implements PublicationPort {
|
||||||
private final PublicationRepository repository;
|
private final PublicationRepository repository;
|
||||||
private final PublicationSearchCriteriaJpaAdapter publicationSearchCriteriaJpaAdapter;
|
private final PublicationSearchCriteriaJpaAdapter publicationSearchCriteriaJpaAdapter;
|
||||||
|
private final ParserService parserService;
|
||||||
|
|
||||||
public PublicationJpaAdapter(
|
public PublicationJpaAdapter(
|
||||||
PublicationRepository repository,
|
PublicationRepository repository,
|
||||||
PublicationSearchCriteriaJpaAdapter publicationSearchCriteriaJpaAdapter
|
PublicationSearchCriteriaJpaAdapter publicationSearchCriteriaJpaAdapter,
|
||||||
|
ParserService parserService
|
||||||
) {
|
) {
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
this.publicationSearchCriteriaJpaAdapter = publicationSearchCriteriaJpaAdapter;
|
this.publicationSearchCriteriaJpaAdapter = publicationSearchCriteriaJpaAdapter;
|
||||||
|
this.parserService = parserService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -35,8 +41,24 @@ public class PublicationJpaAdapter implements PublicationPort {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Publication> findById(UUID publicationId) {
|
public Optional<Publication> findById(UUID publicationId) {
|
||||||
return repository.findById(publicationId)
|
Optional<Publication> result = repository.findById(publicationId)
|
||||||
.map(PublicationEntity::toDomain);
|
.map(PublicationEntity::toDomain);
|
||||||
|
|
||||||
|
if (result.isPresent()) {
|
||||||
|
Publication publication = result.get();
|
||||||
|
if (isEmpty(publication.parsedText())) {
|
||||||
|
Publication editedPublication = aPublication()
|
||||||
|
.basedOn(publication)
|
||||||
|
.withParsedText(parserService.parse(publication.text()))
|
||||||
|
.build();
|
||||||
|
PublicationEntity editedPublicationEntity = new PublicationEntity(editedPublication);
|
||||||
|
repository.save(editedPublicationEntity);
|
||||||
|
|
||||||
|
result = Optional.of(editedPublication);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,22 +1,16 @@
|
|||||||
package org.codiki.infrastructure.publication.model;
|
package org.codiki.infrastructure.publication.model;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import jakarta.persistence.*;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.codiki.domain.publication.model.Publication;
|
|
||||||
import org.codiki.infrastructure.category.model.CategoryEntity;
|
|
||||||
|
|
||||||
import static jakarta.persistence.FetchType.LAZY;
|
|
||||||
import jakarta.persistence.Column;
|
|
||||||
import jakarta.persistence.Entity;
|
|
||||||
import jakarta.persistence.Id;
|
|
||||||
import jakarta.persistence.JoinColumn;
|
|
||||||
import jakarta.persistence.ManyToOne;
|
|
||||||
import jakarta.persistence.Table;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.codiki.domain.publication.model.Publication;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static jakarta.persistence.FetchType.LAZY;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "publication")
|
@Table(name = "publication")
|
||||||
@@ -34,6 +28,8 @@ public class PublicationEntity {
|
|||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String text;
|
private String text;
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
|
private String parsedText;
|
||||||
|
@Column(nullable = false)
|
||||||
private String description;
|
private String description;
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private ZonedDateTime creationDate;
|
private ZonedDateTime creationDate;
|
||||||
@@ -51,6 +47,7 @@ public class PublicationEntity {
|
|||||||
publication.key(),
|
publication.key(),
|
||||||
publication.title(),
|
publication.title(),
|
||||||
publication.text(),
|
publication.text(),
|
||||||
|
publication.parsedText(),
|
||||||
publication.description(),
|
publication.description(),
|
||||||
publication.creationDate(),
|
publication.creationDate(),
|
||||||
publication.illustrationId(),
|
publication.illustrationId(),
|
||||||
@@ -65,6 +62,7 @@ public class PublicationEntity {
|
|||||||
key,
|
key,
|
||||||
title,
|
title,
|
||||||
text,
|
text,
|
||||||
|
parsedText,
|
||||||
description,
|
description,
|
||||||
creationDate,
|
creationDate,
|
||||||
illustrationId,
|
illustrationId,
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ CREATE TABLE IF NOT EXISTS publication (
|
|||||||
key VARCHAR(14) NOT NULL,
|
key VARCHAR(14) NOT NULL,
|
||||||
title VARCHAR NOT NULL,
|
title VARCHAR NOT NULL,
|
||||||
text VARCHAR NOT NULL,
|
text VARCHAR NOT NULL,
|
||||||
|
parsed_text VARCHAR,
|
||||||
description VARCHAR NOT NULL,
|
description VARCHAR NOT NULL,
|
||||||
creation_date TIMESTAMP NOT NULL,
|
creation_date TIMESTAMP NOT NULL,
|
||||||
illustration_id UUID NOT NULL,
|
illustration_id UUID NOT NULL,
|
||||||
|
|||||||
Reference in New Issue
Block a user