blob: 26ac52551ff2ae90733c9b6b82f7393bcb2890b4 [file] [log] [blame]
package org.eclipse.jst.jsf.core.jsfappconfig.internal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.jst.jsf.common.internal.managedobject.AbstractManagedObject;
import org.eclipse.jst.jsf.core.jsfappconfig.IFacesConfigChangeListener;
import org.eclipse.jst.jsf.core.jsfappconfig.IJSFAppConfigLocater;
import org.eclipse.jst.jsf.core.jsfappconfig.IJSFAppConfigProvider;
import org.eclipse.jst.jsf.core.jsfappconfig.IJSFAppConfigProvidersChangeListener;
import org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigProvidersChangeEvent;
import org.eclipse.jst.jsf.core.jsfappconfig.JSFAppConfigUtils;
import org.eclipse.jst.jsf.facesconfig.emf.ApplicationType;
import org.eclipse.jst.jsf.facesconfig.emf.BehaviorType;
import org.eclipse.jst.jsf.facesconfig.emf.ComponentType;
import org.eclipse.jst.jsf.facesconfig.emf.ConverterType;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigExtensionType;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigType;
import org.eclipse.jst.jsf.facesconfig.emf.FactoryType;
import org.eclipse.jst.jsf.facesconfig.emf.FromViewIdType;
import org.eclipse.jst.jsf.facesconfig.emf.LifecycleType;
import org.eclipse.jst.jsf.facesconfig.emf.ManagedBeanType;
import org.eclipse.jst.jsf.facesconfig.emf.NavigationRuleType;
import org.eclipse.jst.jsf.facesconfig.emf.PropertyResolverType;
import org.eclipse.jst.jsf.facesconfig.emf.ReferencedBeanType;
import org.eclipse.jst.jsf.facesconfig.emf.RenderKitType;
import org.eclipse.jst.jsf.facesconfig.emf.ResourceBundleType;
import org.eclipse.jst.jsf.facesconfig.emf.ValidatorType;
import org.eclipse.jst.jsf.facesconfig.emf.VariableResolverType;
/**
* Abstract JSFAppConfigManager that implementers of {@link IJSFAppConfigManager} MUST
* extend.
* <p>
* JSFAppConfigManager provides an entry point to an entire JSF application
* configuration, which is defined in one or more application configuration
* resource files.
*/
public abstract class AbstractJSFAppConfigManager
extends AbstractManagedObject
implements IJSFAppConfigManager {
/**
* The IProject
* @deprecated - use getProject()
*/
protected IProject _project;
/**
* Collection of {@link IJSFAppConfigLocater} instances.
*/
protected List<IJSFAppConfigLocater> configLocaters;
/**
* Collection of {@link IJSFAppConfigProvidersChangeListener} instances.
*/
protected List<IJSFAppConfigProvidersChangeListener> configProvidersChangeListeners;
/**
* Map of application configuration model EMF classes to
* {@link IFacesConfigChangeListener} instances.
*/
protected Map<Class, IFacesConfigChangeListener> facesConfigChangeListeners;
/**
* Single {@link FacesConfigChangeAdapter} instance.
*/
protected FacesConfigChangeAdapter facesConfigChangeAdapter;
/**
* Constructor
* @param project
*/
public AbstractJSFAppConfigManager(final IProject project) {
_project = project;
initialize();
}
public IProject getProject() {
return _project;
}
/**
* Initializes instance by:
* <ul>
* <li>creating facesConfigChangeListeners collection, </li>
* <li>creating configProvidersChangeListeners collection, </li>
* <li>creating and populating configLocaters collection, </li>
* <li>invoking the startLocating() method on all configLocaters, </li>
* </ul>
*/
protected void initialize() {
//create collections
facesConfigChangeListeners = new HashMap<Class, IFacesConfigChangeListener>();
configProvidersChangeListeners = new ArrayList<IJSFAppConfigProvidersChangeListener>();
configLocaters = new ArrayList<IJSFAppConfigLocater>();
//populate initial set of locaters
populateConfigLocaters();
//instruct locaters to start locating
startConfigLocaters();
}
/**
* Populates configLocaters using @link IJSFAppConfigLocater} implementations
* from CompositeLocatorProviderStrategy
*/
protected void populateConfigLocaters() {
final CompositeJSFAppConfigLocatorProviderStrategy clps = new CompositeJSFAppConfigLocatorProviderStrategy(this.getProject());
for (final IJSFAppConfigLocater locator : clps.getLocators()) {
locator.setJSFAppConfigManager(this);
configLocaters.add(locator);
}
}
/**
* Instructs set of {@link IJSFAppConfigLocater} instances to start
* locating JSF application configuration resources.
*/
protected void startConfigLocaters() {
for (final IJSFAppConfigLocater configLocater : configLocaters) {
configLocater.startLocating();
}
}
/**
* Instructs set of {@link IJSFAppConfigLocater} instances to stop
* locating JSF application configuration resources.
*/
protected void stopConfigLocaters() {
for (final IJSFAppConfigLocater configLocater : configLocaters) {
configLocater.stopLocating();
configLocater.dispose();
}
}
/**
* Called to respond to a change in the IProject instance to which this
* instance belongs. Changes the cached IProject instance, stops all config
* locaters, starts all config locaters.
*
* @param newProject New IProject instance to which this manager belongs.
* @deprecated - SHOULD NOT USE
*/
protected void changeProject(final IProject newProject) {
_project = newProject;
stopConfigLocaters();
startConfigLocaters();
}
public boolean addJSFAppConfigProvidersChangeListener(final IJSFAppConfigProvidersChangeListener listener) {
return configProvidersChangeListeners.add(listener);
}
public boolean removeJSFAppConfigProvidersChangeListener(final IJSFAppConfigProvidersChangeListener listener) {
return configProvidersChangeListeners.remove(listener);
}
public void notifyJSFAppConfigProvidersChangeListeners(final IJSFAppConfigProvider configProvider, final int eventType) {
final JSFAppConfigProvidersChangeEvent event = new JSFAppConfigProvidersChangeEvent(configProvider, eventType);
for (final IJSFAppConfigProvidersChangeListener listener : configProvidersChangeListeners) {
listener.changedJSFAppConfigProviders(event);
}
}
public Object addFacesConfigChangeListener(Class emfClass, IFacesConfigChangeListener listener) {
/*
* Get all models, which will ensure that each one has had a
* FacesConfigChangeAdapter added to it (if the model is updateable).
*/
getFacesConfigModels();
return facesConfigChangeListeners.put(emfClass, listener);
}
public Object removeFacesConfigChangeListener(Class emfClass) {
return facesConfigChangeListeners.remove(emfClass);
}
public void notifyFacesConfigChangeListeners(final Notification notification) {
final Object emfFeature = notification.getFeature();
if (emfFeature instanceof EStructuralFeature) {
final Class emfClass = ((EStructuralFeature)emfFeature).getEType().getInstanceClass();
final IFacesConfigChangeListener listener = facesConfigChangeListeners.get(emfClass);
if (listener != null) {
listener.notifyChanged(notification);
}
}
}
/**
* @return Set of {@link IJSFAppConfigProvider}s
*/
protected Set<IJSFAppConfigProvider> getJSFAppConfigProviders() {
final Set<IJSFAppConfigProvider> allConfigProviders = new LinkedHashSet<IJSFAppConfigProvider>();
final Iterator itConfigLocaters = configLocaters.iterator();
while (itConfigLocaters.hasNext()) {
final IJSFAppConfigLocater configLocater = (IJSFAppConfigLocater)itConfigLocaters.next();
allConfigProviders.addAll(configLocater.getJSFAppConfigProviders());
}
return allConfigProviders;
}
/**
* Gets all {@link FacesConfigType} instances from all
* {@link IJSFAppConfigProvider} instances.
*
* @return List of all {@link FacesConfigType} instances.
*/
protected List<FacesConfigType> getFacesConfigModels() {
final List<FacesConfigType> facesConfigModels = new ArrayList<FacesConfigType>();
for(final IJSFAppConfigProvider configProvider : getJSFAppConfigProviders()) {
final FacesConfigType facesConfig = configProvider.getFacesConfigModel();
if (facesConfig != null) {
facesConfigModels.add(facesConfig);
}
}
return facesConfigModels;
}
//----------------------- IManagedObject lifecycle methods ----------------------------//
/**
* Disposes of resources by:
* <ul>
* <li>removing a resource change listener to the workspace</li>
* <li>removing instance as a session property of the IProject instance</li>
* <li>invoking the stopLocating() method on all configLocaters</li>
* <li>clearing the configLocaters collection</li>
* <li>clearing the configProvidersChangeListeners collection</li>
* <li>clearing the facesConfigChangeListeners collection</li>
* </ul>
*/
public void dispose() {
//instruct locaters to stop locating
stopConfigLocaters();
//clear collections
configLocaters.clear();
configProvidersChangeListeners.clear();
facesConfigChangeListeners.clear();
}
public void destroy() {
//
}
public void checkpoint() {
//
}
//-------------------------------------------------------------------------------------------------//
public List<ManagedBeanType> getManagedBeans() {
final List<ManagedBeanType> allManagedBeans = new ArrayList<ManagedBeanType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList managedBeans = facesConfig.getManagedBean();
allManagedBeans.addAll(managedBeans);
}
return allManagedBeans;
}
public final List<String> getPropertyResolvers()
{
final List<String> allPropertyResolvers = new ArrayList<String>();
final List<ApplicationType> applications = getApplications();
for (final ApplicationType application : applications)
{
for (final Iterator it = application.getPropertyResolver().iterator(); it.hasNext();)
{
final PropertyResolverType propRes = (PropertyResolverType) it.next();
String propClass = propRes.getTextContent();
if (propClass != null)
{
propClass = propClass.trim();
if (!"".equals(propClass)) //$NON-NLS-1$
{
allPropertyResolvers.add(propClass);
}
}
}
}
return allPropertyResolvers;
}
public List<ValidatorType> getValidators() {
final List<ValidatorType> allValidators = new ArrayList<ValidatorType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList validators = facesConfig.getValidator();
allValidators.addAll(validators);
}
return allValidators;
}
public final List<String> getVariableResolvers()
{
final List<String> allVariableResolvers = new ArrayList<String>();
final List<ApplicationType> applications = getApplications();
for ( final ApplicationType application : applications)
{
for (final Iterator it = application.getVariableResolver().iterator(); it.hasNext();)
{
final VariableResolverType varRes = (VariableResolverType) it.next();
String varClass = varRes.getTextContent();
if (varClass != null)
{
varClass = varClass.trim();
if (!"".equals(varClass)) //$NON-NLS-1$
{
allVariableResolvers.add(varClass);
}
}
}
}
return allVariableResolvers;
}
public List<ConverterType> getConverters() {
final List<ConverterType> allConverters = new ArrayList<ConverterType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList converters = facesConfig.getConverter();
allConverters.addAll(converters);
}
return allConverters;
}
public List<NavigationRuleType> getNavigationRules() {
final List<NavigationRuleType> allNavigationRules = new ArrayList<NavigationRuleType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList navigationRules = facesConfig.getNavigationRule();
allNavigationRules.addAll(navigationRules);
}
return allNavigationRules;
}
public List<NavigationRuleType> getNavigationRulesForPage(final IFile pageFile) {
final List<NavigationRuleType> navigationRulesForPage = new ArrayList<NavigationRuleType>();
final IPath pageFilePath = JSFAppConfigUtils.getWebContentFolderRelativePath(pageFile);
if (pageFilePath != null) {
String pageFileString = pageFilePath.toString();
if (!pageFileString.startsWith("/")) { //$NON-NLS-1$
pageFileString = "/" + pageFileString; //$NON-NLS-1$
}
final List<NavigationRuleType> navigationRules = getNavigationRules();
for (final NavigationRuleType navigationRule : navigationRules) {
FromViewIdType fromViewIdType = navigationRule.getFromViewId();
if (fromViewIdType != null) {
final String fromViewId = fromViewIdType.getTextContent();
if (fromViewId != null && fromViewId.length() > 0) {
if (!fromViewId.equals("*")) { //$NON-NLS-1$
if (fromViewId.equals(pageFileString)) {
//exact match
navigationRulesForPage.add(navigationRule);
} else if (fromViewId.endsWith("*")) { //$NON-NLS-1$
final String prefixFromViewId = fromViewId.substring(0, fromViewId.length() - 1);
if (pageFileString.startsWith(prefixFromViewId)) {
//prefix match
navigationRulesForPage.add(navigationRule);
}
}
} else {
//from-view-id == "*" - matches all pages
navigationRulesForPage.add(navigationRule);
}
}
} else {
//no from-view-id element - matches all pages
navigationRulesForPage.add(navigationRule);
}
}
}
return navigationRulesForPage;
}
public List<ApplicationType> getApplications() {
final List<ApplicationType> allApplications = new ArrayList<ApplicationType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList applications = facesConfig.getApplication();
allApplications.addAll(applications);
}
return allApplications;
}
public List<FactoryType> getFactories() {
final List<FactoryType> allFactories = new ArrayList<FactoryType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList factories = facesConfig.getFactory();
allFactories.addAll(factories);
}
return allFactories;
}
public List<ComponentType> getComponents() {
final List<ComponentType> allComponents = new ArrayList<ComponentType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList components = facesConfig.getComponent();
allComponents.addAll(components);
}
return allComponents;
}
public List<ReferencedBeanType> getReferencedBeans() {
final List<ReferencedBeanType> allReferencedBeans = new ArrayList<ReferencedBeanType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList referencedBeans = facesConfig.getReferencedBean();
allReferencedBeans.addAll(referencedBeans);
}
return allReferencedBeans;
}
public List<RenderKitType> getRenderKits() {
final List<RenderKitType> allRenderKits = new ArrayList<RenderKitType> ();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList renderKits = facesConfig.getRenderKit();
allRenderKits.addAll(renderKits);
}
return allRenderKits;
}
public List<LifecycleType> getLifecycles() {
final List<LifecycleType> allLifecycles = new ArrayList<LifecycleType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList lifecycles = facesConfig.getLifecycle();
allLifecycles.addAll(lifecycles);
}
return allLifecycles;
}
public List<ResourceBundleType> getResourceBundles()
{
final List<ResourceBundleType> allResourceBundles = new ArrayList<ResourceBundleType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
for (final Iterator applicationIt = facesConfig.getApplication().iterator(); applicationIt.hasNext();)
{
final ApplicationType appType = (ApplicationType) applicationIt.next();
allResourceBundles.addAll(appType.getResourceBundle());
}
}
return allResourceBundles;
}
public List<BehaviorType> getBehaviors()
{
final List<BehaviorType> allBehaviors = new ArrayList<BehaviorType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList behaviors = facesConfig.getBehavior();
allBehaviors.addAll(behaviors);
}
return allBehaviors;
}
public List<FacesConfigExtensionType> getFacesConfigExtensions()
{
final List<FacesConfigExtensionType> allFCExts = new ArrayList<FacesConfigExtensionType>();
for (final FacesConfigType facesConfig : getFacesConfigModels()) {
final EList fcExts = facesConfig.getFacesConfigExtension();
allFCExts.addAll(fcExts);
}
return allFCExts;
}
public void addFacesConfigChangeAdapter(final FacesConfigType facesConfig) {
if (facesConfig != null) {
if (facesConfigChangeAdapter == null) {
facesConfigChangeAdapter = new FacesConfigChangeAdapter();
}
facesConfig.eAdapters().add(facesConfigChangeAdapter);
}
}
public void removeFacesConfigChangeAdapter(final FacesConfigType facesConfig) {
if (facesConfig != null && facesConfigChangeAdapter != null) {
facesConfig.eAdapters().remove(facesConfigChangeAdapter);
}
}
/**
* FacesConfigChangeAdapter is an EMF adapter which provides a mechanism
* for notification of changes to features in any application configuration
* model for which {@link IFacesConfigChangeListener} instances have
* registered an interest.
*
* @author Ian Trimble - Oracle
*/
class FacesConfigChangeAdapter extends EContentAdapter {
/*
* (non-Javadoc)
* @see org.eclipse.emf.ecore.util.EContentAdapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
*/
public void notifyChanged(final Notification notification) {
super.notifyChanged(notification);
notifyFacesConfigChangeListeners(notification);
}
}
}