Refactor publication parser location.
This commit is contained in:
@@ -33,6 +33,10 @@
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
package org.codiki.application.publication;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.apache.commons.text.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();
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ import java.util.UUID;
|
||||
|
||||
import static org.codiki.domain.publication.model.builder.AuthorBuilder.anAuthor;
|
||||
import static org.codiki.domain.publication.model.builder.PublicationBuilder.aPublication;
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
|
||||
import org.codiki.application.category.CategoryUseCases;
|
||||
import org.codiki.application.picture.PictureUseCases;
|
||||
import org.codiki.application.user.UserUseCases;
|
||||
@@ -31,6 +33,7 @@ public class PublicationUseCases {
|
||||
private final CategoryUseCases categoryUseCases;
|
||||
private final Clock clock;
|
||||
private final KeyGenerator keyGenerator;
|
||||
private final ParserService parserService;
|
||||
private final PictureUseCases pictureUseCases;
|
||||
private final PublicationCreationRequestValidator publicationCreationRequestValidator;
|
||||
private final PublicationPort publicationPort;
|
||||
@@ -39,19 +42,21 @@ public class PublicationUseCases {
|
||||
private final UserUseCases userUseCases;
|
||||
|
||||
public PublicationUseCases(
|
||||
CategoryUseCases categoryUseCases,
|
||||
Clock clock,
|
||||
KeyGenerator keyGenerator,
|
||||
PictureUseCases pictureUseCases,
|
||||
PublicationCreationRequestValidator publicationCreationRequestValidator,
|
||||
PublicationPort publicationPort,
|
||||
PublicationSearchCriteriaFactory publicationSearchCriteriaFactory,
|
||||
PublicationUpdateRequestValidator publicationUpdateRequestValidator,
|
||||
UserUseCases userUseCases
|
||||
CategoryUseCases categoryUseCases,
|
||||
Clock clock,
|
||||
KeyGenerator keyGenerator,
|
||||
ParserService parserService,
|
||||
PictureUseCases pictureUseCases,
|
||||
PublicationCreationRequestValidator publicationCreationRequestValidator,
|
||||
PublicationPort publicationPort,
|
||||
PublicationSearchCriteriaFactory publicationSearchCriteriaFactory,
|
||||
PublicationUpdateRequestValidator publicationUpdateRequestValidator,
|
||||
UserUseCases userUseCases
|
||||
) {
|
||||
this.categoryUseCases = categoryUseCases;
|
||||
this.clock = clock;
|
||||
this.keyGenerator = keyGenerator;
|
||||
this.parserService = parserService;
|
||||
this.publicationCreationRequestValidator = publicationCreationRequestValidator;
|
||||
this.publicationPort = publicationPort;
|
||||
this.publicationUpdateRequestValidator = publicationUpdateRequestValidator;
|
||||
@@ -83,6 +88,7 @@ public class PublicationUseCases {
|
||||
.withKey(keyGenerator.generateKey())
|
||||
.withTitle(request.title())
|
||||
.withText(request.text())
|
||||
.withParsedText(parserService.parse(request.text()))
|
||||
.withDescription(request.description())
|
||||
.withCreationDate(ZonedDateTime.now(clock))
|
||||
.withIllustrationId(request.illustrationId())
|
||||
@@ -116,6 +122,7 @@ public class PublicationUseCases {
|
||||
|
||||
if (!isNull(request.text())) {
|
||||
publicationBuilder.withText(request.text());
|
||||
publicationBuilder.withParsedText(parserService.parse(request.text()));
|
||||
}
|
||||
|
||||
if (!isNull(request.description())) {
|
||||
@@ -163,7 +170,19 @@ public class PublicationUseCases {
|
||||
}
|
||||
|
||||
public Optional<Publication> findById(UUID publicationId) {
|
||||
return publicationPort.findById(publicationId);
|
||||
return publicationPort.findById(publicationId)
|
||||
.map(publication -> {
|
||||
Publication result = publication;
|
||||
if (isEmpty(publication.parsedText())) {
|
||||
Publication editedPublication = aPublication()
|
||||
.basedOn(publication)
|
||||
.withParsedText(parserService.parse(publication.text()))
|
||||
.build();
|
||||
publicationPort.save(editedPublication);
|
||||
result = editedPublication;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
public List<Publication> searchPublications(String searchQuery) {
|
||||
|
||||
Reference in New Issue
Block a user