/******************************************************************************* * Copyright (c) 2008 Oracle Corporation. * 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: * Cameron Bateman - initial API and implementation *******************************************************************************/ package org.eclipse.jst.jsf.facelet.core.internal.registry.taglib; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jem.internal.proxy.core.IBeanProxy; import org.eclipse.jem.internal.proxy.core.IBeanTypeProxy; import org.eclipse.jem.internal.proxy.core.IStringBeanProxy; import org.eclipse.jem.internal.proxy.core.ProxyFactoryRegistry; import org.eclipse.jst.jsf.core.internal.JSFCorePlugin; import org.eclipse.jst.jsf.core.internal.jem.BeanProxyUtil; 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.facelet.core.internal.registry.taglib.faceletTaglib.FaceletTaglibTag; import org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.faceletTaglib_1_0.FaceletLibraryClassTagLib; /** * @author cbateman * */ /* package */class LibraryClassBasedTagRecord extends FaceletTagRecord { // private static final String METHOD_NAME_GET_VALUE = "getValue"; //$NON-NLS-1$ // private static final String METHOD_NAME_GET_KEY = "getKey"; //$NON-NLS-1$ // private static final String METHOD_NAME_HAS_NEXT = "hasNext"; //$NON-NLS-1$ // private static final String METHOD_NAME_NEXT = "next"; //$NON-NLS-1$ // private static final String METHOD_NAME_ITERATOR = "iterator"; //$NON-NLS-1$ // private static final String METHOD_NAME_ENTRY_SET = "entrySet"; //$NON-NLS-1$ // private static final String PROPERTY_NAME_FACTORIES = "factories"; //$NON-NLS-1$ // private static final String QUALIFIED_CLASS_NAME__COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY = "com.sun.facelets.tag.AbstractTagLibrary"; //$NON-NLS-1$ // private static final String QUALIFIED_CLASS_NAME_JAVA_UTIL_MAP = "java.util.Map"; //$NON-NLS-1$ // // private static final String COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_HANDLER_FACTORY = "com.sun.facelets.tag.AbstractTagLibrary$HandlerFactory"; //$NON-NLS-1$ // private static final String COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_CONVERTER_HANDLER_FACTORY = "com.sun.facelets.tag.AbstractTagLibrary$UserConverterHandlerFactory"; //$NON-NLS-1$ // private static final String COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_CONVERTER_HANDLER_FACTORY = "com.sun.facelets.tag.AbstractTagLibrary$ConverterHandlerFactory"; //$NON-NLS-1$ // private static final String COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_VALIDATOR_HANDLER_FACTORY = "com.sun.facelets.tag.AbstractTagLibrary$UserValidatorHandlerFactory"; //$NON-NLS-1$ // private static final String COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_VALIDATOR_HANDLER_FACTORY = "com.sun.facelets.tag.AbstractTagLibrary$ValidatorHandlerFactory"; //$NON-NLS-1$ // private static final String COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_COMPONENT_HANDLER_FACTORY = "com.sun.facelets.tag.AbstractTagLibrary$UserComponentHandlerFactory"; //$NON-NLS-1$ // private static final String COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_COMPONENT_HANDLER_FACTORY = "com.sun.facelets.tag.AbstractTagLibrary$ComponentHandlerFactory"; //$NON-NLS-1$ // // private static final String FIELD_NAME_CONVERTER_ID = "converterId"; //$NON-NLS-1$ // private static final String FIELD_NAME_VALIDATOR_ID = "validatorId"; //$NON-NLS-1$ // private static final String FIELD_NAME_RENDER_TYPE = "renderType"; //$NON-NLS-1$ // private static final String FIELD_NAME_COMPONENT_TYPE = "componentType"; //$NON-NLS-1$ /** * */ private static final long serialVersionUID = 4174629773250721041L; private static final String STATIC_MEMBER_NAMESPACE = "Namespace"; //$NON-NLS-1$ private static final String METHOD_NAME_GET_NAMESPACE = "getNamespace"; //$NON-NLS-1$ private final IProject _project; private final FaceletLibraryClassTagLib _model; private final ProxyFactoryRegistry _registry; private final AtomicBoolean _isInitialized = new AtomicBoolean( false); private String _uri; private BeanProxyWrapper _classTypeWrapper; private Map<String, FaceletTaglibTag> _tags; /** * @param registry * @param model * @param project * @param descriptor */ public LibraryClassBasedTagRecord(final ProxyFactoryRegistry registry, final FaceletLibraryClassTagLib model, final IProject project, TagRecordDescriptor descriptor) { super(descriptor); _registry = registry; _model = model; _project = project; } public void initURI() throws CoreException { if (_isInitialized.get()) { throw new CoreException( new Status( IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, "Cannot initURI once the library is initialized for: " + _model.getLibraryClass())); //$NON-NLS-1$ } final IBeanTypeProxy libFactoryTypeProxy = _registry .getBeanTypeProxyFactory().getBeanTypeProxy( _model.getLibraryClass()); if (libFactoryTypeProxy == null) { throw new CoreException(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, "Couldn't find type proxy for " + _model.getLibraryClass())); //$NON-NLS-1$ } // TODO: wrap in try per the Glassfish patch _classTypeWrapper = new BeanProxyWrapper(_project, libFactoryTypeProxy); try { _classTypeWrapper.init(); } catch (final ProxyException e) { throw new CoreException(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, "Couldn't load class: " + _model.getLibraryClass(), e)); //$NON-NLS-1$ } final String namespace = resolveNS(_classTypeWrapper); System.out.println(namespace); if (namespace == null) { throw new CoreException(new Status(IStatus.ERROR, JSFCorePlugin.PLUGIN_ID, "Couldn't load uri: " + _model.getLibraryClass())); //$NON-NLS-1$ } _uri = namespace; } @Override public synchronized FaceletTaglibTag getTag(final String name) { // initializeIfNecessary(); return _tags.get(name); } @Override public synchronized Collection<? extends FaceletTaglibTag> getTags() { // initializeIfNecessary(); return Collections.unmodifiableCollection(_tags.values()); } // private void initializeIfNecessary() // { // if (_isInitialized.compareAndSet(false, true)) // { // if (_tags == null) // { // _tags = resolveTags(); // } // } // } /* * (non-Javadoc) * * @see * org.eclipse.jst.jsf.facelet.core.internal.registry.taglib.FaceletTagRecord * #getURI() */ @Override public String getURI() { return _uri; } // private Map<String, FaceletTaglibTag> resolveTags() // { // final Map<String, FaceletTaglibTag> tags = new HashMap<String, FaceletTaglibTag>(); // // // if the tag factory is a child of AbstractTagFactory, then we // // can try to get our hands on its private parts ... // final IBeanTypeProxy mapTypeProxy = _registry.getBeanTypeProxyFactory() // .getBeanTypeProxy(QUALIFIED_CLASS_NAME_JAVA_UTIL_MAP); // final IBeanTypeProxy componentFactoryTypeProxy = _registry // .getBeanTypeProxyFactory() // .getBeanTypeProxy( // QUALIFIED_CLASS_NAME__COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY); // // if (mapTypeProxy != null && componentFactoryTypeProxy != null) // { // final IFieldProxy fieldProxy = componentFactoryTypeProxy // .getDeclaredFieldProxy(PROPERTY_NAME_FACTORIES); // // if (fieldProxy != null) // { // if (fieldProxy.getFieldType().isKindOf(mapTypeProxy)) // { // IBeanProxy factories = null; // // try // { // // need to turn off security checking on the private // // field // fieldProxy.setAccessible(true); // factories = fieldProxy.get(_classTypeWrapper // .getInstance()); // } // catch (final ThrowableProxy e) // { // FaceletCorePlugin.log( // "Error getting factories from bean instance", //$NON-NLS-1$ // e); // } // // if (factories != null) // { // final IMethodProxy entrySetMethod = fieldProxy // .getFieldType().getMethodProxy( // METHOD_NAME_ENTRY_SET); // if (entrySetMethod != null) // { // try // { // entrySetMethod.setAccessible(true); // final IBeanProxy entrySetProxy = entrySetMethod // .invoke(factories); // // if (entrySetProxy != null) // { // final IMethodProxy iteratorMethod = entrySetProxy // .getTypeProxy().getMethodProxy( // METHOD_NAME_ITERATOR); // iteratorMethod.setAccessible(true); // final IBeanProxy iteratorProxy = iteratorMethod // .invoke(entrySetProxy); // // if (iteratorProxy != null) // { // final IMethodProxy nextMethod = iteratorProxy // .getTypeProxy().getMethodProxy( // METHOD_NAME_NEXT); // nextMethod.setAccessible(true); // final IMethodProxy hasNextMethod = iteratorProxy // .getTypeProxy().getMethodProxy( // METHOD_NAME_HAS_NEXT); // hasNextMethod.setAccessible(true); // // while (((IBooleanBeanProxy) hasNextMethod // .invoke(iteratorProxy)) // .booleanValue()) // { // final IBeanProxy entryProxy = nextMethod // .invoke(iteratorProxy); // final IMethodProxy getKeyProxy = entryProxy // .getTypeProxy() // .getMethodProxy( // METHOD_NAME_GET_KEY); // final IMethodProxy getValueProxy = entryProxy // .getTypeProxy() // .getMethodProxy( // METHOD_NAME_GET_VALUE); // if (getKeyProxy != null // && getValueProxy != null) // { // getKeyProxy.setAccessible(true); // final IBeanProxy key = getKeyProxy // .invoke(entryProxy); // // if (key instanceof IStringBeanProxy) // { // final String name = ((IStringBeanProxy) key) // .stringValue(); // getValueProxy // .setAccessible(true); // final IBeanProxy value = getValueProxy // .invoke(entryProxy); // // if (value != null) // { // final FaceletTaglibTag tagDefn = createTagDefn( // name, // value); // if (tagDefn != null) // { // tags.put(name, // tagDefn); // } // } // } // } // } // } // } // } // catch (final ThrowableProxy e) // { // FaceletCorePlugin.log( // "Error invoking entrySet", e); //$NON-NLS-1$ // } // } // } // // } // } // } // return tags; // } // private FaceletTaglibTag createTagDefn(final String name, // final IBeanProxy handlerValueProxy) { // final IBeanTypeProxy handlerTypeProxy = handlerValueProxy.getTypeProxy(); // final FaceletTaglibFactory TAGDEFN_FACTORY = FaceletTaglibFactory.eINSTANCE; // // final IBeanTypeProxy componentHandlerFactory = _registry // .getBeanTypeProxyFactory() // .getBeanTypeProxy( // COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_COMPONENT_HANDLER_FACTORY); // final IBeanTypeProxy userComponentHandlerFactory = _registry // .getBeanTypeProxyFactory() // .getBeanTypeProxy( // COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_COMPONENT_HANDLER_FACTORY); // final IBeanTypeProxy validatorHandlerFactory = _registry // .getBeanTypeProxyFactory() // .getBeanTypeProxy( // COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_VALIDATOR_HANDLER_FACTORY); // final IBeanTypeProxy userValidatorHandlerFactory = _registry // .getBeanTypeProxyFactory() // .getBeanTypeProxy( // COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_VALIDATOR_HANDLER_FACTORY); // final IBeanTypeProxy converterHandlerFactory = _registry // .getBeanTypeProxyFactory() // .getBeanTypeProxy( // COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_CONVERTER_HANDLER_FACTORY); // final IBeanTypeProxy userConverterHandlerFactory = _registry // .getBeanTypeProxyFactory() // .getBeanTypeProxy( // COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_USER_CONVERTER_HANDLER_FACTORY); // final IBeanTypeProxy handlerFactory = _registry // .getBeanTypeProxyFactory() // .getBeanTypeProxy( // COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_HANDLER_FACTORY); // final IBeanTypeProxy userTagFactory = _registry // .getBeanTypeProxyFactory() // .getBeanTypeProxy( // COM_SUN_FACELETS_TAG_ABSTRACT_TAG_LIBRARY$_HANDLER_FACTORY); // // FaceletTaglibTag tagDefn = null; // // if (handlerTypeProxy.isKindOf(componentHandlerFactory) // || handlerTypeProxy.isKindOf(userComponentHandlerFactory)) // { // final IFieldProxy componentTypeProxy = handlerTypeProxy // .getDeclaredFieldProxy(FIELD_NAME_COMPONENT_TYPE); // final IFieldProxy rendererTypeProxy = handlerTypeProxy // .getDeclaredFieldProxy(FIELD_NAME_RENDER_TYPE); // try // { // if (componentTypeProxy != null) // { // componentTypeProxy.setAccessible(true); // rendererTypeProxy.setAccessible(true); // final IBeanProxy componentType = componentTypeProxy // .get(handlerValueProxy); // // final IBeanProxy rendererType = rendererTypeProxy // // .get(handlerValueProxy); // // // render type is optional, but must have component type // if (componentType instanceof IStringBeanProxy) // { // final String componentTypeValue = getMeaningfulString(((IStringBeanProxy) componentType) // .stringValue()); // // if (componentTypeValue != null) // { // final ComponentTagDefn compTagDefn = TAGDEFN_FACTORY // .createComponentTagDefn(); // compTagDefn.setComponentType(componentTypeValue); // // if (rendererType instanceof IStringBeanProxy) // // { // // compTagDefn // // .setRendererType(getMeaningfulString((( // // IStringBeanProxy) rendererType) // // .stringValue())); // // } // tagDefn = compTagDefn; // } // } // } // } // catch (final ThrowableProxy e) // { // FaceletCorePlugin.log("Error get component info", e); //$NON-NLS-1$ // } // } // else if (handlerTypeProxy.isKindOf(validatorHandlerFactory) // || handlerTypeProxy.isKindOf(userValidatorHandlerFactory)) // { // final IFieldProxy validatorIdProxy = handlerTypeProxy // .getDeclaredFieldProxy(FIELD_NAME_VALIDATOR_ID); // // try // { // if (validatorIdProxy != null) // { // validatorIdProxy.setAccessible(true); // final IBeanProxy validatorId = validatorIdProxy // .get(handlerValueProxy); // // final ValidatorTagDefn valTagDefn = TAGDEFN_FACTORY // .createValidatorTagDefn(); // tagDefn = valTagDefn; // // if (validatorId instanceof IStringBeanProxy) // { // final String validatorIdValue = getMeaningfulString(((IStringBeanProxy) validatorId) // .stringValue()); // // if (validatorIdValue != null) // { // valTagDefn.setValidatorId(validatorIdValue); // } // } // } // } // catch (final ThrowableProxy e) // { // FaceletCorePlugin.log("Error getting validator info", e); //$NON-NLS-1$ // } // } // else if (handlerTypeProxy.isKindOf(converterHandlerFactory) // || handlerTypeProxy.isKindOf(userConverterHandlerFactory)) // { // final IFieldProxy converterIdProxy = handlerTypeProxy // .getDeclaredFieldProxy(FIELD_NAME_CONVERTER_ID); // // try // { // if (converterIdProxy != null) // { // converterIdProxy.setAccessible(true); // final IBeanProxy converterId = converterIdProxy // .get(handlerValueProxy); // // final ConverterTagDefn converterTagDefn = TAGDEFN_FACTORY // .createConverterTagDefn(); // tagDefn = converterTagDefn; // // if (converterId instanceof IStringBeanProxy) // { // final String converterIdValue = getMeaningfulString(((IStringBeanProxy) converterId) // .stringValue()); // // if (converterIdValue != null) // { // converterTagDefn.setConverterId(converterIdValue); // } // } // } // } // catch (final ThrowableProxy e) // { // FaceletCorePlugin.log("Error getting validator info", e); //$NON-NLS-1$ // } // } // else if (handlerTypeProxy.isKindOf(handlerFactory) // || handlerTypeProxy.isKindOf(userTagFactory)) // { // tagDefn = TAGDEFN_FACTORY.createHandlerTagDefn(); // } // // if (tagDefn != null) // { // tagDefn.setName(name); // } // return tagDefn; } // private String getMeaningfulString(final String value) // { // if (value == null) // { // return null; // } // // String retValue = value.trim(); // // if ("".equals(retValue)) //$NON-NLS-1$ // { // retValue = null; // } // return retValue; // } private String resolveNS(final BeanProxyWrapper beanProxy) { IBeanProxy resultProxy = null; try { resultProxy = beanProxy.call(METHOD_NAME_GET_NAMESPACE); if (resultProxy instanceof IStringBeanProxy) { return ((IStringBeanProxy) resultProxy).stringValue(); } } catch (final BeanProxyUtil.ProxyException e) { // fall through } return resolveNSAggressively(beanProxy); } private String resolveNSAggressively(final BeanProxyWrapper beanProxy) { try { return beanProxy.getStringFieldValue(STATIC_MEMBER_NAMESPACE); } catch (final ProxyException e) { // fall through } return null; } public synchronized int getNumTags() { // initializeIfNecessary(); return _tags.size(); } }