Index: common/ant/glassfishV3.1/container.xml =================================================================== --- common/ant/glassfishV3.1/container.xml (revision 8807) +++ common/ant/glassfishV3.1/container.xml (working copy) @@ -167,10 +167,14 @@ + + + + Index: jsf-ri/src/main/java/com/sun/faces/config/ConfigManager.java =================================================================== --- jsf-ri/src/main/java/com/sun/faces/config/ConfigManager.java (revision 8807) +++ jsf-ri/src/main/java/com/sun/faces/config/ConfigManager.java (working copy) @@ -110,6 +110,8 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.lang.annotation.Annotation; +import java.net.URI; +import java.util.Iterator; import org.w3c.dom.*; import org.xml.sax.SAXParseException; @@ -1090,7 +1092,28 @@ * ConfigurationResourceProvider */ public Collection call() throws Exception { - return provider.getResources(sc); + Collection result = Collections.emptyList(); + Collection collection = provider.getResources(sc); + if (!collection.isEmpty()) { + result = new ArrayList(); + Iterator iter = collection.iterator(); + Object cur = iter.next(); + if (cur instanceof URL) { + do { + result.add((URL)cur); + cur = (iter.hasNext()) ? iter.next() : null; + } while (null != cur); + } else if (cur instanceof URI) { + do { + result.add(((URI)cur).toURL()); + cur = (iter.hasNext()) ? iter.next() : null; + } while (null != cur); + } else { + throw new IllegalArgumentException("Expected argument of type URI or URL, instead type is " + + cur.getClass().getName()); + } + } + return result; } } // END URLTask Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.container.common.spi.JCDIService; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; +import com.sun.enterprise.container.common.spi.util.InjectionException; +import com.sun.enterprise.container.common.spi.util.InjectionManager; +import com.sun.enterprise.web.ServerConfigLookup; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.InjectionInfo; +import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.faces.spi.DiscoverableInjectionProvider; +import com.sun.faces.spi.InjectionProviderException; +import com.sun.faces.util.FacesLogger; +import org.glassfish.api.invocation.ComponentInvocation; +import org.glassfish.api.invocation.InvocationManager; +import org.jvnet.hk2.component.Habitat; + +import javax.servlet.ServletContext; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import com.sun.enterprise.web.WebModule; +import com.sun.faces.config.WebConfiguration; +import org.apache.catalina.core.StandardContext; +/** + *

This InjectionProvider is specific to the + * GlassFish/SJSAS 9.x PE/EE application servers.

