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

273 lines
16 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 com.vdurmont.semver4j.Semver;
import lombok.extern.slf4j.Slf4j;
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.implementations.faults.InvalidUserRoleException;
import org.gcube.application.cms.implementations.faults.ProjectNotFoundException;
import org.gcube.application.cms.implementations.faults.RegistrationException;
import org.gcube.application.cms.implementations.faults.UnauthorizedAccess;
import org.gcube.application.cms.plugins.IndexerPluginInterface;
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.reports.StepExecutionReport;
import org.gcube.application.cms.plugins.requests.BaseRequest;
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.access.Access;
import org.gcube.application.geoportal.common.model.document.access.AccessPolicy;
import org.gcube.application.geoportal.common.model.document.filesets.RegisteredFileSet;
import org.gcube.application.geoportal.common.model.document.lifecycle.LifecycleInformation;
import org.gcube.application.geoportal.common.model.document.relationships.RelationshipNavigationObject;
import org.gcube.application.geoportal.common.model.legacy.report.ConstraintCheck;
import org.gcube.application.geoportal.common.model.rest.ConfigurationException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@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));
rel.putIfAbsent(RegisteredFileSet.CREATION_INFO,c.getInfo().getCreationInfo());
rel.putIfAbsent(RegisteredFileSet.ACCESS,c.getInfo().getAccess());
Access relAccess=Serialization.convert(rel.get(RegisteredFileSet.ACCESS),Access.class);
relAccess.setLicense(ConstraintCheck.defaultFor(relAccess.getLicense(),"CC-BY-4.0").evaluate());
relAccess.setPolicy(ConstraintCheck.defaultFor(relAccess.getPolicy(), AccessPolicy.OPEN).evaluate());
rel.put(RegisteredFileSet.ACCESS,relAccess);
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");
abs.putIfAbsent(RegisteredFileSet.CREATION_INFO,c.getInfo().getCreationInfo());
abs.putIfAbsent(RegisteredFileSet.ACCESS,c.getInfo().getAccess());
Access absAccess=Serialization.convert(abs.get(RegisteredFileSet.ACCESS),Access.class);
absAccess.setLicense(ConstraintCheck.defaultFor(absAccess.getLicense(),"CC-BY-4.0").evaluate());
absAccess.setPolicy(ConstraintCheck.defaultFor(absAccess.getPolicy(), AccessPolicy.OPEN).evaluate());
abs.put(RegisteredFileSet.ACCESS,absAccess);
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));
pos.putIfAbsent(RegisteredFileSet.CREATION_INFO,c.getInfo().getCreationInfo());
pos.putIfAbsent(RegisteredFileSet.ACCESS,c.getInfo().getAccess());
Access posAccess=Serialization.convert(rel.get(RegisteredFileSet.ACCESS),Access.class);
posAccess.setLicense(ConstraintCheck.defaultFor(posAccess.getLicense(),"CC-BY-4.0").evaluate());
posAccess.setPolicy(ConstraintCheck.defaultFor(posAccess.getPolicy(), AccessPolicy.OPEN).evaluate());
pos.put(RegisteredFileSet.ACCESS,posAccess);
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));
imgDoc.putIfAbsent(RegisteredFileSet.CREATION_INFO,c.getInfo().getCreationInfo());
imgDoc.putIfAbsent(RegisteredFileSet.ACCESS,c.getInfo().getAccess());
Access imgAccess=Serialization.convert(imgDoc.get(RegisteredFileSet.ACCESS),Access.class);
imgAccess.setLicense(ConstraintCheck.defaultFor(imgAccess.getLicense(),"CC-BY-4.0").evaluate());
imgAccess.setPolicy(ConstraintCheck.defaultFor(imgAccess.getPolicy(), AccessPolicy.OPEN).evaluate());
imgDoc.put(RegisteredFileSet.ACCESS,imgAccess);
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));
piantaDoc.putIfAbsent(RegisteredFileSet.CREATION_INFO,c.getInfo().getCreationInfo());
piantaDoc.putIfAbsent(RegisteredFileSet.ACCESS,c.getInfo().getAccess());
Access posAccess=Serialization.convert(rel.get(RegisteredFileSet.ACCESS),Access.class);
posAccess.setLicense(ConstraintCheck.defaultFor(posAccess.getLicense(),"CC-BY-4.0").evaluate());
posAccess.setPolicy(ConstraintCheck.defaultFor(posAccess.getPolicy(), AccessPolicy.OPEN).evaluate());
piantaDoc.put(RegisteredFileSet.ACCESS,posAccess);
wrapper.setElement("$."+ProfiledConcessione.PIANTE_FINE_SCAVO+"["+i+"]",piantaDoc);
}
}
c.setTheDocument(Serialization.read(wrapper.getValueCTX().jsonString(),Document.class));
return c;
}
@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 Last ID in relationship chain. Current Concessione 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());
List<String> toDisplayId = new ArrayList<>();
List<String> toHideIds = new ArrayList<>();
log.trace("Checking from LAST.. ");
// Projects is time -ordered so we scan from last
for(int i = projects.size()-1;i>=0;i--) {
Project p = projects.get(i);
log.debug("Currently checking {} : {}",p.getId(),p.getTheDocument().get("nome"));
if(!toDisplayId.isEmpty())
toHideIds.add(p.getId());
else {
//Still need to find candidate for displaying feature
//Our currently indexing project is always a good candidate
if(p.getId().equals(indexingProject.getId()))
toDisplayId.add(p.getId());
//We check PHASE in order to skip projects not yet in the PHASE we are indexing
else switch(indexingProject.getLifecycleInformation().getPhase()){
case Phases.PENDING_APPROVAL:{
if ((p.getLifecycleInformation().getPhase().equals(Phases.PENDING_APPROVAL)||
p.getLifecycleInformation().getPhase().equals(Phases.PUBLISHED)))
toDisplayId.add(p.getId());
break;
}
case Phases.PUBLISHED:{
if (p.getLifecycleInformation().getPhase().equals(Phases.PUBLISHED))
toDisplayId.add(p.getId());
break;
}
}
if(!toDisplayId.isEmpty())
log.debug("Found last concessioni candidate for displaying. ID {}, PHASE {} ",toDisplayId,p.getLifecycleInformation().getPhase());
else toHideIds.add(p.getId()); // Still not found
}
}
toReturn.put("_toHideIds",toHideIds);
toReturn.put("_toDisplayIds",toDisplayId);
log.info("Indexing request for Concessione [ID {}] with to HIDE {} and toDisplay {} ",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));
}
}