Skip to content

Commit

Permalink
#10 - Cleaning up implementations. Adding concept of a Derived Label …
Browse files Browse the repository at this point in the history
…which can be used instead in the front-end of both the Admin and Site and making sure the proper fields are translatable
  • Loading branch information
elbertbautista committed May 8, 2014
1 parent b3ef415 commit 3a16919
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* #%L
* BroadleafCommerce Menu
* %%
* Copyright (C) 2009 - 2014 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.menu.admin.server.handler;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.broadleafcommerce.common.exception.ServiceException;
import org.broadleafcommerce.common.presentation.client.SupportedFieldType;
import org.broadleafcommerce.common.presentation.client.VisibilityEnum;
import org.broadleafcommerce.menu.domain.MenuItem;
import org.broadleafcommerce.menu.domain.MenuItemImpl;
import org.broadleafcommerce.menu.service.MenuService;
import org.broadleafcommerce.openadmin.dto.BasicFieldMetadata;
import org.broadleafcommerce.openadmin.dto.ClassMetadata;
import org.broadleafcommerce.openadmin.dto.CriteriaTransferObject;
import org.broadleafcommerce.openadmin.dto.DynamicResultSet;
import org.broadleafcommerce.openadmin.dto.Entity;
import org.broadleafcommerce.openadmin.dto.FieldMetadata;
import org.broadleafcommerce.openadmin.dto.MergedPropertyType;
import org.broadleafcommerce.openadmin.dto.PersistencePackage;
import org.broadleafcommerce.openadmin.dto.PersistencePerspective;
import org.broadleafcommerce.openadmin.dto.Property;
import org.broadleafcommerce.openadmin.server.dao.DynamicEntityDao;
import org.broadleafcommerce.openadmin.server.service.handler.CustomPersistenceHandlerAdapter;
import org.broadleafcommerce.openadmin.server.service.persistence.module.BasicPersistenceModule;
import org.broadleafcommerce.openadmin.server.service.persistence.module.InspectHelper;
import org.broadleafcommerce.openadmin.server.service.persistence.module.RecordHelper;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;

