/* * #%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.broadleafcommerce.common.presentation.AdminPresentationCollection; import org.broadleafcommerce.common.presentation.AdminPresentationMap; import org.broadleafcommerce.common.presentation.client.VisibilityEnum; import org.broadleafcommerce.openadmin.dto.BasicFieldMetadata; import org.broadleafcommerce.openadmin.dto.CollectionMetadata; import org.broadleafcommerce.openadmin.dto.FieldMetadata; import org.broadleafcommerce.openadmin.server.dao.FieldInfo; import org.broadleafcommerce.openadmin.server.dao.provider.metadata.request.AddMetadataFromFieldTypeRequest; import org.broadleafcommerce.openadmin.server.service.type.FieldProviderResponse; import java.lang.reflect.ParameterizedType; import java.util.HashMap; import java.util.Map; import javax.annotation.Resource; /** * @author Jeff Fischer */ public class AdvancedCollectionFieldMetadataProvider extends FieldMetadataProviderAdapter { public static String FOREIGN_KEY_ADDITIONAL_METADATA_KEY = "foreign_key"; @Resource(name = "blDefaultFieldMetadataProvider") protected DefaultFieldMetadataProvider defaultMetadataProvider; protected boolean canHandleFieldForTypeMetadata(AddMetadataFromFieldTypeRequest addMetadataFromFieldTypeRequest, Map<String, FieldMetadata> metadata) { AdminPresentationMap map = addMetadataFromFieldTypeRequest.getRequestedField().getAnnotation(AdminPresentationMap.class); AdminPresentationCollection collection = addMetadataFromFieldTypeRequest.getRequestedField().getAnnotation(AdminPresentationCollection.class); return map != null || collection != null; } @Override public FieldProviderResponse addMetadataFromFieldType(AddMetadataFromFieldTypeRequest addMetadataFromFieldTypeRequest, Map<String, FieldMetadata> metadata) { if (!canHandleFieldForTypeMetadata(addMetadataFromFieldTypeRequest, metadata)) { return FieldProviderResponse.NOT_HANDLED; } CollectionMetadata fieldMetadata = (CollectionMetadata) addMetadataFromFieldTypeRequest.getPresentationAttribute(); if (StringUtils.isEmpty(fieldMetadata.getCollectionCeilingEntity())) { ParameterizedType listType = (ParameterizedType) addMetadataFromFieldTypeRequest.getRequestedField().getGenericType(); Class<?> listClass = (Class<?>) listType.getActualTypeArguments()[0]; fieldMetadata.setCollectionCeilingEntity(listClass.getName()); } if (addMetadataFromFieldTypeRequest.getTargetClass() != null) { if (StringUtils.isEmpty(fieldMetadata.getInheritedFromType())) { fieldMetadata.setInheritedFromType(addMetadataFromFieldTypeRequest.getTargetClass().getName()); } if (ArrayUtils.isEmpty(fieldMetadata.getAvailableToTypes())) { fieldMetadata.setAvailableToTypes(new String[]{addMetadataFromFieldTypeRequest.getTargetClass().getName()}); } } // Handle scenarios where the collection metadata is also a foreign key. The {@link BasicFieldMetadata} that has all // of the information about the foreign key will travel along with the built {@link BasicCollectionMetadata} under // the {@link FieldMetadata#getAdditionalMetadata()} field. This is then pulled out within // {@link BasicPersistenceModule#filterOutCollectionMetadata} if (addMetadataFromFieldTypeRequest.getForeignField() != null && addMetadataFromFieldTypeRequest.isPropertyForeignKey()) { FieldInfo info = buildFieldInfo(addMetadataFromFieldTypeRequest.getRequestedField()); BasicFieldMetadata basicMetadata = new BasicFieldMetadata(); basicMetadata.setName(info.getName()); basicMetadata.setExcluded(false); // Don't show this anywhere on the form and ensure it's explicitly not required basicMetadata.setVisibility(VisibilityEnum.HIDDEN_ALL); basicMetadata.setRequired(false); setClassOwnership(addMetadataFromFieldTypeRequest.getReturnedClass(), addMetadataFromFieldTypeRequest.getTargetClass(), metadata, info); Map<String, FieldMetadata> fakedMd = new HashMap<String, FieldMetadata>(); fakedMd.put(addMetadataFromFieldTypeRequest.getRequestedField().getName(), basicMetadata); // Fake out a request and some metadata to pass along as additional metadata within this metadata AddMetadataFromFieldTypeRequest fakedRequest = new AddMetadataFromFieldTypeRequest(addMetadataFromFieldTypeRequest.getRequestedField(), addMetadataFromFieldTypeRequest.getTargetClass(), addMetadataFromFieldTypeRequest.getForeignField(), addMetadataFromFieldTypeRequest.getAdditionalForeignFields(), addMetadataFromFieldTypeRequest.getMergedPropertyType(), addMetadataFromFieldTypeRequest.getComponentProperties(), addMetadataFromFieldTypeRequest.getIdProperty(), addMetadataFromFieldTypeRequest.getPrefix(), addMetadataFromFieldTypeRequest.getRequestedPropertyName(), addMetadataFromFieldTypeRequest.getType(), addMetadataFromFieldTypeRequest.isPropertyForeignKey(), addMetadataFromFieldTypeRequest.getAdditionalForeignKeyIndexPosition(), fakedMd, basicMetadata, addMetadataFromFieldTypeRequest.getExplicitType(), addMetadataFromFieldTypeRequest.getReturnedClass(), addMetadataFromFieldTypeRequest.getDynamicEntityDao()); defaultMetadataProvider.addMetadataFromFieldType(fakedRequest, fakedMd); fieldMetadata.getAdditionalMetadata().put(FOREIGN_KEY_ADDITIONAL_METADATA_KEY, basicMetadata); } metadata.put(addMetadataFromFieldTypeRequest.getRequestedPropertyName(), fieldMetadata); return FieldProviderResponse.HANDLED; } }