Permalink
Browse files

Merge remote-tracking branch 'origin/master'

Conflicts:
	pom.xml
  • Loading branch information...
DirkMahler committed May 15, 2018
2 parents ebf88bc + 7fc3e36 commit 5c1618ce4fde8ce8117bd8158871e0a443607b51
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.parent</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.api</artifactId>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.parent</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xo.distribution</artifactId>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.parent</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xo.doc</artifactId>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.parent</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.impl</artifactId>
@@ -110,10 +110,10 @@ public AbstractInstanceManager(TransactionalCache<DatastoreId> cache, InstanceLi
private void validateTypes(TypeMetadataSet<?> types) {
int size = types.size();
if (size == 1) {
if (types.containsAbstractType()) {
if (types.isAbstract()) {
throw new XOException("Cannot create an instance of a single abstract type " + types);
}
} else if (types.containsFinalType()) {
} else if (types.isFinal()) {
throw new XOException("Cannot create an instance overriding a final type " + types);
}
}
@@ -1,37 +1,55 @@
package com.buschmais.xo.impl.metadata;
import java.util.*;
import java.util.concurrent.ExecutionException;
import com.buschmais.xo.api.XOException;
import com.buschmais.xo.api.bootstrap.XOUnit;
import com.buschmais.xo.spi.datastore.DatastoreEntityMetadata;
import com.buschmais.xo.spi.datastore.TypeMetadataSet;
import com.buschmais.xo.spi.metadata.type.EntityTypeMetadata;
import com.buschmais.xo.spi.metadata.type.TypeMetadata;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* Allows resolving types from entity discriminators as provided by the
* datastores.
*
* @param <Discriminator> The discriminator type of the datastore (e.g. Neo4j labels or
* strings for JSON stores).
* @param <Discriminator>
* The discriminator type of the datastore (e.g. Neo4j labels or
* strings for JSON stores).
*/
public class EntityTypeMetadataResolver<EntityMetadata extends DatastoreEntityMetadata<Discriminator>, Discriminator> {
private static final Logger LOGGER = LoggerFactory.getLogger(EntityTypeMetadataResolver.class);
private final Map<EntityTypeMetadata<EntityMetadata>, Set<Discriminator>> aggregatedDiscriminators = new HashMap<>();
private final Map<Discriminator, Set<EntityTypeMetadata<EntityMetadata>>> typeMetadataByDiscriminator = new HashMap<>();
private final Map<EntityTypeMetadata<EntityMetadata>, Set<EntityTypeMetadata<EntityMetadata>>> aggregatedSuperTypes = new HashMap<>();
private final Map<EntityTypeMetadata<EntityMetadata>, Set<EntityTypeMetadata<EntityMetadata>>> aggregatedSubTypes = new HashMap<>();
private final Cache<Set<Discriminator>, TypeMetadataSet<EntityTypeMetadata<EntityMetadata>>> cache = CacheBuilder.newBuilder().build();
/**
* Constructor.
*
* @param metadataByType A map of all types with their metadata.
* @param metadataByType
* A map of all types with their metadata.
*/
public EntityTypeMetadataResolver(Map<Class<?>, TypeMetadata> metadataByType, XOUnit.MappingConfiguration mappingConfiguration) {
LOGGER.debug("Type metadata = '{}'", metadataByType);
// Aggregate all super types
for (TypeMetadata typeMetadata : metadataByType.values()) {
if (typeMetadata instanceof EntityTypeMetadata) {
EntityTypeMetadata<EntityMetadata> entityTypeMetadata = (EntityTypeMetadata<EntityMetadata>) typeMetadata;
aggregateSuperTypes(entityTypeMetadata);
}
}
Map<Set<Discriminator>, Set<EntityTypeMetadata<EntityMetadata>>> entityMetadataByDiscriminators = new HashMap<>();
for (TypeMetadata typeMetadata : metadataByType.values()) {
if (typeMetadata instanceof EntityTypeMetadata) {
@@ -46,17 +64,19 @@ public EntityTypeMetadataResolver(Map<Class<?>, TypeMetadata> metadataByType, XO
LOGGER.debug("Aggregated discriminators of '{}' = '{}'", typeMetadata, discriminators);
}
}
for (TypeMetadata typeMetadata : metadataByType.values()) {
if (typeMetadata instanceof EntityTypeMetadata) {
Set<Discriminator> discriminators = aggregatedDiscriminators.get(typeMetadata);
for (Discriminator discriminator : discriminators) {
Set<EntityTypeMetadata<EntityMetadata>> entityTypeMetadataOfDiscriminator = typeMetadataByDiscriminator.get(discriminator);
if (entityTypeMetadataOfDiscriminator == null) {
entityTypeMetadataOfDiscriminator = new HashSet<>();
typeMetadataByDiscriminator.put(discriminator, entityTypeMetadataOfDiscriminator);
EntityTypeMetadata<EntityMetadata> metadata = (EntityTypeMetadata<EntityMetadata>) typeMetadata;
Set<Discriminator> discriminators = getAggregatedDiscriminators(metadata);
for (Discriminator discriminator : discriminators) {
Set<EntityTypeMetadata<EntityMetadata>> entityTypeMetadata = typeMetadataByDiscriminator.get(discriminator);
if (entityTypeMetadata == null) {
entityTypeMetadata = new HashSet<>();
typeMetadataByDiscriminator.put(discriminator, entityTypeMetadata);
}
entityTypeMetadata.add(metadata);
}
entityTypeMetadataOfDiscriminator.add((EntityTypeMetadata<EntityMetadata>) typeMetadata);
}
}
}
LOGGER.debug("Type metadata by discriminators: '{}'", typeMetadataByDiscriminator);
@@ -77,11 +97,42 @@ public EntityTypeMetadataResolver(Map<Class<?>, TypeMetadata> metadataByType, XO
}
}
private Set<EntityTypeMetadata<EntityMetadata>> aggregateSuperTypes(EntityTypeMetadata<EntityMetadata> entityTypeMetadata) {
Set<EntityTypeMetadata<EntityMetadata>> superTypes = aggregatedSuperTypes.get(entityTypeMetadata);
if (superTypes == null) {
superTypes = new TypeMetadataSet<>();
for (TypeMetadata metadata : entityTypeMetadata.getSuperTypes()) {
if (metadata instanceof EntityTypeMetadata) {
EntityTypeMetadata<EntityMetadata> superTypeMetadata = (EntityTypeMetadata<EntityMetadata>) metadata;
superTypes.add(superTypeMetadata);
addSubType(superTypeMetadata, entityTypeMetadata);
Set<EntityTypeMetadata<EntityMetadata>> aggregatedSuperTypes = aggregateSuperTypes(superTypeMetadata);
superTypes.addAll(aggregatedSuperTypes);
for (EntityTypeMetadata<EntityMetadata> superType : superTypes) {
addSubType(superType, entityTypeMetadata);
}
}
}
aggregatedSuperTypes.put(entityTypeMetadata, superTypes);
}
return superTypes;
};
private void addSubType(EntityTypeMetadata<EntityMetadata> superType, EntityTypeMetadata<EntityMetadata> subType) {
Set<EntityTypeMetadata<EntityMetadata>> subTypes = aggregatedSubTypes.get(superType);
if (subTypes == null) {
subTypes = new TypeMetadataSet<>();
aggregatedSubTypes.put(superType, subTypes);
}
subTypes.add(subType);
}
/**
* Determine the set of discriminators for one type, i.e. the discriminator
* of the type itself and of all it's super types.
* Determine the set of discriminators for one type, i.e. the discriminator of
* the type itself and of all it's super types.
*
* @param typeMetadata The type.
* @param typeMetadata
* The type.
* @return The set of discriminators.
*/
private Set<Discriminator> getAggregatedDiscriminators(EntityTypeMetadata<EntityMetadata> typeMetadata) {
@@ -92,9 +143,10 @@ public EntityTypeMetadataResolver(Map<Class<?>, TypeMetadata> metadataByType, XO
if (discriminator != null) {
discriminators.add(discriminator);
}
for (TypeMetadata superTypeMetadata : typeMetadata.getSuperTypes()) {
if (superTypeMetadata instanceof EntityTypeMetadata) {
discriminators.addAll(getAggregatedDiscriminators((EntityTypeMetadata<EntityMetadata>) superTypeMetadata));
for (EntityTypeMetadata<EntityMetadata> superTypeMetadata : aggregatedSuperTypes.get(typeMetadata)) {
discriminator = superTypeMetadata.getDatastoreMetadata().getDiscriminator();
if (discriminator != null) {
discriminators.add(discriminator);
}
}
aggregatedDiscriminators.put(typeMetadata, discriminators);
@@ -103,31 +155,41 @@ public EntityTypeMetadataResolver(Map<Class<?>, TypeMetadata> metadataByType, XO
}
/**
* Return a {@link com.buschmais.xo.spi.datastore.TypeMetadataSet}
* containing all types matching to the given entity discriminators.
* Return a {@link com.buschmais.xo.spi.datastore.TypeMetadataSet} containing
* all types matching to the given entity discriminators.
*
* @param discriminators The discriminators.
* @param discriminators
* The discriminators.
* @return The {@link com.buschmais.xo.spi.datastore.TypeMetadataSet}.
*/
public TypeMetadataSet<EntityTypeMetadata<EntityMetadata>> getTypes(Set<Discriminator> discriminators) {
// Get all types matching the discriminators
TypeMetadataSet<EntityTypeMetadata<EntityMetadata>> allEntityTypeMetadatas = new TypeMetadataSet<>();
for (Discriminator discriminator : discriminators) {
Set<EntityTypeMetadata<EntityMetadata>> entityTypeMetadataOfDiscriminator = typeMetadataByDiscriminator.get(discriminator);
if (entityTypeMetadataOfDiscriminator != null) {
for (EntityTypeMetadata<EntityMetadata> entityTypeMetadata : entityTypeMetadataOfDiscriminator) {
Set<Discriminator> entityDiscriminators = aggregatedDiscriminators.get(entityTypeMetadata);
if (discriminators.size() >= entityDiscriminators.size() && discriminators.containsAll(entityDiscriminators)) {
allEntityTypeMetadatas.add(entityTypeMetadata);
try {
return cache.get(discriminators, () -> {
TypeMetadataSet<EntityTypeMetadata<EntityMetadata>> result = new TypeMetadataSet<>();
for (Discriminator discriminator : discriminators) {
Set<EntityTypeMetadata<EntityMetadata>> candidates = typeMetadataByDiscriminator.get(discriminator);
if (candidates != null) {
for (EntityTypeMetadata<EntityMetadata> candidate : candidates) {
Set<EntityTypeMetadata<EntityMetadata>> candidateSubTypes = aggregatedSubTypes.get(candidate);
if (candidateSubTypes == null || !result.containsAny(candidateSubTypes)) {
Set<Discriminator> entityDiscriminators = aggregatedDiscriminators.get(candidate);
if (discriminators.size() >= entityDiscriminators.size() && discriminators.containsAll(entityDiscriminators)) {
result.add(candidate);
result.removeAll(aggregatedSuperTypes.get(candidate));
}
}
}
}
}
}
return result;
});
} catch (ExecutionException e) {
throw new XOException("Cannot resolve types for discriminators " + discriminators);
}
return allEntityTypeMetadatas;
}
};
public Set<Discriminator> getDiscriminators(EntityTypeMetadata<EntityMetadata> entityTypeMetadata) {
Set<Discriminator> discriminators = aggregatedDiscriminators.get(entityTypeMetadata);
return discriminators != null ? discriminators : Collections.<Discriminator>emptySet();
return discriminators != null ? discriminators : Collections.<Discriminator> emptySet();
}
}
@@ -17,7 +17,7 @@ public Object invoke(T datastoreType, Object instance, Object[] args) {
}
String id = getId(datastoreType);
if (id != null) {
stringBuffer.append(", id=");
stringBuffer.append(":");
stringBuffer.append(id);
}
stringBuffer.append(getProperties(datastoreType));
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.parent</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.inject</artifactId>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.parent</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.json</artifactId>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.neo4j</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.neo4j.api</artifactId>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.neo4j</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.neo4j.doc</artifactId>
@@ -38,25 +38,25 @@
<!-- For using an embedded Neo4j instance -->
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.neo4j.embedded</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</dependency>
<dependency>
<!-- For using a remote Neo4j instance -->
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.neo4j.remote</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</dependency>
<dependency>
<!-- The XO API -->
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.api</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</dependency>
<dependency>
<!-- The XO runtime implementation -->
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.impl</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
<dependency>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.neo4j</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.neo4j.embedded</artifactId>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.parent</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.neo4j</artifactId>
<packaging>pom</packaging>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.neo4j</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.neo4j.remote</artifactId>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.neo4j</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.neo4j.spi</artifactId>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.neo4j</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.neo4j.test</artifactId>
@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.parent</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>eXtended Objects</name>
@@ -3,7 +3,7 @@
<parent>
<groupId>com.buschmais.xo</groupId>
<artifactId>xo.parent</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.11.0-SNAPSHOT</version>
</parent>
<artifactId>xo.spi</artifactId>
Oops, something went wrong.

0 comments on commit 5c1618c

Please sign in to comment.