org.broadleafcommerce.openadmin.server.dao.provider.metadata.MapFieldsFieldMetadataProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.broadleafcommerce.openadmin.server.dao.provider.metadata.MapFieldsFieldMetadataProvider.java

Source

/*
 * #%L
 * BroadleafCommerce Open Admin Platform
 * %%
 * Copyright (C) 2009 - 2013 Broadleaf Commerce
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package org.broadleafcommerce.openadmin.server.dao.provider.metadata;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.broadleafcommerce.common.presentation.AdminPresentationMap;
import org.broadleafcommerce.common.presentation.AdminPresentationMapField;
import org.broadleafcommerce.common.presentation.AdminPresentationMapFields;
import org.broadleafcommerce.common.presentation.client.CustomFieldSearchableTypes;
import org.broadleafcommerce.common.presentation.client.SupportedFieldType;
import org.broadleafcommerce.openadmin.dto.BasicFieldMetadata;
import org.broadleafcommerce.openadmin.dto.FieldMetadata;
import org.broadleafcommerce.openadmin.dto.override.FieldMetadataOverride;
import org.broadleafcommerce.openadmin.server.dao.FieldInfo;
import org.broadleafcommerce.openadmin.server.dao.provider.metadata.request.AddMetadataFromFieldTypeRequest;
import org.broadleafcommerce.openadmin.server.dao.provider.metadata.request.AddMetadataRequest;
import org.broadleafcommerce.openadmin.server.dao.provider.metadata.request.OverrideViaAnnotationRequest;
import org.broadleafcommerce.openadmin.server.dao.provider.metadata.request.OverrideViaXmlRequest;
import org.broadleafcommerce.openadmin.server.service.persistence.module.FieldManager;
import org.broadleafcommerce.openadmin.server.service.type.FieldProviderResponse;
import org.hibernate.internal.TypeLocatorImpl;
import org.hibernate.type.Type;
import org.hibernate.type.TypeResolver;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.lang.reflect.ParameterizedType;
import java.util.Map;

/**
 * @author Jeff Fischer
 */
@Component("blMapFieldsFieldMetadataProvider")
@Scope("prototype")
public class MapFieldsFieldMetadataProvider extends DefaultFieldMetadataProvider {

    private static final Log LOG = LogFactory.getLog(MapFieldsFieldMetadataProvider.class);

    protected boolean canHandleFieldForConfiguredMetadata(AddMetadataRequest addMetadataRequest,
            Map<String, FieldMetadata> metadata) {
        AdminPresentationMapFields annot = addMetadataRequest.getRequestedField()
                .getAnnotation(AdminPresentationMapFields.class);
        return annot != null;
    }

    protected boolean canHandleFieldForTypeMetadata(AddMetadataFromFieldTypeRequest addMetadataFromFieldTypeRequest,
            Map<String, FieldMetadata> metadata) {
        AdminPresentationMapFields annot = addMetadataFromFieldTypeRequest.getRequestedField()
                .getAnnotation(AdminPresentationMapFields.class);
        return annot != null;
    }

