| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with this |
| * work for additional information regarding copyright ownership. The ASF |
| * licenses this file to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package javax.validation; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.net.URL; |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Enumeration; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.WeakHashMap; |
| |
| import javax.validation.bootstrap.GenericBootstrap; |
| import javax.validation.bootstrap.ProviderSpecificBootstrap; |
| import javax.validation.spi.BootstrapState; |
| import javax.validation.spi.ValidationProvider; |
| |
| import org.apache.geronimo.osgi.locator.ProviderLocator; |
| |
| /** |
| * Note: From Section 4.4.5 Validation of the 1.0 PFD Spec - Validation |
| * implementations may only provide the following three public static methods: |
| * buildDefaultValidatorFactory(), byDefaultProvider(), byProvider() |
| * |
| * @version $Rev$ $Date$ |
| */ |
| public class Validation { |
| |
| public static ValidatorFactory buildDefaultValidatorFactory() { |
| return byDefaultProvider().configure().buildValidatorFactory(); |
| } |
| |
| public static GenericBootstrap byDefaultProvider() { |
| return new GenericBootstrapImpl(); |
| } |
| |
| public static <T extends Configuration<T>, U extends ValidationProvider<T>> |
| ProviderSpecificBootstrap<T> byProvider(Class<U> providerType) { |
| return new ProviderSpecificBootstrapImpl<T, U>(providerType); |
| } |
| |
| /* |
| * (non-Javadoc) See Section 4.4.5 Validation - Must be private |
| * |
| * Geronimo implementation specific code. |
| */ |
| private static class ProviderSpecificBootstrapImpl<T extends Configuration<T>, U extends ValidationProvider<T>> |
| implements ProviderSpecificBootstrap<T> { |
| |
| private final Class<U> providerClass; |
| private ValidationProviderResolver vpResolver; |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.validation.bootstrap.ProviderSpecificBootstrap#ProviderSpecificBootstrap(Class<T>) |
| */ |
| |
| public ProviderSpecificBootstrapImpl(Class<U> validationProviderClass) { |
| providerClass = validationProviderClass; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.validation.bootstrap.ProviderSpecificBootstrap#providerResolver(javax.validation.ValidationProviderResolver) |
| */ |
| public ProviderSpecificBootstrap<T> providerResolver(ValidationProviderResolver resolver) { |
| vpResolver = resolver; |
| return this; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.validation.bootstrap.ProviderSpecificBootstrap#configure() |
| */ |
| public T configure() { |
| if (providerClass == null) |
| throw new ValidationException("No resolver provided"); |
| |
| // create a default resolver if not supplied by providerResolver() |
| GenericBootstrapImpl impl = new GenericBootstrapImpl(); |
| if ( vpResolver == null ) |
| vpResolver = impl.getDefaultValidationProviderResolver(); |
| else |
| impl.providerResolver(vpResolver); |
| |
| // check each provider discovered by the resolver |
| for (ValidationProvider<?> vProvider : vpResolver.getValidationProviders()) { |
| if (providerClass.isAssignableFrom(vProvider.getClass())) { |
| // Create a ValidationProvider<T> from the above bootstrap impl |
| // and configurationType |
| return providerClass.cast(vProvider).createSpecializedConfiguration(impl); |
| } |
| } |
| |
| // throw a Spec required exception |
| throw new ValidationException("No provider found for " + providerClass); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) See Section 4.4.5 Validation - Must be private |
| * |
| * Geronimo implementation specific code. |
| */ |
| private static class GenericBootstrapImpl implements GenericBootstrap, BootstrapState { |
| |
| private ValidationProviderResolver vpDefaultResolver; |
| private ValidationProviderResolver vpResolver; |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.validation.bootstrap.GenericBootstrap#providerResolver(javax.validation.ValidationProviderResolver) |
| */ |
| public GenericBootstrap providerResolver(ValidationProviderResolver resolver) { |
| vpResolver = resolver; |
| return this; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.validation.spi.BootstrapState#getValidationProviderResolver() |
| */ |
| public ValidationProviderResolver getValidationProviderResolver() { |
| return vpResolver; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.validation.spi.BootstrapState#getDefaultValidationProviderResolver() |
| */ |
| public ValidationProviderResolver getDefaultValidationProviderResolver() { |
| if (vpDefaultResolver == null) |
| vpDefaultResolver = new DefaultValidationProviderResolver(); |
| return vpDefaultResolver; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.validation.bootstrap.GenericBootstrap#configure() |
| */ |
| public Configuration<?> configure() { |
| ValidationProviderResolver resolv = vpResolver; |
| try { |
| if (resolv == null) |
| resolv = getDefaultValidationProviderResolver(); |
| return resolv.getValidationProviders().get(0).createGenericConfiguration(this); |
| } catch (Exception e) { |
| throw new ValidationException("Could not create Configuration.", e); |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) See Section 4.4.5 Validation - Must be private |
| * |
| * Geronimo implementation specific code. |
| */ |
| private static class DefaultValidationProviderResolver implements ValidationProviderResolver { |
| // cache of providers per class loader |
| private volatile WeakHashMap<ClassLoader, List<ValidationProvider<?>>> providerCache = |
| new WeakHashMap<ClassLoader, List<ValidationProvider<?>>>(); |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.validation.ValidationProviderResolver#getValidationProviders() |
| */ |
| public List<ValidationProvider<?>> getValidationProviders() { |
| List<ValidationProvider<?>> providers; |
| |
| // get our class loader |
| ClassLoader cl = PrivClassLoader.get(null); |
| if (cl == null) |
| cl = PrivClassLoader.get(DefaultValidationProviderResolver.class); |
| |
| // use any previously cached providers |
| providers = providerCache.get(cl); |
| if (providers == null) { |
| // need to discover and load them for this class loader |
| providers = new ArrayList<ValidationProvider<?>>(); |
| try { |
| List<Object> serviceProviders = ProviderLocator.getServices(ValidationProvider.class.getName(), this.getClass(), cl); |
| for (Object provider : serviceProviders) { |
| // create an instance to return |
| providers.add((ValidationProvider<?>) provider); |
| } |
| } catch (ClassNotFoundException e) { |
| throw new ValidationException("Failed to load provider", e); |
| } catch (InstantiationException e) { |
| throw new ValidationException("Failed to instantiate provider", e); |
| } catch (IllegalAccessException e) { |
| throw new ValidationException("Failed to access provider", e); |
| } catch (ClassCastException e) { |
| throw new ValidationException("Invalid provider definition", e); |
| } catch (Exception e) { |
| throw new ValidationException("Failed to instantiate provider", e); |
| } |
| |
| // cache the discovered providers |
| providerCache.put(cl, providers); |
| } |
| |
| // caller must handle the case of no providers found |
| return providers; |
| } |
| |
| private static class PrivClassLoader implements PrivilegedAction<ClassLoader> { |
| private final Class<?> c; |
| |
| public static ClassLoader get(Class<?> c) { |
| final PrivClassLoader action = new PrivClassLoader(c); |
| if (System.getSecurityManager() != null) |
| return AccessController.doPrivileged(action); |
| else |
| return action.run(); |
| } |
| |
| private PrivClassLoader(Class<?> c) { |
| this.c = c; |
| } |
| |
| public ClassLoader run() { |
| if (c != null) |
| return c.getClassLoader(); |
| else |
| return Thread.currentThread().getContextClassLoader(); |
| } |
| } |
| } |
| } |
| |