Skip to content

Commit

Permalink
Plural datatype property support - OOM implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
ledsoft committed Dec 9, 2016
1 parent 5705df3 commit 9f27c39
Show file tree
Hide file tree
Showing 17 changed files with 468 additions and 119 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* Copyright (C) 2016 Czech Technical University in Prague
*
* <p>
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
Expand All @@ -14,10 +14,15 @@
*/
package cz.cvut.kbss.jopa.model.metamodel;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* Instances of the type PluralAttribute represent persistent collection-valued
* attributes.
*
*
* @param <X>
* The type the represented collection belongs to
* @param <C>
Expand All @@ -27,21 +32,36 @@
*/
public interface PluralAttribute<X, C, E> extends Attribute<X, C>, Bindable<E> {

enum CollectionType {
COLLECTION, SET, LIST, MAP
}

/**
* Return the collection type.
*
* @return collection type
*/
CollectionType getCollectionType();

/**
* Return the type representing the element type of the collection.
*
* @return element type
*/
Type<E> getElementType();
enum CollectionType {
SET(Set.class), LIST(List.class), COLLECTION(Collection.class), MAP(Map.class);

CollectionType(Class<?> cls) {
this.collectionClass = cls;
}

private final Class<?> collectionClass;

public static CollectionType fromClass(Class<?> cls) {
for (CollectionType type : values()) {
if (type.collectionClass.isAssignableFrom(cls)) {
return type;
}
}
throw new IllegalArgumentException("Unsupported collection class " + cls);
}
}

/**
* Return the collection type.
*
* @return collection type
*/
CollectionType getCollectionType();

/**
* Return the type representing the element type of the collection.
*
* @return element type
*/
Type<E> getElementType();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cz.cvut.kbss.jopa.oom;

import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
import cz.cvut.kbss.jopa.model.metamodel.Attribute;
import cz.cvut.kbss.jopa.model.metamodel.EntityType;
import cz.cvut.kbss.ontodriver.model.Assertion;

abstract class DataPropertyFieldStrategy<X> extends FieldStrategy<Attribute<? super X, ?>, X> {

DataPropertyFieldStrategy(EntityType<X> et, Attribute<? super X, ?> att, Descriptor attributeDescriptor,
EntityMappingHelper mapper) {
super(et, att, attributeDescriptor, mapper);
}

boolean isValidRange(Object value) {
return attribute.getJavaType().isAssignableFrom(value.getClass()) || isFieldEnum();
}

boolean isFieldEnum() {
final Class<?> cls = attribute.getJavaField().getType();
return cls.isEnum();
}

Object resolveEnumValue(Object value) {
final Class cls = attribute.getJavaField().getType();
return Enum.valueOf(cls, value.toString());
}

@Override
Assertion createAssertion() {
return Assertion.createDataPropertyAssertion(attribute.getIRI().toURI(), attribute.isInferred());
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* Copyright (C) 2016 Czech Technical University in Prague
*
* <p>
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
Expand Down Expand Up @@ -51,8 +51,10 @@ abstract class FieldStrategy<T extends FieldSpecification<? super X, ?>, X> {
if (attribute.isCollection()) {
switch (attribute.getPersistentAttributeType()) {
case ANNOTATION:
case DATA:
throw new NotYetImplementedException();
case DATA:
return new PluralDataPropertyStrategy<X>(et, (PluralAttribute<? super X, ?, ?>) attribute,
fieldDescriptor, mapper);
case OBJECT:
return createPluralObjectPropertyStrategy(et, (PluralAttribute<? super X, ?, ?>) attribute,
fieldDescriptor, mapper);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package cz.cvut.kbss.jopa.oom;

import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
import cz.cvut.kbss.jopa.model.metamodel.EntityType;
import cz.cvut.kbss.jopa.model.metamodel.PluralAttribute;
import cz.cvut.kbss.jopa.utils.CollectionFactory;
import cz.cvut.kbss.ontodriver.model.Axiom;
import cz.cvut.kbss.ontodriver.model.Value;

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

public class PluralDataPropertyStrategy<X> extends DataPropertyFieldStrategy<X> {

private PluralAttribute<? super X, ?, ?> pluralAtt;

private Collection<Object> values;

PluralDataPropertyStrategy(EntityType<X> et, PluralAttribute<? super X, ?, ?> att, Descriptor attributeDescriptor,
EntityMappingHelper mapper) {
super(et, att, attributeDescriptor, mapper);
this.pluralAtt = att;
this.values = CollectionFactory.createDefaultCollection(pluralAtt.getCollectionType());
}

@Override
void addValueFromAxiom(Axiom<?> ax) {
final Object value = ax.getValue().getValue();
if (isValidRange(value)) {
this.values.add(value);
}
}

boolean isValidRange(Object value) {
return pluralAtt.getElementType().getJavaType().isAssignableFrom(value.getClass());
}

@Override
void buildInstanceFieldValue(Object instance) throws IllegalAccessException {
if (!values.isEmpty()) {
setValueOnInstance(instance, values);
}
}

@Override
void buildAxiomValuesFromInstance(X instance, AxiomValueGatherer valueBuilder) throws IllegalAccessException {
final Object value = extractFieldValueFromInstance(instance);
assert value instanceof Collection || value == null;
final Collection<?> valueCollection = (Collection<?>) value;
if (valueCollection == null || valueCollection.isEmpty()) {
valueBuilder.addValue(createAssertion(), Value.nullValue(), getAttributeContext());
} else {
final Set<Value<?>> assertionValues = valueCollection.stream().map(Value::new).collect(Collectors.toSet());
valueBuilder.addValues(createAssertion(), assertionValues, getAttributeContext());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* Copyright (C) 2016 Czech Technical University in Prague
*
* <p>
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
Expand All @@ -18,40 +18,24 @@
import cz.cvut.kbss.jopa.model.metamodel.Attribute;
import cz.cvut.kbss.jopa.model.metamodel.EntityType;
import cz.cvut.kbss.jopa.model.metamodel.PluralAttribute;
import cz.cvut.kbss.jopa.utils.CollectionFactory;
import cz.cvut.kbss.jopa.utils.IdentifierTransformer;
import cz.cvut.kbss.ontodriver.exception.NotYetImplementedException;
import cz.cvut.kbss.ontodriver.model.Assertion;
import cz.cvut.kbss.ontodriver.model.Axiom;
import cz.cvut.kbss.ontodriver.model.NamedResource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;

abstract class PluralObjectPropertyStrategy<X> extends FieldStrategy<Attribute<? super X, ?>, X> {

final PluralAttribute<? super X, ?, ?> pluralAtt;
private Collection<Object> values;

public PluralObjectPropertyStrategy(EntityType<X> et, Attribute<? super X, ?> att,
Descriptor descriptor, EntityMappingHelper mapper) {
PluralObjectPropertyStrategy(EntityType<X> et, Attribute<? super X, ?> att, Descriptor descriptor,
EntityMappingHelper mapper) {
super(et, att, descriptor, mapper);
this.pluralAtt = (PluralAttribute<? super X, ?, ?>) attribute;
initCollection();
}

private void initCollection() {
switch (pluralAtt.getCollectionType()) {
case LIST:
this.values = new ArrayList<>();
break;
case COLLECTION:
case SET:
this.values = new HashSet<>();
break;
default:
throw new NotYetImplementedException("This type of collection is not supported yet.");
}
this.values = CollectionFactory.createDefaultCollection(pluralAtt.getCollectionType());
}

@Override
Expand All @@ -70,7 +54,9 @@ void addValueFromAxiom(Axiom<?> ax) {

@Override
void buildInstanceFieldValue(Object instance) throws IllegalAccessException {
setValueOnInstance(instance, values.isEmpty() ? null : values);
if (!values.isEmpty()) {
setValueOnInstance(instance, values);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.net.URI;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

class SimpleSetPropertyStrategy<X> extends PluralObjectPropertyStrategy<X> {
Expand All @@ -48,7 +49,7 @@ private <T> void extractValues(Collection<T> valueCollection, AxiomValueGatherer
}
final Set<Value<?>> assertionValues = new HashSet<>(valueCollection.size());
if (IdentifierTransformer.isValidIdentifierType(pluralAtt.getBindableJavaType())) {
valueCollection.stream().filter(item -> item != null).forEach(item -> assertionValues
valueCollection.stream().filter(Objects::nonNull).forEach(item -> assertionValues
.add(new Value<>(NamedResource.create(IdentifierTransformer.valueAsUri(item)))));
} else {
final EntityType<T> et = (EntityType<T>) mapper.getEntityType(pluralAtt.getBindableJavaType());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/**
* Copyright (C) 2016 Czech Technical University in Prague
*
* <p>
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
Expand All @@ -18,12 +18,11 @@
import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
import cz.cvut.kbss.jopa.model.metamodel.Attribute;
import cz.cvut.kbss.jopa.model.metamodel.EntityType;
import cz.cvut.kbss.ontodriver.model.Assertion;
import cz.cvut.kbss.ontodriver.model.Axiom;
import cz.cvut.kbss.ontodriver.model.NamedResource;
import cz.cvut.kbss.ontodriver.model.Value;

class SingularDataPropertyStrategy<X> extends FieldStrategy<Attribute<? super X, ?>, X> {
class SingularDataPropertyStrategy<X> extends DataPropertyFieldStrategy<X> {

Object value;

Expand All @@ -50,37 +49,17 @@ void verifyCardinalityConstraint(NamedResource subject) {
}
}

boolean isValidRange(Object value) {
return attribute.getJavaType().isAssignableFrom(value.getClass()) || isFieldEnum();
}

private boolean isFieldEnum() {
final Class<?> cls = attribute.getJavaField().getType();
return cls.isEnum();
}

@Override
void buildInstanceFieldValue(Object entity) throws IllegalAccessException {
final Object toAssign = isFieldEnum() ? resolveEnumValue() : value;
final Object toAssign = isFieldEnum() ? resolveEnumValue(value) : value;
setValueOnInstance(entity, toAssign);
}

private Object resolveEnumValue() {
final Class cls = attribute.getJavaField().getType();
return Enum.valueOf(cls, value.toString());
}

@Override
void buildAxiomValuesFromInstance(X instance, AxiomValueGatherer valueBuilder) throws IllegalAccessException {
final Object extractedValue = extractFieldValueFromInstance(instance);

final Value<?> val = extractedValue != null ? new Value<>(extractedValue) : Value.nullValue();
valueBuilder.addValue(createAssertion(), val, getAttributeContext());
}

@Override
Assertion createAssertion() {
return Assertion.createDataPropertyAssertion(attribute.getIRI().toURI(),
attribute.isInferred());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import cz.cvut.kbss.jopa.exceptions.OWLPersistenceException;
import cz.cvut.kbss.jopa.model.annotations.Types;
import cz.cvut.kbss.jopa.model.descriptors.Descriptor;
import cz.cvut.kbss.jopa.model.metamodel.PluralAttribute;
import cz.cvut.kbss.jopa.utils.CollectionFactory;
import cz.cvut.kbss.jopa.utils.EntityPropertiesUtils;

import java.lang.reflect.Constructor;
Expand Down Expand Up @@ -222,13 +224,7 @@ void mergeChanges(Field field, Object target, Object originalValue, Object clone
}

private Collection<Object> createDefaultCollection(Class<?> cls) {
if (Set.class.isAssignableFrom(cls)) {
return new HashSet<>();
} else if (List.class.isAssignableFrom(cls)) {
return new ArrayList<>();
} else {
throw new IllegalArgumentException("Unsupported type of collection: " + cls);
}
return CollectionFactory.createDefaultCollection(PluralAttribute.CollectionType.fromClass(cls));
}

/**
Expand Down
Loading

0 comments on commit 9f27c39

Please sign in to comment.