package org.springframework.roo.addon.jsf.application; import static org.springframework.roo.addon.jsf.JsfJavaType.APPLICATION; import static org.springframework.roo.addon.jsf.JsfJavaType.APPLICATION_SCOPED; import static org.springframework.roo.addon.jsf.JsfJavaType.DISPLAY_CREATE_DIALOG; import static org.springframework.roo.addon.jsf.JsfJavaType.DISPLAY_LIST; import static org.springframework.roo.addon.jsf.JsfJavaType.EL_CONTEXT; import static org.springframework.roo.addon.jsf.JsfJavaType.EXPRESSION_FACTORY; import static org.springframework.roo.addon.jsf.JsfJavaType.FACES_CONTEXT; import static org.springframework.roo.addon.jsf.JsfJavaType.MANAGED_BEAN; import static org.springframework.roo.addon.jsf.JsfJavaType.PRIMEFACES_DEFAULT_MENU_MODEL; import static org.springframework.roo.addon.jsf.JsfJavaType.PRIMEFACES_MENU_ITEM; import static org.springframework.roo.addon.jsf.JsfJavaType.PRIMEFACES_MENU_MODEL; import static org.springframework.roo.addon.jsf.JsfJavaType.PRIMEFACES_SUB_MENU; import static org.springframework.roo.addon.jsf.JsfJavaType.REQUEST_SCOPED; import static org.springframework.roo.addon.jsf.JsfJavaType.SESSION_SCOPED; import static org.springframework.roo.addon.jsf.JsfJavaType.VIEW_SCOPED; import static org.springframework.roo.model.JdkJavaType.POST_CONSTRUCT; import static org.springframework.roo.model.RooJavaType.ROO_JSF_MANAGED_BEAN; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.builder.ToStringBuilder; import org.springframework.roo.classpath.PhysicalTypeIdentifierNamingUtils; import org.springframework.roo.classpath.PhysicalTypeMetadata; import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails; import org.springframework.roo.classpath.details.MemberFindingUtils; import org.springframework.roo.classpath.details.MethodMetadataBuilder; import org.springframework.roo.classpath.details.annotations.AnnotatedJavaType; import org.springframework.roo.classpath.details.annotations.AnnotationAttributeValue; import org.springframework.roo.classpath.details.annotations.AnnotationMetadata; import org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder; import org.springframework.roo.classpath.itd.AbstractItdTypeDetailsProvidingMetadataItem; import org.springframework.roo.classpath.itd.InvocableMemberBodyBuilder; import org.springframework.roo.metadata.MetadataIdentificationUtils; import org.springframework.roo.model.JavaSymbolName; import org.springframework.roo.model.JavaType; import org.springframework.roo.project.LogicalPath; /** * Metadata for {@link RooJsfApplicationBean}. * * @author Alan Stewart * @since 1.2.0 */ public class JsfApplicationBeanMetadata extends AbstractItdTypeDetailsProvidingMetadataItem { private static final String CREATE_ICON = "ui-icon ui-icon-document"; private static final String LIST_ICON = "ui-icon ui-icon-folder-open"; private static final JavaSymbolName MENU_MODEL = new JavaSymbolName( "menuModel"); private static final String PROVIDES_TYPE_STRING = JsfApplicationBeanMetadata.class .getName(); private static final String PROVIDES_TYPE = MetadataIdentificationUtils .create(PROVIDES_TYPE_STRING); public static String createIdentifier(final JavaType javaType, final LogicalPath path) { return PhysicalTypeIdentifierNamingUtils.createIdentifier( PROVIDES_TYPE_STRING, javaType, path); } public static JavaType getJavaType(final String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.getJavaType( PROVIDES_TYPE_STRING, metadataIdentificationString); } public static String getMetadataIdentiferType() { return PROVIDES_TYPE; } public static LogicalPath getPath(final String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.getPath(PROVIDES_TYPE_STRING, metadataIdentificationString); } public static boolean isValid(final String metadataIdentificationString) { return PhysicalTypeIdentifierNamingUtils.isValid(PROVIDES_TYPE_STRING, metadataIdentificationString); } private Set<ClassOrInterfaceTypeDetails> managedBeans; public JsfApplicationBeanMetadata(final String identifier, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final Set<ClassOrInterfaceTypeDetails> managedBeans, final String projectName) { super(identifier, aspectName, governorPhysicalTypeMetadata); Validate.isTrue(isValid(identifier), "Metadata identification string '" + identifier + "' does not appear to be a valid"); Validate.notNull(managedBeans, "Managed beans required"); Validate.isTrue(StringUtils.isNotBlank(projectName), "Project name required"); if (!isValid()) { return; } if (managedBeans.isEmpty()) { valid = false; return; } this.managedBeans = managedBeans; // Add @ManagedBean annotation if required builder.addAnnotation(getManagedBeanAnnotation()); // Add @SessionScoped annotation if required builder.addAnnotation(getScopeAnnotation()); // Add menu model field builder.addField(getField(MENU_MODEL, PRIMEFACES_MENU_MODEL)); // Add init() method builder.addMethod(getInitMethod()); // Add model field accessor method builder.addMethod(getAccessorMethod(MENU_MODEL, PRIMEFACES_MENU_MODEL)); // Add application name accessor method builder.addMethod(getMethod( Modifier.PUBLIC, new JavaSymbolName("getAppName"), JavaType.STRING, null, null, InvocableMemberBodyBuilder.getInstance().appendFormalLine( "return \"" + StringUtils.capitalize(projectName) + "\";"))); // Create a representation of the desired output ITD itdTypeDetails = builder.build(); } private MethodMetadataBuilder getInitMethod() { final JavaSymbolName methodName = new JavaSymbolName("init"); if (governorHasMethod(methodName)) { return null; } builder.getImportRegistrationResolver().addImports(EL_CONTEXT, APPLICATION, EXPRESSION_FACTORY, FACES_CONTEXT, PRIMEFACES_MENU_ITEM, PRIMEFACES_SUB_MENU, PRIMEFACES_DEFAULT_MENU_MODEL); final InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder(); bodyBuilder .appendFormalLine("FacesContext facesContext = FacesContext.getCurrentInstance();"); bodyBuilder .appendFormalLine("Application application = facesContext.getApplication();"); bodyBuilder .appendFormalLine("ExpressionFactory expressionFactory = application.getExpressionFactory();"); bodyBuilder .appendFormalLine("ELContext elContext = facesContext.getELContext();"); bodyBuilder.appendFormalLine(""); bodyBuilder.appendFormalLine("menuModel = new DefaultMenuModel();"); bodyBuilder.appendFormalLine("Submenu submenu;"); bodyBuilder.appendFormalLine("MenuItem item;"); for (final ClassOrInterfaceTypeDetails managedBean : managedBeans) { final AnnotationMetadata annotation = MemberFindingUtils .getAnnotationOfType(managedBean.getAnnotations(), ROO_JSF_MANAGED_BEAN); if (annotation == null) { continue; } final AnnotationAttributeValue<?> includeOnMenuAttributeValue = annotation .getAttribute(new JavaSymbolName("includeOnMenu")); if (includeOnMenuAttributeValue != null && !((Boolean) includeOnMenuAttributeValue.getValue()) .booleanValue()) { continue; } final AnnotationAttributeValue<?> entityAttributeValue = annotation .getAttribute(new JavaSymbolName("entity")); final JavaType entity = (JavaType) entityAttributeValue.getValue(); final String entityLabel = entity.getSimpleTypeName().length() > 26 ? entity .getSimpleTypeName().substring(0, 23) + "..." : entity.getSimpleTypeName(); final AnnotationAttributeValue<?> beanNameAttributeValue = annotation .getAttribute(new JavaSymbolName("beanName")); final String beanName = (String) beanNameAttributeValue.getValue(); bodyBuilder.appendFormalLine(""); bodyBuilder.appendFormalLine("submenu = new Submenu();"); bodyBuilder.appendFormalLine("submenu.setId(\"" + StringUtils.uncapitalize(entity.getSimpleTypeName()) + "Submenu\");"); bodyBuilder.appendFormalLine("submenu.setLabel(\"" + entityLabel + "\");"); bodyBuilder.appendFormalLine("item = new MenuItem();"); bodyBuilder.appendFormalLine("item.setId(\"create" + entity.getSimpleTypeName() + "MenuItem\");"); bodyBuilder .appendFormalLine("item.setValueExpression(\"value\", expressionFactory.createValueExpression(elContext, \"#{messages.label_create}\", String.class));"); bodyBuilder .appendFormalLine("item.setActionExpression(expressionFactory.createMethodExpression(elContext, \"#{" + beanName + "." + DISPLAY_CREATE_DIALOG + "}\", String.class, new Class[0]));"); bodyBuilder.appendFormalLine("item.setIcon(\"" + CREATE_ICON + "\");"); bodyBuilder.appendFormalLine("item.setAjax(false);"); bodyBuilder.appendFormalLine("item.setAsync(false);"); bodyBuilder.appendFormalLine("item.setUpdate(\":dataForm:data\");"); bodyBuilder.appendFormalLine("submenu.getChildren().add(item);"); bodyBuilder.appendFormalLine("item = new MenuItem();"); bodyBuilder.appendFormalLine("item.setId(\"list" + entity.getSimpleTypeName() + "MenuItem\");"); bodyBuilder .appendFormalLine("item.setValueExpression(\"value\", expressionFactory.createValueExpression(elContext, \"#{messages.label_list}\", String.class));"); bodyBuilder .appendFormalLine("item.setActionExpression(expressionFactory.createMethodExpression(elContext, \"#{" + beanName + "." + DISPLAY_LIST + "}\", String.class, new Class[0]));"); bodyBuilder .appendFormalLine("item.setIcon(\"" + LIST_ICON + "\");"); bodyBuilder.appendFormalLine("item.setAjax(false);"); bodyBuilder.appendFormalLine("item.setAsync(false);"); bodyBuilder.appendFormalLine("item.setUpdate(\":dataForm:data\");"); bodyBuilder.appendFormalLine("submenu.getChildren().add(item);"); bodyBuilder.appendFormalLine("menuModel.addSubmenu(submenu);"); } final MethodMetadataBuilder methodBuilder = new MethodMetadataBuilder( getId(), Modifier.PUBLIC, methodName, JavaType.VOID_PRIMITIVE, new ArrayList<AnnotatedJavaType>(), new ArrayList<JavaSymbolName>(), bodyBuilder); methodBuilder.addAnnotation(new AnnotationMetadataBuilder( POST_CONSTRUCT)); return methodBuilder; } private AnnotationMetadata getManagedBeanAnnotation() { return getTypeAnnotation(MANAGED_BEAN); } private AnnotationMetadata getScopeAnnotation() { if (hasScopeAnnotation()) { return null; } return new AnnotationMetadataBuilder(REQUEST_SCOPED).build(); } private boolean hasScopeAnnotation() { return governorTypeDetails.getAnnotation(SESSION_SCOPED) != null || governorTypeDetails.getAnnotation(VIEW_SCOPED) != null || governorTypeDetails.getAnnotation(REQUEST_SCOPED) != null || governorTypeDetails.getAnnotation(APPLICATION_SCOPED) != null; } @Override public String toString() { final ToStringBuilder builder = new ToStringBuilder(this); builder.append("identifier", getId()); builder.append("valid", valid); builder.append("aspectName", aspectName); builder.append("destinationType", destination); builder.append("governor", governorPhysicalTypeMetadata.getId()); builder.append("itdTypeDetails", itdTypeDetails); return builder.toString(); } }