use of org.broadleafcommerce.openadmin.dto.FieldMetadata in project BroadleafCommerce by BroadleafCommerce.
the class DynamicEntityDaoImpl method getMergedProperties.
@Override
public Map<String, FieldMetadata> getMergedProperties(String ceilingEntityFullyQualifiedClassname, Class<?>[] entities, ForeignKey foreignField, String[] additionalNonPersistentProperties, ForeignKey[] additionalForeignFields, MergedPropertyType mergedPropertyType, Boolean populateManyToOneFields, String[] includeFields, String[] excludeFields, String configurationKey, String prefix) {
Map<String, FieldMetadata> mergedProperties = getMergedPropertiesRecursively(ceilingEntityFullyQualifiedClassname, entities, foreignField, additionalNonPersistentProperties, additionalForeignFields, mergedPropertyType, populateManyToOneFields, includeFields, excludeFields, configurationKey, new ArrayList<Class<?>>(), prefix, false, "");
final List<String> removeKeys = new ArrayList<>();
for (final String key : mergedProperties.keySet()) {
if (mergedProperties.get(key).getExcluded() != null && mergedProperties.get(key).getExcluded()) {
removeKeys.add(key);
}
}
for (String removeKey : removeKeys) {
mergedProperties.remove(removeKey);
}
// Allow field metadata providers to contribute additional fields here. These latestage handlers take place
// after any cached lookups occur, and are ideal for adding in dynamic properties that are not globally cacheable
// like properties gleaned from reflection typically are.
Set<String> keys = new HashSet<>(mergedProperties.keySet());
for (Class<?> targetClass : entities) {
for (String key : keys) {
LateStageAddMetadataRequest amr = new LateStageAddMetadataRequest(key, null, targetClass, this, "");
boolean foundOneOrMoreHandlers = false;
for (FieldMetadataProvider fieldMetadataProvider : fieldMetadataProviders) {
MetadataProviderResponse response = fieldMetadataProvider.lateStageAddMetadata(amr, mergedProperties);
if (MetadataProviderResponse.NOT_HANDLED != response) {
foundOneOrMoreHandlers = true;
}
if (MetadataProviderResponse.HANDLED_BREAK == response) {
break;
}
}
if (!foundOneOrMoreHandlers) {
defaultFieldMetadataProvider.lateStageAddMetadata(amr, mergedProperties);
}
}
}
return mergedProperties;
}
use of org.broadleafcommerce.openadmin.dto.FieldMetadata in project BroadleafCommerce by BroadleafCommerce.
the class DynamicEntityDaoImpl method buildPropertiesFromPolymorphicEntities.
protected void buildPropertiesFromPolymorphicEntities(Class<?>[] entities, ForeignKey foreignField, String[] additionalNonPersistentProperties, ForeignKey[] additionalForeignFields, MergedPropertyType mergedPropertyType, Boolean populateManyToOneFields, String[] includeFields, String[] excludeFields, String configurationKey, String ceilingEntityFullyQualifiedClassname, Map<String, FieldMetadata> mergedProperties, List<Class<?>> parentClasses, String prefix, Boolean isParentExcluded, String parentPrefix) {
for (Class<?> clazz : entities) {
String cacheKey = getCacheKey(ceilingEntityFullyQualifiedClassname, foreignField, additionalNonPersistentProperties, additionalForeignFields, mergedPropertyType, populateManyToOneFields, clazz, configurationKey, isParentExcluded);
Map<String, FieldMetadata> cacheData = null;
synchronized (DynamicDaoHelperImpl.LOCK_OBJECT) {
if (useCache()) {
cacheData = METADATA_CACHE.get(cacheKey);
}
if (cacheData == null) {
Map<String, FieldMetadata> props = getPropertiesForEntityClass(clazz, foreignField, additionalNonPersistentProperties, additionalForeignFields, mergedPropertyType, populateManyToOneFields, includeFields, excludeFields, configurationKey, ceilingEntityFullyQualifiedClassname, parentClasses, prefix, isParentExcluded, parentPrefix);
// first check all the properties currently in there to see if my entity inherits from them
for (Class<?> clazz2 : entities) {
if (!clazz2.getName().equals(clazz.getName())) {
for (Map.Entry<String, FieldMetadata> entry : props.entrySet()) {
FieldMetadata metadata = entry.getValue();
try {
if (Class.forName(metadata.getInheritedFromType()).isAssignableFrom(clazz2)) {
String[] both = ArrayUtils.addAll(metadata.getAvailableToTypes(), new String[] { clazz2.getName() });
metadata.setAvailableToTypes(both);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
}
METADATA_CACHE.put(cacheKey, props);
if (LOG.isTraceEnabled()) {
LOG.trace("Added " + props.size() + " to the metadata cache with key " + cacheKey + " for the class " + ceilingEntityFullyQualifiedClassname);
}
if (validateMetadataCacheSizes) {
Integer previousSize = METADATA_CACHE_SIZES.get(cacheKey);
Integer currentSize = props.size();
if (previousSize == null) {
METADATA_CACHE_SIZES.put(cacheKey, currentSize);
} else if (!currentSize.equals(previousSize)) {
String msg = "Attempted to store " + currentSize + " properties in the cache for the key " + cacheKey + " but we had previously stored " + previousSize + " properties";
LOG.error(msg);
throw new RuntimeException(msg);
}
}
cacheData = props;
} else {
if (LOG.isTraceEnabled()) {
LOG.trace("Read " + cacheData.size() + " from the metada cache with key " + cacheKey + " for the class " + ceilingEntityFullyQualifiedClassname);
}
}
}
// clone the metadata before passing to the system
Map<String, FieldMetadata> clonedCache = new HashMap<>(cacheData.size());
for (Map.Entry<String, FieldMetadata> entry : cacheData.entrySet()) {
clonedCache.put(entry.getKey(), entry.getValue().cloneFieldMetadata());
}
mergedProperties.putAll(clonedCache);
}
}
use of org.broadleafcommerce.openadmin.dto.FieldMetadata in project BroadleafCommerce by BroadleafCommerce.
the class DynamicEntityDaoImpl method applyIncludesAndExcludes.
protected void applyIncludesAndExcludes(String[] includeFields, String[] excludeFields, String prefix, Boolean isParentExcluded, Map<String, FieldMetadata> mergedProperties) {
// check includes
if (!ArrayUtils.isEmpty(includeFields)) {
for (String include : includeFields) {
for (String key : mergedProperties.keySet()) {
String testKey = prefix + key;
if (!(testKey.startsWith(include + ".") || testKey.equals(include))) {
FieldMetadata metadata = mergedProperties.get(key);
LOG.debug("applyIncludesAndExcludes:Excluding " + key + " because this field did not appear in the explicit includeFields list");
metadata.setExcluded(true);
} else {
FieldMetadata metadata = mergedProperties.get(key);
if (!isParentExcluded) {
LOG.debug("applyIncludesAndExcludes:Showing " + key + " because this field appears in the explicit includeFields list");
metadata.setExcluded(false);
}
}
}
}
} else if (!ArrayUtils.isEmpty(excludeFields)) {
// check excludes
for (String exclude : excludeFields) {
for (String key : mergedProperties.keySet()) {
String testKey = prefix + key;
if (testKey.startsWith(exclude + ".") || testKey.equals(exclude)) {
FieldMetadata metadata = mergedProperties.get(key);
LOG.debug("applyIncludesAndExcludes:Excluding " + key + " because this field appears in the explicit excludeFields list");
metadata.setExcluded(true);
} else {
FieldMetadata metadata = mergedProperties.get(key);
if (!isParentExcluded) {
LOG.debug("applyIncludesAndExcludes:Showing " + key + " because this field did not appear in the explicit excludeFields list");
metadata.setExcluded(false);
}
}
}
}
}
}
use of org.broadleafcommerce.openadmin.dto.FieldMetadata in project BroadleafCommerce by BroadleafCommerce.
the class DynamicEntityDaoImpl method buildBasicProperty.
protected void buildBasicProperty(Field field, Class<?> targetClass, ForeignKey foreignField, ForeignKey[] additionalForeignFields, String[] additionalNonPersistentProperties, MergedPropertyType mergedPropertyType, Map<String, FieldMetadata> presentationAttributes, List<Property> componentProperties, Map<String, FieldMetadata> fields, String idProperty, Boolean populateManyToOneFields, String[] includeFields, String[] excludeFields, String configurationKey, String ceilingEntityFullyQualifiedClassname, List<Class<?>> parentClasses, String prefix, Boolean isParentExcluded, String propertyName, Type type, boolean propertyForeignKey, int additionalForeignKeyIndexPosition, Boolean isComponentPrefix, String parentPrefix) {
FieldMetadata presentationAttribute = presentationAttributes.get(propertyName);
Boolean amIExcluded = isParentExcluded || !testPropertyInclusion(presentationAttribute);
Boolean includeField = !testPropertyRecursion(prefix, parentClasses, propertyName, targetClass, ceilingEntityFullyQualifiedClassname, isComponentPrefix, parentPrefix);
SupportedFieldType explicitType = null;
if (presentationAttribute != null && presentationAttribute instanceof BasicFieldMetadata) {
explicitType = ((BasicFieldMetadata) presentationAttribute).getExplicitFieldType();
}
Class<?> returnedClass = type.getReturnedClass();
checkProp: {
if (type.isComponentType() && includeField) {
buildComponentProperties(targetClass, foreignField, additionalForeignFields, additionalNonPersistentProperties, mergedPropertyType, fields, idProperty, populateManyToOneFields, includeFields, excludeFields, configurationKey, ceilingEntityFullyQualifiedClassname, propertyName, type, returnedClass, parentClasses, amIExcluded, prefix, parentPrefix);
break checkProp;
}
/*
* Currently we do not support ManyToOne fields whose class type is the same
* as the target type, since this forms an infinite loop and will cause a stack overflow.
*/
if (type.isEntityType() && !returnedClass.isAssignableFrom(targetClass) && populateManyToOneFields && includeField) {
buildEntityProperties(fields, foreignField, additionalForeignFields, additionalNonPersistentProperties, populateManyToOneFields, includeFields, excludeFields, configurationKey, ceilingEntityFullyQualifiedClassname, propertyName, returnedClass, targetClass, parentClasses, prefix, amIExcluded, parentPrefix);
break checkProp;
}
}
// Don't include this property if it failed manyToOne inclusion and is not a specified foreign key
if (includeField || propertyForeignKey || additionalForeignKeyIndexPosition >= 0) {
defaultFieldMetadataProvider.addMetadataFromFieldType(new AddMetadataFromFieldTypeRequest(field, targetClass, foreignField, additionalForeignFields, mergedPropertyType, componentProperties, idProperty, prefix, propertyName, type, propertyForeignKey, additionalForeignKeyIndexPosition, presentationAttributes, presentationAttribute, explicitType, returnedClass, this), fields);
}
}
use of org.broadleafcommerce.openadmin.dto.FieldMetadata in project BroadleafCommerce by BroadleafCommerce.
the class MapFieldsFieldMetadataProvider method addMetadataFromFieldType.
@Override
public MetadataProviderResponse addMetadataFromFieldType(AddMetadataFromFieldTypeRequest addMetadataFromFieldTypeRequest, Map<String, FieldMetadata> metadata) {
if (!canHandleFieldForTypeMetadata(addMetadataFromFieldTypeRequest, metadata)) {
return MetadataProviderResponse.NOT_HANDLED;
}
// look for any map field metadata that was previously added for the requested field
for (Map.Entry<String, FieldMetadata> entry : addMetadataFromFieldTypeRequest.getPresentationAttributes().entrySet()) {
if (entry.getKey().startsWith(addMetadataFromFieldTypeRequest.getRequestedPropertyName() + FieldManager.MAPFIELDSEPARATOR)) {
TypeLocatorImpl typeLocator = new TypeLocatorImpl(new TypeResolver());
Type myType = null;
// first, check if an explicit type was declared
String valueClass = ((BasicFieldMetadata) entry.getValue()).getMapFieldValueClass();
if (valueClass != null) {
myType = typeLocator.entity(valueClass);
}
if (myType == null) {
SupportedFieldType fieldType = ((BasicFieldMetadata) entry.getValue()).getExplicitFieldType();
Class<?> basicJavaType = getBasicJavaType(fieldType);
if (basicJavaType != null) {
myType = typeLocator.basic(basicJavaType);
}
}
if (myType == null) {
java.lang.reflect.Type genericType = addMetadataFromFieldTypeRequest.getRequestedField().getGenericType();
if (genericType instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) genericType;
Class<?> clazz = (Class<?>) pType.getActualTypeArguments()[1];
Class<?>[] entities = addMetadataFromFieldTypeRequest.getDynamicEntityDao().getAllPolymorphicEntitiesFromCeiling(clazz);
if (!ArrayUtils.isEmpty(entities)) {
myType = typeLocator.entity(entities[entities.length - 1]);
}
}
}
if (myType == null) {
throw new IllegalArgumentException("Unable to establish the type for the property (" + entry.getKey() + ")");
}
// add property for this map field as if it was a normal field
super.addMetadataFromFieldType(new AddMetadataFromFieldTypeRequest(addMetadataFromFieldTypeRequest.getRequestedField(), addMetadataFromFieldTypeRequest.getTargetClass(), addMetadataFromFieldTypeRequest.getForeignField(), addMetadataFromFieldTypeRequest.getAdditionalForeignFields(), addMetadataFromFieldTypeRequest.getMergedPropertyType(), addMetadataFromFieldTypeRequest.getComponentProperties(), addMetadataFromFieldTypeRequest.getIdProperty(), addMetadataFromFieldTypeRequest.getPrefix(), entry.getKey(), myType, addMetadataFromFieldTypeRequest.isPropertyForeignKey(), addMetadataFromFieldTypeRequest.getAdditionalForeignKeyIndexPosition(), addMetadataFromFieldTypeRequest.getPresentationAttributes(), entry.getValue(), ((BasicFieldMetadata) entry.getValue()).getExplicitFieldType(), myType.getReturnedClass(), addMetadataFromFieldTypeRequest.getDynamicEntityDao()), metadata);
}
}
return MetadataProviderResponse.HANDLED;
}
Aggregations