package org.javers.core.metamodel.object; import org.javers.common.collections.Lists; import org.javers.core.metamodel.type.EntityType; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import static org.javers.common.validation.Validate.argumentsAreNotNull; /** * ValueObject global unique identifier. * <br> <br> * * Since ValueObjects doesn't have public Id, * they are identified by <i>fragment path</i> in the context of owning Entity instance. * * @author bartosz walacik */ public class ValueObjectId extends GlobalId { private static final String SEGMENT_SEP = "/"; private final GlobalId ownerId; private final String fragment; public ValueObjectId(String typeName, GlobalId ownerId, String fragment) { super(typeName); argumentsAreNotNull(ownerId, fragment); this.ownerId = ownerId; this.fragment = fragment; } /** * Path to ValueObject, should be unique in the Entity <b>instance</b> scope. * Usually, property name. * It works like <i>fragment identifier</i> in URL */ public String getFragment() { return fragment; } public boolean hasOwnerOfType(EntityType entityType){ return ownerId.getTypeName().equals(entityType.getName()); } public GlobalId getOwnerId() { return ownerId; } @Override public String value() { return getOwnerId().value() +"#"+ fragment; } public Set<ValueObjectId> getParentValueObjectIds() { List<String> segments = segments(); if (segments.size() == 1) { return Collections.emptySet(); } return segments.stream() .limit(segments.size()-1) .map(s -> new ValueObjectId(this.getTypeName(), ownerId, s)) .collect(Collectors.toSet()); } private List<String> segments() { String[] segments = fragment.split(SEGMENT_SEP); List<String> joinedSegments = Lists.asList(segments[0]); if (segments.length > 1) { for (int i = 1; i < segments.length; i++) { joinedSegments.add(joinedSegments.get(i - 1) + SEGMENT_SEP + segments[i]); } } return joinedSegments; } }