package org.springframework.roo.addon.jsf.application;
import static org.springframework.roo.model.RooJavaType.ROO_JSF_APPLICATION_BEAN;
import static org.springframework.roo.model.RooJavaType.ROO_JSF_MANAGED_BEAN;
import java.util.Set;
import org.apache.commons.lang3.Validate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.component.ComponentContext;
import org.springframework.roo.addon.configurable.ConfigurableMetadataProvider;
import org.springframework.roo.addon.jsf.managedbean.JsfManagedBeanMetadata;
import org.springframework.roo.classpath.PhysicalTypeIdentifier;
import org.springframework.roo.classpath.PhysicalTypeMetadata;
import org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails;
import org.springframework.roo.classpath.itd.AbstractItdMetadataProvider;
import org.springframework.roo.classpath.itd.ItdTypeDetailsProvidingMetadataItem;
import org.springframework.roo.metadata.MetadataIdentificationUtils;
import org.springframework.roo.model.JavaType;
import org.springframework.roo.project.LogicalPath;
import org.springframework.roo.project.ProjectMetadata;
import org.springframework.roo.project.ProjectOperations;
/**
* Implementation of {@link JsfApplicationBeanMetadataProvider}.
*
* @author Alan Stewart
* @since 1.2.0
*/
@Component(immediate = true)
@Service
public class JsfApplicationBeanMetadataProviderImpl extends
AbstractItdMetadataProvider implements
JsfApplicationBeanMetadataProvider {
@Reference private ConfigurableMetadataProvider configurableMetadataProvider;
@Reference private ProjectOperations projectOperations;
// Stores the MID (as accepted by this JsfApplicationBeanMetadataProvider)
// for the one (and only one) application-wide menu bean
private String applicationBeanMid;
protected void activate(final ComponentContext context) {
metadataDependencyRegistry.registerDependency(
PhysicalTypeIdentifier.getMetadataIdentiferType(),
getProvidesType());
metadataDependencyRegistry.registerDependency(
JsfManagedBeanMetadata.getMetadataIdentiferType(),
getProvidesType());
addMetadataTrigger(ROO_JSF_APPLICATION_BEAN);
configurableMetadataProvider
.addMetadataTrigger(ROO_JSF_APPLICATION_BEAN);
}
@Override
protected String createLocalIdentifier(final JavaType javaType,
final LogicalPath path) {
return JsfApplicationBeanMetadata.createIdentifier(javaType, path);
}
protected void deactivate(final ComponentContext context) {
metadataDependencyRegistry.deregisterDependency(
PhysicalTypeIdentifier.getMetadataIdentiferType(),
getProvidesType());
metadataDependencyRegistry.deregisterDependency(
JsfManagedBeanMetadata.getMetadataIdentiferType(),
getProvidesType());
removeMetadataTrigger(ROO_JSF_APPLICATION_BEAN);
configurableMetadataProvider
.removeMetadataTrigger(ROO_JSF_APPLICATION_BEAN);
}
@Override
protected String getGovernorPhysicalTypeIdentifier(
final String metadataIdentificationString) {
final JavaType javaType = JsfApplicationBeanMetadata
.getJavaType(metadataIdentificationString);
final LogicalPath path = JsfApplicationBeanMetadata
.getPath(metadataIdentificationString);
return PhysicalTypeIdentifier.createIdentifier(javaType, path);
}
public String getItdUniquenessFilenameSuffix() {
return "ApplicationBean";
}
@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(
final String metadataIdentificationString,
final JavaType aspectName,
final PhysicalTypeMetadata governorPhysicalTypeMetadata,
final String itdFilename) {
applicationBeanMid = metadataIdentificationString;
// To get here we know the governor is the MenuBean so let's go ahead
// and create its ITD
final Set<ClassOrInterfaceTypeDetails> managedBeans = typeLocationService
.findClassesOrInterfaceDetailsWithAnnotation(ROO_JSF_MANAGED_BEAN);
for (final ClassOrInterfaceTypeDetails managedBean : managedBeans) {
metadataDependencyRegistry.registerDependency(
managedBean.getDeclaredByMetadataId(),
metadataIdentificationString);
}
final ProjectMetadata projectMetadata = projectOperations
.getFocusedProjectMetadata();
Validate.notNull(projectMetadata, "Project metadata required");
return new JsfApplicationBeanMetadata(metadataIdentificationString,
aspectName, governorPhysicalTypeMetadata, managedBeans,
projectMetadata.getPom().getDisplayName());
}
public String getProvidesType() {
return JsfApplicationBeanMetadata.getMetadataIdentiferType();
}
@Override
protected String resolveDownstreamDependencyIdentifier(
final String upstreamDependency) {
if (MetadataIdentificationUtils.getMetadataClass(upstreamDependency)
.equals(MetadataIdentificationUtils
.getMetadataClass(JsfManagedBeanMetadata
.getMetadataIdentiferType()))) {
// A JsfManagedBeanMetadata upstream MID has changed or become
// available for the first time
// It's OK to return null if we don't yet know the MID because its
// JavaType has never been found
return applicationBeanMid;
}
// It wasn't a JsfManagedBeanMetadata, so we can let the superclass
// handle it
// (it's expected it would be a PhysicalTypeIdentifier notification, as
// that's the only other thing we registered to receive)
return super.resolveDownstreamDependencyIdentifier(upstreamDependency);
}
}