Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 21-oidc-refactor-2
  • 21-se-connecter-avec-agent-connect
  • 25-ci-cd-ne-pas-declencher-la-pipeline-sur-les-mr-en-brouillons
  • 390-analyse-du-sitemap
  • ga21-se-connecter-avec-agentconnect
  • main
  • main_backup
  • 0.1.0
  • 0.2.0
  • 0.3.0
  • 0.4.0
  • 0.4.1
  • 0.4.2
  • 0.4.6
  • 1.0.0
  • 1.0.1
  • 2.0.0
  • 2.0.1
  • 2.0.2
  • 2.1.0
  • 2.1.1
  • 2.1.10
  • 2.1.11
  • 2.1.12
  • 2.1.2
  • 2.1.3
  • 2.1.4
  • 2.1.5
  • 2.1.6
  • 2.1.7
  • 2.1.8
  • 2.1.9
  • 2.2.0
  • 2.2.1
  • 2.2.2
  • 2.2.3
  • 2.2.4
  • 2.2.5
  • 2.2.6
  • 2.2.7
40 results

Target

Select target project
  • pub/numeco/misis/misis-backend
1 result
Select Git revision
  • 21-oidc-refactor-2
  • 21-se-connecter-avec-agent-connect
  • 25-ci-cd-ne-pas-declencher-la-pipeline-sur-les-mr-en-brouillons
  • 390-analyse-du-sitemap
  • ga21-se-connecter-avec-agentconnect
  • main
  • main_backup
  • 0.1.0
  • 0.2.0
  • 0.3.0
  • 0.4.0
  • 0.4.1
  • 0.4.2
  • 0.4.6
  • 1.0.0
  • 1.0.1
  • 2.0.0
  • 2.0.1
  • 2.0.2
  • 2.1.0
  • 2.1.1
  • 2.1.10
  • 2.1.11
  • 2.1.12
  • 2.1.2
  • 2.1.3
  • 2.1.4
  • 2.1.5
  • 2.1.6
  • 2.1.7
  • 2.1.8
  • 2.1.9
  • 2.2.0
  • 2.2.1
  • 2.2.2
  • 2.2.3
  • 2.2.4
  • 2.2.5
  • 2.2.6
  • 2.2.7
