blob: c62cffed4d9b5357a13d46b9cff9d5e0f963f3e8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2008 Oracle Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Oracle Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsf.designtime.internal.view;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jem.internal.proxy.core.IBeanTypeProxy;
import org.eclipse.jem.internal.proxy.core.IConfigurationContributor;
import org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory;
import org.eclipse.jem.internal.proxy.core.ProxyFactoryRegistry;
import org.eclipse.jem.internal.proxy.ide.IDERegistration;
import org.eclipse.jst.jsf.common.internal.types.TypeInfoCache;
import org.eclipse.jst.jsf.common.runtime.internal.model.component.ComponentTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ConverterTypeInfo;
import org.eclipse.jst.jsf.common.runtime.internal.model.decorator.ValidatorTypeInfo;
import org.eclipse.jst.jsf.common.util.JDTBeanIntrospector;
import org.eclipse.jst.jsf.common.util.JDTBeanProperty;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.core.internal.JSFCoreTraceOptions;
import org.eclipse.jst.jsf.core.internal.jem.BeanProxyUtil.BeanProxyWrapper;
import org.eclipse.jst.jsf.core.internal.jem.BeanProxyUtil.ProxyException;
import org.eclipse.jst.jsf.core.jsfappconfig.internal.IJSFAppConfigManager;
import org.eclipse.jst.jsf.core.jsfappconfig.internal.JSFAppConfigManagerFactory;
import org.eclipse.jst.jsf.facesconfig.emf.ComponentType;
import org.eclipse.jst.jsf.facesconfig.emf.ConverterType;
import org.eclipse.jst.jsf.facesconfig.emf.ValidatorType;
/**
* Utility class for finding and bean introspecting component and related
* classes.
*
* @author cbateman
*
*/
public final class DTComponentIntrospector
{
/**
* A shared type cache for doing tag class introspection. The cache stores
* type hierarchies and updates them on detected changes to reduce the
* overhead of doing such lookups
*/
private static TypeInfoCache TYPE_CACHE; // lazily created, don't access
// directly
/**
* @return the type cache used by all DTComponentIntrospector internally.
*/
public static TypeInfoCache getSharedTypeCache()
{
if (TYPE_CACHE == null)
{
TYPE_CACHE = TypeInfoCache.createNewInstance();
}
return TYPE_CACHE;
}
/**
* @param classType
* @param className
* @param project
* @param contributors may be null
* @return the component type info for the class type or null if none. Adds
* contributors to the class path
*/
public static ComponentTypeInfo getComponent(final String classType,
final String className, final IProject project,
final IConfigurationContributor[] contributors)
{
ProxyFactoryRegistry registry = null;
try
{
registry = getProxyFactoryRegistry(project,
contributors);
if (registry != null)
{
final IStandardBeanTypeProxyFactory factory = registry
.getBeanTypeProxyFactory();
final IBeanTypeProxy classTypeProxy = factory
.getBeanTypeProxy(className);
final BeanProxyWrapper classTypeWrapper = new BeanProxyWrapper(project,
classTypeProxy);
String family = null;
String renderer = null;
try
{
classTypeWrapper.init();
family = classTypeWrapper.callStringMethod("getFamily"); //$NON-NLS-1$
renderer = classTypeWrapper.callStringMethod("getRendererType"); //$NON-NLS-1$
}
catch (ProxyException e1)
{
// fall through
if (JSFCoreTraceOptions.TRACE_JSPTAGINTROSPECTOR)
{
JSFCoreTraceOptions.log("DTComponentIntrospector.getComponent:", e1); //$NON-NLS-1$
}
}
IType type = null;
try
{
type = JavaCore.create(project).findType(className);
}
catch (JavaModelException e)
{
// fall through;
}
List<String> interfaces = new ArrayList<String>();
List<String> superClasses = new ArrayList<String>();
if (type != null)
{
TypeInfoCache typeCache = getSharedTypeCache();
IType[] interfaceTypes = typeCache.cacheInterfaceTypesFor(type);
for (IType interfaze : interfaceTypes)
{
interfaces.add(interfaze.getFullyQualifiedName());
}
IType[] superClassTypes = typeCache.cacheSupertypesFor(type);
for (IType superClass : superClassTypes)
{
superClasses.add(superClass.getFullyQualifiedName());
}
}
return new ComponentTypeInfo(classType, className, superClasses
.toArray(new String[0]), interfaces.toArray(new String[0]),
family, renderer);
}
}
finally
{
if (registry != null)
{
registry.terminateRegistry(true);
}
}
return null;
}
/**
* @param classType
* @param className
* @param project
* @return the component type info with no additional classpath
* contributions. May return null;
*/
public static ComponentTypeInfo getComponent(final String classType,
final String className, final IProject project)
{
return getComponent(classType, className, project, null);
}
/**
* @param converterId
* @param converterClass
* @return a new converter type info for the converter id.
*/
public static ConverterTypeInfo getConverter(final String converterId,
final String converterClass)
{
return new ConverterTypeInfo(converterClass, converterId);
}
/**
* @param validatorId
* @param validatorClass
* @return a new validator type info for the validator id
*/
public static ValidatorTypeInfo getValidator(final String validatorId,
final String validatorClass)
{
return new ValidatorTypeInfo(validatorClass, validatorId);
}
/**
* @param componentType
* @param project
* @return the configured class name for the JSF component type id or null
* if not found.
*/
public static String findComponentClass(final String componentType,
final IProject project)
{
final IJSFAppConfigManager manager = JSFAppConfigManagerFactory
.getJSFAppConfigManagerInstance(project);
final List<ComponentType> components = manager.getComponents();
for (final ComponentType component : components)
{
final String type = component.getComponentType().getTextContent()
.trim();
if (componentType.equals(type) && component.getComponentClass() != null && component.getComponentClass().getTextContent() != null)
{
return component.getComponentClass().getTextContent().trim();
}
}
return null;
}
/**
* @param converterId
* @param project
* @return a fully qualified class name corresponding to converterId or null
* if none.
*/
public static String findConverterClass(final String converterId,
final IProject project)
{
final IJSFAppConfigManager manager = JSFAppConfigManagerFactory
.getJSFAppConfigManagerInstance(project);
final List<ConverterType> converters = manager.getConverters();
for (final ConverterType converter : converters)
{
if (converter != null && converter.getConverterId() != null
&& converter.getConverterId().getTextContent() != null)
{
final String type = converter.getConverterId().getTextContent()
.trim();
if (converterId.equals(type))
{
if (converter.getConverterClass() != null && converter.getConverterClass().getTextContent()!=null)
{
return converter.getConverterClass().getTextContent()
.trim();
}
return null;
}
}
}
return null;
}
/**
* @param validatorId
* @param project
* @return a fully qualified class name corresponding to the validatorId or
* null if none.
*/
public static String findValidatorClass(final String validatorId,
final IProject project)
{
final IJSFAppConfigManager manager = JSFAppConfigManagerFactory
.getJSFAppConfigManagerInstance(project);
final List<ValidatorType> validators = manager.getValidators();
for (final ValidatorType validatorType : validators)
{
if (validatorType != null && validatorType.getValidatorId() != null &&
validatorType.getValidatorId().getTextContent() != null)
{
final String type = validatorType.getValidatorId().getTextContent()
.trim();
if (validatorId.equals(type))
{
return validatorType.getValidatorClass().getTextContent()
.trim();
}
}
}
return null;
}
/**
* @param type
* @param checkInstanceOf
* @return true if type resolves to a type that is an instance of one of the
* types in checkInstanceOf.
*/
public static boolean isTypeNameInstanceOfClass(final IType type,
final Set<String> checkInstanceOf)
{
if (checkInstanceOf == null)
{
throw new AssertionError();
}
if (type != null)
{
// first and foremost, are these exactly droids you're
// looking for and not just their predecessors?
if (checkInstanceOf.contains(type.getFullyQualifiedName()))
{
return true;
}
for (final IType supertype : getSharedTypeCache()
.cacheSupertypesFor(type))
{
if (checkInstanceOf.contains(supertype.getFullyQualifiedName()))
{
return true;
}
}
for (final IType interfaces : getSharedTypeCache()
.cacheInterfaceTypesFor(type))
{
if (checkInstanceOf
.contains(interfaces.getFullyQualifiedName()))
{
return true;
}
}
}
return false;
}
/**
* @param typeInfo
* @param project
* @return a list of all bean properties (using the POJO method) on
* typeInfo. List may be empty, never null.
*/
public static Map<String, JDTBeanProperty> getBeanProperties(
final ComponentTypeInfo typeInfo, final IProject project)
{
Map<String, JDTBeanProperty> properties = new HashMap<String, JDTBeanProperty>();
IJavaProject javaProject = JavaCore.create(project);
try
{
IType type = javaProject.findType(typeInfo.getClassName());
if (type != null)
{
// TODO: should be able to use type cache for this
final JDTBeanIntrospector introspector = new JDTBeanIntrospector(
type);
properties = introspector.getProperties();
}
}
catch (JavaModelException e)
{
JSFCorePlugin.log("Error finding component type", e); //$NON-NLS-1$
}
return properties;
}
/**
* @param project
* @return a new proxy factory registry or null;
*
* TODO: caching?
*/
private static ProxyFactoryRegistry getProxyFactoryRegistry(
final IProject project, final IConfigurationContributor[] contributors)
{
try
{
return IDERegistration.startAnImplementation(contributors, false, project,
project.getName(), JSFCorePlugin.PLUGIN_ID,
new NullProgressMonitor());
}
catch (final CoreException e)
{
JSFCorePlugin.log("Error starting vm for project: " //$NON-NLS-1$
+ project.getName(), e);
}
return null;
}
private DTComponentIntrospector()
{
// no external instantiation
}
// private static class
}