package eu.dnetlib.iis.wf.export.actionmanager.module; import java.util.Arrays; import java.util.List; import org.apache.hadoop.conf.Configuration; import com.google.common.base.Preconditions; import eu.dnetlib.actionmanager.actions.AtomicAction; import eu.dnetlib.actionmanager.common.Agent; import eu.dnetlib.data.mapreduce.util.OafDecoder; import eu.dnetlib.data.proto.KindProtos.Kind; import eu.dnetlib.data.proto.OafProtos.Oaf; import eu.dnetlib.data.proto.OafProtos.OafRel; import eu.dnetlib.data.proto.RelTypeProtos.RelType; import eu.dnetlib.data.proto.RelTypeProtos.SubRelType; import eu.dnetlib.data.proto.ResultOrganizationProtos.ResultOrganization; import eu.dnetlib.data.proto.ResultOrganizationProtos.ResultOrganization.Affiliation; import eu.dnetlib.iis.wf.affmatching.model.MatchedOrganization; /** * {@link MatchedOrganization} action builder factory module. * * @author mhorst * */ public class MatchedOrganizationActionBuilderModuleFactory extends AbstractActionBuilderFactory<MatchedOrganization> { private static final String REL_CLASS_HAS_AUTHOR_INSTITUTION_OF = Affiliation.RelName.hasAuthorInstitution.toString(); private static final String REL_CLASS_IS_AUTHOR_INSTITUTION_OF = Affiliation.RelName.isAuthorInstitutionOf.toString(); private static final String SEMANTIC_SCHEME_DNET_RELATIONS_RESULT_ORG = "dnet:result_organization_relations"; // ------------------------ CONSTRUCTORS -------------------------- public MatchedOrganizationActionBuilderModuleFactory() { super(AlgorithmName.document_affiliations); } // ------------------------ LOGIC --------------------------------- @Override public ActionBuilderModule<MatchedOrganization> instantiate(Configuration config, Agent agent, String actionSetId) { return new MatchedOrganizationActionBuilderModule(provideTrustLevelThreshold(config), agent, actionSetId); } // ------------------------ INNER CLASS --------------------------------- /** * {@link MatchedOrganization} action builder module. * */ class MatchedOrganizationActionBuilderModule extends AbstractBuilderModule<MatchedOrganization> { // ------------------------ CONSTRUCTORS -------------------------- /** * @param trustLevelThreshold trust level threshold or null when all records should be exported * @param agent action manager agent details * @param actionSetId action set identifier */ public MatchedOrganizationActionBuilderModule(Float trustLevelThreshold, Agent agent, String actionSetId) { super(trustLevelThreshold, buildInferenceProvenance(), Preconditions.checkNotNull(agent), Preconditions.checkNotNull(actionSetId)); } // ------------------------ LOGIC --------------------------------- @Override public List<AtomicAction> build(MatchedOrganization object) throws TrustLevelThresholdExceededException { Preconditions.checkNotNull(object); String docId = object.getDocumentId().toString(); String orgId = object.getOrganizationId().toString(); Oaf.Builder oafBuilder = Oaf.newBuilder(); oafBuilder.setKind(Kind.relation); OafRel.Builder relBuilder = OafRel.newBuilder(); relBuilder.setChild(false); relBuilder.setRelType(RelType.resultOrganization); relBuilder.setSubRelType(SubRelType.affiliation); relBuilder.setRelClass(REL_CLASS_HAS_AUTHOR_INSTITUTION_OF); relBuilder.setSource(docId); relBuilder.setTarget(orgId); ResultOrganization.Builder resOrgBuilder = ResultOrganization.newBuilder(); Affiliation.Builder affBuilder = Affiliation.newBuilder(); affBuilder.setRelMetadata( buildRelMetadata(SEMANTIC_SCHEME_DNET_RELATIONS_RESULT_ORG, REL_CLASS_HAS_AUTHOR_INSTITUTION_OF)); resOrgBuilder.setAffiliation(affBuilder.build()); relBuilder.setResultOrganization(resOrgBuilder.build()); oafBuilder.setRel(relBuilder.build()); oafBuilder.setDataInfo(buildInference(object.getMatchStrength())); oafBuilder.setLastupdatetimestamp(System.currentTimeMillis()); Oaf oaf = oafBuilder.build(); Oaf oafInverted = invertRelationAndBuild(oafBuilder); return Arrays.asList(new AtomicAction[] { getActionFactory().createAtomicAction(getActionSetId(), getAgent(), docId, OafDecoder.decode(oaf).getCFQ(), orgId, oaf.toByteArray()), // setting reverse relation in referenced object getActionFactory().createAtomicAction(getActionSetId(), getAgent(), orgId, OafDecoder.decode(oafInverted).getCFQ(), docId, oafInverted.toByteArray()) }); } // ------------------------ PRIVATE --------------------------------- /** * Clones builder provided as parameter, inverts relations and builds {@link Oaf} object. */ private Oaf invertRelationAndBuild(Oaf.Builder existingBuilder) { // works on builder clone to prevent changes in existing builder if (existingBuilder.getRel() != null) { if (existingBuilder.getRel().getSource() != null && existingBuilder.getRel().getTarget() != null) { Oaf.Builder builder = existingBuilder.clone(); OafRel.Builder relBuilder = builder.getRelBuilder(); String source = relBuilder.getSource(); String target = relBuilder.getTarget(); relBuilder.setSource(target); relBuilder.setTarget(source); relBuilder.setRelClass(REL_CLASS_IS_AUTHOR_INSTITUTION_OF); relBuilder.getResultOrganizationBuilder().getAffiliationBuilder().getRelMetadataBuilder() .getSemanticsBuilder().setClassid(REL_CLASS_IS_AUTHOR_INSTITUTION_OF); relBuilder.getResultOrganizationBuilder().getAffiliationBuilder().getRelMetadataBuilder() .getSemanticsBuilder().setClassname(REL_CLASS_IS_AUTHOR_INSTITUTION_OF); builder.setRel(relBuilder.build()); builder.setLastupdatetimestamp(System.currentTimeMillis()); return builder.build(); } else { throw new RuntimeException("invalid state: " + "either source or target relation was missing!"); } } else { throw new RuntimeException("invalid state: " + "no relation object found!"); } } } }