gcube-cms-suite/concessioni-lifecycle/src/main/java/org/gcube/application/cms/concessioni/plugins/ConcessioniLifeCycleManager...

317 lines
13 KiB
Java
Raw Normal View History

2022-01-12 18:42:22 +01:00
package org.gcube.application.cms.concessioni.plugins;
2023-03-13 15:25:57 +01:00
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
2022-01-27 15:02:53 +01:00
import org.bson.Document;
2022-09-26 16:17:37 +02:00
import org.gcube.application.cms.custom.gna.concessioni.model.ProfiledConcessione;
2022-10-27 17:17:44 +02:00
import org.gcube.application.cms.implementations.ImplementationProvider;
import org.gcube.application.cms.implementations.ProjectAccess;
2022-09-26 16:17:37 +02:00
import org.gcube.application.cms.plugins.LifecycleManager;
2022-10-27 17:31:30 +02:00
import org.gcube.application.cms.plugins.faults.IndexingException;
2022-03-28 16:35:30 +02:00
import org.gcube.application.cms.plugins.implementations.Default3PhaseManager;
2022-05-10 14:42:11 +02:00
import org.gcube.application.cms.plugins.reports.EventExecutionReport;
import org.gcube.application.cms.plugins.reports.Report;
2022-10-27 17:17:44 +02:00
import org.gcube.application.cms.plugins.requests.IndexDocumentRequest;
2022-02-01 15:24:39 +01:00
import org.gcube.application.cms.serialization.Serialization;
2022-05-10 14:42:11 +02:00
import org.gcube.application.geoportal.common.model.JSONPathWrapper;
2022-09-26 16:17:37 +02:00
import org.gcube.application.geoportal.common.model.document.Project;
2023-03-13 15:25:57 +01:00
import org.gcube.application.geoportal.common.model.document.relationships.Relationship;
2022-10-27 17:17:44 +02:00
import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject;
2022-01-27 15:02:53 +01:00
import org.gcube.application.geoportal.common.model.legacy.report.ConstraintCheck;
2023-03-13 15:25:57 +01:00
import com.vdurmont.semver4j.Semver;
import lombok.extern.slf4j.Slf4j;
2022-05-10 14:42:11 +02:00
2022-01-12 18:42:22 +01:00
@Slf4j
2023-03-13 15:25:57 +01:00
/**
* Overrides 3 Phases lifecycle with override of default values
2022-03-28 16:35:30 +02:00
*
*/
public class ConcessioniLifeCycleManager extends Default3PhaseManager implements LifecycleManager {
2022-01-12 18:42:22 +01:00
2023-03-13 15:25:57 +01:00
private static final String FOLLOWS = "follows";
private static final String PRECEDES = "precedes";
public ConcessioniLifeCycleManager() {
DESCRIPTOR.setId("GNA-CONCESSIONI-LC");
DESCRIPTOR.setDescription(
"GNA Concessioni. This plugin supports custom lifecycle management for the GNA Concessioni UseCase.");
DESCRIPTOR.setVersion(new Semver("1.0.0"));
}
@Override
public EventExecutionReport setDefault(EventExecutionReport currentReport) {
EventExecutionReport report = super.setDefault(currentReport);
try {
report.setResultingDocument(setDefaults(report.getTheRequest().getDocument()).getTheDocument());
} catch (Throwable t) {
log.error("Unable to evaluate defaults for concessione "
+ currentReport.getTheRequest().getDocument().getId(), t);
log.debug("Object was {} ", report.getTheRequest().getDocument());
report.setStatus(Report.Status.ERROR);
report.getMessages().add("Unable to evaluate defaults : " + t.getMessage());
}
return report;
}
// STATIC ROUTINES
static final Project setDefaults(Project document) throws IOException {
log.info("Concessione ID {}, setting defaults..", document.getId());
log.debug("Full concessione is {}", document);
ProfiledConcessione c = Serialization.convert(document, ProfiledConcessione.class);
Document doc = c.getTheDocument();
doc.putIfAbsent(ProfiledConcessione.SOGGETTO, new String[] { "Research Excavation", "Archaeology" });
doc.putIfAbsent(ProfiledConcessione.DESCRIZIONE_CONTENUTO,
"Relazione di fine scavo e relativo abstract; selezione di immagini rappresentative;"
+ " posizionamento topografico dell'area indagata, pianta di fine scavo.");
// Super Section
// TODO read from UCD
c.getInfo().getAccess()
.setLicense(ConstraintCheck.defaultFor(c.getInfo().getAccess().getLicense(), "CC0-1.0").evaluate());
// RELAZIONE
Document rel = doc.containsKey(ProfiledConcessione.RELAZIONE_SCAVO)
? Serialization.convert(doc.get(ProfiledConcessione.RELAZIONE_SCAVO), Document.class)
: new Document();
log.debug("Concessione {}, managing relazione {}", document.getId(), rel);
rel.putIfAbsent(ProfiledConcessione.Sections.TITOLO,
doc.getString(ProfiledConcessione.NOME) + " relazione di scavo");
rel.putIfAbsent(ProfiledConcessione.SOGGETTO, doc.get(ProfiledConcessione.SOGGETTO));
doc.put(ProfiledConcessione.RELAZIONE_SCAVO, rel);
// ABSTRACT Relazione
Document abs = doc.containsKey(ProfiledConcessione.ABSTRACT_RELAZIONE)
? Serialization.convert(doc.get(ProfiledConcessione.ABSTRACT_RELAZIONE), Document.class)
: new Document();
log.debug("Concessione {}, managing abstract relazione {}", document.getId(), abs);
abs.putIfAbsent(ProfiledConcessione.Sections.TITOLO,
doc.getString(ProfiledConcessione.NOME) + " abstract relazione di scavo");
doc.put(ProfiledConcessione.ABSTRACT_RELAZIONE, abs);
// Posizionamento scavo
if (doc.containsKey(ProfiledConcessione.POSIZIONAMENTO_SCAVO)) {
Document pos = Serialization.convert(doc.get(ProfiledConcessione.POSIZIONAMENTO_SCAVO), Document.class);
log.debug("Concessione {}, managing posizionamento scavo {}", document.getId(), pos);
pos.putIfAbsent(ProfiledConcessione.Sections.TITOLO,
doc.getString(ProfiledConcessione.NOME) + " posizionamento scavo");
pos.putIfAbsent(ProfiledConcessione.Sections.ABSTRACT,
"Posizionamento topografico georeferenziato dellarea interessata dalle indagini");
pos.putIfAbsent(ProfiledConcessione.Layers.TOPIC, "Society");
pos.putIfAbsent(ProfiledConcessione.Layers.SUB_TOPIC, "Archeology");
pos.putIfAbsent(ProfiledConcessione.PAROLE_CHIAVE_LIBERE,
doc.get(ProfiledConcessione.PAROLE_CHIAVE_LIBERE));
pos.putIfAbsent(ProfiledConcessione.PAREOLE_CHIAVE_ICCD, doc.get(ProfiledConcessione.PAREOLE_CHIAVE_ICCD));
// BBOX in registered filesets
pos.put(ProfiledConcessione.RESPONSABILE, doc.get(ProfiledConcessione.RESPONSABILE));
doc.put(ProfiledConcessione.POSIZIONAMENTO_SCAVO, pos);
}
// IMMAGINI RAPPRESENTATIVE
JSONPathWrapper wrapper = new JSONPathWrapper(Serialization.write(doc));
if (doc.containsKey(ProfiledConcessione.IMMAGINI_RAPPRESENTATIVE)) {
List imgs = wrapper.getByPath("$." + ProfiledConcessione.IMMAGINI_RAPPRESENTATIVE, List.class).get(0);
log.debug("Concessione {}, found imgs {}", document.getId(), imgs.size());
for (int i = 0; i < imgs.size(); i++) {
Document imgDoc = Serialization.asDocument(imgs.get(i));
imgDoc.putIfAbsent(ProfiledConcessione.SOGGETTO, doc.get(ProfiledConcessione.SOGGETTO));
wrapper.setElement("$." + ProfiledConcessione.IMMAGINI_RAPPRESENTATIVE + "[" + i + "]", imgDoc);
}
}
// Layers
if (doc.containsKey(ProfiledConcessione.PIANTE_FINE_SCAVO)) {
List piante = wrapper.getByPath("$." + ProfiledConcessione.PIANTE_FINE_SCAVO, List.class).get(0);
log.debug("Concessione {}, found piante {}", document.getId(), piante.size());
for (int i = 0; i < piante.size(); i++) {
Document piantaDoc = Serialization.asDocument(piante.get(i));
log.debug("Concessione {}, managing pianta {}", document.getId(), piantaDoc);
piantaDoc.putIfAbsent(ProfiledConcessione.Sections.TITOLO,
doc.getString(ProfiledConcessione.NOME) + " pianta fine scavo");
piantaDoc.putIfAbsent(ProfiledConcessione.Sections.ABSTRACT,
"Planimetria georeferenziata dell'area indagata al termine delle attività");
piantaDoc.putIfAbsent(ProfiledConcessione.Layers.TOPIC, "Society");
piantaDoc.putIfAbsent(ProfiledConcessione.Layers.SUB_TOPIC, "Archeology");
piantaDoc.putIfAbsent(ProfiledConcessione.PAROLE_CHIAVE_LIBERE,
doc.get(ProfiledConcessione.PAROLE_CHIAVE_LIBERE));
piantaDoc.putIfAbsent(ProfiledConcessione.PAREOLE_CHIAVE_ICCD,
doc.get(ProfiledConcessione.PAREOLE_CHIAVE_ICCD));
// BBOX in registered filesets
piantaDoc.put(ProfiledConcessione.RESPONSABILE, doc.get(ProfiledConcessione.RESPONSABILE));
wrapper.setElement("$." + ProfiledConcessione.PIANTE_FINE_SCAVO + "[" + i + "]", piantaDoc);
}
}
c.setTheDocument(Serialization.read(wrapper.getValueCTX().jsonString(), Document.class));
return c;
}
/**
* New method implemented by Francesco
*/
@Override
protected Document evaluateAdditionalIndexParameters(IndexDocumentRequest request) throws IndexingException {
Document toReturn = super.evaluateAdditionalIndexParameters(request);
if (toReturn == null)
toReturn = new Document();
Project indexingProject = request.getDocument();
// Evaluate to display project IDs
2023-03-14 10:51:02 +01:00
log.info("Evaluating relationship chain. Current ID is {}", indexingProject.getId());
2023-03-13 15:25:57 +01:00
try {
ArrayList<Project> projects = new ArrayList<>();
ProjectAccess access = ImplementationProvider.get().getProvidedObjectByClass(ProjectAccess.class);
// get Last ID in relation chain
projects.add(indexingProject);
if (!indexingProject.getRelationshipsByName(PRECEDES).isEmpty())
scanRelation(projects, access
.getRelations(indexingProject.getProfileID(), indexingProject.getId(), PRECEDES, true).get(0),
false);
if (!indexingProject.getRelationshipsByName(FOLLOWS).isEmpty())
scanRelation(projects, access
.getRelations(indexingProject.getProfileID(), indexingProject.getId(), FOLLOWS, true).get(0),
false);
log.debug("Produced full chain [size : {}] from {}, evaluating last available for PHASE {} ",
projects.size(), indexingProject.getId(), indexingProject.getLifecycleInformation().getPhase());
log.info("projects are: " + projects.size());
List<String> toDisplayId = new ArrayList<>();
List<String> toHideIds = new ArrayList<>();
// Reverse Order means from the last FOLLOW to the first one (temporal reverse
// order)
Collections.sort(projects, Collections.reverseOrder(new ProjectRelationComparator()));
2023-03-13 16:14:38 +01:00
if (log.isInfoEnabled()) {
2023-03-13 15:25:57 +01:00
int j = 0;
2023-03-13 16:14:38 +01:00
log.info("Printing project reverse order....");
2023-03-13 15:25:57 +01:00
for (Project theProject : projects) {
2023-03-13 16:14:38 +01:00
log.info(++j + ") " + theProject.getId() + " data inizio: "
2023-03-13 15:25:57 +01:00
+ theProject.getTheDocument().get("dataInizioProgetto"));
}
}
log.trace("Checking from LAST.. ");
for (int i = 0; i < projects.size(); i++) {
Project p = projects.get(i);
2023-03-13 17:14:07 +01:00
String phase = p.getLifecycleInformation().getPhase();
2023-03-13 15:25:57 +01:00
2023-03-14 10:51:02 +01:00
// IS TO DISPLAY EMPTY? Step into only once.
// Indexing the first project that is in PENDING APPROVAL or PUBLISHED or
// updating the phase of the indexing (selected) project
2023-03-13 15:25:57 +01:00
if (toDisplayId.isEmpty()) {
// IF PHASE IS PENDING APPROVAL OR PUBLISHED adding toDisplayId
2023-03-13 17:14:07 +01:00
if ((phase.equals(Phases.PENDING_APPROVAL) || phase.equals(Phases.PUBLISHED))) {
toDisplayId.add(p.getId());
2023-03-14 10:51:02 +01:00
} else if (p.getId().compareTo(indexingProject.getId()) == 0) {
// Means that the operation has been called on the indexing project from DRAFT
// phase to PENDING_APPROVAL or PUBLISH
2023-03-13 17:42:47 +01:00
toDisplayId.add(p.getId());
2023-03-13 17:14:07 +01:00
}
2023-03-14 10:51:02 +01:00
2023-03-13 15:25:57 +01:00
} else {
2023-03-14 10:51:02 +01:00
// Hides the centroid regardless of project phase
2023-03-13 16:46:32 +01:00
toHideIds.add(p.getId());
2023-03-13 15:25:57 +01:00
}
}
toReturn.put("_toHideIds", toHideIds);
toReturn.put("_toDisplayIds", toDisplayId);
2023-03-14 10:51:02 +01:00
log.info(
"Indexing request for " + indexingProject.getProfileID()
+ " [ID {}] with to _toHideIds {} and _toDisplayIds {} ",
2023-03-13 15:25:57 +01:00
indexingProject.getId(), toHideIds, toDisplayId);
return toReturn;
} catch (Exception e) {
log.error("Unable to evaluate to Hide and Display Ids ", e);
throw new IndexingException("Unable to evaluate chain ids to hide / display", e);
}
}
private static void scanRelation(ArrayList chain, RelationshipNavigationObject obj, boolean putBefore) {
if (putBefore)
chain.add(0, obj.getTarget());
else
chain.add(obj.getTarget());
if (obj.getChildren() != null)
obj.getChildren().forEach(r -> scanRelation(chain, r, putBefore));
}
public static class ProjectRelationComparator implements Comparator<Project> {
@Override
public int compare(Project p1, Project p2) {
if (p1 == null)
return 1;
if (p2 == null)
return -1;
Integer compareResult = null;
compareResult = compareProjectAgainstRelations(p1, p2);
log.trace("p1 & p2, comparator result: {}", compareResult);
if (compareResult == null) {
log.debug("No relations beetween p1 & p2, checking inverted relations");
compareResult = compareProjectAgainstRelations(p2, p1);
log.trace("p2 & p1, comparator result: {}", compareResult);
if (compareResult == null) {
log.trace("p1 & p2, are not comparable, returning 0");
compareResult = 0;
}
}
log.debug("p1 & p2, comparator result, returns: {}", compareResult);
return compareResult;
}
}
public static Integer compareProjectAgainstRelations(Project source, Project target) {
log.debug("comparing source {} and target {}", source.getId(), target.getId());
List<Relationship> listRel = source.getRelationships();
log.debug("relationships of {} are : {}", source.getId(), listRel);
if (listRel != null) {
String targetId = target.getId();
for (Relationship relationship : listRel) {
String relTargetId = relationship.getTargetID();
if (targetId.compareTo(relTargetId) == 0) {
String relationName = relationship.getRelationshipName();
if (relationName.equals(PRECEDES)) {
log.debug("source {} [rel {} ] target {}, so source < target ", source.getId(), PRECEDES,
target.getId());
// source < target
return -1;
} else if (relationName.equals(FOLLOWS)) {
log.debug("source {} [rel {} ] target {}, so source > target ", source.getId(), FOLLOWS,
target.getId());
// source > target
return 1;
}
}
}
}
log.debug("No relations beetween a & b");
return null;
}
2022-01-12 18:42:22 +01:00
}