+ */ +public class GlassFishInjectionProvider extends DiscoverableInjectionProvider { + + private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); + private static final String HABITAT_ATTRIBUTE = + "org.glassfish.servlet.habitat"; + private ComponentEnvManager compEnvManager; + private InjectionManager injectionManager; + private InvocationManager invokeMgr; + private JCDIService jcdiService; + private ServerConfigLookup serverConfigLookup; + + /** + *

Constructs a new GlassFishInjectionProvider instance.

+ * + * @param servletContext + */ + public GlassFishInjectionProvider(ServletContext servletContext) { + Habitat defaultHabitat = (Habitat)servletContext.getAttribute( + HABITAT_ATTRIBUTE); + compEnvManager = defaultHabitat.getByContract(ComponentEnvManager.class); + invokeMgr = defaultHabitat.getByContract(InvocationManager.class); + injectionManager = defaultHabitat.getByContract(InjectionManager.class); + jcdiService = defaultHabitat.getByContract(JCDIService.class); + serverConfigLookup = defaultHabitat.getComponent(ServerConfigLookup.class); + + } + + /** + *

The implementation of this method must perform the following + * steps: + *

    + *
  • Inject the supported resources per the Servlet 2.5 + * specification into the provided object
  • + *
+ *

+ * + * @param managedBean the target managed bean + */ + @Override + public void inject(Object managedBean) throws InjectionProviderException { + try { + injectionManager.injectInstance(managedBean, + getNamingEnvironment(), + false); + + if (jcdiService.isCurrentModuleJCDIEnabled()) { + jcdiService.injectManagedObject(managedBean, getBundle()); + + } + + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + /** + *

The implemenation of this method must invoke any + * method marked with the @PreDestroy annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + */ + @Override + public void invokePreDestroy(Object managedBean) + throws InjectionProviderException { + try { + injectionManager.invokeInstancePreDestroy(managedBean); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + + /** + *

The implemenation of this method must invoke any + * method marked with the @PostConstruct annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + * + * @throws com.sun.faces.spi.InjectionProviderException + * if an error occurs when invoking + * the method annotated by the @PostConstruct annotation + */ + @Override + public void invokePostConstruct(Object managedBean) + throws InjectionProviderException { + try { + this.invokePostConstruct(managedBean, getNamingEnvironment()); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + + } + + + // --------------------------------------------------------- Private Methods + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @return JndiNameEnvironment + * @throws InjectionException if we're unable to obtain the + * JndiNameEnvironment + */ + private JndiNameEnvironment getNamingEnvironment() + throws InjectionException { + ComponentInvocation inv = invokeMgr.getCurrentInvocation(); + + if (inv != null) { + + if (inv.getInvocationType()== ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION) { + + JndiNameEnvironment componentEnv = (JndiNameEnvironment) + inv.jndiEnvironment; + + if (componentEnv != null) { + return componentEnv; + } else { + throw new InjectionException("No descriptor registered for " + " current invocation : " + inv); + } + } else { + throw new InjectionException("Wrong invocation type"); + } + } else { + throw new InjectionException("null invocation context"); + } + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * + * @param instance managed bean instance + * @param envDescriptor JNDI environment + * @throws InjectionException if an error occurs + */ + private void invokePostConstruct(Object instance, + JndiNameEnvironment envDescriptor) + throws InjectionException { + LinkedList postConstructMethods = new LinkedList(); + + Class nextClass = instance.getClass(); + + // Process each class in the inheritance hierarchy, starting with + // the most derived class and ignoring java.lang.Object. + while ((!Object.class.equals(nextClass)) && (nextClass != null)) { + + InjectionInfo injInfo = + envDescriptor.getInjectionInfoByClass(nextClass); + + if (injInfo.getPostConstructMethodName() != null) { + + Method postConstructMethod = getPostConstructMethod + (injInfo, nextClass); + + // Invoke the preDestroy methods starting from + // the least-derived class downward. + postConstructMethods.addFirst(postConstructMethod); + } + + nextClass = nextClass.getSuperclass(); + } + + for (Method postConstructMethod : postConstructMethods) { + + invokeLifecycleMethod(postConstructMethod, instance); + + } + + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param injInfo InjectionInfo + * @param resourceClass target class + * @return a Method marked with the @PostConstruct annotation + * @throws InjectionException if an error occurs + */ + private Method getPostConstructMethod(InjectionInfo injInfo, + Class resourceClass) + throws InjectionException { + + Method m = injInfo.getPostConstructMethod(); + + if( m == null ) { + String postConstructMethodName = + injInfo.getPostConstructMethodName(); + + // Check for the method within the resourceClass only. + // This does not include super-classses. + for(Method next : resourceClass.getDeclaredMethods()) { + // InjectionManager only handles injection into PostConstruct + // methods with no arguments. + if( next.getName().equals(postConstructMethodName) && + (next.getParameterTypes().length == 0) ) { + m = next; + injInfo.setPostConstructMethod(m); + break; + } + } + } + + if( m == null ) { + throw new InjectionException + ("InjectionManager exception. PostConstruct method " + + injInfo.getPostConstructMethodName() + + " could not be found in class " + + injInfo.getClassName()); + } + + return m; + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param lifecycleMethod the method to invoke + * @param instance the instanced to invoke the method against + * @throws InjectionException if an error occurs + */ + private void invokeLifecycleMethod(final Method lifecycleMethod, + final Object instance) + throws InjectionException { + + try { + + if(LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Calling lifecycle method {0} on class {1}", new Object[]{lifecycleMethod, lifecycleMethod.getDeclaringClass()}); + } + + // Wrap actual value insertion in doPrivileged to + // allow for private/protected field access. + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + @Override + public java.lang.Object run() throws Exception { + if( !lifecycleMethod.isAccessible() ) { + lifecycleMethod.setAccessible(true); + } + lifecycleMethod.invoke(instance); + return null; + } + }); + } catch( Exception t) { + + String msg = "Exception attempting invoke lifecycle " + + " method " + lifecycleMethod; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, msg, t); + } + InjectionException ie = new InjectionException(msg); + Throwable cause = (t instanceof InvocationTargetException) ? + t.getCause() : t; + ie.initCause( cause ); + throw ie; + + } + + return; + + } + + private BundleDescriptor getBundle() { + + JndiNameEnvironment env = compEnvManager.getCurrentJndiNameEnvironment(); + + BundleDescriptor bundle = null; + + if( env instanceof BundleDescriptor) { + + bundle = (BundleDescriptor) env; + + } + + if( bundle == null ) { + throw new IllegalStateException("Invalid context for managed bean creation"); + } + + return bundle; + + } + + /** + * Method to test with HA has been enabled. + * If so, then set the JSF context param + * com.sun.faces.enableAgressiveSessionDirtying to true + * @param ctx + */ + public void enableHighAvailability(ServletContext ctx) { + //look at the following values for the web app + //1> has in the web.xml + //2> Was deployed with --availabilityenabled --target + WebConfiguration config = WebConfiguration.getInstance(ctx); + if (!config.isSet(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying)) { + if (ctx instanceof org.apache.catalina.core.ApplicationContextFacade) { + org.apache.catalina.core.ApplicationContext applicationContext = + ((org.apache.catalina.core.ApplicationContextFacade) ctx).getApplicationContext(); + StandardContext stdContext = applicationContext.getStandardContext(); + WebBundleDescriptor desc = ((WebModule) stdContext).getWebModuleConfig().getDescriptor(); + boolean isDistributable = desc.isDistributable(); + boolean enableHA = serverConfigLookup.calculateWebAvailabilityEnabledFromConfig((WebModule) stdContext); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, + "isDistributable = {0} enableHA = {1}", + new Object[]{isDistributable, enableHA}); + } + if (isDistributable && enableHA) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("setting the EnableAgressiveSessionDirtying to true"); + } + config.overrideContextInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying, + Boolean.TRUE); + } + } + } + } +} // END GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) @@ -0,0 +1,175 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.module.Module; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.util.net.JarURIPattern; +import com.sun.logging.LogDomains; +import org.glassfish.api.web.TldProvider; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.PostConstruct; +import org.jvnet.hk2.component.Singleton; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Implementation of TldProvider for JSF. + * @author Shing Wai Chan + * @author Sahoo + */ + +@Service(name="jsfTld") +@Scoped(Singleton.class) +public class GlassFishTldProvider implements TldProvider, PostConstruct { + + private static final Logger logger = + LogDomains.getLogger(GlassFishTldProvider.class, + LogDomains.WEB_LOGGER); + + private static final ResourceBundle rb = logger.getResourceBundle(); + + @Inject + ModulesRegistry registry; + + private Map> tldMap = + new HashMap>(); + + private Map> tldListenerMap = null; + + /** + * Gets the name of this TldProvider + */ + public String getName() { + return "jsfTld"; + } + + /** + * Gets a mapping from JAR files to their TLD resources. + */ + public Map> getTldMap() { + return (Map>)((HashMap)tldMap).clone(); + } + + /** + * Gets a mapping from JAR files to their TLD resources + * that are known to contain listener declarations. + */ + public synchronized Map> getTldListenerMap() { + if (tldListenerMap == null) { + tldListenerMap = new HashMap>(); + for (URI uri : tldMap.keySet()) { + /* + * In the case of JSF, the only TLD that declares any + * listener is META-INF/jsf_core.tld + */ + if (tldMap.get(uri).contains("META-INF/jsf_core.tld")) { + tldListenerMap.put(uri, tldMap.get(uri)); + break; + } + } + tldListenerMap = Collections.unmodifiableMap(tldListenerMap); + } + + return tldListenerMap; + } + + public void postConstruct() { + + Class jsfImplClass = null; + try { + jsfImplClass = getClass().getClassLoader().loadClass( + "com.sun.faces.spi.InjectionProvider"); + } catch (ClassNotFoundException ignored) { + } + + URI[] uris = null; + Module m = null; + if (jsfImplClass != null) { + m = registry.find(jsfImplClass); + } + if (m != null) { + uris = m.getModuleDefinition().getLocations(); + } else { + ClassLoader classLoader = getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader)classLoader).getURLs(); + if (urls != null && urls.length > 0) { + uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + try { + uris[i] = urls[i].toURI(); + } catch(URISyntaxException e) { + String msg = rb.getString("tldProvider.ignoreUrl"); + msg = MessageFormat.format(msg, urls[i]); + logger.log(Level.WARNING, msg, e); + } + } + } + } else { + logger.log(Level.WARNING, + "taglibs.unableToDetermineTldResources", + new Object[] {"JSF", classLoader, + GlassFishTldProvider.class.getName()}); + } + } + + if (uris != null && uris.length > 0) { + Pattern pattern = Pattern.compile("META-INF/.*\\.tld"); + for (URI uri : uris) { + List entries = JarURIPattern.getJarEntries(uri, pattern); + if (entries != null && entries.size() > 0) { + tldMap.put(uri, entries); + } + } + } + } +} Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) @@ -0,0 +1 @@ +org.glassfish.faces.integration.GlassFishInjectionProvider:org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) @@ -0,0 +1,6 @@ +# Hack to make GlassFishInjectionProvider visible globally in GFv3, +# so that jsf-impl.jar can discover it from webapp classloaders. +# +# When HK2 sees the service discovery pattern, it exposes the classes +# to all the modules in the habitat (AKA class loader punch-in) +org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/osgi.bundle =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/osgi.bundle (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/osgi.bundle (revision 0) @@ -0,0 +1,45 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. +# +# The contents of this file are subject to the terms of either the GNU +# General Public License Version 2 only ("GPL") or the Common Development +# and Distribution License("CDDL") (collectively, the "License"). You +# may not use this file except in compliance with the License. You can +# obtain a copy of the License at +# https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html +# or packager/legal/LICENSE.txt. See the License for the specific +# language governing permissions and limitations under the License. +# +# When distributing the software, include this License Header Notice in each +# file and include the License file at packager/legal/LICENSE.txt. +# +# GPL Classpath Exception: +# Oracle designates this particular file as subject to the "Classpath" +# exception as provided by Oracle in the GPL Version 2 section of the License +# file that accompanied this code. +# +# Modifications: +# If applicable, add the following below the License Header, with the fields +# enclosed by brackets [] replaced by your own identifying information: +# "Portions Copyright [year] [name of copyright owner]" +# +# Contributor(s): +# If you wish your version of this file to be governed by only the CDDL or +# only the GPL Version 2, indicate your decision by adding "[Contributor] +# elects to include this software in this distribution under the [CDDL or GPL +# Version 2] license." If you don't indicate a single choice of license, a +# recipient has the option to distribute your version of this file under +# either the CDDL, the GPL Version 2 or to extend the choice of license to +# its licensees as provided above. However, if you add GPL Version 2 code +# and therefore, elected the GPL Version 2 license, then the option applies +# only if the new code is made subject to such option by the copyright +# holder. +# + +-exportcontents: org.glassfish.faces.integration.*; version=${project.osgi.version} + +Import-Package: \ + com.sun.logging.enterprise.system.container.web, \ + * Index: jsf-connector/jsf-connector-glassfishV3.1/pom.xml =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/pom.xml (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/pom.xml (revision 0) @@ -0,0 +1,351 @@ + + + + + 4.0.0 + org.glassfish.web + jsf-connector + 2.0.4 + hk2-jar + JSF implementation connector module for running Mojarra 2.0.X in GlassFish 3.1.X + + Generated by running mvn help:effective-pom on + https://svn.java.net/svn/glassfish~svn/trunk/v3/web/jsf-connector/pom.xml + + + + + org.apache.maven.wagon + wagon-webdav + 1.0-beta-2 + + + jsf-connector + + + + com.sun.enterprise + hk2-maven-plugin + 1.0.72 + + + com.sun.enterprise + osgiversion-maven-plugin + 1.0.72 + + + com.sun.enterprise + consolidatedbundle-maven-plugin + 1.0.72 + + + org.jvnet.maven-antrun-extended-plugin + maven-antrun-extended-plugin + 1.41 + + + org.glassfish.build + maven-glassfishbuild-plugin + 3.1-SNAPSHOT + + . + true + + org.glassfish.distributions + web + 3.1-SNAPSHOT + + + + + org.codehaus.mojo + antlr-maven-plugin + 2.1 + + + org.jvnet.updatecenter2 + maven-makepkgs-plugin + 0.5.1 + + + + + + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + maven-enforcer-plugin + 1.0-beta-1 + + + enforce-versions + + enforce + + + + + [1.6.0-4,) + You need JDK 1.6.0_04 and above! + + + [2.2.1,) + You need Maven 2.2.1 or above! + + + + + + + + org.apache.felix + maven-bundle-plugin + 2.0.1 + + + bundle-manifest + process-classes + + manifest + + + + + + + hk2-jar + bundle + + + <_include>-${project.basedir}/osgi.bundle + + + + + maven-source-plugin + 2.1 + + + attach-sources + verify + + jar-no-fork + + + + + true + + + + com.sun.enterprise + hk2-maven-plugin + 1.0.72 + true + + + ${project.basedir}/target/classes/META-INF/MANIFEST.MF + + + + + com.sun.enterprise + osgiversion-maven-plugin + 1.0.72 + + + compute-osgi-version + + compute-osgi-version + + + qualifier + project.osgi.version + + + + + + maven-jar-plugin + 2.2 + + + org.apache.maven + maven-archiver + 2.4 + compile + + + + + org.glassfish.build + maven-glassfishbuild-plugin + 3.1-SNAPSHOT + + + echo + validate + + echo + + + + Building in ${project.basedir}/jsf-connector + + + + + + . + true + + org.glassfish.distributions + web + 3.1-SNAPSHOT + + + + + + + + + never + + glassfish-repo-archive + Nexus repository collection for Glassfish + http://maven.glassfish.org/content/groups/glassfish + + + + false + + central + Maven Repository Switchboard + http://repo1.maven.org/maven2 + + + + + + never + + glassfish-repo-archive + Nexus repository collection for Glassfish + http://maven.glassfish.org/content/groups/glassfish + + + + never + + + false + + central + Maven Plugin Repository + http://repo1.maven.org/maven2 + + + + + com.sun.enterprise + hk2 + 1.0.72 + compile + + + org.glassfish.web + web-glue + 3.1-SNAPSHOT + compile + + + com.sun.faces + jsf-api + 2.1.0-b10 + provided + + + com.sun.faces + jsf-impl + 2.1.0-b10 + provided + + + org.glassfish.common + glassfish-api + 3.1-SNAPSHOT + compile + + + org.glassfish.common + common-util + 3.1-SNAPSHOT + compile + + + org.glassfish.common + container-common + 3.1-SNAPSHOT + compile + + + org.glassfish.deployment + dol + 3.1-SNAPSHOT + compile + + + junit + junit + 4.3.1 + test + true + + + Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.container.common.spi.JCDIService; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; +import com.sun.enterprise.container.common.spi.util.InjectionException; +import com.sun.enterprise.container.common.spi.util.InjectionManager; +import com.sun.enterprise.web.ServerConfigLookup; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.InjectionInfo; +import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.faces.spi.DiscoverableInjectionProvider; +import com.sun.faces.spi.InjectionProviderException; +import com.sun.faces.util.FacesLogger; +import org.glassfish.api.invocation.ComponentInvocation; +import org.glassfish.api.invocation.InvocationManager; +import org.jvnet.hk2.component.Habitat; + +import javax.servlet.ServletContext; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import com.sun.enterprise.web.WebModule; +import com.sun.faces.config.WebConfiguration; +import org.apache.catalina.core.StandardContext; +/** + *

This InjectionProvider is specific to the + * GlassFish/SJSAS 9.x PE/EE application servers.

+ */ +public class GlassFishInjectionProvider extends DiscoverableInjectionProvider { + + private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); + private static final String HABITAT_ATTRIBUTE = + "org.glassfish.servlet.habitat"; + private ComponentEnvManager compEnvManager; + private InjectionManager injectionManager; + private InvocationManager invokeMgr; + private JCDIService jcdiService; + private ServerConfigLookup serverConfigLookup; + + /** + *

Constructs a new GlassFishInjectionProvider instance.

+ * + * @param servletContext + */ + public GlassFishInjectionProvider(ServletContext servletContext) { + Habitat defaultHabitat = (Habitat)servletContext.getAttribute( + HABITAT_ATTRIBUTE); + compEnvManager = defaultHabitat.getByContract(ComponentEnvManager.class); + invokeMgr = defaultHabitat.getByContract(InvocationManager.class); + injectionManager = defaultHabitat.getByContract(InjectionManager.class); + jcdiService = defaultHabitat.getByContract(JCDIService.class); + serverConfigLookup = defaultHabitat.getComponent(ServerConfigLookup.class); + + } + + /** + *

The implementation of this method must perform the following + * steps: + *

    + *
  • Inject the supported resources per the Servlet 2.5 + * specification into the provided object
  • + *
+ *

+ * + * @param managedBean the target managed bean + */ + @Override + public void inject(Object managedBean) throws InjectionProviderException { + try { + injectionManager.injectInstance(managedBean, + getNamingEnvironment(), + false); + + if (jcdiService.isCurrentModuleJCDIEnabled()) { + jcdiService.injectManagedObject(managedBean, getBundle()); + + } + + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + /** + *

The implemenation of this method must invoke any + * method marked with the @PreDestroy annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + */ + @Override + public void invokePreDestroy(Object managedBean) + throws InjectionProviderException { + try { + injectionManager.invokeInstancePreDestroy(managedBean); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + + /** + *

The implemenation of this method must invoke any + * method marked with the @PostConstruct annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + * + * @throws com.sun.faces.spi.InjectionProviderException + * if an error occurs when invoking + * the method annotated by the @PostConstruct annotation + */ + @Override + public void invokePostConstruct(Object managedBean) + throws InjectionProviderException { + try { + this.invokePostConstruct(managedBean, getNamingEnvironment()); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + + } + + + // --------------------------------------------------------- Private Methods + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @return JndiNameEnvironment + * @throws InjectionException if we're unable to obtain the + * JndiNameEnvironment + */ + private JndiNameEnvironment getNamingEnvironment() + throws InjectionException { + ComponentInvocation inv = invokeMgr.getCurrentInvocation(); + + if (inv != null) { + + if (inv.getInvocationType()== ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION) { + + JndiNameEnvironment componentEnv = (JndiNameEnvironment) + inv.jndiEnvironment; + + if (componentEnv != null) { + return componentEnv; + } else { + throw new InjectionException("No descriptor registered for " + " current invocation : " + inv); + } + } else { + throw new InjectionException("Wrong invocation type"); + } + } else { + throw new InjectionException("null invocation context"); + } + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * + * @param instance managed bean instance + * @param envDescriptor JNDI environment + * @throws InjectionException if an error occurs + */ + private void invokePostConstruct(Object instance, + JndiNameEnvironment envDescriptor) + throws InjectionException { + LinkedList postConstructMethods = new LinkedList(); + + Class nextClass = instance.getClass(); + + // Process each class in the inheritance hierarchy, starting with + // the most derived class and ignoring java.lang.Object. + while ((!Object.class.equals(nextClass)) && (nextClass != null)) { + + InjectionInfo injInfo = + envDescriptor.getInjectionInfoByClass(nextClass); + + if (injInfo.getPostConstructMethodName() != null) { + + Method postConstructMethod = getPostConstructMethod + (injInfo, nextClass); + + // Invoke the preDestroy methods starting from + // the least-derived class downward. + postConstructMethods.addFirst(postConstructMethod); + } + + nextClass = nextClass.getSuperclass(); + } + + for (Method postConstructMethod : postConstructMethods) { + + invokeLifecycleMethod(postConstructMethod, instance); + + } + + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param injInfo InjectionInfo + * @param resourceClass target class + * @return a Method marked with the @PostConstruct annotation + * @throws InjectionException if an error occurs + */ + private Method getPostConstructMethod(InjectionInfo injInfo, + Class resourceClass) + throws InjectionException { + + Method m = injInfo.getPostConstructMethod(); + + if( m == null ) { + String postConstructMethodName = + injInfo.getPostConstructMethodName(); + + // Check for the method within the resourceClass only. + // This does not include super-classses. + for(Method next : resourceClass.getDeclaredMethods()) { + // InjectionManager only handles injection into PostConstruct + // methods with no arguments. + if( next.getName().equals(postConstructMethodName) && + (next.getParameterTypes().length == 0) ) { + m = next; + injInfo.setPostConstructMethod(m); + break; + } + } + } + + if( m == null ) { + throw new InjectionException + ("InjectionManager exception. PostConstruct method " + + injInfo.getPostConstructMethodName() + + " could not be found in class " + + injInfo.getClassName()); + } + + return m; + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param lifecycleMethod the method to invoke + * @param instance the instanced to invoke the method against + * @throws InjectionException if an error occurs + */ + private void invokeLifecycleMethod(final Method lifecycleMethod, + final Object instance) + throws InjectionException { + + try { + + if(LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Calling lifecycle method {0} on class {1}", new Object[]{lifecycleMethod, lifecycleMethod.getDeclaringClass()}); + } + + // Wrap actual value insertion in doPrivileged to + // allow for private/protected field access. + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + @Override + public java.lang.Object run() throws Exception { + if( !lifecycleMethod.isAccessible() ) { + lifecycleMethod.setAccessible(true); + } + lifecycleMethod.invoke(instance); + return null; + } + }); + } catch( Exception t) { + + String msg = "Exception attempting invoke lifecycle " + + " method " + lifecycleMethod; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, msg, t); + } + InjectionException ie = new InjectionException(msg); + Throwable cause = (t instanceof InvocationTargetException) ? + t.getCause() : t; + ie.initCause( cause ); + throw ie; + + } + + return; + + } + + private BundleDescriptor getBundle() { + + JndiNameEnvironment env = compEnvManager.getCurrentJndiNameEnvironment(); + + BundleDescriptor bundle = null; + + if( env instanceof BundleDescriptor) { + + bundle = (BundleDescriptor) env; + + } + + if( bundle == null ) { + throw new IllegalStateException("Invalid context for managed bean creation"); + } + + return bundle; + + } + + /** + * Method to test with HA has been enabled. + * If so, then set the JSF context param + * com.sun.faces.enableAgressiveSessionDirtying to true + * @param ctx + */ + public void enableHighAvailability(ServletContext ctx) { + //look at the following values for the web app + //1> has in the web.xml + //2> Was deployed with --availabilityenabled --target + WebConfiguration config = WebConfiguration.getInstance(ctx); + if (!config.isSet(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying)) { + if (ctx instanceof org.apache.catalina.core.ApplicationContextFacade) { + org.apache.catalina.core.ApplicationContext applicationContext = + ((org.apache.catalina.core.ApplicationContextFacade) ctx).getApplicationContext(); + StandardContext stdContext = applicationContext.getStandardContext(); + WebBundleDescriptor desc = ((WebModule) stdContext).getWebModuleConfig().getDescriptor(); + boolean isDistributable = desc.isDistributable(); + boolean enableHA = serverConfigLookup.calculateWebAvailabilityEnabledFromConfig((WebModule) stdContext); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, + "isDistributable = {0} enableHA = {1}", + new Object[]{isDistributable, enableHA}); + } + if (isDistributable && enableHA) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("setting the EnableAgressiveSessionDirtying to true"); + } + config.overrideContextInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying, + Boolean.TRUE); + } + } + } + } +} // END GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) @@ -0,0 +1,175 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.module.Module; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.util.net.JarURIPattern; +import com.sun.logging.LogDomains; +import org.glassfish.api.web.TldProvider; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.PostConstruct; +import org.jvnet.hk2.component.Singleton; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Implementation of TldProvider for JSF. + * @author Shing Wai Chan + * @author Sahoo + */ + +@Service(name="jsfTld") +@Scoped(Singleton.class) +public class GlassFishTldProvider implements TldProvider, PostConstruct { + + private static final Logger logger = + LogDomains.getLogger(GlassFishTldProvider.class, + LogDomains.WEB_LOGGER); + + private static final ResourceBundle rb = logger.getResourceBundle(); + + @Inject + ModulesRegistry registry; + + private Map> tldMap = + new HashMap>(); + + private Map> tldListenerMap = null; + + /** + * Gets the name of this TldProvider + */ + public String getName() { + return "jsfTld"; + } + + /** + * Gets a mapping from JAR files to their TLD resources. + */ + public Map> getTldMap() { + return (Map>)((HashMap)tldMap).clone(); + } + + /** + * Gets a mapping from JAR files to their TLD resources + * that are known to contain listener declarations. + */ + public synchronized Map> getTldListenerMap() { + if (tldListenerMap == null) { + tldListenerMap = new HashMap>(); + for (URI uri : tldMap.keySet()) { + /* + * In the case of JSF, the only TLD that declares any + * listener is META-INF/jsf_core.tld + */ + if (tldMap.get(uri).contains("META-INF/jsf_core.tld")) { + tldListenerMap.put(uri, tldMap.get(uri)); + break; + } + } + tldListenerMap = Collections.unmodifiableMap(tldListenerMap); + } + + return tldListenerMap; + } + + public void postConstruct() { + + Class jsfImplClass = null; + try { + jsfImplClass = getClass().getClassLoader().loadClass( + "com.sun.faces.spi.InjectionProvider"); + } catch (ClassNotFoundException ignored) { + } + + URI[] uris = null; + Module m = null; + if (jsfImplClass != null) { + m = registry.find(jsfImplClass); + } + if (m != null) { + uris = m.getModuleDefinition().getLocations(); + } else { + ClassLoader classLoader = getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader)classLoader).getURLs(); + if (urls != null && urls.length > 0) { + uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + try { + uris[i] = urls[i].toURI(); + } catch(URISyntaxException e) { + String msg = rb.getString("tldProvider.ignoreUrl"); + msg = MessageFormat.format(msg, urls[i]); + logger.log(Level.WARNING, msg, e); + } + } + } + } else { + logger.log(Level.WARNING, + "taglibs.unableToDetermineTldResources", + new Object[] {"JSF", classLoader, + GlassFishTldProvider.class.getName()}); + } + } + + if (uris != null && uris.length > 0) { + Pattern pattern = Pattern.compile("META-INF/.*\\.tld"); + for (URI uri : uris) { + List entries = JarURIPattern.getJarEntries(uri, pattern); + if (entries != null && entries.size() > 0) { + tldMap.put(uri, entries); + } + } + } + } +} Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) @@ -0,0 +1 @@ +org.glassfish.faces.integration.GlassFishInjectionProvider:org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) @@ -0,0 +1,6 @@ +# Hack to make GlassFishInjectionProvider visible globally in GFv3, +# so that jsf-impl.jar can discover it from webapp classloaders. +# +# When HK2 sees the service discovery pattern, it exposes the classes +# to all the modules in the habitat (AKA class loader punch-in) +org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/osgi.bundle =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/osgi.bundle (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/osgi.bundle (revision 0) @@ -0,0 +1,45 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. +# +# The contents of this file are subject to the terms of either the GNU +# General Public License Version 2 only ("GPL") or the Common Development +# and Distribution License("CDDL") (collectively, the "License"). You +# may not use this file except in compliance with the License. You can +# obtain a copy of the License at +# https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html +# or packager/legal/LICENSE.txt. See the License for the specific +# language governing permissions and limitations under the License. +# +# When distributing the software, include this License Header Notice in each +# file and include the License file at packager/legal/LICENSE.txt. +# +# GPL Classpath Exception: +# Oracle designates this particular file as subject to the "Classpath" +# exception as provided by Oracle in the GPL Version 2 section of the License +# file that accompanied this code. +# +# Modifications: +# If applicable, add the following below the License Header, with the fields +# enclosed by brackets [] replaced by your own identifying information: +# "Portions Copyright [year] [name of copyright owner]" +# +# Contributor(s): +# If you wish your version of this file to be governed by only the CDDL or +# only the GPL Version 2, indicate your decision by adding "[Contributor] +# elects to include this software in this distribution under the [CDDL or GPL +# Version 2] license." If you don't indicate a single choice of license, a +# recipient has the option to distribute your version of this file under +# either the CDDL, the GPL Version 2 or to extend the choice of license to +# its licensees as provided above. However, if you add GPL Version 2 code +# and therefore, elected the GPL Version 2 license, then the option applies +# only if the new code is made subject to such option by the copyright +# holder. +# + +-exportcontents: org.glassfish.faces.integration.*; version=${project.osgi.version} + +Import-Package: \ + com.sun.logging.enterprise.system.container.web, \ + * Index: jsf-connector/jsf-connector-glassfishV3.1/pom.xml =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/pom.xml (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/pom.xml (revision 0) @@ -0,0 +1,351 @@ + + + + + 4.0.0 + org.glassfish.web + jsf-connector + 2.0.4 + hk2-jar + JSF implementation connector module for running Mojarra 2.0.X in GlassFish 3.1.X + + Generated by running mvn help:effective-pom on + https://svn.java.net/svn/glassfish~svn/trunk/v3/web/jsf-connector/pom.xml + + + + + org.apache.maven.wagon + wagon-webdav + 1.0-beta-2 + + + jsf-connector + + + + com.sun.enterprise + hk2-maven-plugin + 1.0.72 + + + com.sun.enterprise + osgiversion-maven-plugin + 1.0.72 + + + com.sun.enterprise + consolidatedbundle-maven-plugin + 1.0.72 + + + org.jvnet.maven-antrun-extended-plugin + maven-antrun-extended-plugin + 1.41 + + + org.glassfish.build + maven-glassfishbuild-plugin + 3.1-SNAPSHOT + + . + true + + org.glassfish.distributions + web + 3.1-SNAPSHOT + + + + + org.codehaus.mojo + antlr-maven-plugin + 2.1 + + + org.jvnet.updatecenter2 + maven-makepkgs-plugin + 0.5.1 + + + + + + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + maven-enforcer-plugin + 1.0-beta-1 + + + enforce-versions + + enforce + + + + + [1.6.0-4,) + You need JDK 1.6.0_04 and above! + + + [2.2.1,) + You need Maven 2.2.1 or above! + + + + + + + + org.apache.felix + maven-bundle-plugin + 2.0.1 + + + bundle-manifest + process-classes + + manifest + + + + + + + hk2-jar + bundle + + + <_include>-${project.basedir}/osgi.bundle + + + + + maven-source-plugin + 2.1 + + + attach-sources + verify + + jar-no-fork + + + + + true + + + + com.sun.enterprise + hk2-maven-plugin + 1.0.72 + true + + + ${project.basedir}/target/classes/META-INF/MANIFEST.MF + + + + + com.sun.enterprise + osgiversion-maven-plugin + 1.0.72 + + + compute-osgi-version + + compute-osgi-version + + + qualifier + project.osgi.version + + + + + + maven-jar-plugin + 2.2 + + + org.apache.maven + maven-archiver + 2.4 + compile + + + + + org.glassfish.build + maven-glassfishbuild-plugin + 3.1-SNAPSHOT + + + echo + validate + + echo + + + + Building in ${project.basedir}/jsf-connector + + + + + + . + true + + org.glassfish.distributions + web + 3.1-SNAPSHOT + + + + + + + + + never + + glassfish-repo-archive + Nexus repository collection for Glassfish + http://maven.glassfish.org/content/groups/glassfish + + + + false + + central + Maven Repository Switchboard + http://repo1.maven.org/maven2 + + + + + + never + + glassfish-repo-archive + Nexus repository collection for Glassfish + http://maven.glassfish.org/content/groups/glassfish + + + + never + + + false + + central + Maven Plugin Repository + http://repo1.maven.org/maven2 + + + + + com.sun.enterprise + hk2 + 1.0.72 + compile + + + org.glassfish.web + web-glue + 3.1-SNAPSHOT + compile + + + com.sun.faces + jsf-api + 2.1.0-b10 + provided + + + com.sun.faces + jsf-impl + 2.1.0-b10 + provided + + + org.glassfish.common + glassfish-api + 3.1-SNAPSHOT + compile + + + org.glassfish.common + common-util + 3.1-SNAPSHOT + compile + + + org.glassfish.common + container-common + 3.1-SNAPSHOT + compile + + + org.glassfish.deployment + dol + 3.1-SNAPSHOT + compile + + + junit + junit + 4.3.1 + test + true + + + Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.container.common.spi.JCDIService; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; +import com.sun.enterprise.container.common.spi.util.InjectionException; +import com.sun.enterprise.container.common.spi.util.InjectionManager; +import com.sun.enterprise.web.ServerConfigLookup; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.InjectionInfo; +import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.faces.spi.DiscoverableInjectionProvider; +import com.sun.faces.spi.InjectionProviderException; +import com.sun.faces.util.FacesLogger; +import org.glassfish.api.invocation.ComponentInvocation; +import org.glassfish.api.invocation.InvocationManager; +import org.jvnet.hk2.component.Habitat; + +import javax.servlet.ServletContext; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import com.sun.enterprise.web.WebModule; +import com.sun.faces.config.WebConfiguration; +import org.apache.catalina.core.StandardContext; +/** + *

This InjectionProvider is specific to the + * GlassFish/SJSAS 9.x PE/EE application servers.

+ */ +public class GlassFishInjectionProvider extends DiscoverableInjectionProvider { + + private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); + private static final String HABITAT_ATTRIBUTE = + "org.glassfish.servlet.habitat"; + private ComponentEnvManager compEnvManager; + private InjectionManager injectionManager; + private InvocationManager invokeMgr; + private JCDIService jcdiService; + private ServerConfigLookup serverConfigLookup; + + /** + *

Constructs a new GlassFishInjectionProvider instance.

+ * + * @param servletContext + */ + public GlassFishInjectionProvider(ServletContext servletContext) { + Habitat defaultHabitat = (Habitat)servletContext.getAttribute( + HABITAT_ATTRIBUTE); + compEnvManager = defaultHabitat.getByContract(ComponentEnvManager.class); + invokeMgr = defaultHabitat.getByContract(InvocationManager.class); + injectionManager = defaultHabitat.getByContract(InjectionManager.class); + jcdiService = defaultHabitat.getByContract(JCDIService.class); + serverConfigLookup = defaultHabitat.getComponent(ServerConfigLookup.class); + + } + + /** + *

The implementation of this method must perform the following + * steps: + *

    + *
  • Inject the supported resources per the Servlet 2.5 + * specification into the provided object
  • + *
+ *

+ * + * @param managedBean the target managed bean + */ + @Override + public void inject(Object managedBean) throws InjectionProviderException { + try { + injectionManager.injectInstance(managedBean, + getNamingEnvironment(), + false); + + if (jcdiService.isCurrentModuleJCDIEnabled()) { + jcdiService.injectManagedObject(managedBean, getBundle()); + + } + + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + /** + *

The implemenation of this method must invoke any + * method marked with the @PreDestroy annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + */ + @Override + public void invokePreDestroy(Object managedBean) + throws InjectionProviderException { + try { + injectionManager.invokeInstancePreDestroy(managedBean); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + + /** + *

The implemenation of this method must invoke any + * method marked with the @PostConstruct annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + * + * @throws com.sun.faces.spi.InjectionProviderException + * if an error occurs when invoking + * the method annotated by the @PostConstruct annotation + */ + @Override + public void invokePostConstruct(Object managedBean) + throws InjectionProviderException { + try { + this.invokePostConstruct(managedBean, getNamingEnvironment()); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + + } + + + // --------------------------------------------------------- Private Methods + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @return JndiNameEnvironment + * @throws InjectionException if we're unable to obtain the + * JndiNameEnvironment + */ + private JndiNameEnvironment getNamingEnvironment() + throws InjectionException { + ComponentInvocation inv = invokeMgr.getCurrentInvocation(); + + if (inv != null) { + + if (inv.getInvocationType()== ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION) { + + JndiNameEnvironment componentEnv = (JndiNameEnvironment) + inv.jndiEnvironment; + + if (componentEnv != null) { + return componentEnv; + } else { + throw new InjectionException("No descriptor registered for " + " current invocation : " + inv); + } + } else { + throw new InjectionException("Wrong invocation type"); + } + } else { + throw new InjectionException("null invocation context"); + } + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * + * @param instance managed bean instance + * @param envDescriptor JNDI environment + * @throws InjectionException if an error occurs + */ + private void invokePostConstruct(Object instance, + JndiNameEnvironment envDescriptor) + throws InjectionException { + LinkedList postConstructMethods = new LinkedList(); + + Class nextClass = instance.getClass(); + + // Process each class in the inheritance hierarchy, starting with + // the most derived class and ignoring java.lang.Object. + while ((!Object.class.equals(nextClass)) && (nextClass != null)) { + + InjectionInfo injInfo = + envDescriptor.getInjectionInfoByClass(nextClass); + + if (injInfo.getPostConstructMethodName() != null) { + + Method postConstructMethod = getPostConstructMethod + (injInfo, nextClass); + + // Invoke the preDestroy methods starting from + // the least-derived class downward. + postConstructMethods.addFirst(postConstructMethod); + } + + nextClass = nextClass.getSuperclass(); + } + + for (Method postConstructMethod : postConstructMethods) { + + invokeLifecycleMethod(postConstructMethod, instance); + + } + + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param injInfo InjectionInfo + * @param resourceClass target class + * @return a Method marked with the @PostConstruct annotation + * @throws InjectionException if an error occurs + */ + private Method getPostConstructMethod(InjectionInfo injInfo, + Class resourceClass) + throws InjectionException { + + Method m = injInfo.getPostConstructMethod(); + + if( m == null ) { + String postConstructMethodName = + injInfo.getPostConstructMethodName(); + + // Check for the method within the resourceClass only. + // This does not include super-classses. + for(Method next : resourceClass.getDeclaredMethods()) { + // InjectionManager only handles injection into PostConstruct + // methods with no arguments. + if( next.getName().equals(postConstructMethodName) && + (next.getParameterTypes().length == 0) ) { + m = next; + injInfo.setPostConstructMethod(m); + break; + } + } + } + + if( m == null ) { + throw new InjectionException + ("InjectionManager exception. PostConstruct method " + + injInfo.getPostConstructMethodName() + + " could not be found in class " + + injInfo.getClassName()); + } + + return m; + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param lifecycleMethod the method to invoke + * @param instance the instanced to invoke the method against + * @throws InjectionException if an error occurs + */ + private void invokeLifecycleMethod(final Method lifecycleMethod, + final Object instance) + throws InjectionException { + + try { + + if(LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Calling lifecycle method {0} on class {1}", new Object[]{lifecycleMethod, lifecycleMethod.getDeclaringClass()}); + } + + // Wrap actual value insertion in doPrivileged to + // allow for private/protected field access. + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + @Override + public java.lang.Object run() throws Exception { + if( !lifecycleMethod.isAccessible() ) { + lifecycleMethod.setAccessible(true); + } + lifecycleMethod.invoke(instance); + return null; + } + }); + } catch( Exception t) { + + String msg = "Exception attempting invoke lifecycle " + + " method " + lifecycleMethod; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, msg, t); + } + InjectionException ie = new InjectionException(msg); + Throwable cause = (t instanceof InvocationTargetException) ? + t.getCause() : t; + ie.initCause( cause ); + throw ie; + + } + + return; + + } + + private BundleDescriptor getBundle() { + + JndiNameEnvironment env = compEnvManager.getCurrentJndiNameEnvironment(); + + BundleDescriptor bundle = null; + + if( env instanceof BundleDescriptor) { + + bundle = (BundleDescriptor) env; + + } + + if( bundle == null ) { + throw new IllegalStateException("Invalid context for managed bean creation"); + } + + return bundle; + + } + + /** + * Method to test with HA has been enabled. + * If so, then set the JSF context param + * com.sun.faces.enableAgressiveSessionDirtying to true + * @param ctx + */ + public void enableHighAvailability(ServletContext ctx) { + //look at the following values for the web app + //1> has in the web.xml + //2> Was deployed with --availabilityenabled --target + WebConfiguration config = WebConfiguration.getInstance(ctx); + if (!config.isSet(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying)) { + if (ctx instanceof org.apache.catalina.core.ApplicationContextFacade) { + org.apache.catalina.core.ApplicationContext applicationContext = + ((org.apache.catalina.core.ApplicationContextFacade) ctx).getApplicationContext(); + StandardContext stdContext = applicationContext.getStandardContext(); + WebBundleDescriptor desc = ((WebModule) stdContext).getWebModuleConfig().getDescriptor(); + boolean isDistributable = desc.isDistributable(); + boolean enableHA = serverConfigLookup.calculateWebAvailabilityEnabledFromConfig((WebModule) stdContext); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, + "isDistributable = {0} enableHA = {1}", + new Object[]{isDistributable, enableHA}); + } + if (isDistributable && enableHA) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("setting the EnableAgressiveSessionDirtying to true"); + } + config.overrideContextInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying, + Boolean.TRUE); + } + } + } + } +} // END GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) @@ -0,0 +1,175 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.module.Module; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.util.net.JarURIPattern; +import com.sun.logging.LogDomains; +import org.glassfish.api.web.TldProvider; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.PostConstruct; +import org.jvnet.hk2.component.Singleton; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Implementation of TldProvider for JSF. + * @author Shing Wai Chan + * @author Sahoo + */ + +@Service(name="jsfTld") +@Scoped(Singleton.class) +public class GlassFishTldProvider implements TldProvider, PostConstruct { + + private static final Logger logger = + LogDomains.getLogger(GlassFishTldProvider.class, + LogDomains.WEB_LOGGER); + + private static final ResourceBundle rb = logger.getResourceBundle(); + + @Inject + ModulesRegistry registry; + + private Map> tldMap = + new HashMap>(); + + private Map> tldListenerMap = null; + + /** + * Gets the name of this TldProvider + */ + public String getName() { + return "jsfTld"; + } + + /** + * Gets a mapping from JAR files to their TLD resources. + */ + public Map> getTldMap() { + return (Map>)((HashMap)tldMap).clone(); + } + + /** + * Gets a mapping from JAR files to their TLD resources + * that are known to contain listener declarations. + */ + public synchronized Map> getTldListenerMap() { + if (tldListenerMap == null) { + tldListenerMap = new HashMap>(); + for (URI uri : tldMap.keySet()) { + /* + * In the case of JSF, the only TLD that declares any + * listener is META-INF/jsf_core.tld + */ + if (tldMap.get(uri).contains("META-INF/jsf_core.tld")) { + tldListenerMap.put(uri, tldMap.get(uri)); + break; + } + } + tldListenerMap = Collections.unmodifiableMap(tldListenerMap); + } + + return tldListenerMap; + } + + public void postConstruct() { + + Class jsfImplClass = null; + try { + jsfImplClass = getClass().getClassLoader().loadClass( + "com.sun.faces.spi.InjectionProvider"); + } catch (ClassNotFoundException ignored) { + } + + URI[] uris = null; + Module m = null; + if (jsfImplClass != null) { + m = registry.find(jsfImplClass); + } + if (m != null) { + uris = m.getModuleDefinition().getLocations(); + } else { + ClassLoader classLoader = getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader)classLoader).getURLs(); + if (urls != null && urls.length > 0) { + uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + try { + uris[i] = urls[i].toURI(); + } catch(URISyntaxException e) { + String msg = rb.getString("tldProvider.ignoreUrl"); + msg = MessageFormat.format(msg, urls[i]); + logger.log(Level.WARNING, msg, e); + } + } + } + } else { + logger.log(Level.WARNING, + "taglibs.unableToDetermineTldResources", + new Object[] {"JSF", classLoader, + GlassFishTldProvider.class.getName()}); + } + } + + if (uris != null && uris.length > 0) { + Pattern pattern = Pattern.compile("META-INF/.*\\.tld"); + for (URI uri : uris) { + List entries = JarURIPattern.getJarEntries(uri, pattern); + if (entries != null && entries.size() > 0) { + tldMap.put(uri, entries); + } + } + } + } +} Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) @@ -0,0 +1 @@ +org.glassfish.faces.integration.GlassFishInjectionProvider:org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) @@ -0,0 +1,6 @@ +# Hack to make GlassFishInjectionProvider visible globally in GFv3, +# so that jsf-impl.jar can discover it from webapp classloaders. +# +# When HK2 sees the service discovery pattern, it exposes the classes +# to all the modules in the habitat (AKA class loader punch-in) +org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.container.common.spi.JCDIService; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; +import com.sun.enterprise.container.common.spi.util.InjectionException; +import com.sun.enterprise.container.common.spi.util.InjectionManager; +import com.sun.enterprise.web.ServerConfigLookup; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.InjectionInfo; +import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.faces.spi.DiscoverableInjectionProvider; +import com.sun.faces.spi.InjectionProviderException; +import com.sun.faces.util.FacesLogger; +import org.glassfish.api.invocation.ComponentInvocation; +import org.glassfish.api.invocation.InvocationManager; +import org.jvnet.hk2.component.Habitat; + +import javax.servlet.ServletContext; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import com.sun.enterprise.web.WebModule; +import com.sun.faces.config.WebConfiguration; +import org.apache.catalina.core.StandardContext; +/** + *

This InjectionProvider is specific to the + * GlassFish/SJSAS 9.x PE/EE application servers.

+ */ +public class GlassFishInjectionProvider extends DiscoverableInjectionProvider { + + private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); + private static final String HABITAT_ATTRIBUTE = + "org.glassfish.servlet.habitat"; + private ComponentEnvManager compEnvManager; + private InjectionManager injectionManager; + private InvocationManager invokeMgr; + private JCDIService jcdiService; + private ServerConfigLookup serverConfigLookup; + + /** + *

Constructs a new GlassFishInjectionProvider instance.

+ * + * @param servletContext + */ + public GlassFishInjectionProvider(ServletContext servletContext) { + Habitat defaultHabitat = (Habitat)servletContext.getAttribute( + HABITAT_ATTRIBUTE); + compEnvManager = defaultHabitat.getByContract(ComponentEnvManager.class); + invokeMgr = defaultHabitat.getByContract(InvocationManager.class); + injectionManager = defaultHabitat.getByContract(InjectionManager.class); + jcdiService = defaultHabitat.getByContract(JCDIService.class); + serverConfigLookup = defaultHabitat.getComponent(ServerConfigLookup.class); + + } + + /** + *

The implementation of this method must perform the following + * steps: + *

    + *
  • Inject the supported resources per the Servlet 2.5 + * specification into the provided object
  • + *
+ *

+ * + * @param managedBean the target managed bean + */ + @Override + public void inject(Object managedBean) throws InjectionProviderException { + try { + injectionManager.injectInstance(managedBean, + getNamingEnvironment(), + false); + + if (jcdiService.isCurrentModuleJCDIEnabled()) { + jcdiService.injectManagedObject(managedBean, getBundle()); + + } + + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + /** + *

The implemenation of this method must invoke any + * method marked with the @PreDestroy annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + */ + @Override + public void invokePreDestroy(Object managedBean) + throws InjectionProviderException { + try { + injectionManager.invokeInstancePreDestroy(managedBean); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + + /** + *

The implemenation of this method must invoke any + * method marked with the @PostConstruct annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + * + * @throws com.sun.faces.spi.InjectionProviderException + * if an error occurs when invoking + * the method annotated by the @PostConstruct annotation + */ + @Override + public void invokePostConstruct(Object managedBean) + throws InjectionProviderException { + try { + this.invokePostConstruct(managedBean, getNamingEnvironment()); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + + } + + + // --------------------------------------------------------- Private Methods + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @return JndiNameEnvironment + * @throws InjectionException if we're unable to obtain the + * JndiNameEnvironment + */ + private JndiNameEnvironment getNamingEnvironment() + throws InjectionException { + ComponentInvocation inv = invokeMgr.getCurrentInvocation(); + + if (inv != null) { + + if (inv.getInvocationType()== ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION) { + + JndiNameEnvironment componentEnv = (JndiNameEnvironment) + inv.jndiEnvironment; + + if (componentEnv != null) { + return componentEnv; + } else { + throw new InjectionException("No descriptor registered for " + " current invocation : " + inv); + } + } else { + throw new InjectionException("Wrong invocation type"); + } + } else { + throw new InjectionException("null invocation context"); + } + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * + * @param instance managed bean instance + * @param envDescriptor JNDI environment + * @throws InjectionException if an error occurs + */ + private void invokePostConstruct(Object instance, + JndiNameEnvironment envDescriptor) + throws InjectionException { + LinkedList postConstructMethods = new LinkedList(); + + Class nextClass = instance.getClass(); + + // Process each class in the inheritance hierarchy, starting with + // the most derived class and ignoring java.lang.Object. + while ((!Object.class.equals(nextClass)) && (nextClass != null)) { + + InjectionInfo injInfo = + envDescriptor.getInjectionInfoByClass(nextClass); + + if (injInfo.getPostConstructMethodName() != null) { + + Method postConstructMethod = getPostConstructMethod + (injInfo, nextClass); + + // Invoke the preDestroy methods starting from + // the least-derived class downward. + postConstructMethods.addFirst(postConstructMethod); + } + + nextClass = nextClass.getSuperclass(); + } + + for (Method postConstructMethod : postConstructMethods) { + + invokeLifecycleMethod(postConstructMethod, instance); + + } + + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param injInfo InjectionInfo + * @param resourceClass target class + * @return a Method marked with the @PostConstruct annotation + * @throws InjectionException if an error occurs + */ + private Method getPostConstructMethod(InjectionInfo injInfo, + Class resourceClass) + throws InjectionException { + + Method m = injInfo.getPostConstructMethod(); + + if( m == null ) { + String postConstructMethodName = + injInfo.getPostConstructMethodName(); + + // Check for the method within the resourceClass only. + // This does not include super-classses. + for(Method next : resourceClass.getDeclaredMethods()) { + // InjectionManager only handles injection into PostConstruct + // methods with no arguments. + if( next.getName().equals(postConstructMethodName) && + (next.getParameterTypes().length == 0) ) { + m = next; + injInfo.setPostConstructMethod(m); + break; + } + } + } + + if( m == null ) { + throw new InjectionException + ("InjectionManager exception. PostConstruct method " + + injInfo.getPostConstructMethodName() + + " could not be found in class " + + injInfo.getClassName()); + } + + return m; + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param lifecycleMethod the method to invoke + * @param instance the instanced to invoke the method against + * @throws InjectionException if an error occurs + */ + private void invokeLifecycleMethod(final Method lifecycleMethod, + final Object instance) + throws InjectionException { + + try { + + if(LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Calling lifecycle method {0} on class {1}", new Object[]{lifecycleMethod, lifecycleMethod.getDeclaringClass()}); + } + + // Wrap actual value insertion in doPrivileged to + // allow for private/protected field access. + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + @Override + public java.lang.Object run() throws Exception { + if( !lifecycleMethod.isAccessible() ) { + lifecycleMethod.setAccessible(true); + } + lifecycleMethod.invoke(instance); + return null; + } + }); + } catch( Exception t) { + + String msg = "Exception attempting invoke lifecycle " + + " method " + lifecycleMethod; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, msg, t); + } + InjectionException ie = new InjectionException(msg); + Throwable cause = (t instanceof InvocationTargetException) ? + t.getCause() : t; + ie.initCause( cause ); + throw ie; + + } + + return; + + } + + private BundleDescriptor getBundle() { + + JndiNameEnvironment env = compEnvManager.getCurrentJndiNameEnvironment(); + + BundleDescriptor bundle = null; + + if( env instanceof BundleDescriptor) { + + bundle = (BundleDescriptor) env; + + } + + if( bundle == null ) { + throw new IllegalStateException("Invalid context for managed bean creation"); + } + + return bundle; + + } + + /** + * Method to test with HA has been enabled. + * If so, then set the JSF context param + * com.sun.faces.enableAgressiveSessionDirtying to true + * @param ctx + */ + public void enableHighAvailability(ServletContext ctx) { + //look at the following values for the web app + //1> has in the web.xml + //2> Was deployed with --availabilityenabled --target + WebConfiguration config = WebConfiguration.getInstance(ctx); + if (!config.isSet(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying)) { + if (ctx instanceof org.apache.catalina.core.ApplicationContextFacade) { + org.apache.catalina.core.ApplicationContext applicationContext = + ((org.apache.catalina.core.ApplicationContextFacade) ctx).getApplicationContext(); + StandardContext stdContext = applicationContext.getStandardContext(); + WebBundleDescriptor desc = ((WebModule) stdContext).getWebModuleConfig().getDescriptor(); + boolean isDistributable = desc.isDistributable(); + boolean enableHA = serverConfigLookup.calculateWebAvailabilityEnabledFromConfig((WebModule) stdContext); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, + "isDistributable = {0} enableHA = {1}", + new Object[]{isDistributable, enableHA}); + } + if (isDistributable && enableHA) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("setting the EnableAgressiveSessionDirtying to true"); + } + config.overrideContextInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying, + Boolean.TRUE); + } + } + } + } +} // END GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) @@ -0,0 +1,175 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.module.Module; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.util.net.JarURIPattern; +import com.sun.logging.LogDomains; +import org.glassfish.api.web.TldProvider; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.PostConstruct; +import org.jvnet.hk2.component.Singleton; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Implementation of TldProvider for JSF. + * @author Shing Wai Chan + * @author Sahoo + */ + +@Service(name="jsfTld") +@Scoped(Singleton.class) +public class GlassFishTldProvider implements TldProvider, PostConstruct { + + private static final Logger logger = + LogDomains.getLogger(GlassFishTldProvider.class, + LogDomains.WEB_LOGGER); + + private static final ResourceBundle rb = logger.getResourceBundle(); + + @Inject + ModulesRegistry registry; + + private Map> tldMap = + new HashMap>(); + + private Map> tldListenerMap = null; + + /** + * Gets the name of this TldProvider + */ + public String getName() { + return "jsfTld"; + } + + /** + * Gets a mapping from JAR files to their TLD resources. + */ + public Map> getTldMap() { + return (Map>)((HashMap)tldMap).clone(); + } + + /** + * Gets a mapping from JAR files to their TLD resources + * that are known to contain listener declarations. + */ + public synchronized Map> getTldListenerMap() { + if (tldListenerMap == null) { + tldListenerMap = new HashMap>(); + for (URI uri : tldMap.keySet()) { + /* + * In the case of JSF, the only TLD that declares any + * listener is META-INF/jsf_core.tld + */ + if (tldMap.get(uri).contains("META-INF/jsf_core.tld")) { + tldListenerMap.put(uri, tldMap.get(uri)); + break; + } + } + tldListenerMap = Collections.unmodifiableMap(tldListenerMap); + } + + return tldListenerMap; + } + + public void postConstruct() { + + Class jsfImplClass = null; + try { + jsfImplClass = getClass().getClassLoader().loadClass( + "com.sun.faces.spi.InjectionProvider"); + } catch (ClassNotFoundException ignored) { + } + + URI[] uris = null; + Module m = null; + if (jsfImplClass != null) { + m = registry.find(jsfImplClass); + } + if (m != null) { + uris = m.getModuleDefinition().getLocations(); + } else { + ClassLoader classLoader = getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader)classLoader).getURLs(); + if (urls != null && urls.length > 0) { + uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + try { + uris[i] = urls[i].toURI(); + } catch(URISyntaxException e) { + String msg = rb.getString("tldProvider.ignoreUrl"); + msg = MessageFormat.format(msg, urls[i]); + logger.log(Level.WARNING, msg, e); + } + } + } + } else { + logger.log(Level.WARNING, + "taglibs.unableToDetermineTldResources", + new Object[] {"JSF", classLoader, + GlassFishTldProvider.class.getName()}); + } + } + + if (uris != null && uris.length > 0) { + Pattern pattern = Pattern.compile("META-INF/.*\\.tld"); + for (URI uri : uris) { + List entries = JarURIPattern.getJarEntries(uri, pattern); + if (entries != null && entries.size() > 0) { + tldMap.put(uri, entries); + } + } + } + } +} Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) @@ -0,0 +1 @@ +org.glassfish.faces.integration.GlassFishInjectionProvider:org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) @@ -0,0 +1,6 @@ +# Hack to make GlassFishInjectionProvider visible globally in GFv3, +# so that jsf-impl.jar can discover it from webapp classloaders. +# +# When HK2 sees the service discovery pattern, it exposes the classes +# to all the modules in the habitat (AKA class loader punch-in) +org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.container.common.spi.JCDIService; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; +import com.sun.enterprise.container.common.spi.util.InjectionException; +import com.sun.enterprise.container.common.spi.util.InjectionManager; +import com.sun.enterprise.web.ServerConfigLookup; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.InjectionInfo; +import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.faces.spi.DiscoverableInjectionProvider; +import com.sun.faces.spi.InjectionProviderException; +import com.sun.faces.util.FacesLogger; +import org.glassfish.api.invocation.ComponentInvocation; +import org.glassfish.api.invocation.InvocationManager; +import org.jvnet.hk2.component.Habitat; + +import javax.servlet.ServletContext; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import com.sun.enterprise.web.WebModule; +import com.sun.faces.config.WebConfiguration; +import org.apache.catalina.core.StandardContext; +/** + *

This InjectionProvider is specific to the + * GlassFish/SJSAS 9.x PE/EE application servers.

+ */ +public class GlassFishInjectionProvider extends DiscoverableInjectionProvider { + + private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); + private static final String HABITAT_ATTRIBUTE = + "org.glassfish.servlet.habitat"; + private ComponentEnvManager compEnvManager; + private InjectionManager injectionManager; + private InvocationManager invokeMgr; + private JCDIService jcdiService; + private ServerConfigLookup serverConfigLookup; + + /** + *

Constructs a new GlassFishInjectionProvider instance.

+ * + * @param servletContext + */ + public GlassFishInjectionProvider(ServletContext servletContext) { + Habitat defaultHabitat = (Habitat)servletContext.getAttribute( + HABITAT_ATTRIBUTE); + compEnvManager = defaultHabitat.getByContract(ComponentEnvManager.class); + invokeMgr = defaultHabitat.getByContract(InvocationManager.class); + injectionManager = defaultHabitat.getByContract(InjectionManager.class); + jcdiService = defaultHabitat.getByContract(JCDIService.class); + serverConfigLookup = defaultHabitat.getComponent(ServerConfigLookup.class); + + } + + /** + *

The implementation of this method must perform the following + * steps: + *

    + *
  • Inject the supported resources per the Servlet 2.5 + * specification into the provided object
  • + *
+ *

+ * + * @param managedBean the target managed bean + */ + @Override + public void inject(Object managedBean) throws InjectionProviderException { + try { + injectionManager.injectInstance(managedBean, + getNamingEnvironment(), + false); + + if (jcdiService.isCurrentModuleJCDIEnabled()) { + jcdiService.injectManagedObject(managedBean, getBundle()); + + } + + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + /** + *

The implemenation of this method must invoke any + * method marked with the @PreDestroy annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + */ + @Override + public void invokePreDestroy(Object managedBean) + throws InjectionProviderException { + try { + injectionManager.invokeInstancePreDestroy(managedBean); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + + /** + *

The implemenation of this method must invoke any + * method marked with the @PostConstruct annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + * + * @throws com.sun.faces.spi.InjectionProviderException + * if an error occurs when invoking + * the method annotated by the @PostConstruct annotation + */ + @Override + public void invokePostConstruct(Object managedBean) + throws InjectionProviderException { + try { + this.invokePostConstruct(managedBean, getNamingEnvironment()); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + + } + + + // --------------------------------------------------------- Private Methods + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @return JndiNameEnvironment + * @throws InjectionException if we're unable to obtain the + * JndiNameEnvironment + */ + private JndiNameEnvironment getNamingEnvironment() + throws InjectionException { + ComponentInvocation inv = invokeMgr.getCurrentInvocation(); + + if (inv != null) { + + if (inv.getInvocationType()== ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION) { + + JndiNameEnvironment componentEnv = (JndiNameEnvironment) + inv.jndiEnvironment; + + if (componentEnv != null) { + return componentEnv; + } else { + throw new InjectionException("No descriptor registered for " + " current invocation : " + inv); + } + } else { + throw new InjectionException("Wrong invocation type"); + } + } else { + throw new InjectionException("null invocation context"); + } + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * + * @param instance managed bean instance + * @param envDescriptor JNDI environment + * @throws InjectionException if an error occurs + */ + private void invokePostConstruct(Object instance, + JndiNameEnvironment envDescriptor) + throws InjectionException { + LinkedList postConstructMethods = new LinkedList(); + + Class nextClass = instance.getClass(); + + // Process each class in the inheritance hierarchy, starting with + // the most derived class and ignoring java.lang.Object. + while ((!Object.class.equals(nextClass)) && (nextClass != null)) { + + InjectionInfo injInfo = + envDescriptor.getInjectionInfoByClass(nextClass); + + if (injInfo.getPostConstructMethodName() != null) { + + Method postConstructMethod = getPostConstructMethod + (injInfo, nextClass); + + // Invoke the preDestroy methods starting from + // the least-derived class downward. + postConstructMethods.addFirst(postConstructMethod); + } + + nextClass = nextClass.getSuperclass(); + } + + for (Method postConstructMethod : postConstructMethods) { + + invokeLifecycleMethod(postConstructMethod, instance); + + } + + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param injInfo InjectionInfo + * @param resourceClass target class + * @return a Method marked with the @PostConstruct annotation + * @throws InjectionException if an error occurs + */ + private Method getPostConstructMethod(InjectionInfo injInfo, + Class resourceClass) + throws InjectionException { + + Method m = injInfo.getPostConstructMethod(); + + if( m == null ) { + String postConstructMethodName = + injInfo.getPostConstructMethodName(); + + // Check for the method within the resourceClass only. + // This does not include super-classses. + for(Method next : resourceClass.getDeclaredMethods()) { + // InjectionManager only handles injection into PostConstruct + // methods with no arguments. + if( next.getName().equals(postConstructMethodName) && + (next.getParameterTypes().length == 0) ) { + m = next; + injInfo.setPostConstructMethod(m); + break; + } + } + } + + if( m == null ) { + throw new InjectionException + ("InjectionManager exception. PostConstruct method " + + injInfo.getPostConstructMethodName() + + " could not be found in class " + + injInfo.getClassName()); + } + + return m; + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param lifecycleMethod the method to invoke + * @param instance the instanced to invoke the method against + * @throws InjectionException if an error occurs + */ + private void invokeLifecycleMethod(final Method lifecycleMethod, + final Object instance) + throws InjectionException { + + try { + + if(LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Calling lifecycle method {0} on class {1}", new Object[]{lifecycleMethod, lifecycleMethod.getDeclaringClass()}); + } + + // Wrap actual value insertion in doPrivileged to + // allow for private/protected field access. + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + @Override + public java.lang.Object run() throws Exception { + if( !lifecycleMethod.isAccessible() ) { + lifecycleMethod.setAccessible(true); + } + lifecycleMethod.invoke(instance); + return null; + } + }); + } catch( Exception t) { + + String msg = "Exception attempting invoke lifecycle " + + " method " + lifecycleMethod; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, msg, t); + } + InjectionException ie = new InjectionException(msg); + Throwable cause = (t instanceof InvocationTargetException) ? + t.getCause() : t; + ie.initCause( cause ); + throw ie; + + } + + return; + + } + + private BundleDescriptor getBundle() { + + JndiNameEnvironment env = compEnvManager.getCurrentJndiNameEnvironment(); + + BundleDescriptor bundle = null; + + if( env instanceof BundleDescriptor) { + + bundle = (BundleDescriptor) env; + + } + + if( bundle == null ) { + throw new IllegalStateException("Invalid context for managed bean creation"); + } + + return bundle; + + } + + /** + * Method to test with HA has been enabled. + * If so, then set the JSF context param + * com.sun.faces.enableAgressiveSessionDirtying to true + * @param ctx + */ + public void enableHighAvailability(ServletContext ctx) { + //look at the following values for the web app + //1> has in the web.xml + //2> Was deployed with --availabilityenabled --target + WebConfiguration config = WebConfiguration.getInstance(ctx); + if (!config.isSet(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying)) { + if (ctx instanceof org.apache.catalina.core.ApplicationContextFacade) { + org.apache.catalina.core.ApplicationContext applicationContext = + ((org.apache.catalina.core.ApplicationContextFacade) ctx).getApplicationContext(); + StandardContext stdContext = applicationContext.getStandardContext(); + WebBundleDescriptor desc = ((WebModule) stdContext).getWebModuleConfig().getDescriptor(); + boolean isDistributable = desc.isDistributable(); + boolean enableHA = serverConfigLookup.calculateWebAvailabilityEnabledFromConfig((WebModule) stdContext); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, + "isDistributable = {0} enableHA = {1}", + new Object[]{isDistributable, enableHA}); + } + if (isDistributable && enableHA) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("setting the EnableAgressiveSessionDirtying to true"); + } + config.overrideContextInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying, + Boolean.TRUE); + } + } + } + } +} // END GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) @@ -0,0 +1,175 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.module.Module; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.util.net.JarURIPattern; +import com.sun.logging.LogDomains; +import org.glassfish.api.web.TldProvider; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.PostConstruct; +import org.jvnet.hk2.component.Singleton; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Implementation of TldProvider for JSF. + * @author Shing Wai Chan + * @author Sahoo + */ + +@Service(name="jsfTld") +@Scoped(Singleton.class) +public class GlassFishTldProvider implements TldProvider, PostConstruct { + + private static final Logger logger = + LogDomains.getLogger(GlassFishTldProvider.class, + LogDomains.WEB_LOGGER); + + private static final ResourceBundle rb = logger.getResourceBundle(); + + @Inject + ModulesRegistry registry; + + private Map> tldMap = + new HashMap>(); + + private Map> tldListenerMap = null; + + /** + * Gets the name of this TldProvider + */ + public String getName() { + return "jsfTld"; + } + + /** + * Gets a mapping from JAR files to their TLD resources. + */ + public Map> getTldMap() { + return (Map>)((HashMap)tldMap).clone(); + } + + /** + * Gets a mapping from JAR files to their TLD resources + * that are known to contain listener declarations. + */ + public synchronized Map> getTldListenerMap() { + if (tldListenerMap == null) { + tldListenerMap = new HashMap>(); + for (URI uri : tldMap.keySet()) { + /* + * In the case of JSF, the only TLD that declares any + * listener is META-INF/jsf_core.tld + */ + if (tldMap.get(uri).contains("META-INF/jsf_core.tld")) { + tldListenerMap.put(uri, tldMap.get(uri)); + break; + } + } + tldListenerMap = Collections.unmodifiableMap(tldListenerMap); + } + + return tldListenerMap; + } + + public void postConstruct() { + + Class jsfImplClass = null; + try { + jsfImplClass = getClass().getClassLoader().loadClass( + "com.sun.faces.spi.InjectionProvider"); + } catch (ClassNotFoundException ignored) { + } + + URI[] uris = null; + Module m = null; + if (jsfImplClass != null) { + m = registry.find(jsfImplClass); + } + if (m != null) { + uris = m.getModuleDefinition().getLocations(); + } else { + ClassLoader classLoader = getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader)classLoader).getURLs(); + if (urls != null && urls.length > 0) { + uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + try { + uris[i] = urls[i].toURI(); + } catch(URISyntaxException e) { + String msg = rb.getString("tldProvider.ignoreUrl"); + msg = MessageFormat.format(msg, urls[i]); + logger.log(Level.WARNING, msg, e); + } + } + } + } else { + logger.log(Level.WARNING, + "taglibs.unableToDetermineTldResources", + new Object[] {"JSF", classLoader, + GlassFishTldProvider.class.getName()}); + } + } + + if (uris != null && uris.length > 0) { + Pattern pattern = Pattern.compile("META-INF/.*\\.tld"); + for (URI uri : uris) { + List entries = JarURIPattern.getJarEntries(uri, pattern); + if (entries != null && entries.size() > 0) { + tldMap.put(uri, entries); + } + } + } + } +} Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.container.common.spi.JCDIService; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; +import com.sun.enterprise.container.common.spi.util.InjectionException; +import com.sun.enterprise.container.common.spi.util.InjectionManager; +import com.sun.enterprise.web.ServerConfigLookup; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.InjectionInfo; +import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.faces.spi.DiscoverableInjectionProvider; +import com.sun.faces.spi.InjectionProviderException; +import com.sun.faces.util.FacesLogger; +import org.glassfish.api.invocation.ComponentInvocation; +import org.glassfish.api.invocation.InvocationManager; +import org.jvnet.hk2.component.Habitat; + +import javax.servlet.ServletContext; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import com.sun.enterprise.web.WebModule; +import com.sun.faces.config.WebConfiguration; +import org.apache.catalina.core.StandardContext; +/** + *

This InjectionProvider is specific to the + * GlassFish/SJSAS 9.x PE/EE application servers.

+ */ +public class GlassFishInjectionProvider extends DiscoverableInjectionProvider { + + private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); + private static final String HABITAT_ATTRIBUTE = + "org.glassfish.servlet.habitat"; + private ComponentEnvManager compEnvManager; + private InjectionManager injectionManager; + private InvocationManager invokeMgr; + private JCDIService jcdiService; + private ServerConfigLookup serverConfigLookup; + + /** + *

Constructs a new GlassFishInjectionProvider instance.

+ * + * @param servletContext + */ + public GlassFishInjectionProvider(ServletContext servletContext) { + Habitat defaultHabitat = (Habitat)servletContext.getAttribute( + HABITAT_ATTRIBUTE); + compEnvManager = defaultHabitat.getByContract(ComponentEnvManager.class); + invokeMgr = defaultHabitat.getByContract(InvocationManager.class); + injectionManager = defaultHabitat.getByContract(InjectionManager.class); + jcdiService = defaultHabitat.getByContract(JCDIService.class); + serverConfigLookup = defaultHabitat.getComponent(ServerConfigLookup.class); + + } + + /** + *

The implementation of this method must perform the following + * steps: + *

    + *
  • Inject the supported resources per the Servlet 2.5 + * specification into the provided object
  • + *
+ *

+ * + * @param managedBean the target managed bean + */ + @Override + public void inject(Object managedBean) throws InjectionProviderException { + try { + injectionManager.injectInstance(managedBean, + getNamingEnvironment(), + false); + + if (jcdiService.isCurrentModuleJCDIEnabled()) { + jcdiService.injectManagedObject(managedBean, getBundle()); + + } + + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + /** + *

The implemenation of this method must invoke any + * method marked with the @PreDestroy annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + */ + @Override + public void invokePreDestroy(Object managedBean) + throws InjectionProviderException { + try { + injectionManager.invokeInstancePreDestroy(managedBean); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + + /** + *

The implemenation of this method must invoke any + * method marked with the @PostConstruct annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + * + * @throws com.sun.faces.spi.InjectionProviderException + * if an error occurs when invoking + * the method annotated by the @PostConstruct annotation + */ + @Override + public void invokePostConstruct(Object managedBean) + throws InjectionProviderException { + try { + this.invokePostConstruct(managedBean, getNamingEnvironment()); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + + } + + + // --------------------------------------------------------- Private Methods + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @return JndiNameEnvironment + * @throws InjectionException if we're unable to obtain the + * JndiNameEnvironment + */ + private JndiNameEnvironment getNamingEnvironment() + throws InjectionException { + ComponentInvocation inv = invokeMgr.getCurrentInvocation(); + + if (inv != null) { + + if (inv.getInvocationType()== ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION) { + + JndiNameEnvironment componentEnv = (JndiNameEnvironment) + inv.jndiEnvironment; + + if (componentEnv != null) { + return componentEnv; + } else { + throw new InjectionException("No descriptor registered for " + " current invocation : " + inv); + } + } else { + throw new InjectionException("Wrong invocation type"); + } + } else { + throw new InjectionException("null invocation context"); + } + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * + * @param instance managed bean instance + * @param envDescriptor JNDI environment + * @throws InjectionException if an error occurs + */ + private void invokePostConstruct(Object instance, + JndiNameEnvironment envDescriptor) + throws InjectionException { + LinkedList postConstructMethods = new LinkedList(); + + Class nextClass = instance.getClass(); + + // Process each class in the inheritance hierarchy, starting with + // the most derived class and ignoring java.lang.Object. + while ((!Object.class.equals(nextClass)) && (nextClass != null)) { + + InjectionInfo injInfo = + envDescriptor.getInjectionInfoByClass(nextClass); + + if (injInfo.getPostConstructMethodName() != null) { + + Method postConstructMethod = getPostConstructMethod + (injInfo, nextClass); + + // Invoke the preDestroy methods starting from + // the least-derived class downward. + postConstructMethods.addFirst(postConstructMethod); + } + + nextClass = nextClass.getSuperclass(); + } + + for (Method postConstructMethod : postConstructMethods) { + + invokeLifecycleMethod(postConstructMethod, instance); + + } + + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param injInfo InjectionInfo + * @param resourceClass target class + * @return a Method marked with the @PostConstruct annotation + * @throws InjectionException if an error occurs + */ + private Method getPostConstructMethod(InjectionInfo injInfo, + Class resourceClass) + throws InjectionException { + + Method m = injInfo.getPostConstructMethod(); + + if( m == null ) { + String postConstructMethodName = + injInfo.getPostConstructMethodName(); + + // Check for the method within the resourceClass only. + // This does not include super-classses. + for(Method next : resourceClass.getDeclaredMethods()) { + // InjectionManager only handles injection into PostConstruct + // methods with no arguments. + if( next.getName().equals(postConstructMethodName) && + (next.getParameterTypes().length == 0) ) { + m = next; + injInfo.setPostConstructMethod(m); + break; + } + } + } + + if( m == null ) { + throw new InjectionException + ("InjectionManager exception. PostConstruct method " + + injInfo.getPostConstructMethodName() + + " could not be found in class " + + injInfo.getClassName()); + } + + return m; + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param lifecycleMethod the method to invoke + * @param instance the instanced to invoke the method against + * @throws InjectionException if an error occurs + */ + private void invokeLifecycleMethod(final Method lifecycleMethod, + final Object instance) + throws InjectionException { + + try { + + if(LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Calling lifecycle method {0} on class {1}", new Object[]{lifecycleMethod, lifecycleMethod.getDeclaringClass()}); + } + + // Wrap actual value insertion in doPrivileged to + // allow for private/protected field access. + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + @Override + public java.lang.Object run() throws Exception { + if( !lifecycleMethod.isAccessible() ) { + lifecycleMethod.setAccessible(true); + } + lifecycleMethod.invoke(instance); + return null; + } + }); + } catch( Exception t) { + + String msg = "Exception attempting invoke lifecycle " + + " method " + lifecycleMethod; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, msg, t); + } + InjectionException ie = new InjectionException(msg); + Throwable cause = (t instanceof InvocationTargetException) ? + t.getCause() : t; + ie.initCause( cause ); + throw ie; + + } + + return; + + } + + private BundleDescriptor getBundle() { + + JndiNameEnvironment env = compEnvManager.getCurrentJndiNameEnvironment(); + + BundleDescriptor bundle = null; + + if( env instanceof BundleDescriptor) { + + bundle = (BundleDescriptor) env; + + } + + if( bundle == null ) { + throw new IllegalStateException("Invalid context for managed bean creation"); + } + + return bundle; + + } + + /** + * Method to test with HA has been enabled. + * If so, then set the JSF context param + * com.sun.faces.enableAgressiveSessionDirtying to true + * @param ctx + */ + public void enableHighAvailability(ServletContext ctx) { + //look at the following values for the web app + //1> has in the web.xml + //2> Was deployed with --availabilityenabled --target + WebConfiguration config = WebConfiguration.getInstance(ctx); + if (!config.isSet(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying)) { + if (ctx instanceof org.apache.catalina.core.ApplicationContextFacade) { + org.apache.catalina.core.ApplicationContext applicationContext = + ((org.apache.catalina.core.ApplicationContextFacade) ctx).getApplicationContext(); + StandardContext stdContext = applicationContext.getStandardContext(); + WebBundleDescriptor desc = ((WebModule) stdContext).getWebModuleConfig().getDescriptor(); + boolean isDistributable = desc.isDistributable(); + boolean enableHA = serverConfigLookup.calculateWebAvailabilityEnabledFromConfig((WebModule) stdContext); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, + "isDistributable = {0} enableHA = {1}", + new Object[]{isDistributable, enableHA}); + } + if (isDistributable && enableHA) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("setting the EnableAgressiveSessionDirtying to true"); + } + config.overrideContextInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying, + Boolean.TRUE); + } + } + } + } +} // END GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) @@ -0,0 +1,175 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.module.Module; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.util.net.JarURIPattern; +import com.sun.logging.LogDomains; +import org.glassfish.api.web.TldProvider; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.PostConstruct; +import org.jvnet.hk2.component.Singleton; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Implementation of TldProvider for JSF. + * @author Shing Wai Chan + * @author Sahoo + */ + +@Service(name="jsfTld") +@Scoped(Singleton.class) +public class GlassFishTldProvider implements TldProvider, PostConstruct { + + private static final Logger logger = + LogDomains.getLogger(GlassFishTldProvider.class, + LogDomains.WEB_LOGGER); + + private static final ResourceBundle rb = logger.getResourceBundle(); + + @Inject + ModulesRegistry registry; + + private Map> tldMap = + new HashMap>(); + + private Map> tldListenerMap = null; + + /** + * Gets the name of this TldProvider + */ + public String getName() { + return "jsfTld"; + } + + /** + * Gets a mapping from JAR files to their TLD resources. + */ + public Map> getTldMap() { + return (Map>)((HashMap)tldMap).clone(); + } + + /** + * Gets a mapping from JAR files to their TLD resources + * that are known to contain listener declarations. + */ + public synchronized Map> getTldListenerMap() { + if (tldListenerMap == null) { + tldListenerMap = new HashMap>(); + for (URI uri : tldMap.keySet()) { + /* + * In the case of JSF, the only TLD that declares any + * listener is META-INF/jsf_core.tld + */ + if (tldMap.get(uri).contains("META-INF/jsf_core.tld")) { + tldListenerMap.put(uri, tldMap.get(uri)); + break; + } + } + tldListenerMap = Collections.unmodifiableMap(tldListenerMap); + } + + return tldListenerMap; + } + + public void postConstruct() { + + Class jsfImplClass = null; + try { + jsfImplClass = getClass().getClassLoader().loadClass( + "com.sun.faces.spi.InjectionProvider"); + } catch (ClassNotFoundException ignored) { + } + + URI[] uris = null; + Module m = null; + if (jsfImplClass != null) { + m = registry.find(jsfImplClass); + } + if (m != null) { + uris = m.getModuleDefinition().getLocations(); + } else { + ClassLoader classLoader = getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader)classLoader).getURLs(); + if (urls != null && urls.length > 0) { + uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + try { + uris[i] = urls[i].toURI(); + } catch(URISyntaxException e) { + String msg = rb.getString("tldProvider.ignoreUrl"); + msg = MessageFormat.format(msg, urls[i]); + logger.log(Level.WARNING, msg, e); + } + } + } + } else { + logger.log(Level.WARNING, + "taglibs.unableToDetermineTldResources", + new Object[] {"JSF", classLoader, + GlassFishTldProvider.class.getName()}); + } + } + + if (uris != null && uris.length > 0) { + Pattern pattern = Pattern.compile("META-INF/.*\\.tld"); + for (URI uri : uris) { + List entries = JarURIPattern.getJarEntries(uri, pattern); + if (entries != null && entries.size() > 0) { + tldMap.put(uri, entries); + } + } + } + } +} Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.container.common.spi.JCDIService; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; +import com.sun.enterprise.container.common.spi.util.InjectionException; +import com.sun.enterprise.container.common.spi.util.InjectionManager; +import com.sun.enterprise.web.ServerConfigLookup; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.InjectionInfo; +import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.faces.spi.DiscoverableInjectionProvider; +import com.sun.faces.spi.InjectionProviderException; +import com.sun.faces.util.FacesLogger; +import org.glassfish.api.invocation.ComponentInvocation; +import org.glassfish.api.invocation.InvocationManager; +import org.jvnet.hk2.component.Habitat; + +import javax.servlet.ServletContext; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import com.sun.enterprise.web.WebModule; +import com.sun.faces.config.WebConfiguration; +import org.apache.catalina.core.StandardContext; +/** + *

This InjectionProvider is specific to the + * GlassFish/SJSAS 9.x PE/EE application servers.

+ */ +public class GlassFishInjectionProvider extends DiscoverableInjectionProvider { + + private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); + private static final String HABITAT_ATTRIBUTE = + "org.glassfish.servlet.habitat"; + private ComponentEnvManager compEnvManager; + private InjectionManager injectionManager; + private InvocationManager invokeMgr; + private JCDIService jcdiService; + private ServerConfigLookup serverConfigLookup; + + /** + *

Constructs a new GlassFishInjectionProvider instance.

+ * + * @param servletContext + */ + public GlassFishInjectionProvider(ServletContext servletContext) { + Habitat defaultHabitat = (Habitat)servletContext.getAttribute( + HABITAT_ATTRIBUTE); + compEnvManager = defaultHabitat.getByContract(ComponentEnvManager.class); + invokeMgr = defaultHabitat.getByContract(InvocationManager.class); + injectionManager = defaultHabitat.getByContract(InjectionManager.class); + jcdiService = defaultHabitat.getByContract(JCDIService.class); + serverConfigLookup = defaultHabitat.getComponent(ServerConfigLookup.class); + + } + + /** + *

The implementation of this method must perform the following + * steps: + *

    + *
  • Inject the supported resources per the Servlet 2.5 + * specification into the provided object
  • + *
+ *

+ * + * @param managedBean the target managed bean + */ + @Override + public void inject(Object managedBean) throws InjectionProviderException { + try { + injectionManager.injectInstance(managedBean, + getNamingEnvironment(), + false); + + if (jcdiService.isCurrentModuleJCDIEnabled()) { + jcdiService.injectManagedObject(managedBean, getBundle()); + + } + + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + /** + *

The implemenation of this method must invoke any + * method marked with the @PreDestroy annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + */ + @Override + public void invokePreDestroy(Object managedBean) + throws InjectionProviderException { + try { + injectionManager.invokeInstancePreDestroy(managedBean); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + + /** + *

The implemenation of this method must invoke any + * method marked with the @PostConstruct annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + * + * @throws com.sun.faces.spi.InjectionProviderException + * if an error occurs when invoking + * the method annotated by the @PostConstruct annotation + */ + @Override + public void invokePostConstruct(Object managedBean) + throws InjectionProviderException { + try { + this.invokePostConstruct(managedBean, getNamingEnvironment()); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + + } + + + // --------------------------------------------------------- Private Methods + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @return JndiNameEnvironment + * @throws InjectionException if we're unable to obtain the + * JndiNameEnvironment + */ + private JndiNameEnvironment getNamingEnvironment() + throws InjectionException { + ComponentInvocation inv = invokeMgr.getCurrentInvocation(); + + if (inv != null) { + + if (inv.getInvocationType()== ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION) { + + JndiNameEnvironment componentEnv = (JndiNameEnvironment) + inv.jndiEnvironment; + + if (componentEnv != null) { + return componentEnv; + } else { + throw new InjectionException("No descriptor registered for " + " current invocation : " + inv); + } + } else { + throw new InjectionException("Wrong invocation type"); + } + } else { + throw new InjectionException("null invocation context"); + } + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * + * @param instance managed bean instance + * @param envDescriptor JNDI environment + * @throws InjectionException if an error occurs + */ + private void invokePostConstruct(Object instance, + JndiNameEnvironment envDescriptor) + throws InjectionException { + LinkedList postConstructMethods = new LinkedList(); + + Class nextClass = instance.getClass(); + + // Process each class in the inheritance hierarchy, starting with + // the most derived class and ignoring java.lang.Object. + while ((!Object.class.equals(nextClass)) && (nextClass != null)) { + + InjectionInfo injInfo = + envDescriptor.getInjectionInfoByClass(nextClass); + + if (injInfo.getPostConstructMethodName() != null) { + + Method postConstructMethod = getPostConstructMethod + (injInfo, nextClass); + + // Invoke the preDestroy methods starting from + // the least-derived class downward. + postConstructMethods.addFirst(postConstructMethod); + } + + nextClass = nextClass.getSuperclass(); + } + + for (Method postConstructMethod : postConstructMethods) { + + invokeLifecycleMethod(postConstructMethod, instance); + + } + + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param injInfo InjectionInfo + * @param resourceClass target class + * @return a Method marked with the @PostConstruct annotation + * @throws InjectionException if an error occurs + */ + private Method getPostConstructMethod(InjectionInfo injInfo, + Class resourceClass) + throws InjectionException { + + Method m = injInfo.getPostConstructMethod(); + + if( m == null ) { + String postConstructMethodName = + injInfo.getPostConstructMethodName(); + + // Check for the method within the resourceClass only. + // This does not include super-classses. + for(Method next : resourceClass.getDeclaredMethods()) { + // InjectionManager only handles injection into PostConstruct + // methods with no arguments. + if( next.getName().equals(postConstructMethodName) && + (next.getParameterTypes().length == 0) ) { + m = next; + injInfo.setPostConstructMethod(m); + break; + } + } + } + + if( m == null ) { + throw new InjectionException + ("InjectionManager exception. PostConstruct method " + + injInfo.getPostConstructMethodName() + + " could not be found in class " + + injInfo.getClassName()); + } + + return m; + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param lifecycleMethod the method to invoke + * @param instance the instanced to invoke the method against + * @throws InjectionException if an error occurs + */ + private void invokeLifecycleMethod(final Method lifecycleMethod, + final Object instance) + throws InjectionException { + + try { + + if(LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Calling lifecycle method {0} on class {1}", new Object[]{lifecycleMethod, lifecycleMethod.getDeclaringClass()}); + } + + // Wrap actual value insertion in doPrivileged to + // allow for private/protected field access. + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + @Override + public java.lang.Object run() throws Exception { + if( !lifecycleMethod.isAccessible() ) { + lifecycleMethod.setAccessible(true); + } + lifecycleMethod.invoke(instance); + return null; + } + }); + } catch( Exception t) { + + String msg = "Exception attempting invoke lifecycle " + + " method " + lifecycleMethod; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, msg, t); + } + InjectionException ie = new InjectionException(msg); + Throwable cause = (t instanceof InvocationTargetException) ? + t.getCause() : t; + ie.initCause( cause ); + throw ie; + + } + + return; + + } + + private BundleDescriptor getBundle() { + + JndiNameEnvironment env = compEnvManager.getCurrentJndiNameEnvironment(); + + BundleDescriptor bundle = null; + + if( env instanceof BundleDescriptor) { + + bundle = (BundleDescriptor) env; + + } + + if( bundle == null ) { + throw new IllegalStateException("Invalid context for managed bean creation"); + } + + return bundle; + + } + + /** + * Method to test with HA has been enabled. + * If so, then set the JSF context param + * com.sun.faces.enableAgressiveSessionDirtying to true + * @param ctx + */ + public void enableHighAvailability(ServletContext ctx) { + //look at the following values for the web app + //1> has in the web.xml + //2> Was deployed with --availabilityenabled --target + WebConfiguration config = WebConfiguration.getInstance(ctx); + if (!config.isSet(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying)) { + if (ctx instanceof org.apache.catalina.core.ApplicationContextFacade) { + org.apache.catalina.core.ApplicationContext applicationContext = + ((org.apache.catalina.core.ApplicationContextFacade) ctx).getApplicationContext(); + StandardContext stdContext = applicationContext.getStandardContext(); + WebBundleDescriptor desc = ((WebModule) stdContext).getWebModuleConfig().getDescriptor(); + boolean isDistributable = desc.isDistributable(); + boolean enableHA = serverConfigLookup.calculateWebAvailabilityEnabledFromConfig((WebModule) stdContext); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, + "isDistributable = {0} enableHA = {1}", + new Object[]{isDistributable, enableHA}); + } + if (isDistributable && enableHA) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("setting the EnableAgressiveSessionDirtying to true"); + } + config.overrideContextInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying, + Boolean.TRUE); + } + } + } + } +} // END GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) @@ -0,0 +1,175 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.module.Module; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.util.net.JarURIPattern; +import com.sun.logging.LogDomains; +import org.glassfish.api.web.TldProvider; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.PostConstruct; +import org.jvnet.hk2.component.Singleton; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Implementation of TldProvider for JSF. + * @author Shing Wai Chan + * @author Sahoo + */ + +@Service(name="jsfTld") +@Scoped(Singleton.class) +public class GlassFishTldProvider implements TldProvider, PostConstruct { + + private static final Logger logger = + LogDomains.getLogger(GlassFishTldProvider.class, + LogDomains.WEB_LOGGER); + + private static final ResourceBundle rb = logger.getResourceBundle(); + + @Inject + ModulesRegistry registry; + + private Map> tldMap = + new HashMap>(); + + private Map> tldListenerMap = null; + + /** + * Gets the name of this TldProvider + */ + public String getName() { + return "jsfTld"; + } + + /** + * Gets a mapping from JAR files to their TLD resources. + */ + public Map> getTldMap() { + return (Map>)((HashMap)tldMap).clone(); + } + + /** + * Gets a mapping from JAR files to their TLD resources + * that are known to contain listener declarations. + */ + public synchronized Map> getTldListenerMap() { + if (tldListenerMap == null) { + tldListenerMap = new HashMap>(); + for (URI uri : tldMap.keySet()) { + /* + * In the case of JSF, the only TLD that declares any + * listener is META-INF/jsf_core.tld + */ + if (tldMap.get(uri).contains("META-INF/jsf_core.tld")) { + tldListenerMap.put(uri, tldMap.get(uri)); + break; + } + } + tldListenerMap = Collections.unmodifiableMap(tldListenerMap); + } + + return tldListenerMap; + } + + public void postConstruct() { + + Class jsfImplClass = null; + try { + jsfImplClass = getClass().getClassLoader().loadClass( + "com.sun.faces.spi.InjectionProvider"); + } catch (ClassNotFoundException ignored) { + } + + URI[] uris = null; + Module m = null; + if (jsfImplClass != null) { + m = registry.find(jsfImplClass); + } + if (m != null) { + uris = m.getModuleDefinition().getLocations(); + } else { + ClassLoader classLoader = getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader)classLoader).getURLs(); + if (urls != null && urls.length > 0) { + uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + try { + uris[i] = urls[i].toURI(); + } catch(URISyntaxException e) { + String msg = rb.getString("tldProvider.ignoreUrl"); + msg = MessageFormat.format(msg, urls[i]); + logger.log(Level.WARNING, msg, e); + } + } + } + } else { + logger.log(Level.WARNING, + "taglibs.unableToDetermineTldResources", + new Object[] {"JSF", classLoader, + GlassFishTldProvider.class.getName()}); + } + } + + if (uris != null && uris.length > 0) { + Pattern pattern = Pattern.compile("META-INF/.*\\.tld"); + for (URI uri : uris) { + List entries = JarURIPattern.getJarEntries(uri, pattern); + if (entries != null && entries.size() > 0) { + tldMap.put(uri, entries); + } + } + } + } +} Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.container.common.spi.JCDIService; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; +import com.sun.enterprise.container.common.spi.util.InjectionException; +import com.sun.enterprise.container.common.spi.util.InjectionManager; +import com.sun.enterprise.web.ServerConfigLookup; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.InjectionInfo; +import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.faces.spi.DiscoverableInjectionProvider; +import com.sun.faces.spi.InjectionProviderException; +import com.sun.faces.util.FacesLogger; +import org.glassfish.api.invocation.ComponentInvocation; +import org.glassfish.api.invocation.InvocationManager; +import org.jvnet.hk2.component.Habitat; + +import javax.servlet.ServletContext; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import com.sun.enterprise.web.WebModule; +import com.sun.faces.config.WebConfiguration; +import org.apache.catalina.core.StandardContext; +/** + *

This InjectionProvider is specific to the + * GlassFish/SJSAS 9.x PE/EE application servers.

+ */ +public class GlassFishInjectionProvider extends DiscoverableInjectionProvider { + + private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); + private static final String HABITAT_ATTRIBUTE = + "org.glassfish.servlet.habitat"; + private ComponentEnvManager compEnvManager; + private InjectionManager injectionManager; + private InvocationManager invokeMgr; + private JCDIService jcdiService; + private ServerConfigLookup serverConfigLookup; + + /** + *

Constructs a new GlassFishInjectionProvider instance.

+ * + * @param servletContext + */ + public GlassFishInjectionProvider(ServletContext servletContext) { + Habitat defaultHabitat = (Habitat)servletContext.getAttribute( + HABITAT_ATTRIBUTE); + compEnvManager = defaultHabitat.getByContract(ComponentEnvManager.class); + invokeMgr = defaultHabitat.getByContract(InvocationManager.class); + injectionManager = defaultHabitat.getByContract(InjectionManager.class); + jcdiService = defaultHabitat.getByContract(JCDIService.class); + serverConfigLookup = defaultHabitat.getComponent(ServerConfigLookup.class); + + } + + /** + *

The implementation of this method must perform the following + * steps: + *

    + *
  • Inject the supported resources per the Servlet 2.5 + * specification into the provided object
  • + *
+ *

+ * + * @param managedBean the target managed bean + */ + @Override + public void inject(Object managedBean) throws InjectionProviderException { + try { + injectionManager.injectInstance(managedBean, + getNamingEnvironment(), + false); + + if (jcdiService.isCurrentModuleJCDIEnabled()) { + jcdiService.injectManagedObject(managedBean, getBundle()); + + } + + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + /** + *

The implemenation of this method must invoke any + * method marked with the @PreDestroy annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + */ + @Override + public void invokePreDestroy(Object managedBean) + throws InjectionProviderException { + try { + injectionManager.invokeInstancePreDestroy(managedBean); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + + /** + *

The implemenation of this method must invoke any + * method marked with the @PostConstruct annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + * + * @throws com.sun.faces.spi.InjectionProviderException + * if an error occurs when invoking + * the method annotated by the @PostConstruct annotation + */ + @Override + public void invokePostConstruct(Object managedBean) + throws InjectionProviderException { + try { + this.invokePostConstruct(managedBean, getNamingEnvironment()); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + + } + + + // --------------------------------------------------------- Private Methods + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @return JndiNameEnvironment + * @throws InjectionException if we're unable to obtain the + * JndiNameEnvironment + */ + private JndiNameEnvironment getNamingEnvironment() + throws InjectionException { + ComponentInvocation inv = invokeMgr.getCurrentInvocation(); + + if (inv != null) { + + if (inv.getInvocationType()== ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION) { + + JndiNameEnvironment componentEnv = (JndiNameEnvironment) + inv.jndiEnvironment; + + if (componentEnv != null) { + return componentEnv; + } else { + throw new InjectionException("No descriptor registered for " + " current invocation : " + inv); + } + } else { + throw new InjectionException("Wrong invocation type"); + } + } else { + throw new InjectionException("null invocation context"); + } + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * + * @param instance managed bean instance + * @param envDescriptor JNDI environment + * @throws InjectionException if an error occurs + */ + private void invokePostConstruct(Object instance, + JndiNameEnvironment envDescriptor) + throws InjectionException { + LinkedList postConstructMethods = new LinkedList(); + + Class nextClass = instance.getClass(); + + // Process each class in the inheritance hierarchy, starting with + // the most derived class and ignoring java.lang.Object. + while ((!Object.class.equals(nextClass)) && (nextClass != null)) { + + InjectionInfo injInfo = + envDescriptor.getInjectionInfoByClass(nextClass); + + if (injInfo.getPostConstructMethodName() != null) { + + Method postConstructMethod = getPostConstructMethod + (injInfo, nextClass); + + // Invoke the preDestroy methods starting from + // the least-derived class downward. + postConstructMethods.addFirst(postConstructMethod); + } + + nextClass = nextClass.getSuperclass(); + } + + for (Method postConstructMethod : postConstructMethods) { + + invokeLifecycleMethod(postConstructMethod, instance); + + } + + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param injInfo InjectionInfo + * @param resourceClass target class + * @return a Method marked with the @PostConstruct annotation + * @throws InjectionException if an error occurs + */ + private Method getPostConstructMethod(InjectionInfo injInfo, + Class resourceClass) + throws InjectionException { + + Method m = injInfo.getPostConstructMethod(); + + if( m == null ) { + String postConstructMethodName = + injInfo.getPostConstructMethodName(); + + // Check for the method within the resourceClass only. + // This does not include super-classses. + for(Method next : resourceClass.getDeclaredMethods()) { + // InjectionManager only handles injection into PostConstruct + // methods with no arguments. + if( next.getName().equals(postConstructMethodName) && + (next.getParameterTypes().length == 0) ) { + m = next; + injInfo.setPostConstructMethod(m); + break; + } + } + } + + if( m == null ) { + throw new InjectionException + ("InjectionManager exception. PostConstruct method " + + injInfo.getPostConstructMethodName() + + " could not be found in class " + + injInfo.getClassName()); + } + + return m; + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param lifecycleMethod the method to invoke + * @param instance the instanced to invoke the method against + * @throws InjectionException if an error occurs + */ + private void invokeLifecycleMethod(final Method lifecycleMethod, + final Object instance) + throws InjectionException { + + try { + + if(LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Calling lifecycle method {0} on class {1}", new Object[]{lifecycleMethod, lifecycleMethod.getDeclaringClass()}); + } + + // Wrap actual value insertion in doPrivileged to + // allow for private/protected field access. + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + @Override + public java.lang.Object run() throws Exception { + if( !lifecycleMethod.isAccessible() ) { + lifecycleMethod.setAccessible(true); + } + lifecycleMethod.invoke(instance); + return null; + } + }); + } catch( Exception t) { + + String msg = "Exception attempting invoke lifecycle " + + " method " + lifecycleMethod; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, msg, t); + } + InjectionException ie = new InjectionException(msg); + Throwable cause = (t instanceof InvocationTargetException) ? + t.getCause() : t; + ie.initCause( cause ); + throw ie; + + } + + return; + + } + + private BundleDescriptor getBundle() { + + JndiNameEnvironment env = compEnvManager.getCurrentJndiNameEnvironment(); + + BundleDescriptor bundle = null; + + if( env instanceof BundleDescriptor) { + + bundle = (BundleDescriptor) env; + + } + + if( bundle == null ) { + throw new IllegalStateException("Invalid context for managed bean creation"); + } + + return bundle; + + } + + /** + * Method to test with HA has been enabled. + * If so, then set the JSF context param + * com.sun.faces.enableAgressiveSessionDirtying to true + * @param ctx + */ + public void enableHighAvailability(ServletContext ctx) { + //look at the following values for the web app + //1> has in the web.xml + //2> Was deployed with --availabilityenabled --target + WebConfiguration config = WebConfiguration.getInstance(ctx); + if (!config.isSet(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying)) { + if (ctx instanceof org.apache.catalina.core.ApplicationContextFacade) { + org.apache.catalina.core.ApplicationContext applicationContext = + ((org.apache.catalina.core.ApplicationContextFacade) ctx).getApplicationContext(); + StandardContext stdContext = applicationContext.getStandardContext(); + WebBundleDescriptor desc = ((WebModule) stdContext).getWebModuleConfig().getDescriptor(); + boolean isDistributable = desc.isDistributable(); + boolean enableHA = serverConfigLookup.calculateWebAvailabilityEnabledFromConfig((WebModule) stdContext); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, + "isDistributable = {0} enableHA = {1}", + new Object[]{isDistributable, enableHA}); + } + if (isDistributable && enableHA) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("setting the EnableAgressiveSessionDirtying to true"); + } + config.overrideContextInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying, + Boolean.TRUE); + } + } + } + } +} // END GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) @@ -0,0 +1,175 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.module.Module; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.util.net.JarURIPattern; +import com.sun.logging.LogDomains; +import org.glassfish.api.web.TldProvider; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.PostConstruct; +import org.jvnet.hk2.component.Singleton; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Implementation of TldProvider for JSF. + * @author Shing Wai Chan + * @author Sahoo + */ + +@Service(name="jsfTld") +@Scoped(Singleton.class) +public class GlassFishTldProvider implements TldProvider, PostConstruct { + + private static final Logger logger = + LogDomains.getLogger(GlassFishTldProvider.class, + LogDomains.WEB_LOGGER); + + private static final ResourceBundle rb = logger.getResourceBundle(); + + @Inject + ModulesRegistry registry; + + private Map> tldMap = + new HashMap>(); + + private Map> tldListenerMap = null; + + /** + * Gets the name of this TldProvider + */ + public String getName() { + return "jsfTld"; + } + + /** + * Gets a mapping from JAR files to their TLD resources. + */ + public Map> getTldMap() { + return (Map>)((HashMap)tldMap).clone(); + } + + /** + * Gets a mapping from JAR files to their TLD resources + * that are known to contain listener declarations. + */ + public synchronized Map> getTldListenerMap() { + if (tldListenerMap == null) { + tldListenerMap = new HashMap>(); + for (URI uri : tldMap.keySet()) { + /* + * In the case of JSF, the only TLD that declares any + * listener is META-INF/jsf_core.tld + */ + if (tldMap.get(uri).contains("META-INF/jsf_core.tld")) { + tldListenerMap.put(uri, tldMap.get(uri)); + break; + } + } + tldListenerMap = Collections.unmodifiableMap(tldListenerMap); + } + + return tldListenerMap; + } + + public void postConstruct() { + + Class jsfImplClass = null; + try { + jsfImplClass = getClass().getClassLoader().loadClass( + "com.sun.faces.spi.InjectionProvider"); + } catch (ClassNotFoundException ignored) { + } + + URI[] uris = null; + Module m = null; + if (jsfImplClass != null) { + m = registry.find(jsfImplClass); + } + if (m != null) { + uris = m.getModuleDefinition().getLocations(); + } else { + ClassLoader classLoader = getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader)classLoader).getURLs(); + if (urls != null && urls.length > 0) { + uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + try { + uris[i] = urls[i].toURI(); + } catch(URISyntaxException e) { + String msg = rb.getString("tldProvider.ignoreUrl"); + msg = MessageFormat.format(msg, urls[i]); + logger.log(Level.WARNING, msg, e); + } + } + } + } else { + logger.log(Level.WARNING, + "taglibs.unableToDetermineTldResources", + new Object[] {"JSF", classLoader, + GlassFishTldProvider.class.getName()}); + } + } + + if (uris != null && uris.length > 0) { + Pattern pattern = Pattern.compile("META-INF/.*\\.tld"); + for (URI uri : uris) { + List entries = JarURIPattern.getJarEntries(uri, pattern); + if (entries != null && entries.size() > 0) { + tldMap.put(uri, entries); + } + } + } + } +} Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.container.common.spi.JCDIService; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; +import com.sun.enterprise.container.common.spi.util.InjectionException; +import com.sun.enterprise.container.common.spi.util.InjectionManager; +import com.sun.enterprise.web.ServerConfigLookup; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.InjectionInfo; +import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.faces.spi.DiscoverableInjectionProvider; +import com.sun.faces.spi.InjectionProviderException; +import com.sun.faces.util.FacesLogger; +import org.glassfish.api.invocation.ComponentInvocation; +import org.glassfish.api.invocation.InvocationManager; +import org.jvnet.hk2.component.Habitat; + +import javax.servlet.ServletContext; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import com.sun.enterprise.web.WebModule; +import com.sun.faces.config.WebConfiguration; +import org.apache.catalina.core.StandardContext; +/** + *

This InjectionProvider is specific to the + * GlassFish/SJSAS 9.x PE/EE application servers.

+ */ +public class GlassFishInjectionProvider extends DiscoverableInjectionProvider { + + private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); + private static final String HABITAT_ATTRIBUTE = + "org.glassfish.servlet.habitat"; + private ComponentEnvManager compEnvManager; + private InjectionManager injectionManager; + private InvocationManager invokeMgr; + private JCDIService jcdiService; + private ServerConfigLookup serverConfigLookup; + + /** + *

Constructs a new GlassFishInjectionProvider instance.

+ * + * @param servletContext + */ + public GlassFishInjectionProvider(ServletContext servletContext) { + Habitat defaultHabitat = (Habitat)servletContext.getAttribute( + HABITAT_ATTRIBUTE); + compEnvManager = defaultHabitat.getByContract(ComponentEnvManager.class); + invokeMgr = defaultHabitat.getByContract(InvocationManager.class); + injectionManager = defaultHabitat.getByContract(InjectionManager.class); + jcdiService = defaultHabitat.getByContract(JCDIService.class); + serverConfigLookup = defaultHabitat.getComponent(ServerConfigLookup.class); + + } + + /** + *

The implementation of this method must perform the following + * steps: + *

    + *
  • Inject the supported resources per the Servlet 2.5 + * specification into the provided object
  • + *
+ *

+ * + * @param managedBean the target managed bean + */ + @Override + public void inject(Object managedBean) throws InjectionProviderException { + try { + injectionManager.injectInstance(managedBean, + getNamingEnvironment(), + false); + + if (jcdiService.isCurrentModuleJCDIEnabled()) { + jcdiService.injectManagedObject(managedBean, getBundle()); + + } + + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + /** + *

The implemenation of this method must invoke any + * method marked with the @PreDestroy annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + */ + @Override + public void invokePreDestroy(Object managedBean) + throws InjectionProviderException { + try { + injectionManager.invokeInstancePreDestroy(managedBean); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + + /** + *

The implemenation of this method must invoke any + * method marked with the @PostConstruct annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + * + * @throws com.sun.faces.spi.InjectionProviderException + * if an error occurs when invoking + * the method annotated by the @PostConstruct annotation + */ + @Override + public void invokePostConstruct(Object managedBean) + throws InjectionProviderException { + try { + this.invokePostConstruct(managedBean, getNamingEnvironment()); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + + } + + + // --------------------------------------------------------- Private Methods + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @return JndiNameEnvironment + * @throws InjectionException if we're unable to obtain the + * JndiNameEnvironment + */ + private JndiNameEnvironment getNamingEnvironment() + throws InjectionException { + ComponentInvocation inv = invokeMgr.getCurrentInvocation(); + + if (inv != null) { + + if (inv.getInvocationType()== ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION) { + + JndiNameEnvironment componentEnv = (JndiNameEnvironment) + inv.jndiEnvironment; + + if (componentEnv != null) { + return componentEnv; + } else { + throw new InjectionException("No descriptor registered for " + " current invocation : " + inv); + } + } else { + throw new InjectionException("Wrong invocation type"); + } + } else { + throw new InjectionException("null invocation context"); + } + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * + * @param instance managed bean instance + * @param envDescriptor JNDI environment + * @throws InjectionException if an error occurs + */ + private void invokePostConstruct(Object instance, + JndiNameEnvironment envDescriptor) + throws InjectionException { + LinkedList postConstructMethods = new LinkedList(); + + Class nextClass = instance.getClass(); + + // Process each class in the inheritance hierarchy, starting with + // the most derived class and ignoring java.lang.Object. + while ((!Object.class.equals(nextClass)) && (nextClass != null)) { + + InjectionInfo injInfo = + envDescriptor.getInjectionInfoByClass(nextClass); + + if (injInfo.getPostConstructMethodName() != null) { + + Method postConstructMethod = getPostConstructMethod + (injInfo, nextClass); + + // Invoke the preDestroy methods starting from + // the least-derived class downward. + postConstructMethods.addFirst(postConstructMethod); + } + + nextClass = nextClass.getSuperclass(); + } + + for (Method postConstructMethod : postConstructMethods) { + + invokeLifecycleMethod(postConstructMethod, instance); + + } + + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param injInfo InjectionInfo + * @param resourceClass target class + * @return a Method marked with the @PostConstruct annotation + * @throws InjectionException if an error occurs + */ + private Method getPostConstructMethod(InjectionInfo injInfo, + Class resourceClass) + throws InjectionException { + + Method m = injInfo.getPostConstructMethod(); + + if( m == null ) { + String postConstructMethodName = + injInfo.getPostConstructMethodName(); + + // Check for the method within the resourceClass only. + // This does not include super-classses. + for(Method next : resourceClass.getDeclaredMethods()) { + // InjectionManager only handles injection into PostConstruct + // methods with no arguments. + if( next.getName().equals(postConstructMethodName) && + (next.getParameterTypes().length == 0) ) { + m = next; + injInfo.setPostConstructMethod(m); + break; + } + } + } + + if( m == null ) { + throw new InjectionException + ("InjectionManager exception. PostConstruct method " + + injInfo.getPostConstructMethodName() + + " could not be found in class " + + injInfo.getClassName()); + } + + return m; + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param lifecycleMethod the method to invoke + * @param instance the instanced to invoke the method against + * @throws InjectionException if an error occurs + */ + private void invokeLifecycleMethod(final Method lifecycleMethod, + final Object instance) + throws InjectionException { + + try { + + if(LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Calling lifecycle method {0} on class {1}", new Object[]{lifecycleMethod, lifecycleMethod.getDeclaringClass()}); + } + + // Wrap actual value insertion in doPrivileged to + // allow for private/protected field access. + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + @Override + public java.lang.Object run() throws Exception { + if( !lifecycleMethod.isAccessible() ) { + lifecycleMethod.setAccessible(true); + } + lifecycleMethod.invoke(instance); + return null; + } + }); + } catch( Exception t) { + + String msg = "Exception attempting invoke lifecycle " + + " method " + lifecycleMethod; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, msg, t); + } + InjectionException ie = new InjectionException(msg); + Throwable cause = (t instanceof InvocationTargetException) ? + t.getCause() : t; + ie.initCause( cause ); + throw ie; + + } + + return; + + } + + private BundleDescriptor getBundle() { + + JndiNameEnvironment env = compEnvManager.getCurrentJndiNameEnvironment(); + + BundleDescriptor bundle = null; + + if( env instanceof BundleDescriptor) { + + bundle = (BundleDescriptor) env; + + } + + if( bundle == null ) { + throw new IllegalStateException("Invalid context for managed bean creation"); + } + + return bundle; + + } + + /** + * Method to test with HA has been enabled. + * If so, then set the JSF context param + * com.sun.faces.enableAgressiveSessionDirtying to true + * @param ctx + */ + public void enableHighAvailability(ServletContext ctx) { + //look at the following values for the web app + //1> has in the web.xml + //2> Was deployed with --availabilityenabled --target + WebConfiguration config = WebConfiguration.getInstance(ctx); + if (!config.isSet(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying)) { + if (ctx instanceof org.apache.catalina.core.ApplicationContextFacade) { + org.apache.catalina.core.ApplicationContext applicationContext = + ((org.apache.catalina.core.ApplicationContextFacade) ctx).getApplicationContext(); + StandardContext stdContext = applicationContext.getStandardContext(); + WebBundleDescriptor desc = ((WebModule) stdContext).getWebModuleConfig().getDescriptor(); + boolean isDistributable = desc.isDistributable(); + boolean enableHA = serverConfigLookup.calculateWebAvailabilityEnabledFromConfig((WebModule) stdContext); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, + "isDistributable = {0} enableHA = {1}", + new Object[]{isDistributable, enableHA}); + } + if (isDistributable && enableHA) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("setting the EnableAgressiveSessionDirtying to true"); + } + config.overrideContextInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying, + Boolean.TRUE); + } + } + } + } +} // END GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) @@ -0,0 +1,175 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.module.Module; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.util.net.JarURIPattern; +import com.sun.logging.LogDomains; +import org.glassfish.api.web.TldProvider; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.PostConstruct; +import org.jvnet.hk2.component.Singleton; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Implementation of TldProvider for JSF. + * @author Shing Wai Chan + * @author Sahoo + */ + +@Service(name="jsfTld") +@Scoped(Singleton.class) +public class GlassFishTldProvider implements TldProvider, PostConstruct { + + private static final Logger logger = + LogDomains.getLogger(GlassFishTldProvider.class, + LogDomains.WEB_LOGGER); + + private static final ResourceBundle rb = logger.getResourceBundle(); + + @Inject + ModulesRegistry registry; + + private Map> tldMap = + new HashMap>(); + + private Map> tldListenerMap = null; + + /** + * Gets the name of this TldProvider + */ + public String getName() { + return "jsfTld"; + } + + /** + * Gets a mapping from JAR files to their TLD resources. + */ + public Map> getTldMap() { + return (Map>)((HashMap)tldMap).clone(); + } + + /** + * Gets a mapping from JAR files to their TLD resources + * that are known to contain listener declarations. + */ + public synchronized Map> getTldListenerMap() { + if (tldListenerMap == null) { + tldListenerMap = new HashMap>(); + for (URI uri : tldMap.keySet()) { + /* + * In the case of JSF, the only TLD that declares any + * listener is META-INF/jsf_core.tld + */ + if (tldMap.get(uri).contains("META-INF/jsf_core.tld")) { + tldListenerMap.put(uri, tldMap.get(uri)); + break; + } + } + tldListenerMap = Collections.unmodifiableMap(tldListenerMap); + } + + return tldListenerMap; + } + + public void postConstruct() { + + Class jsfImplClass = null; + try { + jsfImplClass = getClass().getClassLoader().loadClass( + "com.sun.faces.spi.InjectionProvider"); + } catch (ClassNotFoundException ignored) { + } + + URI[] uris = null; + Module m = null; + if (jsfImplClass != null) { + m = registry.find(jsfImplClass); + } + if (m != null) { + uris = m.getModuleDefinition().getLocations(); + } else { + ClassLoader classLoader = getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader)classLoader).getURLs(); + if (urls != null && urls.length > 0) { + uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + try { + uris[i] = urls[i].toURI(); + } catch(URISyntaxException e) { + String msg = rb.getString("tldProvider.ignoreUrl"); + msg = MessageFormat.format(msg, urls[i]); + logger.log(Level.WARNING, msg, e); + } + } + } + } else { + logger.log(Level.WARNING, + "taglibs.unableToDetermineTldResources", + new Object[] {"JSF", classLoader, + GlassFishTldProvider.class.getName()}); + } + } + + if (uris != null && uris.length > 0) { + Pattern pattern = Pattern.compile("META-INF/.*\\.tld"); + for (URI uri : uris) { + List entries = JarURIPattern.getJarEntries(uri, pattern); + if (entries != null && entries.size() > 0) { + tldMap.put(uri, entries); + } + } + } + } +} Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishInjectionProvider.java (revision 0) @@ -0,0 +1,390 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.container.common.spi.JCDIService; +import com.sun.enterprise.container.common.spi.util.ComponentEnvManager; +import com.sun.enterprise.container.common.spi.util.InjectionException; +import com.sun.enterprise.container.common.spi.util.InjectionManager; +import com.sun.enterprise.web.ServerConfigLookup; +import com.sun.enterprise.deployment.BundleDescriptor; +import com.sun.enterprise.deployment.InjectionInfo; +import com.sun.enterprise.deployment.JndiNameEnvironment; +import com.sun.faces.spi.DiscoverableInjectionProvider; +import com.sun.faces.spi.InjectionProviderException; +import com.sun.faces.util.FacesLogger; +import org.glassfish.api.invocation.ComponentInvocation; +import org.glassfish.api.invocation.InvocationManager; +import org.jvnet.hk2.component.Habitat; + +import javax.servlet.ServletContext; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.LinkedList; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.sun.enterprise.deployment.WebBundleDescriptor; +import com.sun.enterprise.web.WebModule; +import com.sun.faces.config.WebConfiguration; +import org.apache.catalina.core.StandardContext; +/** + *

This InjectionProvider is specific to the + * GlassFish/SJSAS 9.x PE/EE application servers.

+ */ +public class GlassFishInjectionProvider extends DiscoverableInjectionProvider { + + private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); + private static final String HABITAT_ATTRIBUTE = + "org.glassfish.servlet.habitat"; + private ComponentEnvManager compEnvManager; + private InjectionManager injectionManager; + private InvocationManager invokeMgr; + private JCDIService jcdiService; + private ServerConfigLookup serverConfigLookup; + + /** + *

Constructs a new GlassFishInjectionProvider instance.

+ * + * @param servletContext + */ + public GlassFishInjectionProvider(ServletContext servletContext) { + Habitat defaultHabitat = (Habitat)servletContext.getAttribute( + HABITAT_ATTRIBUTE); + compEnvManager = defaultHabitat.getByContract(ComponentEnvManager.class); + invokeMgr = defaultHabitat.getByContract(InvocationManager.class); + injectionManager = defaultHabitat.getByContract(InjectionManager.class); + jcdiService = defaultHabitat.getByContract(JCDIService.class); + serverConfigLookup = defaultHabitat.getComponent(ServerConfigLookup.class); + + } + + /** + *

The implementation of this method must perform the following + * steps: + *

    + *
  • Inject the supported resources per the Servlet 2.5 + * specification into the provided object
  • + *
+ *

+ * + * @param managedBean the target managed bean + */ + @Override + public void inject(Object managedBean) throws InjectionProviderException { + try { + injectionManager.injectInstance(managedBean, + getNamingEnvironment(), + false); + + if (jcdiService.isCurrentModuleJCDIEnabled()) { + jcdiService.injectManagedObject(managedBean, getBundle()); + + } + + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + /** + *

The implemenation of this method must invoke any + * method marked with the @PreDestroy annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + */ + @Override + public void invokePreDestroy(Object managedBean) + throws InjectionProviderException { + try { + injectionManager.invokeInstancePreDestroy(managedBean); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + } + + + /** + *

The implemenation of this method must invoke any + * method marked with the @PostConstruct annotation + * (per the Common Annotations Specification). + * + * @param managedBean the target managed bean + * + * @throws com.sun.faces.spi.InjectionProviderException + * if an error occurs when invoking + * the method annotated by the @PostConstruct annotation + */ + @Override + public void invokePostConstruct(Object managedBean) + throws InjectionProviderException { + try { + this.invokePostConstruct(managedBean, getNamingEnvironment()); + } catch (InjectionException ie) { + throw new InjectionProviderException(ie); + } + + } + + + // --------------------------------------------------------- Private Methods + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @return JndiNameEnvironment + * @throws InjectionException if we're unable to obtain the + * JndiNameEnvironment + */ + private JndiNameEnvironment getNamingEnvironment() + throws InjectionException { + ComponentInvocation inv = invokeMgr.getCurrentInvocation(); + + if (inv != null) { + + if (inv.getInvocationType()== ComponentInvocation.ComponentInvocationType.SERVLET_INVOCATION) { + + JndiNameEnvironment componentEnv = (JndiNameEnvironment) + inv.jndiEnvironment; + + if (componentEnv != null) { + return componentEnv; + } else { + throw new InjectionException("No descriptor registered for " + " current invocation : " + inv); + } + } else { + throw new InjectionException("Wrong invocation type"); + } + } else { + throw new InjectionException("null invocation context"); + } + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * + * @param instance managed bean instance + * @param envDescriptor JNDI environment + * @throws InjectionException if an error occurs + */ + private void invokePostConstruct(Object instance, + JndiNameEnvironment envDescriptor) + throws InjectionException { + LinkedList postConstructMethods = new LinkedList(); + + Class nextClass = instance.getClass(); + + // Process each class in the inheritance hierarchy, starting with + // the most derived class and ignoring java.lang.Object. + while ((!Object.class.equals(nextClass)) && (nextClass != null)) { + + InjectionInfo injInfo = + envDescriptor.getInjectionInfoByClass(nextClass); + + if (injInfo.getPostConstructMethodName() != null) { + + Method postConstructMethod = getPostConstructMethod + (injInfo, nextClass); + + // Invoke the preDestroy methods starting from + // the least-derived class downward. + postConstructMethods.addFirst(postConstructMethod); + } + + nextClass = nextClass.getSuperclass(); + } + + for (Method postConstructMethod : postConstructMethods) { + + invokeLifecycleMethod(postConstructMethod, instance); + + } + + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param injInfo InjectionInfo + * @param resourceClass target class + * @return a Method marked with the @PostConstruct annotation + * @throws InjectionException if an error occurs + */ + private Method getPostConstructMethod(InjectionInfo injInfo, + Class resourceClass) + throws InjectionException { + + Method m = injInfo.getPostConstructMethod(); + + if( m == null ) { + String postConstructMethodName = + injInfo.getPostConstructMethodName(); + + // Check for the method within the resourceClass only. + // This does not include super-classses. + for(Method next : resourceClass.getDeclaredMethods()) { + // InjectionManager only handles injection into PostConstruct + // methods with no arguments. + if( next.getName().equals(postConstructMethodName) && + (next.getParameterTypes().length == 0) ) { + m = next; + injInfo.setPostConstructMethod(m); + break; + } + } + } + + if( m == null ) { + throw new InjectionException + ("InjectionManager exception. PostConstruct method " + + injInfo.getPostConstructMethodName() + + " could not be found in class " + + injInfo.getClassName()); + } + + return m; + } + + + /** + *

This is based off of code in InjectionManagerImpl.

+ * @param lifecycleMethod the method to invoke + * @param instance the instanced to invoke the method against + * @throws InjectionException if an error occurs + */ + private void invokeLifecycleMethod(final Method lifecycleMethod, + final Object instance) + throws InjectionException { + + try { + + if(LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Calling lifecycle method {0} on class {1}", new Object[]{lifecycleMethod, lifecycleMethod.getDeclaringClass()}); + } + + // Wrap actual value insertion in doPrivileged to + // allow for private/protected field access. + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + @Override + public java.lang.Object run() throws Exception { + if( !lifecycleMethod.isAccessible() ) { + lifecycleMethod.setAccessible(true); + } + lifecycleMethod.invoke(instance); + return null; + } + }); + } catch( Exception t) { + + String msg = "Exception attempting invoke lifecycle " + + " method " + lifecycleMethod; + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, msg, t); + } + InjectionException ie = new InjectionException(msg); + Throwable cause = (t instanceof InvocationTargetException) ? + t.getCause() : t; + ie.initCause( cause ); + throw ie; + + } + + return; + + } + + private BundleDescriptor getBundle() { + + JndiNameEnvironment env = compEnvManager.getCurrentJndiNameEnvironment(); + + BundleDescriptor bundle = null; + + if( env instanceof BundleDescriptor) { + + bundle = (BundleDescriptor) env; + + } + + if( bundle == null ) { + throw new IllegalStateException("Invalid context for managed bean creation"); + } + + return bundle; + + } + + /** + * Method to test with HA has been enabled. + * If so, then set the JSF context param + * com.sun.faces.enableAgressiveSessionDirtying to true + * @param ctx + */ + public void enableHighAvailability(ServletContext ctx) { + //look at the following values for the web app + //1> has in the web.xml + //2> Was deployed with --availabilityenabled --target + WebConfiguration config = WebConfiguration.getInstance(ctx); + if (!config.isSet(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying)) { + if (ctx instanceof org.apache.catalina.core.ApplicationContextFacade) { + org.apache.catalina.core.ApplicationContext applicationContext = + ((org.apache.catalina.core.ApplicationContextFacade) ctx).getApplicationContext(); + StandardContext stdContext = applicationContext.getStandardContext(); + WebBundleDescriptor desc = ((WebModule) stdContext).getWebModuleConfig().getDescriptor(); + boolean isDistributable = desc.isDistributable(); + boolean enableHA = serverConfigLookup.calculateWebAvailabilityEnabledFromConfig((WebModule) stdContext); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, + "isDistributable = {0} enableHA = {1}", + new Object[]{isDistributable, enableHA}); + } + if (isDistributable && enableHA) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("setting the EnableAgressiveSessionDirtying to true"); + } + config.overrideContextInitParameter(WebConfiguration.BooleanWebContextInitParameter.EnableAgressiveSessionDirtying, + Boolean.TRUE); + } + } + } + } +} // END GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/java/org/glassfish/faces/integration/GlassFishTldProvider.java (revision 0) @@ -0,0 +1,175 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can + * obtain a copy of the License at + * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html + * or packager/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * Oracle designates this particular file as subject to the "Classpath" + * exception as provided by Oracle in the GPL Version 2 section of the License + * file that accompanied this code. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * Contributor(s): + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + */ + +package org.glassfish.faces.integration; + +import com.sun.enterprise.module.Module; +import com.sun.enterprise.module.ModulesRegistry; +import com.sun.enterprise.util.net.JarURIPattern; +import com.sun.logging.LogDomains; +import org.glassfish.api.web.TldProvider; +import org.jvnet.hk2.annotations.Inject; +import org.jvnet.hk2.annotations.Scoped; +import org.jvnet.hk2.annotations.Service; +import org.jvnet.hk2.component.PostConstruct; +import org.jvnet.hk2.component.Singleton; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.text.MessageFormat; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Pattern; + +/** + * Implementation of TldProvider for JSF. + * @author Shing Wai Chan + * @author Sahoo + */ + +@Service(name="jsfTld") +@Scoped(Singleton.class) +public class GlassFishTldProvider implements TldProvider, PostConstruct { + + private static final Logger logger = + LogDomains.getLogger(GlassFishTldProvider.class, + LogDomains.WEB_LOGGER); + + private static final ResourceBundle rb = logger.getResourceBundle(); + + @Inject + ModulesRegistry registry; + + private Map> tldMap = + new HashMap>(); + + private Map> tldListenerMap = null; + + /** + * Gets the name of this TldProvider + */ + public String getName() { + return "jsfTld"; + } + + /** + * Gets a mapping from JAR files to their TLD resources. + */ + public Map> getTldMap() { + return (Map>)((HashMap)tldMap).clone(); + } + + /** + * Gets a mapping from JAR files to their TLD resources + * that are known to contain listener declarations. + */ + public synchronized Map> getTldListenerMap() { + if (tldListenerMap == null) { + tldListenerMap = new HashMap>(); + for (URI uri : tldMap.keySet()) { + /* + * In the case of JSF, the only TLD that declares any + * listener is META-INF/jsf_core.tld + */ + if (tldMap.get(uri).contains("META-INF/jsf_core.tld")) { + tldListenerMap.put(uri, tldMap.get(uri)); + break; + } + } + tldListenerMap = Collections.unmodifiableMap(tldListenerMap); + } + + return tldListenerMap; + } + + public void postConstruct() { + + Class jsfImplClass = null; + try { + jsfImplClass = getClass().getClassLoader().loadClass( + "com.sun.faces.spi.InjectionProvider"); + } catch (ClassNotFoundException ignored) { + } + + URI[] uris = null; + Module m = null; + if (jsfImplClass != null) { + m = registry.find(jsfImplClass); + } + if (m != null) { + uris = m.getModuleDefinition().getLocations(); + } else { + ClassLoader classLoader = getClass().getClassLoader(); + if (classLoader instanceof URLClassLoader) { + URL[] urls = ((URLClassLoader)classLoader).getURLs(); + if (urls != null && urls.length > 0) { + uris = new URI[urls.length]; + for (int i = 0; i < urls.length; i++) { + try { + uris[i] = urls[i].toURI(); + } catch(URISyntaxException e) { + String msg = rb.getString("tldProvider.ignoreUrl"); + msg = MessageFormat.format(msg, urls[i]); + logger.log(Level.WARNING, msg, e); + } + } + } + } else { + logger.log(Level.WARNING, + "taglibs.unableToDetermineTldResources", + new Object[] {"JSF", classLoader, + GlassFishTldProvider.class.getName()}); + } + } + + if (uris != null && uris.length > 0) { + Pattern pattern = Pattern.compile("META-INF/.*\\.tld"); + for (URI uri : uris) { + List entries = JarURIPattern.getJarEntries(uri, pattern); + if (entries != null && entries.size() > 0) { + tldMap.put(uri, entries); + } + } + } + } +} Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) @@ -0,0 +1 @@ +org.glassfish.faces.integration.GlassFishInjectionProvider:org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) @@ -0,0 +1,6 @@ +# Hack to make GlassFishInjectionProvider visible globally in GFv3, +# so that jsf-impl.jar can discover it from webapp classloaders. +# +# When HK2 sees the service discovery pattern, it exposes the classes +# to all the modules in the habitat (AKA class loader punch-in) +org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) @@ -0,0 +1 @@ +org.glassfish.faces.integration.GlassFishInjectionProvider:org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) @@ -0,0 +1,6 @@ +# Hack to make GlassFishInjectionProvider visible globally in GFv3, +# so that jsf-impl.jar can discover it from webapp classloaders. +# +# When HK2 sees the service discovery pattern, it exposes the classes +# to all the modules in the habitat (AKA class loader punch-in) +org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) @@ -0,0 +1 @@ +org.glassfish.faces.integration.GlassFishInjectionProvider:org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) @@ -0,0 +1,6 @@ +# Hack to make GlassFishInjectionProvider visible globally in GFv3, +# so that jsf-impl.jar can discover it from webapp classloaders. +# +# When HK2 sees the service discovery pattern, it exposes the classes +# to all the modules in the habitat (AKA class loader punch-in) +org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/com.sun.faces.spi.injectionprovider (revision 0) @@ -0,0 +1 @@ +org.glassfish.faces.integration.GlassFishInjectionProvider:org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/src/main/resources/META-INF/services/org.glassfish.faces.integration.GlassFishInjectionProvider (revision 0) @@ -0,0 +1,6 @@ +# Hack to make GlassFishInjectionProvider visible globally in GFv3, +# so that jsf-impl.jar can discover it from webapp classloaders. +# +# When HK2 sees the service discovery pattern, it exposes the classes +# to all the modules in the habitat (AKA class loader punch-in) +org.glassfish.faces.integration.GlassFishInjectionProvider Index: jsf-connector/jsf-connector-glassfishV3.1/osgi.bundle =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/osgi.bundle (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/osgi.bundle (revision 0) @@ -0,0 +1,45 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. +# +# The contents of this file are subject to the terms of either the GNU +# General Public License Version 2 only ("GPL") or the Common Development +# and Distribution License("CDDL") (collectively, the "License"). You +# may not use this file except in compliance with the License. You can +# obtain a copy of the License at +# https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html +# or packager/legal/LICENSE.txt. See the License for the specific +# language governing permissions and limitations under the License. +# +# When distributing the software, include this License Header Notice in each +# file and include the License file at packager/legal/LICENSE.txt. +# +# GPL Classpath Exception: +# Oracle designates this particular file as subject to the "Classpath" +# exception as provided by Oracle in the GPL Version 2 section of the License +# file that accompanied this code. +# +# Modifications: +# If applicable, add the following below the License Header, with the fields +# enclosed by brackets [] replaced by your own identifying information: +# "Portions Copyright [year] [name of copyright owner]" +# +# Contributor(s): +# If you wish your version of this file to be governed by only the CDDL or +# only the GPL Version 2, indicate your decision by adding "[Contributor] +# elects to include this software in this distribution under the [CDDL or GPL +# Version 2] license." If you don't indicate a single choice of license, a +# recipient has the option to distribute your version of this file under +# either the CDDL, the GPL Version 2 or to extend the choice of license to +# its licensees as provided above. However, if you add GPL Version 2 code +# and therefore, elected the GPL Version 2 license, then the option applies +# only if the new code is made subject to such option by the copyright +# holder. +# + +-exportcontents: org.glassfish.faces.integration.*; version=${project.osgi.version} + +Import-Package: \ + com.sun.logging.enterprise.system.container.web, \ + * Index: jsf-connector/jsf-connector-glassfishV3.1/pom.xml =================================================================== --- jsf-connector/jsf-connector-glassfishV3.1/pom.xml (revision 0) +++ jsf-connector/jsf-connector-glassfishV3.1/pom.xml (revision 0) @@ -0,0 +1,351 @@ + + + + + 4.0.0 + org.glassfish.web + jsf-connector + 2.0.4 + hk2-jar + JSF implementation connector module for running Mojarra 2.0.X in GlassFish 3.1.X + + Generated by running mvn help:effective-pom on + https://svn.java.net/svn/glassfish~svn/trunk/v3/web/jsf-connector/pom.xml + + + + + org.apache.maven.wagon + wagon-webdav + 1.0-beta-2 + + + jsf-connector + + + + com.sun.enterprise + hk2-maven-plugin + 1.0.72 + + + com.sun.enterprise + osgiversion-maven-plugin + 1.0.72 + + + com.sun.enterprise + consolidatedbundle-maven-plugin + 1.0.72 + + + org.jvnet.maven-antrun-extended-plugin + maven-antrun-extended-plugin + 1.41 + + + org.glassfish.build + maven-glassfishbuild-plugin + 3.1-SNAPSHOT + + . + true + + org.glassfish.distributions + web + 3.1-SNAPSHOT + + + + + org.codehaus.mojo + antlr-maven-plugin + 2.1 + + + org.jvnet.updatecenter2 + maven-makepkgs-plugin + 0.5.1 + + + + + + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + maven-enforcer-plugin + 1.0-beta-1 + + + enforce-versions + + enforce + + + + + [1.6.0-4,) + You need JDK 1.6.0_04 and above! + + + [2.2.1,) + You need Maven 2.2.1 or above! + + + + + + + + org.apache.felix + maven-bundle-plugin + 2.0.1 + + + bundle-manifest + process-classes + + manifest + + + + + + + hk2-jar + bundle + + + <_include>-${project.basedir}/osgi.bundle + + + + + maven-source-plugin + 2.1 + + + attach-sources + verify + + jar-no-fork + + + + + true + + + + com.sun.enterprise + hk2-maven-plugin + 1.0.72 + true + + + ${project.basedir}/target/classes/META-INF/MANIFEST.MF + + + + + com.sun.enterprise + osgiversion-maven-plugin + 1.0.72 + + + compute-osgi-version + + compute-osgi-version + + + qualifier + project.osgi.version + + + + + + maven-jar-plugin + 2.2 + + + org.apache.maven + maven-archiver + 2.4 + compile + + + + + org.glassfish.build + maven-glassfishbuild-plugin + 3.1-SNAPSHOT + + + echo + validate + + echo + + + + Building in ${project.basedir}/jsf-connector + + + + + + . + true + + org.glassfish.distributions + web + 3.1-SNAPSHOT + + + + + + + + + never + + glassfish-repo-archive + Nexus repository collection for Glassfish + http://maven.glassfish.org/content/groups/glassfish + + + + false + + central + Maven Repository Switchboard + http://repo1.maven.org/maven2 + + + + + + never + + glassfish-repo-archive + Nexus repository collection for Glassfish + http://maven.glassfish.org/content/groups/glassfish + + + + never + + + false + + central + Maven Plugin Repository + http://repo1.maven.org/maven2 + + + + + com.sun.enterprise + hk2 + 1.0.72 + compile + + + org.glassfish.web + web-glue + 3.1-SNAPSHOT + compile + + + com.sun.faces + jsf-api + 2.1.0-b10 + provided + + + com.sun.faces + jsf-impl + 2.1.0-b10 + provided + + + org.glassfish.common + glassfish-api + 3.1-SNAPSHOT + compile + + + org.glassfish.common + common-util + 3.1-SNAPSHOT + compile + + + org.glassfish.common + container-common + 3.1-SNAPSHOT + compile + + + org.glassfish.deployment + dol + 3.1-SNAPSHOT + compile + + + junit + junit + 4.3.1 + test + true + + +