ActorsStoreDefault.java

package org.linkedopenactors.rdfpub.store.rdf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.RDFTerm;
import org.linkedopenactors.rdfpub.domain.commonsrdf.Activity;
import org.linkedopenactors.rdfpub.domain.commonsrdf.ActivityPubObject;
import org.linkedopenactors.rdfpub.domain.commonsrdf.ActivityPubStore;
import org.linkedopenactors.rdfpub.domain.commonsrdf.ActivityType;
import org.linkedopenactors.rdfpub.domain.commonsrdf.Actor;
import org.linkedopenactors.rdfpub.domain.commonsrdf.ActorsStore;
import org.linkedopenactors.rdfpub.domain.commonsrdf.RdfFormat;

import lombok.extern.slf4j.Slf4j;

@Slf4j
class ActorsStoreDefault implements ActorsStore {

	private ActivityPubStore activityPubStore;
	private Actor storeOwner;
	private Map<ActivityType,Set<ActivityHandler>> handlerByType;
	
	public ActorsStoreDefault(RDF rdf, Actor storeOwner, ActivityPubStore activityPubStore, List<ActivityHandler> activityHandlers) {
		this.storeOwner = storeOwner;
		this.activityPubStore = activityPubStore;
		this.handlerByType = initHandlerByType(activityHandlers);
	}
	
	private Map<ActivityType,Set<ActivityHandler>> initHandlerByType(List<ActivityHandler> activityHandlers) {
		Map<ActivityType,Set<ActivityHandler>> handlerByType = new HashMap<>();
		List.of(ActivityType.values()).forEach(type->{
			handlerByType.put(type, 
					activityHandlers.stream()
					.filter(h->h.isResponsibleFor(type))
					.collect(Collectors.toSet()));
		});
		return handlerByType;
	}
	
	@Override
	public IRI addToOutbox(Activity activity, String logMsg) {	
		return addToOutbox(storeOwner, activity, logMsg);
	}

	@Override
	public IRI addToOutbox(Actor activityOwner, Activity activity, String logMsg) {
		ActionInfo actionInfo = new ActionInfo(logMsg, activityOwner, activity);
		actionInfo.addMessage("ActorsStoreDefault#addToOutbox");
		Set<ActivityHandler> responsibleHandlers = handlerByType.get(activity.activityType());
		if(responsibleHandlers.isEmpty()) {
			log.warn("##################### WARN #############################");
			log.warn("No handler for: " + activity.activityType());
			log.warn("########################################################");
		} else {
			log.debug("Handlers for ("+activity.activityType()+"): " + responsibleHandlers);
		}
		responsibleHandlers
			.forEach(handler->{
				handler.addToCollection(actionInfo, storeOwner.getOutbox(), activityPubStore);
			});
		// TODO add complete activity to auditlog ??? which should be seperate from the business object repo eg. graph !!
		// maybe actor.getsubject() + "/auditlog" or a completely seperated db, which can be used as eventStream ?!
		
		// TODO replace subject
		return activity.getSubject();
	}

	@Override
	public IRI addToInbox(Activity activity, String logMsg) {
		return addToInbox(storeOwner, activity, logMsg);
	}

	@Override
	public IRI addToInbox(Actor activityOwner, Activity activity, String logMsg) {
		ActionInfo actionInfo = new ActionInfo(logMsg, activityOwner, activity);
		actionInfo.addMessage("ActorsStoreDefault#addToInbox");
		handlerByType.get(activity.activityType())
			.forEach(handler->handler.addToCollection(actionInfo, storeOwner.getInbox(), activityPubStore));
		
		// TODO replace subject
		return activity.getSubject();
	}

	@Override
	public void addFollower(IRI follower) {
		activityPubStore.addCollectionItem(storeOwner.getFollowers(), follower, "addFollower");		
	}

	@Override
	public List<IRI> getInbox() {
		return activityPubStore.getCollection(storeOwner.getSubject(), storeOwner.getInbox());
	}

	@Override
	public List<IRI> getOutbox() {
		return activityPubStore.getCollection(storeOwner.getSubject(), storeOwner.getOutbox());
	}

	@Override
	public List<IRI> getFollowing() {
		return activityPubStore.getCollection(storeOwner.getSubject(), storeOwner.getFollowing());
	}

	@Override
	public List<IRI> getFollowers() {
		return activityPubStore.getCollection(storeOwner.getSubject(), storeOwner.getFollowers());
	}

	@Override
	public List<IRI> getLiked() {
		return activityPubStore.getCollection(storeOwner.getSubject(), storeOwner.getLiked());
	}
	
	@Override
	public Graph dump() {
		Graph graph = activityPubStore.dump(storeOwner.getSubject());
		
		log.debug("DUMP ("+storeOwner.getSubject()+") -->" + new GraphToStringConverterDefault(null).convert(RdfFormat.TURTLE, graph));
		// TODO
		return graph;
	}

	@Override
	public Optional<ActivityPubObject> find(IRI subject) {
		return activityPubStore.find(subject);
	}

	@Override
	public Optional<ActivityPubObject> find(IRI subject, int deep) {
		return activityPubStore.find(subject, deep);
	}

	@Override
	public Optional<ActivityPubObject> find(IRI subject, IRI predicate, RDFTerm object) {
		return activityPubStore.find(subject, predicate, object);
	}

	@Override
	public Set<ActivityPubObject> findAll(Set<IRI> subject) {
		return activityPubStore.findAll(subject);
	}

	@Override
	public Set<IRI> findCollection(IRI member) {
		return activityPubStore.findCollection(member);
	}

	@Override
	public String toString() {
		return "ActorsStoreDefault [storeOwner=" + storeOwner.getSubject() + "]";
	}
}