    @Override
    public FieldProviderResponse addMetadata(AddMetadataRequest addMetadataRequest,
            Map<String, FieldMetadata> metadata) {
        if (!canHandleFieldForConfiguredMetadata(addMetadataRequest, metadata)) {
            return FieldProviderResponse.NOT_HANDLED;
        }
        AdminPresentationMapFields annot = addMetadataRequest.getRequestedField()
                .getAnnotation(AdminPresentationMapFields.class);
        for (AdminPresentationMapField mapField : annot.mapDisplayFields()) {
            if (mapField.fieldPresentation().fieldType() == SupportedFieldType.UNKNOWN) {
                throw new IllegalArgumentException(
                        "fieldType property on AdminPresentation must be set for AdminPresentationMapField");
            }
            FieldMetadataOverride override = constructBasicMetadataOverride(mapField.fieldPresentation(), null,
                    null);
            override.setFriendlyName(mapField.fieldPresentation().friendlyName());
            FieldInfo myInfo = new FieldInfo();
            myInfo.setName(addMetadataRequest.getRequestedField().getName() + FieldManager.MAPFIELDSEPARATOR
                    + mapField.fieldName());
            buildBasicMetadata(addMetadataRequest.getParentClass(), addMetadataRequest.getTargetClass(), metadata,
                    myInfo, override, addMetadataRequest.getDynamicEntityDao());
            setClassOwnership(addMetadataRequest.getParentClass(), addMetadataRequest.getTargetClass(), metadata,
                    myInfo);
            BasicFieldMetadata basicFieldMetadata = (BasicFieldMetadata) metadata.get(myInfo.getName());
            if (!mapField.targetClass().equals(Void.class)) {
                if (mapField.targetClass().isInterface()) {
                    throw new IllegalArgumentException(
                            "targetClass on @AdminPresentationMapField must be a concrete class");
                }
                basicFieldMetadata.setMapFieldValueClass(mapField.targetClass().getName());
            }
            if (mapField.searchable() != CustomFieldSearchableTypes.NOT_SPECIFIED) {
                basicFieldMetadata.setSearchable(mapField.searchable() == CustomFieldSearchableTypes.YES);
            }
            if (!StringUtils.isEmpty(mapField.manyToField())) {
                basicFieldMetadata.setManyToField(mapField.manyToField());
            }
            AdminPresentationMap annotMap = addMetadataRequest.getRequestedField()
                    .getAnnotation(AdminPresentationMap.class);
            if (annotMap != null && !StringUtils.isEmpty(annotMap.toOneTargetProperty())) {
                basicFieldMetadata.setToOneTargetProperty(annotMap.toOneTargetProperty());
            } else if (!StringUtils.isEmpty(annot.toOneTargetProperty())) {
                basicFieldMetadata.setToOneTargetProperty(annot.toOneTargetProperty());
            }
            if (annotMap != null && !StringUtils.isEmpty(annotMap.toOneParentProperty())) {
                basicFieldMetadata.setToOneParentProperty(annotMap.toOneParentProperty());
            } else if (!StringUtils.isEmpty(annot.toOneParentProperty())) {
                basicFieldMetadata.setToOneParentProperty(annot.toOneParentProperty());
            }
            String mapKeyValueProperty = "key";
            if (StringUtils.isNotBlank(myInfo.getMapKey())) {
                mapKeyValueProperty = myInfo.getMapKey();
            }
            if (annotMap != null) {
                if (StringUtils.isNotBlank(annotMap.mapKeyValueProperty())) {
                    mapKeyValueProperty = annotMap.mapKeyValueProperty();
                }
            }
            basicFieldMetadata.setMapKeyValueProperty(mapKeyValueProperty);
        }
        return FieldProviderResponse.HANDLED;
    }

    @Override
    public FieldProviderResponse addMetadataFromFieldType(
            AddMetadataFromFieldTypeRequest addMetadataFromFieldTypeRequest, Map<String, FieldMetadata> metadata) {
        if (!canHandleFieldForTypeMetadata(addMetadataFromFieldTypeRequest, metadata)) {
            return FieldProviderResponse.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 FieldProviderResponse.HANDLED;
    }

    @Override
    public FieldProviderResponse overrideViaAnnotation(OverrideViaAnnotationRequest overrideViaAnnotationRequest,
            Map<String, FieldMetadata> metadata) {
        //TODO support annotation override
        return FieldProviderResponse.NOT_HANDLED;
    }

    @Override
    public FieldProviderResponse overrideViaXml(OverrideViaXmlRequest overrideViaXmlRequest,
            Map<String, FieldMetadata> metadata) {
        //TODO support xml override
        return FieldProviderResponse.NOT_HANDLED;
    }

    @Override
    public int getOrder() {
        return FieldMetadataProvider.MAP_FIELD;
    }
}