SubjectProviderDefault.java

package org.linkedopenactors.rdfpub.domain.commonsrdf;

import java.net.URI;
import java.util.UUID;

import org.apache.commons.rdf.api.IRI;
import org.apache.commons.rdf.api.RDF;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class SubjectProviderDefault implements SubjectProvider {

	private RDF rdf;
	private String baseIriString;
	private SubjectProviderSettings subjectProviderSettings;

	public SubjectProviderDefault(RDF rdf, SubjectProviderSettings subjectProviderSettings ) {
		this.subjectProviderSettings = subjectProviderSettings;
		
		log.debug("subjectProviderSettings: " + subjectProviderSettings);
		
		this.baseIriString = subjectProviderSettings.getInternalUrnString();
		if(!this.baseIriString.endsWith(":")) {
			this.baseIriString = this.baseIriString.endsWith("/") ? this.baseIriString : this.baseIriString + "/";
		}
		this.rdf = rdf;		
	}
	
	@Override
	public IRI provideUniqueActorSubject() {
		return rdf.createIRI(baseIriString + UUID.randomUUID().toString());
	}

	@Override
	public IRI provide(IRI subject) {
		return rdf.createIRI(extractActor(subject) + "/" + UUID.randomUUID().toString());
	}

	@Override
	public IRI provide(Actor actor) {
		String actorId =  actor.getSubject().toString().endsWith("/") ? actor.getSubject().toString() : actor.getSubject().toString() + "/"; 
		return rdf.createIRI(actorId + UUID.randomUUID().toString());
	}

	@Override
	public IRI extractActor(IRI subject) {
		String actorId = StringUtils.replace(subject.toString(), baseIriString, "");
		
		String subjectString = subject.toString();
		subjectString = subjectString.endsWith("/") ? subjectString.substring(0, subjectString.length()-1) : subjectString;
		long count = subjectString.chars()
				.filter(ch -> ch == '/')
				.count();
		if(count == 1) {
			actorId = subjectString;
		} else if(count == 2) {
			actorId = subjectString.substring(0, subjectString.lastIndexOf("/"));
		} else {
			throw new IllegalStateException("we expect an urn, that has exact 1 or 2 slashes. Example: urn:rdfpub/actor123/someObjectId or urn:rdfpub/actor123. But is: " + subject.toString());
		}
		return rdf.createIRI(actorId);
	}
	
	@Override
	public IRI resolveExternal(IRI internalIriParam) {
		String internalAsString = internalIriParam.toString();
		String replace = resolveExternal(internalAsString);
		return rdf.createIRI(replace);
	}

	@Override
	public String getInternaleIriPrefix() {
		return baseIriString;
	}

	@Override
	public String getExternalIriPrefix() {
		return subjectProviderSettings.getInstanceDomainString();
	}

	@Override
	public String resolveExternal(String internalAsString) {
		String instanceDomainString = subjectProviderSettings.getInstanceDomainString();
		instanceDomainString = instanceDomainString.endsWith("/") ? instanceDomainString : instanceDomainString + "/";
		String result = internalAsString.replace(baseIriString, instanceDomainString);
		return result;
//		String internaleIriPrefix = getInternaleIriPrefix();
//		String externalIriPrefix = getExternalIriPrefix();
//		externalIriPrefix = externalIriPrefix.endsWith("/") ? externalIriPrefix : externalIriPrefix + "/";
//		return internalAsString.replace(internaleIriPrefix, externalIriPrefix);		
	}

	@Override
	public IRI resolveInternal(IRI internalAsIri) {
		return rdf.createIRI(resolveInternal(internalAsIri.toString()));
	}
	
	@Override
	public String resolveInternal(String internalAsString) {
		if(internalAsString.startsWith(baseIriString)) {
			return internalAsString; 
		}
			
		URI uri = URI.create(internalAsString);
		String path = uri.getPath();
		if(ObjectUtils.isEmpty(path) ) {
			internalAsString = internalAsString.endsWith("/") ? internalAsString : internalAsString + "/";
		}
		
		String instanceDomainString = subjectProviderSettings.getInstanceDomainString();
		instanceDomainString = instanceDomainString.endsWith("/") ? instanceDomainString : instanceDomainString + "/";
		String result = internalAsString.replace(instanceDomainString, baseIriString);
		return result;
	}
}