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 dell’area 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 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 toDisplayId = new ArrayList<>(); List 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)); } }