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

317 lines
13 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package org.gcube.application.cms.concessioni.plugins;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.bson.Document;
import org.gcube.application.cms.custom.gna.concessioni.model.ProfiledConcessione;
import org.gcube.application.cms.implementations.ImplementationProvider;
import org.gcube.application.cms.implementations.ProjectAccess;
import org.gcube.application.cms.plugins.LifecycleManager;
import org.gcube.application.cms.plugins.faults.IndexingException;
import org.gcube.application.cms.plugins.implementations.Default3PhaseManager;
import org.gcube.application.cms.plugins.reports.EventExecutionReport;
import org.gcube.application.cms.plugins.reports.Report;
import org.gcube.application.cms.plugins.requests.IndexDocumentRequest;
import org.gcube.application.cms.serialization.Serialization;
import org.gcube.application.geoportal.common.model.JSONPathWrapper;
import org.gcube.application.geoportal.common.model.document.Project;
import org.gcube.application.geoportal.common.model.document.relationships.Relationship;
import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject;
import org.gcube.application.geoportal.common.model.legacy.report.ConstraintCheck;
import com.vdurmont.semver4j.Semver;
import lombok.extern.slf4j.Slf4j;
@Slf4j
/**
* Overrides 3 Phases lifecycle with override of default values
*
*/
public class ConcessioniLifeCycleManager extends Default3PhaseManager implements LifecycleManager {
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
log.info("Evaluating relationship chain. Current ID is {}", indexingProject.getId());
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()));
if (log.isInfoEnabled()) {
int j = 0;
log.info("Printing project reverse order....");
for (Project theProject : projects) {
log.info(++j + ") " + theProject.getId() + " data inizio: "
+ theProject.getTheDocument().get("dataInizioProgetto"));
}
}
log.trace("Checking from LAST.. ");
for (int i = 0; i < projects.size(); i++) {
Project p = projects.get(i);
String phase = p.getLifecycleInformation().getPhase();
// 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
if (toDisplayId.isEmpty()) {
// IF PHASE IS PENDING APPROVAL OR PUBLISHED adding toDisplayId
if ((phase.equals(Phases.PENDING_APPROVAL) || phase.equals(Phases.PUBLISHED))) {
toDisplayId.add(p.getId());
} 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
toDisplayId.add(p.getId());
}
} else {
// Hides the centroid regardless of project phase
toHideIds.add(p.getId());
}
}
toReturn.put("_toHideIds", toHideIds);
toReturn.put("_toDisplayIds", toDisplayId);
log.info(
"Indexing request for " + indexingProject.getProfileID()
+ " [ID {}] with to _toHideIds {} and _toDisplayIds {} ",
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;
}
}