ActivityDefault.java

package org.linkedopenactors.rdfpub.domain.commonsrdf;

import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.rdf.api.Graph;
import org.apache.commons.rdf.api.IRI;
import org.apache.commons.rdf.api.RDF;
import org.apache.commons.rdf.api.Triple;
import org.linkedopenactors.rdfpub.domain.commonsrdf.vocab.AS;
import org.linkedopenactors.rdfpub.domain.commonsrdf.vocab.PROV;
import org.linkedopenactors.rdfpub.domain.commonsrdf.vocab.Rdf;
import org.linkedopenactors.rdfpub.domain.commonsrdf.vocab.Vocabularies;

public class ActivityDefault extends ActivityPubObjectDefault implements Activity {

	public ActivityDefault(RDF rdf, IRI subject, Graph graph,
			GraphToStringConverter graphToStringConverter, SubjectProvider subjectProvider, Vocabularies vocabularies, InstanceProperties instanceProperties) {
		super(rdf, subject, graph, graphToStringConverter, subjectProvider, vocabularies, instanceProperties);
	}

	@Override
	public Set<IRI> getObject() {
		return getIris(rdf.createIRI(AS.object));
	}

	@Override
	public void setObject(Set<IRI> object) {
		set(rdf.createIRI(AS.object), object);		
	}

	@Override
	public void addObject(ActivityPubObject activityPubObject) {
		add(rdf.createIRI(AS.object), activityPubObject.getSubject());		
		this.add(activityPubObject.asGraph());
	}

	@Override
	public void setObjects(Set<ActivityPubObject> activityPubObjects) {
		set(rdf.createIRI(AS.object), activityPubObjects.stream()
				.map(ActivityPubObject::getSubject)
				.map(IRI.class::cast)
				.collect(Collectors.toSet()));		
		removeAll(getObject());
		activityPubObjects.stream()
			.map(ActivityPubObject::asGraph)
			.forEach(this::add);
	}

	@Override
	public void addObject(IRI object) {
		add(rdf.createIRI(AS.object), object);		
	}

	@Override
	public Set<ActivityPubObject> resolveObject() {
		return getObject().stream()
				.map(asConvertable()::resolve)
				.filter(Optional::isPresent)
				.map(Optional::get)
				.collect(Collectors.toSet());
	}

	@Override
	public Set<IRI> getActor() {
		return getIris(rdf.createIRI(AS.actor));
	}

	@Override
	public ActivityType activityType() {		
		Set<IRI> types = getIris(rdf.createIRI(Rdf.type));
		
		Set<ActivityType> activityTypes = types.stream()
			.map(ActivityType::valueOf)
			.filter(Optional::isPresent)
			.map(Optional::get)
			.collect(Collectors.toSet());
		
		
		if(activityTypes.stream().count()>1) {
			throw new IllegalStateException("activity has more than one type!");
		}
		
		return activityTypes.stream().findFirst().orElseThrow(()->new IllegalStateException("no activityType!"));
	}

	@Override
	public boolean is(ActivityType activityType) {
		return activityType().equals(activityType);
	}

	@Override
	public void addActor(IRI actor) {
		add(rdf.createIRI(AS.actor), actor);		
	}

	@Override
	public void setActor(Set<IRI> actor) {
		set(rdf.createIRI(AS.actor), actor);		
	}

	@Override
	public void setTarget(IRI target) {
		set(rdf.createIRI(AS.target), target);		
	}

	@Override
	public Optional<IRI> getTarget() {
		return getIris(rdf.createIRI(AS.target)).stream().findFirst();
	}

	@Override
	public boolean isActivity() {
		return true;
	}

	@Override
	public void setWasAssociatedWith(IRI actor) {
		set(rdf.createIRI(PROV.wasAssociatedWith), actor);		
	}

	@Override
	public Optional<IRI> getWasAssociatedWith() {
		return getIris(rdf.createIRI(PROV.wasAssociatedWith)).stream().findFirst();
	}

	@Override
	public void unify() {
		Set<IRI> audience = getAudience();
		Set<IRI> cc = getCc();
		Set<IRI> bcc = getBcc();
		Set<IRI> to = getTo();
		Set<IRI> bto = getBto();
		
		// collect all receivers
		Set<ActivityPubObject> objects = resolveObject();
		objects.forEach(o->{
			audience.addAll(o.getAudience());
			cc.addAll(o.getCc());
			bcc.addAll(o.getBcc());
			to.addAll(o.getTo());
			bto.addAll(o.getBto());
		});
		
		// apply collected receivers to all objects
		objects.forEach(o->{
			o.setAudience(audience);
			o.setCc(cc);
			o.setBcc(bcc);
			o.setTo(to);
			o.setBto(bto);
		});
		
		// apply collected receivers to activity
		setAudience(audience);
		setCc(cc);
		setBcc(bcc);
		setTo(to);
		setBto(bto);
	}


	@Override
	public void replaceSubjects(Actor actor, SubjectProvider subjectProvider) {
		replaceSubjects(actor, subjectProvider, true); 
	}
	
	@Override
	public void replaceSubjects(Actor actor, SubjectProvider subjectProvider, boolean includingObjects) {
				
		if(includingObjects) {
			// get all subjects of the objects without the activity subject
			Set<IRI> objectSubjects = asGraph().stream()
					.map(Triple::getSubject)
					.filter(IRI.class::isInstance)
					.map(IRI.class::cast)
					.filter(s->!s.equals(getSubject()))
					.collect(Collectors.toSet());
			// replace subjects of the objects
			objectSubjects
				.forEach(s->replaceSubject(s, subjectProvider.provide(actor)));
		}
		replaceSubject(actor);
	}

	@Override
	public void replaceSubjectsWithInternals(SubjectProvider subjectProvider) {
		Set<IRI> objectSubjects = asGraph().stream()
				.map(Triple::getSubject)
				.filter(IRI.class::isInstance)
				.map(IRI.class::cast)
				.collect(Collectors.toSet());

		objectSubjects
			.forEach(s->{
				IRI resolveExternal = subjectProvider.resolveInternal(s);
				replaceSubject(s, resolveExternal);
			});
	}

	@Override
	public void replaceObject(ActivityPubObject existing) {
		this.asGraph().remove(existing.getSubject(), null, null);
		this.setObjects(Set.of(existing));		
	}

	@Override
	public void hideBlindReceivers() {
		super.hideBlindReceivers();
		resolveObject().forEach(ActivityPubObject::hideBlindReceivers);
//		System.out.println("");
	}
}