/**
* @author Elbert Bautista (elbertbautista)
*/
@Component("blMenuItemCustomPersistenceHandler")
public class MenuItemCustomPersistenceHandler extends CustomPersistenceHandlerAdapter {

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

public static final String DERIVED_LABEL_FIELD_NAME = "derivedLabel";

@Resource(name = "blMenuService")
protected MenuService menuService;

@Override
public Boolean canHandleInspect(PersistencePackage persistencePackage) {
String ceilingEntityFullyQualifiedClassname = persistencePackage.getCeilingEntityFullyQualifiedClassname();
try {
Class testClass = Class.forName(ceilingEntityFullyQualifiedClassname);
return MenuItem.class.isAssignableFrom(testClass);
} catch (ClassNotFoundException e) {
return false;
}
}

@Override
public Boolean canHandleFetch(PersistencePackage persistencePackage) {
return canHandleInspect(persistencePackage);
}

@Override
public DynamicResultSet inspect(PersistencePackage persistencePackage, DynamicEntityDao dynamicEntityDao, InspectHelper helper) throws ServiceException {
try {
PersistencePerspective persistencePerspective = persistencePackage.getPersistencePerspective();
Map<MergedPropertyType, Map<String, FieldMetadata>> allMergedProperties = new HashMap<MergedPropertyType, Map<String, FieldMetadata>>();

//retrieve the default properties for Menu Item
Map<String, FieldMetadata> properties = helper.getSimpleMergedProperties(MenuItem.class.getName(), persistencePerspective);

//create a new field to hold default content item checkbox
BasicFieldMetadata derivedLabelMetadata = new BasicFieldMetadata();
derivedLabelMetadata.setFieldType(SupportedFieldType.STRING);
derivedLabelMetadata.setMutable(false);
derivedLabelMetadata.setInheritedFromType(MenuItemImpl.class.getName());
derivedLabelMetadata.setAvailableToTypes(new String[]{MenuItemImpl.class.getName()});
derivedLabelMetadata.setForeignKeyCollection(false);
derivedLabelMetadata.setMergedPropertyType(MergedPropertyType.PRIMARY);
derivedLabelMetadata.setName(DERIVED_LABEL_FIELD_NAME);
derivedLabelMetadata.setFriendlyName("MenuItemImpl_Derived_Label");
derivedLabelMetadata.setExplicitFieldType(SupportedFieldType.STRING);
derivedLabelMetadata.setProminent(true);
derivedLabelMetadata.setReadOnly(true);
derivedLabelMetadata.setOrder(500);
derivedLabelMetadata.setGridOrder(500);

derivedLabelMetadata.setVisibility(VisibilityEnum.FORM_HIDDEN);
derivedLabelMetadata.setExcluded(false);
properties.put(DERIVED_LABEL_FIELD_NAME, derivedLabelMetadata);

allMergedProperties.put(MergedPropertyType.PRIMARY, properties);
Class<?>[] entityClasses = dynamicEntityDao.getAllPolymorphicEntitiesFromCeiling(MenuItem.class);
ClassMetadata mergedMetadata = helper.getMergedClassMetadata(entityClasses, allMergedProperties);

return new DynamicResultSet(mergedMetadata, null, null);

} catch (Exception e) {
String className = persistencePackage.getCeilingEntityFullyQualifiedClassname();
ServiceException ex = new ServiceException("Unable to retrieve inspection results for " + className, e);
LOG.error("Unable to retrieve inspection results for " + className, ex);
throw ex;
}
}

@Override
public DynamicResultSet fetch(PersistencePackage persistencePackage, CriteriaTransferObject cto, DynamicEntityDao dynamicEntityDao, RecordHelper helper) throws ServiceException {
DynamicResultSet drs = ((BasicPersistenceModule) helper).fetch(persistencePackage, cto);

for (Entity entity : drs.getRecords()) {
Property menuItemId = entity.findProperty("id");
if (menuItemId != null) {
MenuItem menuItem = menuService.findMenuItemById(Long.parseLong(menuItemId.getValue()));
if (menuItem != null) {
//Call getDerivedLabel() on an actual MenuItem entity
// as it is optional and can be determined by MenuItemType and not by reflection.
Property derivedLabel = new Property();
derivedLabel.setName(DERIVED_LABEL_FIELD_NAME);
derivedLabel.setValue(menuItem.getDerivedLabel());
entity.addProperty(derivedLabel);
}
}
}

return drs;
}

}
2 changes: 2 additions & 0 deletions src/main/java/org/broadleafcommerce/menu/dao/MenuDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public interface MenuDao {

public Menu readMenuById(Long menuId);

public MenuItem readMenuItemById(Long menuItemId);

public Menu readMenuByName(String menuName);

public Menu saveMenu(Menu menu);
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/org/broadleafcommerce/menu/dao/MenuDaoImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.broadleafcommerce.menu.domain.Menu;
import org.broadleafcommerce.menu.domain.MenuImpl;
import org.broadleafcommerce.menu.domain.MenuItem;
import org.broadleafcommerce.menu.domain.MenuItemImpl;
import org.hibernate.ejb.QueryHints;
import org.springframework.stereotype.Repository;
import java.util.List;
Expand Down Expand Up @@ -55,6 +56,11 @@ public Menu readMenuById(Long menuId) {
return em.find(MenuImpl.class, menuId);
}

@Override
public MenuItem readMenuItemById(Long menuItemId) {
return em.find(MenuItemImpl.class, menuItemId);
}

@Override
public Menu readMenuByName(String menuName) {
TypedQuery<Menu> query = em.createNamedQuery("BC_READ_MENU_BY_NAME", Menu.class);
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/org/broadleafcommerce/menu/domain/MenuImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.broadleafcommerce.common.extensibility.jpa.copy.DirectCopyTransformMember;
import org.broadleafcommerce.common.extensibility.jpa.copy.DirectCopyTransformTypes;
import org.broadleafcommerce.common.i18n.domain.TranslatedEntity;
import org.broadleafcommerce.common.i18n.service.DynamicTranslationProvider;
import org.broadleafcommerce.common.presentation.AdminPresentation;
import org.broadleafcommerce.common.presentation.AdminPresentationClass;
import org.broadleafcommerce.common.presentation.AdminPresentationCollection;
Expand Down Expand Up @@ -80,7 +81,8 @@ public class MenuImpl implements Menu, AdminMainEntity {
@AdminPresentation(friendlyName = "MenuImpl_Name",
order = Presentation.FieldOrder.NAME,
gridOrder = Presentation.FieldOrder.NAME,
prominent = true)
prominent = true,
translatable = true)
protected String name;

@OneToMany(mappedBy = "parentMenu", targetEntity = MenuItemImpl.class, cascade = { CascadeType.ALL }, orphanRemoval = true)
Expand All @@ -105,7 +107,7 @@ public void setId(Long id) {

@Override
public String getName() {
return name;
return DynamicTranslationProvider.getValue(this, "name", name);
}

@Override
Expand Down
15 changes: 11 additions & 4 deletions src/main/java/org/broadleafcommerce/menu/domain/MenuItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ public interface MenuItem extends Serializable {
public void setId(Long id);

/**
* The value to show for this menu item when displayed on a site.
* Will return the configured Label, unless of type {@link MenuItemType#PRODUCT}, or {@link MenuItemType#CATEGORY},
* or {@link MenuItemType#SUBMENU} which will return the corresponding linked name.
* Returns the label for this menu item
* @see MenuItem.getDerivedLabel() to get the label based on MenuItemType
* @return
*/
public String getLabel();

Expand Down Expand Up @@ -195,6 +195,13 @@ public interface MenuItem extends Serializable {
*
* @return
*/
public String getUrl();
public String getDerivedUrl();

/**
* Convenience method that will always return the configured Label if specified.
* If it is not specified and of type {@link MenuItemType#PRODUCT}, or {@link MenuItemType#CATEGORY},
* or {@link MenuItemType#SUBMENU}, it will return the corresponding linked name.
*/
public String getDerivedLabel();

}
37 changes: 22 additions & 15 deletions src/main/java/org/broadleafcommerce/menu/domain/MenuItemImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -180,20 +180,7 @@ public void setMenuItemType(MenuItemType menuItemType) {

@Override
public String getLabel() {
String l = DynamicTranslationProvider.getValue(this, "label", label);

if (MenuItemType.PRODUCT.equals(getMenuItemType()) &&
getLinkedProduct() != null) {
l = getLinkedProduct().getName();
} else if (MenuItemType.CATEGORY.equals(getMenuItemType()) &&
getLinkedCategory() != null) {
l = getLinkedCategory().getName();
} else if (MenuItemType.SUBMENU.equals(getMenuItemType()) &&
getLinkedMenu() != null) {
l = getLinkedMenu().getName();
}

return l;
return DynamicTranslationProvider.getValue(this, "label", label);
}

@Override
Expand Down Expand Up @@ -302,7 +289,7 @@ public void setCustomHtml(String customHtml) {
}

@Override
public String getUrl() {
public String getDerivedUrl() {
String url = getActionUrl();

if (MenuItemType.PRODUCT.equals(getMenuItemType()) &&
Expand All @@ -319,6 +306,26 @@ public String getUrl() {
return url;
}

@Override
public String getDerivedLabel() {
String l = getLabel();

if (l == null) {
if (MenuItemType.PRODUCT.equals(getMenuItemType()) &&
getLinkedProduct() != null) {
l = getLinkedProduct().getName();
} else if (MenuItemType.CATEGORY.equals(getMenuItemType()) &&
getLinkedCategory() != null) {
l = getLinkedCategory().getName();
} else if (MenuItemType.SUBMENU.equals(getMenuItemType()) &&
getLinkedMenu() != null) {
l = getLinkedMenu().getName();
}
}

return l;
}

public static class Presentation {

public static class FieldOrder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.broadleafcommerce.menu.service;

import org.broadleafcommerce.menu.domain.Menu;
import org.broadleafcommerce.menu.domain.MenuItem;
import org.broadleafcommerce.menu.dto.MenuItemDTO;
import java.util.List;

Expand All @@ -39,6 +40,13 @@ public interface MenuService {
*/
public Menu findMenuByName(String menuName);

/**
* Returns the menu item matching the passed in id.
* @param menuItemId
* @return
*/
public MenuItem findMenuItemById(Long menuItemId);

/**
* A Utility method that constructs generic MenuItemDTOs that are not dependent on a Menu Item Type.
* Allows for ease of use when building the front-end.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public Menu findMenuByName(String menuName) {
return menuDao.readMenuByName(menuName);
}

@Override
public MenuItem findMenuItemById(Long menuItemId) {
return menuDao.readMenuItemById(menuItemId);
}

@Override
public List<MenuItemDTO> constructMenuItemDTOsForMenu(Menu menu) {
if (CollectionUtils.isNotEmpty(menu.getMenuItems())) {
Expand All @@ -66,8 +71,8 @@ protected MenuItemDTO convertMenuItemToDTO(MenuItem menuItem) {
if (MenuItemType.SUBMENU.equals(menuItem.getMenuItemType()) &&
menuItem.getLinkedMenu() != null) {
MenuItemDTO dto = new MenuItemDTO();
dto.setUrl(menuItem.getUrl());
dto.setLabel(menuItem.getLabel());
dto.setUrl(menuItem.getDerivedUrl());
dto.setLabel(menuItem.getDerivedLabel());

List<MenuItemDTO> submenu = new ArrayList<MenuItemDTO>();
List<MenuItem> items = menuItem.getLinkedMenu().getMenuItems();
Expand All @@ -84,8 +89,8 @@ protected MenuItemDTO convertMenuItemToDTO(MenuItem menuItem) {
return convertCategoryToMenuItemDTO(menuItem.getLinkedCategory());
} else {
MenuItemDTO dto = new MenuItemDTO();
dto.setUrl(menuItem.getUrl());
dto.setLabel(menuItem.getLabel());
dto.setUrl(menuItem.getDerivedUrl());
dto.setLabel(menuItem.getDerivedLabel());
if (menuItem.getImage() != null) {
dto.setImageUrl(menuItem.getImage().getUrl());
dto.setAltText(menuItem.getAltText());
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/bl-menu-admin-applicationContext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
<bean id="blCustomPersistenceHandlers" class="org.springframework.beans.factory.config.ListFactoryBean" scope="prototype">
<property name="sourceList">
<list>
<ref bean="blMenuItemCustomPersistenceHandler"/>
</list>
</property>
</bean>
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/messages/Menu.properties
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ MenuImpl=Menu
MenuImpl_Name=Name
MenuItemImpl_MenuItems=Menu Items
MenuItemImpl_Type=Type
MenuItemImpl_Derived_Label=Derived Label
MenuItemImpl_Label=Label
MenuItemImpl_ActionUrl=Action Url
MenuItemImpl_Image=Image
Expand Down

0 comments on commit 3a16919

Please sign in to comment.