use of com.blazebit.persistence.view.metamodel.SingularAttribute in project blaze-persistence by Blazebit.
the class ViewMapper method createAccessor.
private ObjectMapper createAccessor(ManagedViewType<S> sourceType, ManagedViewType<T> targetType, boolean ignoreMissing, EntityViewKindMapping entityViewKindMapping, EntityViewManager entityViewManager, ProxyFactory proxyFactory, MethodAttribute<? super T, ?> targetAttribute, String prefix, Map<String, Key<Object, Object>> subMappers) {
String newPrefix;
if (prefix.isEmpty()) {
newPrefix = targetAttribute.getName();
} else {
newPrefix = prefix + "." + targetAttribute.getName();
}
Type<?> attributeType;
MappingConstructorImpl<?> constructor = null;
Boolean maybeMarkNew = entityViewKindMapping == EntityViewKindMapping.MARK_NEW ? null : false;
Key<Object, Object> subMapperKey = subMappers.get(newPrefix);
if (subMapperKey == Key.EXCLUDE_MARKER) {
return null;
} else if (subMapperKey != null) {
ignoreMissing = subMapperKey.ignoreMissing;
maybeMarkNew = subMapperKey.markNew;
}
// Try to find a source attribute
MethodAttribute<?, ?> sourceAttribute;
AttributeAccessor accessor;
if (sourceType == null) {
sourceAttribute = null;
if (targetAttribute.getMappingType() == Attribute.MappingType.PARAMETER) {
return new ParameterObjectMapper(((MappingAttribute<?, ?>) targetAttribute).getMapping());
}
accessor = Accessors.forEntityMapping((EntityViewManagerImpl) entityViewManager, targetAttribute);
if (accessor == null) {
if (ignoreMissing) {
return null;
}
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type is missing in source type!", targetType);
}
} else {
sourceAttribute = sourceType.getAttribute(targetAttribute.getName());
if (sourceAttribute == null) {
if (targetAttribute.getMappingType() == Attribute.MappingType.PARAMETER) {
return new ParameterObjectMapper(((MappingAttribute<?, ?>) targetAttribute).getMapping());
}
// Optionally ignore missing attributes
if (ignoreMissing) {
return null;
}
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type is missing in source type!", sourceType, targetType);
}
accessor = Accessors.forViewAttribute(null, sourceAttribute, true);
}
// Handle conversion from one type to another
if (targetAttribute.isCollection()) {
if ((sourceAttribute != null) && (targetAttribute.getConvertedJavaType() != sourceAttribute.getConvertedJavaType())) {
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different plural type than in source type!", sourceType, targetType);
}
PluralAttribute<?, ?, ?> targetPluralAttr = (PluralAttribute<?, ?, ?>) targetAttribute;
Type<?> elementType = (sourceAttribute == null) ? null : ((PluralAttribute<?, ?, ?>) sourceAttribute).getElementType();
ViewMapper<Object, Object> valueMapper = null;
attributeType = targetPluralAttr.getElementType();
if (subMapperKey != null) {
attributeType = subMapperKey.targetType;
constructor = subMapperKey.targetConstructor;
}
if (targetAttribute.isSubview()) {
valueMapper = createViewMapper(elementType, attributeType, constructor, ignoreMissing, maybeMarkNew, entityViewManager, proxyFactory, newPrefix, subMappers);
} else if ((sourceType != null) && (targetPluralAttr.getElementType() != elementType)) {
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different element type than in source type!", sourceType, targetType);
}
boolean needsDirtyTracker = ((AbstractAttribute<?, ?>) targetAttribute).needsDirtyTracker();
if (targetPluralAttr.getCollectionType() == PluralAttribute.CollectionType.MAP) {
MapAttribute<?, ?, ?> targetMapAttr = (MapAttribute<?, ?, ?>) targetAttribute;
Type<?> keyType = (sourceAttribute == null) ? null : ((MapAttribute<?, ?, ?>) sourceAttribute).getKeyType();
ViewMapper<Object, Object> keyMapper = null;
if (targetMapAttr.isKeySubview()) {
String newKeyPrefix = "KEY(" + newPrefix + ")";
Key<Object, Object> keySubMapperKey = subMappers.get(newKeyPrefix);
if (keySubMapperKey == Key.EXCLUDE_MARKER) {
keyMapper = null;
} else {
constructor = null;
Type<?> keyTargetType = targetMapAttr.getKeyType();
Boolean maybeMarkNewKey = entityViewKindMapping == EntityViewKindMapping.MARK_NEW ? null : false;
if (subMapperKey != null) {
constructor = keySubMapperKey.targetConstructor;
keyTargetType = keySubMapperKey.targetType;
ignoreMissing = keySubMapperKey.ignoreMissing;
maybeMarkNewKey = keySubMapperKey.markNew;
}
keyMapper = createViewMapper(keyType, keyTargetType, constructor, ignoreMissing, maybeMarkNewKey, entityViewManager, proxyFactory, newPrefix, subMappers);
}
} else if ((sourceType != null) && (targetMapAttr.getKeyType() != keyType)) {
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different key type than in source type!", sourceType, targetType);
}
MapInstantiatorImplementor<?, ?> mapInstantiator = ((AbstractAttribute<?, ?>) targetAttribute).getMapInstantiator();
return new MapObjectMapper(accessor, needsDirtyTracker, entityViewKindMapping != EntityViewKindMapping.MARK_NEW, mapInstantiator, keyMapper, valueMapper);
} else {
CollectionInstantiatorImplementor<?, ?> collectionInstantiator = ((AbstractAttribute<?, ?>) targetAttribute).getCollectionInstantiator();
return new CollectionObjectMapper(accessor, needsDirtyTracker, entityViewKindMapping != EntityViewKindMapping.MARK_NEW, collectionInstantiator, valueMapper);
}
} else if (targetAttribute.isSubview()) {
attributeType = ((SingularAttribute<?, ?>) targetAttribute).getType();
if (subMapperKey != null) {
attributeType = subMapperKey.targetType;
constructor = subMapperKey.targetConstructor;
}
Type<?> type = (sourceAttribute == null) ? null : ((SingularAttribute<?, ?>) sourceAttribute).getType();
ViewMapper<Object, Object> mapper = createViewMapper(type, attributeType, constructor, ignoreMissing, maybeMarkNew, entityViewManager, proxyFactory, newPrefix, subMappers);
return new AttributeObjectMapper(accessor, mapper);
} else if ((sourceAttribute != null) && (targetAttribute.getConvertedJavaType() != sourceAttribute.getConvertedJavaType())) {
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different type than in source type!", sourceType, targetType);
} else {
return new PassthroughObjectMapper(accessor);
}
}
use of com.blazebit.persistence.view.metamodel.SingularAttribute in project blaze-persistence by Blazebit.
the class Mappers method forViewConvertToViewAttributeMapping.
public static <S, T> Mapper<S, T> forViewConvertToViewAttributeMapping(EntityViewManagerImpl evm, ViewType<S> sourceViewType, ViewType<T> targetViewType, Map<String, String> mapping, Mapper<S, T> additionalMapper) {
List<Mapper<S, T>> mappers = new ArrayList<>();
ExpressionFactory ef = evm.getCriteriaBuilderFactory().getService(ExpressionFactory.class);
for (MethodAttribute<?, ?> attribute : targetViewType.getAttributes()) {
if (attribute.isUpdatable() && attribute instanceof MappingAttribute<?, ?> && attribute instanceof SingularAttribute<?, ?>) {
for (Map.Entry<String, String> entry : mapping.entrySet()) {
if (entry.getValue().equals(((MappingAttribute) attribute).getMapping())) {
Type<?> attributeType = ((SingularAttribute<?, ?>) attribute).getType();
AttributeAccessor entityAccessor;
if (entry.getKey().isEmpty()) {
entityAccessor = Accessors.forEntityMapping(evm, sourceViewType.getEntityClass(), ((MappingAttribute<?, ?>) sourceViewType.getIdAttribute()).getMapping());
} else {
entityAccessor = Accessors.forEntityMapping(evm, sourceViewType.getEntityClass(), entry.getKey());
}
AttributeAccessor targetAttributeAccessor = Accessors.forMutableViewAttribute(evm, attribute);
if (attributeType instanceof ViewType<?>) {
ViewType<?> viewType = (ViewType<?>) attributeType;
Type<?> attributeViewIdType = ((SingularAttribute<?, ?>) viewType.getIdAttribute()).getType();
EntityTupleizer entityTupleizer = null;
ObjectBuilder<?> idViewBuilder = null;
if (attributeViewIdType instanceof ManagedViewType<?>) {
entityTupleizer = new DefaultEntityTupleizer(evm, (ManagedViewType<?>) attributeViewIdType);
idViewBuilder = (ObjectBuilder<Object>) evm.getTemplate(new MacroConfigurationExpressionFactory(ef, ef.getDefaultMacroConfiguration()), (ManagedViewTypeImplementor<?>) attributeViewIdType, null, null, new MutableViewJpqlMacro(), null, new MutableEmbeddingViewJpqlMacro(), 0).createObjectBuilder(null, null, null, 0, false, false);
}
mappers.add(new ReferenceViewAttributeMapper<S, T>(evm, entityAccessor, viewType.getJavaType(), entityTupleizer, targetAttributeAccessor, idViewBuilder));
} else {
mappers.add((Mapper<S, T>) new AttributeMapper<>(Collections.singletonList(entityAccessor), Collections.singletonList(targetAttributeAccessor)));
}
}
}
}
}
if (mappers.isEmpty()) {
return additionalMapper;
}
return new CompositeMapper<>(mappers.toArray(new Mapper[mappers.size()]));
}
use of com.blazebit.persistence.view.metamodel.SingularAttribute in project blaze-persistence by Blazebit.
the class ViewMetamodelTest method testMappingSingularView.
@Test
public void testMappingSingularView() {
ViewMetamodel viewMetamodel = build(PersonViewWithSingularMapping.class).getMetamodel();
ViewType<?> viewType = viewMetamodel.view(PersonViewWithSingularMapping.class);
assertNotNull(viewType);
MethodAttribute<?, ?> attribute = viewType.getAttribute("ownedDocuments");
assertNotNull(attribute);
assertFalse(attribute.isCollection());
assertTrue(attribute instanceof SingularAttribute);
}
use of com.blazebit.persistence.view.metamodel.SingularAttribute in project blaze-persistence by Blazebit.
the class GraphQLEntityViewSupportFactory method create.
/**
* Returns a new {@link GraphQLEntityViewSupport} after registering the entity view types from {@link EntityViewManager}
* on the given {@link TypeDefinitionRegistry}.
*
* @param typeRegistry The registry to register types
* @param entityViewManager The entity view manager
* @return a new {@link GraphQLEntityViewSupport}
*/
public GraphQLEntityViewSupport create(TypeDefinitionRegistry typeRegistry, EntityViewManager entityViewManager) {
EntityMetamodel entityMetamodel = entityViewManager.getService(EntityMetamodel.class);
Map<String, Class<?>> typeNameToClass = new HashMap<>();
Map<String, Map<String, String>> typeNameToFieldMapping = new HashMap<>();
for (ManagedViewType<?> managedView : entityViewManager.getMetamodel().getManagedViews()) {
if (typeFilterPattern != null && !typeFilterPattern.matcher(managedView.getJavaType().getName()).matches()) {
continue;
}
String typeName = getObjectTypeName(managedView);
String inputTypeName = typeName + "Input";
String description = getDescription(managedView.getJavaType());
List<FieldDefinition> fieldDefinitions = new ArrayList<>(managedView.getAttributes().size());
List<InputValueDefinition> valueDefinitions = new ArrayList<>(managedView.getAttributes().size());
for (MethodAttribute<?, ?> attribute : managedView.getAttributes()) {
if (isIgnored(attribute.getJavaMethod())) {
continue;
}
Type type;
Type inputType;
if (attribute instanceof SingularAttribute<?, ?>) {
SingularAttribute<?, ?> singularAttribute = (SingularAttribute<?, ?>) attribute;
if (singularAttribute.isId() && !singularAttribute.isSubview()) {
// Usual numeric ID
type = getIdType(typeRegistry, singularAttribute);
inputType = getInputIdType(typeRegistry, singularAttribute);
} else {
type = getElementType(typeRegistry, singularAttribute, entityMetamodel);
inputType = getInputElementType(typeRegistry, singularAttribute, entityMetamodel);
}
} else if (attribute instanceof MapAttribute<?, ?, ?>) {
MapAttribute<?, ?, ?> mapAttribute = (MapAttribute<?, ?, ?>) attribute;
type = getEntryType(typeRegistry, attribute, getKeyType(typeRegistry, mapAttribute), getElementType(typeRegistry, mapAttribute));
inputType = getInputEntryType(typeRegistry, attribute, getInputKeyType(typeRegistry, mapAttribute), getInputElementType(typeRegistry, mapAttribute));
} else {
type = new ListType(getElementType(typeRegistry, (PluralAttribute<?, ?, ?>) attribute));
inputType = new ListType(getInputElementType(typeRegistry, (PluralAttribute<?, ?, ?>) attribute));
}
String fieldName = getFieldName(attribute);
FieldDefinition fieldDefinition = new FieldDefinition(fieldName, type);
fieldDefinitions.add(fieldDefinition);
addFieldMapping(typeNameToFieldMapping, typeName, attribute, fieldName);
valueDefinitions.add(new InputValueDefinition(fieldName, inputType));
addFieldMapping(typeNameToFieldMapping, inputTypeName, attribute, fieldName);
}
addObjectTypeDefinition(typeRegistry, typeNameToClass, managedView, newObjectTypeDefinition(typeName, fieldDefinitions, description), newInputObjectTypeDefinition(inputTypeName, valueDefinitions, description));
}
Set<String> serializableBasicTypes = new HashSet<>();
for (javax.persistence.metamodel.Type<?> basicType : entityMetamodel.getBasicTypes()) {
for (Class<?> superType : ReflectionUtils.getSuperTypes(basicType.getJavaType())) {
serializableBasicTypes.add(superType.getName());
}
serializableBasicTypes.add(basicType.getJavaType().getName());
}
serializableBasicTypes.add(Serializable[].class.getName());
serializableBasicTypes.add(GraphQLCursor.class.getName());
return new GraphQLEntityViewSupport(typeNameToClass, typeNameToFieldMapping, serializableBasicTypes);
}
use of com.blazebit.persistence.view.metamodel.SingularAttribute in project blaze-persistence by Blazebit.
the class GraphQLEntityViewSupportFactory method create.
/**
* Returns a new {@link GraphQLEntityViewSupport} after registering the entity view types from {@link EntityViewManager}
* on the given {@link TypeDefinitionRegistry}.
*
* @param schemaBuilder The registry to register types
* @param entityViewManager The entity view manager
* @return a new {@link GraphQLEntityViewSupport}
*/
public GraphQLEntityViewSupport create(GraphQLSchema.Builder schemaBuilder, EntityViewManager entityViewManager) {
Set<GraphQLType> additionalTypes = isDefineNormalTypes() ? getAndClearAdditionalTypes(schemaBuilder) : Collections.emptySet();
EntityMetamodel entityMetamodel = entityViewManager.getService(EntityMetamodel.class);
Map<String, Class<?>> typeNameToClass = new HashMap<>();
Map<String, Map<String, String>> typeNameToFieldMapping = new HashMap<>();
Map<Class<?>, String> registeredTypeNames = new HashMap<>();
for (ManagedViewType<?> managedView : entityViewManager.getMetamodel().getManagedViews()) {
if (typeFilterPattern != null && !typeFilterPattern.matcher(managedView.getJavaType().getName()).matches()) {
continue;
}
String typeName = getObjectTypeName(managedView);
String inputTypeName = getInputObjectTypeName(managedView);
String description = getDescription(managedView.getJavaType());
GraphQLObjectType.Builder builder = GraphQLObjectType.newObject().name(typeName);
GraphQLInputObjectType.Builder inputBuilder = GraphQLInputObjectType.newInputObject().name(inputTypeName);
if (description != null) {
builder.description(description);
inputBuilder.description(description);
}
for (MethodAttribute<?, ?> attribute : managedView.getAttributes()) {
if (isIgnored(attribute.getJavaMethod())) {
continue;
}
GraphQLFieldDefinition.Builder fieldBuilder = GraphQLFieldDefinition.newFieldDefinition();
String fieldName = getFieldName(attribute);
fieldBuilder.name(fieldName);
GraphQLOutputType type;
GraphQLInputType inputType;
if (attribute instanceof SingularAttribute<?, ?>) {
SingularAttribute<?, ?> singularAttribute = (SingularAttribute<?, ?>) attribute;
if (singularAttribute.isId() && !singularAttribute.isSubview()) {
type = getIdType(singularAttribute);
inputType = getInputIdType(singularAttribute);
} else {
type = getElementType(schemaBuilder, singularAttribute, registeredTypeNames, entityMetamodel);
inputType = getInputElementType(schemaBuilder, singularAttribute, registeredTypeNames, entityMetamodel);
}
} else if (attribute instanceof MapAttribute<?, ?, ?>) {
MapAttribute<?, ?, ?> mapAttribute = (MapAttribute<?, ?, ?>) attribute;
type = getEntryType(schemaBuilder, attribute, getKeyType(schemaBuilder, mapAttribute, registeredTypeNames), getElementType(schemaBuilder, mapAttribute, registeredTypeNames));
inputType = getInputEntryType(schemaBuilder, attribute, getInputKeyType(schemaBuilder, mapAttribute, registeredTypeNames), getInputElementType(schemaBuilder, mapAttribute, registeredTypeNames));
} else {
type = new GraphQLList(getElementType(schemaBuilder, (PluralAttribute<?, ?, ?>) attribute, registeredTypeNames));
inputType = new GraphQLList(getInputElementType(schemaBuilder, (PluralAttribute<?, ?, ?>) attribute, registeredTypeNames));
}
fieldBuilder.type(type);
builder.field(fieldBuilder);
addFieldMapping(typeNameToFieldMapping, typeName, attribute, fieldName);
inputBuilder.field(GraphQLInputObjectField.newInputObjectField().name(fieldName).type(inputType).build());
addFieldMapping(typeNameToFieldMapping, inputTypeName, attribute, fieldName);
}
addObjectTypeDefinition(schemaBuilder, typeNameToClass, managedView, builder.build(), inputBuilder.build());
}
Set<String> serializableBasicTypes = new HashSet<>();
for (javax.persistence.metamodel.Type<?> basicType : entityMetamodel.getBasicTypes()) {
for (Class<?> superType : ReflectionUtils.getSuperTypes(basicType.getJavaType())) {
serializableBasicTypes.add(superType.getName());
}
serializableBasicTypes.add(basicType.getJavaType().getName());
}
serializableBasicTypes.add(Serializable[].class.getName());
serializableBasicTypes.add(GraphQLCursor.class.getName());
for (GraphQLType additionalType : additionalTypes) {
String typeName;
if (additionalType instanceof GraphQLObjectType) {
typeName = ((GraphQLObjectType) additionalType).getName();
} else if (additionalType instanceof GraphQLInterfaceType) {
typeName = ((GraphQLInterfaceType) additionalType).getName();
} else {
typeName = null;
}
if (typeName == null || typeNameToClass.get(typeName) == null) {
schemaBuilder.additionalType(additionalType);
}
}
return new GraphQLEntityViewSupport(typeNameToClass, typeNameToFieldMapping, serializableBasicTypes);
}
Aggregations