Issue: 10030
Part 1: make @Resource work for Validator and ValidatorFactory
Part 2: Make java:comp/Validator and java:comp/ValidatorFactory work in JNDI
Author: Ken Saks and Ed Burns
SECTION: Changes for Part 1
M deployment/dol/src/main/java/com/sun/enterprise/deployment/JmsDestinationReferenceDescriptor.java
- Make this class aware of Validator and ValidatorFactory as valid
JmsDestinations.
M common/container-common/src/main/java/com/sun/enterprise/container/common/impl/ComponentEnvManagerImpl.java
- Factory boilerplate code for obtaining a reference to an instance of
Validator or ValidatorFactory.
Ken, how do I store it in the ctx so subsequent lookups can find it
there? When I try to bind() it says I can't store into the comp: namespace.
M tests/quicklook/bean-validator/integration-test-servlet/metadata/web.xml
A tests/quicklook/bean-validator/integration-test-servlet/src/java/integration_test_servlet/ValidatorFactoryInjectionTestServlet.java
- Automated test code
SECTION: Diffs for Part 1
Index: tests/quicklook/bean-validator/integration-test-servlet/metadata/web.xml
===================================================================
--- tests/quicklook/bean-validator/integration-test-servlet/metadata/web.xml (revision 32299)
+++ tests/quicklook/bean-validator/integration-test-servlet/metadata/web.xml (working copy)
@@ -1,7 +1,7 @@
-
"); + out.print("Obtained ValidatorFactory: " + validatorFactory + "."); + out.print("
"); + + out.print(""); + out.print("case2: caught IllegalArgumentException. Message: " + + iae.getMessage()); + out.print("
"); + } + Person person = new Person(); + + out.print(""); + out.print(caseId + ": No ConstraintViolations found."); + out.print("
"); + } else { + for (ConstraintViolation"); + out.print(caseId + ": ConstraintViolation: message: " + curViolation.getMessage() + + " propertyPath: " + curViolation.getPropertyPath()); + out.print("
"); + } + } + + } + + +} Index: common/container-common/src/main/java/com/sun/enterprise/container/common/impl/ComponentEnvManagerImpl.java =================================================================== --- common/container-common/src/main/java/com/sun/enterprise/container/common/impl/ComponentEnvManagerImpl.java (revision 32299) +++ common/container-common/src/main/java/com/sun/enterprise/container/common/impl/ComponentEnvManagerImpl.java (working copy) @@ -66,6 +66,11 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; +import javax.validation.Validation; +import javax.validation.ValidationException; +import javax.validation.Validator; +import javax.validation.ValidatorContext; +import javax.validation.ValidatorFactory; @Service public class ComponentEnvManagerImpl @@ -552,6 +557,10 @@ Object value = null; if (next.isEJBContext()) { value = new EjbContextProxy(next.getRefType()); + } else if( next.isValidator() ) { + value = new ValidatorProxy(); + } else if( next.isValidatorFactory() ) { + value = new ValidatorFactoryProxy(); } else if( next.isCDIBeanManager() ) { value = namingUtils.createLazyNamingObjectFactory(name, "java:comp/BeanManager", false); } else { @@ -839,6 +848,100 @@ } + private class ValidatorProxy + implements NamingObjectProxy { + + private volatile ValidatorFactory validatorFactory; + private volatile Validator validator; + + ValidatorProxy() { + } + + @Override + public Object create(Context ctx) + throws NamingException { + final String nameForValidator = "java:comp/Validator"; + String exceptionMessage = "Can not obtain reference to Validator instance "; + + // Phase 1, obtain a reference to the Validator + + // case 1, try to look in the ctx + if (null == validator) { + try { + validator = (Validator) ctx.lookup(nameForValidator); + } catch (NamingException ne) { + exceptionMessage = "Unable to lookup " + + nameForValidator + ":" + ne.toString(); + } + } + + // case 2, Create a new Validator instance + if (null == validator) { + + // case 2a no validatorFactory + if (null == validatorFactory) { + ValidatorFactoryProxy factoryProxy = new ValidatorFactoryProxy(); + validatorFactory = (ValidatorFactory) factoryProxy.create(ctx); + } + + // Use the ValidatorFactory to create a Validator + if (null != validatorFactory) { + ValidatorContext validatorContext = validatorFactory.usingContext(); + validator = validatorContext.getValidator(); + } + } + + if( validator == null ) { + throw new NameNotFoundException(exceptionMessage); + } + + return validator; + } + + } + + private class ValidatorFactoryProxy + implements NamingObjectProxy { + + private volatile ValidatorFactory validatorFactory; + + ValidatorFactoryProxy() { + } + + @Override + public Object create(Context ctx) + throws NamingException { + final String nameForValidatorFactory = "java:comp/ValidatorFactory"; + String exceptionMessage = "Can not obtain reference to ValidatorFactory instance "; + + // Phase 1, obtain a reference to the ValidatorFactory + + // case 1, try to look in the ctx + if (null == validatorFactory) { + try { + validatorFactory = (ValidatorFactory) + ctx.lookup(nameForValidatorFactory); + } catch (NamingException ne) { + exceptionMessage = "Unable to lookup " + + nameForValidatorFactory + ":" + ne.toString(); + } + } + + // case 2, create the ValidatorFactory using the spec. + if (null == validatorFactory) { + try { + validatorFactory = Validation.buildDefaultValidatorFactory(); + } catch (ValidationException e) { + exceptionMessage = "Could not build a default Bean Validator factory: " + + e.toString(); + } + } + + return validatorFactory; + } + + } + private class WebServiceRefProxy implements NamingObjectProxy { Index: deployment/dol/src/main/java/com/sun/enterprise/deployment/JmsDestinationReferenceDescriptor.java =================================================================== --- deployment/dol/src/main/java/com/sun/enterprise/deployment/JmsDestinationReferenceDescriptor.java (revision 32299) +++ deployment/dol/src/main/java/com/sun/enterprise/deployment/JmsDestinationReferenceDescriptor.java (working copy) @@ -50,6 +50,8 @@ private static final String EJB_CTX_TYPE ="javax.ejb.EJBContext"; private static final String EJB_TIMER_SERVICE_TYPE = "javax.ejb.TimerService"; + private static final String VALIDATION_VALIDATOR ="javax.validation.Validator"; + private static final String VALIDATION_VALIDATOR_FACTORY ="javax.validation.ValidatorFactory"; private static final String CDI_BEAN_MANAGER_TYPE = "javax.enterprise.inject.spi.BeanManager"; @@ -106,6 +108,14 @@ getRefType().equals(EJB_TIMER_SERVICE_TYPE)); } + public boolean isValidator() { + return (getRefType().equals(VALIDATION_VALIDATOR)); + } + + public boolean isValidatorFactory() { + return (getRefType().equals(VALIDATION_VALIDATOR_FACTORY)); + } + public boolean isCDIBeanManager() { return (getRefType().equals(CDI_BEAN_MANAGER_TYPE)); } SECTION: Changes for Part 2, in https://svn.dev.java.net/svn/glassfish-svn/trunk/external/modules/bean-validator/bean-validator-source-build A bundle/osgi/src/main/java/org/glassfish/enterprise/bean_validator/BeanValidatorNamingProxy.java - Per Ken Saks's advice, make an HK2 @Service that allows JNDI lookup for java:comp/Validator and java:comp/ValidatorFactory to succeed. A bundle/osgi/src/main/resources/META-INF/inhabitants/default - Per Mahesh Kannan's advice, this is the extra special sauce to declare the @Service annotated class to the system. M bundle/osgi/pom.xml - dependencies to enable compiling the java source part of this jar project. SECTION: Diffs for Part 2, Index: bundle/osgi/src/main/java/org/glassfish/enterprise/bean_validator/BeanValidatorNamingProxy.java =================================================================== --- bundle/osgi/src/main/java/org/glassfish/enterprise/bean_validator/BeanValidatorNamingProxy.java (revision 0) +++ bundle/osgi/src/main/java/org/glassfish/enterprise/bean_validator/BeanValidatorNamingProxy.java (revision 0) @@ -0,0 +1,100 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2007 Sun Microsystems, Inc. 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.html + * or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt. + * Sun designates this particular file as subject to the "Classpath" exception + * as provided by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the License + * Header, with the fields enclosed by brackets [] replaced by your own + * identifying information: "Portions Copyrighted [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.enterprise.bean_validator; + +import javax.naming.NamingException; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorContext; +import javax.validation.ValidatorFactory; +import org.glassfish.api.naming.NamedNamingObjectProxy; +import org.jvnet.hk2.annotations.Service; + +@Service +public class BeanValidatorNamingProxy implements NamedNamingObjectProxy { + + static final String nameForValidator = "java:comp/Validator"; + static final String nameForValidatorFactory = "java:comp/ValidatorFactory"; + + private ValidatorFactory validatorFactory; + private Validator validator; + + + public Object handle(String name) throws NamingException { + Object result = null; + + if (nameForValidator.equals(name)) { + result = getValidator(); + } else if (nameForValidatorFactory.equals(name)) { + result = getValidatorFactory(); + } + return result; + } + + private Validator getValidator() throws NamingException { + if (null == validator) { + try { + ValidatorFactory factory = getValidatorFactory(); + ValidatorContext validatorContext = factory.usingContext(); + validator = validatorContext.getValidator(); + } catch (Throwable t) { + NamingException ne = new NamingException("Error retrieving Validator for " + nameForValidator + " lookup"); + ne.initCause(t); + throw ne; + } + } + return validator; + } + + private ValidatorFactory getValidatorFactory() throws NamingException { + + if (null == validatorFactory) { + try { + validatorFactory = Validation.buildDefaultValidatorFactory(); + } catch (Throwable t) { + NamingException ne = new NamingException("Error retrieving ValidatorFactory for " + nameForValidatorFactory + " lookup"); + ne.initCause(t); + throw ne; + } + } + + return validatorFactory; + } + + + +} Index: bundle/osgi/src/main/resources/META-INF/inhabitants/default =================================================================== --- bundle/osgi/src/main/resources/META-INF/inhabitants/default (revision 0) +++ bundle/osgi/src/main/resources/META-INF/inhabitants/default (revision 0) @@ -0,0 +1 @@ +class=org.glassfish.enterprise.bean_validator.BeanValidatorNamingProxy,index=org.glassfish.api.naming.NamedNamingObjectProxy Index: bundle/osgi/pom.xml =================================================================== --- bundle/osgi/pom.xml (revision 32705) +++ bundle/osgi/pom.xml (working copy) @@ -6,6 +6,27 @@