40 results
Show changes
Commits on Source (11)
Showing
with 407 additions and 39 deletions
......@@ -2,6 +2,10 @@ package fr.numeco.analyser.service;
import fr.numeco.analyser.AnalyzerConfig;
import fr.numeco.misis.analyzer.service.AnalyserService;
import fr.numeco.misis.enums.AnalyseStatut;
import fr.numeco.misis.sitemap.service.SitemapService;
import fr.numeco.misis.suividesite.domain.Page;
import io.quarkus.logging.Log;
import io.quarkus.scheduler.Scheduled;
import static io.quarkus.scheduler.Scheduled.ConcurrentExecution.SKIP;
import io.quarkus.scheduler.ScheduledExecution;
......@@ -12,12 +16,35 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class AnalysisScheduler {
private final SitemapService sitemapService;
private final AnalyserService analyserService;
private final AnalyzerConfig analyzerConfig;
@Scheduled(identity = "AnalysisScheduler", cron = "{analyser.refresh.schedule.cron.expression}", concurrentExecution = SKIP, skipExecutionIf = AnalyserService.class)
void scheduleGroupesDePagesAnalysis(final ScheduledExecution execution) {
analyserService.process(0, analyzerConfig.paginationSize()-1);
sitemapService.process()
.subscribe().with(
this::log,
failure -> Log.error("Sitemap error", failure),
() -> {
analyserService.process(0, analyzerConfig.paginationSize()-1);
if(Log.isDebugEnabled()) {
Log.debug("Flux completed");
}
}
)
;
}
private void log(Page page) {
if(Log.isDebugEnabled()) {
if (page.getAnalyseStatut() == AnalyseStatut.NOUVEAU) {
Log.debugf("Page %s créée par le sitemap.", page.getUrl());
} else {
Log.debugf("Page %s mise à jour par le sitemap.", page.getId());
}
}
}
}
package fr.numeco.analyser.service;
import java.util.List;
import fr.numeco.misis.statistic.service.StatisticService;
import fr.numeco.misis.suividesite.domain.GroupeDePages;
import fr.numeco.misis.suividesite.repository.GroupeDePagesRepository;
......@@ -9,8 +11,6 @@ import io.quarkus.scheduler.ScheduledExecution;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.RequiredArgsConstructor;
import java.util.List;
@ApplicationScoped
@RequiredArgsConstructor
public class StatsScheduler {
......@@ -24,10 +24,11 @@ public class StatsScheduler {
@Scheduled(cron = "{stats.refresh.schedule.cron.expression}")
void scheduleCreationOfPageGroupStatistics(ScheduledExecution execution) {
Log.info(SCHEDULER_START);
final List<GroupeDePages> groupesDePages = groupeDePagesRepository.findGroupsAnalysedForHistorization();
if (!groupesDePages.isEmpty()) {
Log.info(SCHEDULER_START);
}
for (GroupeDePages groupeDePages : groupesDePages) {
statisticService.createStatistics(groupeDePages);
......@@ -40,7 +41,9 @@ public class StatsScheduler {
);
}
Log.info(SCHEDULER_END);
if (!groupesDePages.isEmpty()) {
Log.info(SCHEDULER_END);
}
}
}
package fr.numeco.misis.analyzer.resource;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import fr.numeco.misis.analyzer.service.AnalyserService;
import io.quarkus.panache.common.Page;
import jakarta.ws.rs.GET;
......@@ -9,8 +12,6 @@ import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import lombok.RequiredArgsConstructor;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
@Path("api/analyser")
@RequiredArgsConstructor
......
package fr.numeco.misis.analyzer.service;
import java.util.Map;
import fr.numeco.misis.analyzer.dto.PageDto;
import fr.numeco.misis.analyzer.dto.RessourceDto;
import fr.numeco.misis.suividesite.domain.Page;
import fr.numeco.misis.suividesite.domain.Ressource;
import io.quarkus.scheduler.Scheduled.SkipPredicate;
import java.util.Map;
public interface AnalyserService extends SkipPredicate {
void process(io.quarkus.panache.common.Page pagination);
void process(int startIndex, int lastIndex);
......
......@@ -72,7 +72,9 @@ public class DefaultAnalyserService implements AnalyserService {
} else {
Log.infof("Processing %s page(s)", pageDtos.size());
}
pageRepository.update("analyseStatut=?1 WHERE id IN (?2)", AnalyseStatut.EN_COURS, pagesIds);
if (!pagesIds.isEmpty()) {
pageRepository.update("analyseStatut=?1 WHERE id IN (?2)", AnalyseStatut.EN_COURS, pagesIds);
}
isRunning = Boolean.TRUE;
networkAnalyser.analyse(pageDtos.stream())
.onTermination().invoke(() -> isRunning = Boolean.FALSE)
......
package fr.numeco.misis.enums;
public enum MethodeDeCreationDeGroupe {
MANUELLE
MANUELLE,
AUTOMATIQUE
}
package fr.numeco.misis.enums;
public enum PeriodiciteDuSuivi {
QUOTIDIEN,
QUOTIDIENNE,
HEBDOMADAIRE,
MENSUEL,
MENSUELLE,
}
package fr.numeco.misis.enums;
public enum SitemapMessage {
NUMBER_OF_ITEMS_LIMIT_REACHED,
SERVICE_UNAVAILABLE,
EMPTY_SITEMAP,
SITEMAP_FORMAT_ERROR,
INVALID_SITEMAP
}
package fr.numeco.misis.error;
import fr.numeco.misis.sitemap.exception.SitemapUrlException;
import io.quarkus.logging.Log;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.core.MediaType;
......@@ -34,6 +35,10 @@ public class MisisExceptionHandler implements ExceptionMapper<Exception> {
.entity(errorResponse)
.type(MediaType.APPLICATION_JSON)
.build();
} else if (e instanceof SitemapUrlException) {
return Response
.status(Response.Status.CONFLICT)
.build();
}
Log.error("unhandled exception", e);
......
package fr.numeco.misis.sitemap;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import jakarta.enterprise.context.ApplicationScoped;
public class SitemapConfiguration {
@ApplicationScoped
public DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
documentBuilderFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
return documentBuilderFactory.newDocumentBuilder();
}
}
package fr.numeco.misis.sitemap.dto;
import java.util.Set;
import fr.numeco.misis.enums.SitemapMessage;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@AllArgsConstructor
@Getter @Setter
public class SitemapDto {
private Set<String> urls; //NOSONAR
private Set<SitemapMessage> messages; //NOSONAR
}
package fr.numeco.misis.sitemap.exception;
public class SitemapUrlException extends RuntimeException {
public SitemapUrlException(String message) {
super(message);
}
}
package fr.numeco.misis.sitemap.resource;
import fr.numeco.misis.sitemap.dto.SitemapDto;
import fr.numeco.misis.sitemap.service.SitemapService;
import io.quarkus.security.Authenticated;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import lombok.RequiredArgsConstructor;
@Path("/sitemap")
@RequiredArgsConstructor
@Authenticated
public class SitemapResource {
private final SitemapService sitemapService;
@GET
public SitemapDto getSitemapUrls(@QueryParam("q") String sitemap, @QueryParam("isrecursive") boolean isRecursive) {
return sitemapService.readSitemap(sitemap, true);
}
}
package fr.numeco.misis.sitemap.service;
import fr.numeco.misis.sitemap.dto.SitemapDto;
import fr.numeco.misis.suividesite.domain.Page;
import io.smallrye.mutiny.Multi;
public interface SitemapService {
public SitemapDto readSitemap(String sitemapUrl);
public SitemapDto readSitemap(String sitemapUrl, boolean requireFullResult);
public Multi<Page> process();
}
package fr.numeco.misis.sitemap.service.impl;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import fr.numeco.misis.enums.AnalyseStatut;
import fr.numeco.misis.enums.SitemapMessage;
import fr.numeco.misis.sitemap.dto.SitemapDto;
import fr.numeco.misis.sitemap.exception.SitemapUrlException;
import fr.numeco.misis.sitemap.service.SitemapService;
import fr.numeco.misis.suividesite.domain.GroupeDePages;
import fr.numeco.misis.suividesite.domain.Page;
import fr.numeco.misis.suividesite.dto.PageFormDto;
import fr.numeco.misis.suividesite.repository.GroupeDePagesRepository;
import fr.numeco.misis.suividesite.repository.PageRepository;
import io.quarkus.logging.Log;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.infrastructure.Infrastructure;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
@ApplicationScoped
@Transactional
public class DefaultSitemapService implements SitemapService {
public static final String PAGE_ATTRIBUT_URL = "url";
private static final String SITEMAP_URL_REGEX = "^.*\\.xml(?:/??\\?.+)?";
private static final Pattern SITEMAP_URL_PARTTERN = Pattern.compile(SITEMAP_URL_REGEX, Pattern.CASE_INSENSITIVE);
@Inject
private DocumentBuilder dBuilder;
@Inject
private PageRepository pageRepository;
@Inject
private GroupeDePagesRepository groupeDePagesRepository;
@ConfigProperty(name = "sitemap.size.limit")
private Integer sizeLimit;
public void setGroupeDePagesRepository(final GroupeDePagesRepository groupeDePagesRepository) {
this.groupeDePagesRepository = groupeDePagesRepository;
}
public void setPageRepository(final PageRepository pageRepository) {
this.pageRepository = pageRepository;
}
@Override
public SitemapDto readSitemap(final String sitemapUrl) {
return this.readSitemap(sitemapUrl, false);
}
@Override
public SitemapDto readSitemap(final String sitemapUrl, final boolean requireFullResult) {
final Set<String> urlsExtractedFromSitemap = new LinkedHashSet<>();
Set<SitemapMessage> messages = new LinkedHashSet<>();
if (sitemapUrl == null) {
throw new SitemapUrlException("XML file is missing.");
}
final Matcher xmlMatcher = SITEMAP_URL_PARTTERN.matcher(sitemapUrl);
if (!xmlMatcher.find()) {
throw new SitemapUrlException("Not a XML file.");
}
try {
final Document parsedSitemap = this.dBuilder.parse(sitemapUrl);
parsedSitemap.getDocumentElement().normalize();
final NodeList urlNodeList = parsedSitemap.getElementsByTagName("loc");
final int nodeLength = urlNodeList.getLength();
if (nodeLength == 0) {
messages.add(SitemapMessage.EMPTY_SITEMAP);
}
Log.infof("%s URLs in sitemap %s", nodeLength, sitemapUrl);
for (int i = 0; i < nodeLength; i++) {
if (urlsExtractedFromSitemap.size() == this.sizeLimit) {
messages.add(SitemapMessage.NUMBER_OF_ITEMS_LIMIT_REACHED);
if (!requireFullResult) {
return new SitemapDto(urlsExtractedFromSitemap, messages);
}
}
final Node node = urlNodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE && node instanceof Element urlElement) {
final String url = urlElement.getTextContent();
if (this.isValidUrl(url)) {
urlsExtractedFromSitemap.add(url);
} else {
Log.warnf("invalide url in sitemap %s", url);
}
}
}
} catch (SAXException e) {
messages.add(SitemapMessage.SITEMAP_FORMAT_ERROR);
} catch (IOException e) {
messages.add(SitemapMessage.SERVICE_UNAVAILABLE);
}
return new SitemapDto(urlsExtractedFromSitemap, messages);
}
@Override
public Multi<Page> process() {
final List<GroupeDePages> groupeDePagesSitemap = groupeDePagesRepository.findSitemapGroups();
return Multi.createFrom().items(groupeDePagesSitemap.stream())
.emitOn(Infrastructure.getDefaultExecutor())
.runSubscriptionOn(Infrastructure.getDefaultExecutor())
.onItem().transformToMultiAndMerge(this::createPagesFromSitemap);
}
private Multi<Page> createPagesFromSitemap(final GroupeDePages groupeDePages) {
final List<String> sitemapUrls = this.readSitemap(groupeDePages.getSitemap()).getUrls().stream().toList();
if (sitemapUrls.isEmpty()) {
return Multi.createFrom().empty();
} else {
groupeDePages.setModifiedDate(LocalDate.now());
}
pageRepository.filterOutdatedUrls(sitemapUrls, groupeDePages);
return Multi.createFrom().items(sitemapUrls.stream())
.onItem().transform(value -> new PageFormDto(null, value))
.onItem().transform(value -> this.createPageIfNotExist(value, groupeDePages));
}
private Page createPageIfNotExist(final PageFormDto pageFormDto, final GroupeDePages groupeDePages) {
final Optional<Page> optionalPage = pageRepository.findByUrlAndGroupeDePages(pageFormDto.getUrl(), groupeDePages);
Page page;
if (optionalPage.isPresent()) {
page = optionalPage.get();
} else {
page = new Page();
page.setUrl(pageFormDto.getUrl());
page.setGroupeDePages(groupeDePages);
page.setAnalyseStatut(AnalyseStatut.NOUVEAU);
page.setModifiedAt(LocalDateTime.now());
pageRepository.persist(page);
}
return page;
}
protected boolean isValidUrl(final String url) {
try {
new URI(url).toURL();
return true;
} catch (IllegalArgumentException | URISyntaxException | IOException e) {
return false;
}
}
}
package fr.numeco.misis.suividesite.constraints;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import fr.numeco.misis.suividesite.constraints.validators.MethodeDeCreationDeGroupeValidator;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
@Constraint(validatedBy = MethodeDeCreationDeGroupeValidator.class)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodeDeCreationDeGroupeConstraint {
String message() default "Les champs ne sont pas valides";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
package fr.numeco.misis.suividesite.constraints.validators;
import java.util.Objects;
import fr.numeco.misis.suividesite.constraints.MethodeDeCreationDeGroupeConstraint;
import fr.numeco.misis.suividesite.dto.GroupOfPagesFormDto;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
public class MethodeDeCreationDeGroupeValidator implements ConstraintValidator<MethodeDeCreationDeGroupeConstraint, GroupOfPagesFormDto> {
@Override
public boolean isValid(GroupOfPagesFormDto formDto, ConstraintValidatorContext context) {
return switch(formDto.getMethodeDeCreationDeGroupe()) {
case AUTOMATIQUE -> Objects.nonNull(formDto.getSitemap()) && !formDto.getSitemap().isBlank();
case MANUELLE -> Objects.nonNull(formDto.getPages()) && !formDto.getPages().isEmpty() ;
default -> false;
};
}
}
package fr.numeco.misis.suividesite.domain;
import java.net.URI;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import fr.numeco.misis.enums.MethodeDeCreationDeGroupe;
import fr.numeco.misis.enums.PeriodiciteDuSuivi;
import fr.numeco.misis.permission.domain.Auditable;
import fr.numeco.misis.suividesite.dto.GroupOfPagesFormDto;
import fr.numeco.misis.suividesite.dto.PageFormDto;
import jakarta.persistence.*;
import static io.quarkus.hibernate.orm.panache.Panache.getEntityManager;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static io.quarkus.hibernate.orm.panache.Panache.getEntityManager;
@Entity
@Getter
@Setter
......@@ -44,6 +50,8 @@ public class GroupeDePages extends Auditable {
@ManyToOne(cascade = CascadeType.MERGE)
private SuiviDeSite suiviDeSite;
private String sitemap;
public void addPage(Page page) {
if (Objects.isNull(pages)) {
pages = new ArrayList<>();
......@@ -92,7 +100,13 @@ public class GroupeDePages extends Auditable {
groupeDePages.setName(groupOfPagesFormDto.getName());
groupeDePages.setPeriodiciteDuSuivi(groupOfPagesFormDto.getPeriodiciteDuSuivi());
groupeDePages.setMethodeDeCreationDeGroupe(groupOfPagesFormDto.getMethodeDeCreationDeGroupe());
manageOrphan(Page.createOrUpdate(suiviDeSite.getUrl(), groupOfPagesFormDto.getPages(), groupeDePages), groupeDePages);
if(groupOfPagesFormDto.getMethodeDeCreationDeGroupe() == MethodeDeCreationDeGroupe.MANUELLE) {
manageOrphan(Page.createOrUpdate(suiviDeSite.getUrl(), groupOfPagesFormDto.getPages(), groupeDePages), groupeDePages);
} else {
groupeDePages.setSitemap(URI.create(suiviDeSite.getUrl().trim()).resolve(groupOfPagesFormDto.getSitemap().trim()).toString());
}
if (Objects.isNull(groupeDePages.getCreatedBy())) {
groupeDePages.setCreatedBy(suiviDeSite.getCreatedBy());
}
......@@ -102,7 +116,7 @@ public class GroupeDePages extends Auditable {
}
groupeDePages.setModifiedDate(LocalDate.now());
groupeDePages.setSuiviDeSite(suiviDeSite);
return groupeDePages;
}
......
package fr.numeco.misis.suividesite.dto;
import java.time.LocalDateTime;
import java.util.Set;
import fr.numeco.misis.enums.Alert;
import fr.numeco.misis.enums.RessourceType;
import lombok.AllArgsConstructor;
......@@ -7,8 +10,6 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.Set;
@Getter
@Setter
@AllArgsConstructor
......@@ -16,5 +17,9 @@ import java.util.Set;
public class GroupDetailsDto {
private String name; //NOSONAR
private Set<RessourceType> availableRessourceTypes; //NOSONAR
private Alert alert;
private LocalDateTime createdDate; //NOSONAR
private LocalDateTime lastAnalysis; //NOSONAR
private Integer errorCount; //NOSONAR
private Integer pageCount; //NOSONAR
private Alert alert; //NOSONAR
}
\ No newline at end of file
package fr.numeco.misis.suividesite.dto;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import fr.numeco.misis.enums.MethodeDeCreationDeGroupe;
import fr.numeco.misis.enums.PeriodiciteDuSuivi;
import fr.numeco.misis.suividesite.constraints.MethodeDeCreationDeGroupeConstraint;
import io.quarkus.logging.Log;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@MethodeDeCreationDeGroupeConstraint
public class GroupOfPagesFormDto {
private Long id; //NOSONAR
......@@ -33,12 +34,11 @@ public class GroupOfPagesFormDto {
private PeriodiciteDuSuivi periodiciteDuSuivi; //NOSONAR
@NotNull
private MethodeDeCreationDeGroupe methodeDeCreationDeGroupe; //NOSONAR
@Valid
@Size
private List<PageFormDto> pages; //NOSONAR
private String sitemap; //NOSONAR
public GroupOfPagesFormDto(Long id, final String name, final PeriodiciteDuSuivi periodiciteDuSuivi, final MethodeDeCreationDeGroupe methodeDeCreationDeGroupe, final Object pages) {
this(id, name, periodiciteDuSuivi, methodeDeCreationDeGroupe, map(pages));
public GroupOfPagesFormDto(Long id, final String name, final PeriodiciteDuSuivi periodiciteDuSuivi, final MethodeDeCreationDeGroupe methodeDeCreationDeGroupe, final Object pages, String sitemap) {
this(id, name, periodiciteDuSuivi, methodeDeCreationDeGroupe, map(pages), sitemap);
}
private static List<PageFormDto> map(Object object) {
......