mirror of https://github.com/apache/openjpa.git
OPENJPA-1068 Use validation mode to determine if we should setup a ValidatingLifecycleEventManager or not. Based on patch from Jeremy with one config scenario still to be addressed in OPENJPA-1111.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@780706 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f90952b286
commit
d4c227ef00
|
@ -26,6 +26,7 @@ import org.apache.openjpa.datacache.DataCacheManager;
|
|||
import org.apache.openjpa.ee.ManagedRuntime;
|
||||
import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
|
||||
import org.apache.openjpa.event.BrokerFactoryEventManager;
|
||||
import org.apache.openjpa.event.LifecycleEventManager;
|
||||
import org.apache.openjpa.event.OrphanedKeyAction;
|
||||
import org.apache.openjpa.event.RemoteCommitEventManager;
|
||||
import org.apache.openjpa.event.RemoteCommitProvider;
|
||||
|
@ -1676,7 +1677,7 @@ public interface OpenJPAConfiguration
|
|||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public Object getValidationFactory();
|
||||
public Object getValidationFactoryInstance();
|
||||
|
||||
/**
|
||||
* Set the container or application provided ValidatorFactory instance.
|
||||
|
@ -1685,4 +1686,18 @@ public interface OpenJPAConfiguration
|
|||
* @since 2.0.0
|
||||
*/
|
||||
public void setValidationFactory(Object factory);
|
||||
|
||||
/**
|
||||
* Gets the lifecycle event manager instance
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public LifecycleEventManager getLifecycleEventManagerInstance();
|
||||
|
||||
/**
|
||||
* Sets the lifecycle event manager instance.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public void setLifecycleEventManager(LifecycleEventManager eventMgr);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.openjpa.ee.ManagedRuntime;
|
|||
import org.apache.openjpa.enhance.PCEnhancerAgent;
|
||||
import org.apache.openjpa.enhance.RuntimeUnenhancedClasssesModes;
|
||||
import org.apache.openjpa.event.BrokerFactoryEventManager;
|
||||
import org.apache.openjpa.event.LifecycleEventManager;
|
||||
import org.apache.openjpa.event.OrphanedKeyAction;
|
||||
import org.apache.openjpa.event.RemoteCommitEventManager;
|
||||
import org.apache.openjpa.event.RemoteCommitProvider;
|
||||
|
@ -155,6 +156,8 @@ public class OpenJPAConfigurationImpl
|
|||
public ObjectValue specification;
|
||||
public StringValue validationMode;
|
||||
public ObjectValue validationFactory;
|
||||
public ObjectValue lifecycleEventManager;
|
||||
|
||||
|
||||
// custom values
|
||||
public BrokerFactoryValue brokerFactoryPlugin;
|
||||
|
@ -557,17 +560,8 @@ public class OpenJPAConfigurationImpl
|
|||
queryTimeout.setDynamic(true);
|
||||
|
||||
// kernel can't access javax.persistence.ValidationMode enums here
|
||||
// so the config will be done in PersistenceProductDerivation
|
||||
validationMode = addString("javax.persistence.validation.mode");
|
||||
aliases =
|
||||
new String[] {
|
||||
"AUTO", "auto",
|
||||
"CALLBACK", "callback",
|
||||
"NONE", "none"
|
||||
};
|
||||
validationMode.setAliases(aliases);
|
||||
validationMode.setAliasListComprehensive(true);
|
||||
validationMode.setDefault(aliases[0]);
|
||||
validationMode.set(aliases[0]);
|
||||
validationMode.setDynamic(true);
|
||||
|
||||
validationFactory = addObject("javax.persistence.validation.factory");
|
||||
|
@ -575,6 +569,10 @@ public class OpenJPAConfigurationImpl
|
|||
"getValidationFactoryInstance");
|
||||
validationFactory.setDynamic(true);
|
||||
|
||||
lifecycleEventManager = addObject("LifecycleEventManager");
|
||||
lifecycleEventManager.setInstantiatingGetter(
|
||||
"getLifecycleEventManagerInstance");
|
||||
|
||||
dynamicEnhancementAgent = addBoolean("DynamicEnhancementAgent");
|
||||
dynamicEnhancementAgent.setDefault("true");
|
||||
dynamicEnhancementAgent.set(true);
|
||||
|
@ -1538,11 +1536,15 @@ public class OpenJPAConfigurationImpl
|
|||
}
|
||||
|
||||
public void setValidationMode(String mode) {
|
||||
Thread.dumpStack();
|
||||
validationMode.setString(mode);
|
||||
}
|
||||
|
||||
public String getValidationMode() {
|
||||
return validationMode.getString();
|
||||
String mode = validationMode.getString();
|
||||
if (mode == null)
|
||||
mode = validationMode.getDefault();
|
||||
return mode;
|
||||
}
|
||||
|
||||
public void instantiateAll() {
|
||||
|
@ -1601,10 +1603,6 @@ public class OpenJPAConfigurationImpl
|
|||
return (FinderCache)finderCachePlugin.get();
|
||||
}
|
||||
|
||||
public Object getValidationFactory() {
|
||||
return validationFactory.get();
|
||||
}
|
||||
|
||||
public Object getValidationFactoryInstance() {
|
||||
return validationFactory.get();
|
||||
}
|
||||
|
@ -1612,10 +1610,24 @@ public class OpenJPAConfigurationImpl
|
|||
public void setValidationFactory(Object factory) {
|
||||
validationFactory.set(factory);
|
||||
}
|
||||
|
||||
public LifecycleEventManager getLifecycleEventManagerInstance() {
|
||||
if (lifecycleEventManager.get() == null) {
|
||||
lifecycleEventManager.set(new LifecycleEventManager());
|
||||
}
|
||||
return (LifecycleEventManager)lifecycleEventManager.get();
|
||||
}
|
||||
|
||||
public void setLifecycleEventManager(LifecycleEventManager eventMgr) {
|
||||
lifecycleEventManager.set(eventMgr);
|
||||
}
|
||||
|
||||
public boolean getDynamicEnhancementAgent() {
|
||||
return dynamicEnhancementAgent.get();
|
||||
}
|
||||
|
||||
public void setDynamicEnhancementAgent(boolean dynamic) {
|
||||
dynamicEnhancementAgent.set(dynamic);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ import org.apache.openjpa.util.RuntimeExceptionTranslator;
|
|||
import org.apache.openjpa.util.StoreException;
|
||||
import org.apache.openjpa.util.UnsupportedException;
|
||||
import org.apache.openjpa.util.UserException;
|
||||
import org.apache.openjpa.util.WrappedException;
|
||||
|
||||
/**
|
||||
* Concrete {@link Broker}. The broker handles object-level behavior,
|
||||
|
@ -301,7 +302,7 @@ public class BrokerImpl
|
|||
_runtime = new LocalManagedRuntime(this);
|
||||
|
||||
if (!fromDeserialization) {
|
||||
_lifeEventManager = new LifecycleEventManager();
|
||||
_lifeEventManager = _conf.getLifecycleEventManagerInstance();
|
||||
_transEventManager = new TransactionEventManager();
|
||||
int cmode = _conf.getMetaDataRepositoryInstance().
|
||||
getMetaDataFactory().getDefaults().getCallbackMode();
|
||||
|
@ -315,7 +316,7 @@ public class BrokerImpl
|
|||
// make sure to do this after configuring broker so that store manager
|
||||
// can look to broker configuration; we set both store and lock managers
|
||||
// before initializing them because they may each try to access the
|
||||
// other in thier initialization
|
||||
// other in their initialization
|
||||
_store = sm;
|
||||
_lm = _conf.newLockManagerInstance();
|
||||
_im = _conf.newInverseManagerInstance();
|
||||
|
@ -800,11 +801,17 @@ public class BrokerImpl
|
|||
return;
|
||||
|
||||
OpenJPAException ce;
|
||||
if (exceps.length == 1)
|
||||
ce = new CallbackException(exceps[0]);
|
||||
else
|
||||
if (exceps.length == 1) {
|
||||
// If the exception is already a wrapped exception throw the
|
||||
// exception instead of wrapping it with a callback exception
|
||||
if (exceps[0] instanceof WrappedException)
|
||||
throw (WrappedException)exceps[0];
|
||||
else
|
||||
ce = new CallbackException(exceps[0]);
|
||||
} else {
|
||||
ce = new CallbackException(_loc.get("callback-err")).
|
||||
setNestedThrowables(exceps);
|
||||
}
|
||||
if ((mode & CALLBACK_ROLLBACK) != 0 && (_flags & FLAG_ACTIVE) != 0) {
|
||||
ce.setFatal(true);
|
||||
setRollbackOnlyInternal(ce);
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.apache.openjpa.conf.OpenJPAConfiguration;
|
|||
import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
|
||||
import org.apache.openjpa.conf.OpenJPAProductDerivation;
|
||||
import org.apache.openjpa.conf.Specification;
|
||||
import org.apache.openjpa.kernel.LockLevels;
|
||||
import org.apache.openjpa.kernel.MixedLockLevels;
|
||||
import org.apache.openjpa.lib.conf.AbstractProductDerivation;
|
||||
import org.apache.openjpa.lib.conf.Configuration;
|
||||
|
@ -57,6 +56,10 @@ import org.apache.openjpa.lib.meta.XMLMetaDataParser;
|
|||
import org.apache.openjpa.lib.meta.XMLVersionParser;
|
||||
import org.apache.openjpa.lib.util.J2DoPrivHelper;
|
||||
import org.apache.openjpa.lib.util.Localizer;
|
||||
import org.apache.openjpa.persistence.validation.ValidatorImpl;
|
||||
import org.apache.openjpa.validation.Validator;
|
||||
import org.apache.openjpa.validation.ValidationException;
|
||||
import org.apache.openjpa.validation.ValidatingLifecycleEventManager;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
|
@ -142,6 +145,18 @@ public class PersistenceProductDerivation
|
|||
conf.lockManagerPlugin.setAlias("mixed",
|
||||
"org.apache.openjpa.jdbc.kernel.MixedLockManager");
|
||||
|
||||
String[] aliases = new String[] {
|
||||
String.valueOf(ValidationMode.AUTO),
|
||||
String.valueOf(ValidationMode.AUTO).toLowerCase(),
|
||||
String.valueOf(ValidationMode.CALLBACK),
|
||||
String.valueOf(ValidationMode.CALLBACK).toLowerCase(),
|
||||
String.valueOf(ValidationMode.NONE),
|
||||
String.valueOf(ValidationMode.NONE).toLowerCase()
|
||||
};
|
||||
conf.validationMode.setAliases(aliases);
|
||||
conf.validationMode.setAliasListComprehensive(true);
|
||||
conf.validationMode.setDefault(aliases[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -164,6 +179,39 @@ public class PersistenceProductDerivation
|
|||
Compatibility compatibility = conf.getCompatibilityInstance();
|
||||
compatibility.setFlushBeforeDetach(true);
|
||||
compatibility.setCopyOnDetach(true);
|
||||
} else {
|
||||
// only try creating a ValidatingLifecycleEventManager if needed
|
||||
if (!ValidatorImpl.skipValidation(conf.getValidationMode())) {
|
||||
try {
|
||||
Validator val = new ValidatorImpl(
|
||||
conf.getValidationFactoryInstance(),
|
||||
conf.getValidationMode());
|
||||
// we have a Validator, so try to create a VLEM
|
||||
conf.setLifecycleEventManager(
|
||||
new ValidatingLifecycleEventManager(val));
|
||||
} catch (RuntimeException e) {
|
||||
if (ValidatorImpl.validationRequired(
|
||||
conf.getValidationMode())) {
|
||||
// fatal error - ValidationMode requires a Validator
|
||||
conf.getConfigurationLog().error(
|
||||
_loc.get("vlem-creation-error"), e);
|
||||
// rethrow as a WrappedException
|
||||
throw new ValidationException(e);
|
||||
} else {
|
||||
// unexpected, but validation is optional,
|
||||
// so just log it as a warning
|
||||
conf.getConfigurationLog().warn(
|
||||
_loc.get("vlem-creation-warn"));
|
||||
// if tracing, log the exception details
|
||||
conf.getConfigurationLog().trace(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
conf.getConfigurationLog().trace(
|
||||
"Validation has been disabled by supplied mode.");
|
||||
}
|
||||
// make sure we have at least a LifecycleEventManager created
|
||||
conf.getLifecycleEventManagerInstance();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -64,55 +64,104 @@ public class ValidatorImpl extends AbstractValidator {
|
|||
LifecycleEvent.BEFORE_UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a Validator required based on the given validation mode?
|
||||
* Keeping validation mode logic in a single class...
|
||||
* @param mode
|
||||
* @return true if a Validator is required
|
||||
*/
|
||||
public static boolean validationRequired(String mode) {
|
||||
return String.valueOf(ValidationMode.CALLBACK).equalsIgnoreCase(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip creating a Validator based on the given validation mode?
|
||||
* Keeping validation mode logic in a single class...
|
||||
* @param mode
|
||||
* @return true if a Validator should not be created
|
||||
*/
|
||||
public static boolean skipValidation(String mode) {
|
||||
return String.valueOf(ValidationMode.NONE).equalsIgnoreCase(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default constructor. Builds a default validator factory, if available
|
||||
* and creates the validator.
|
||||
* Returns an Exception if a Validator could not be created.
|
||||
*/
|
||||
public ValidatorImpl() {
|
||||
// Add the default validation groups
|
||||
_validatorFactory = getDefaultValidatorFactory();
|
||||
if (_validatorFactory != null)
|
||||
_validator = _validatorFactory.getValidator();
|
||||
addDefaultValidationGroups();
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-specific constructor
|
||||
* Returns an Exception if a Validator could not be created.
|
||||
* @param validatorFactory Instance of validator factory to use. Specify
|
||||
* null to use the default factory.
|
||||
* @param mode ValdiationMode enum value
|
||||
*/
|
||||
public ValidatorImpl(ValidatorFactory validatorFactory,
|
||||
ValidationMode mode) {
|
||||
if (mode != null) {
|
||||
_mode = mode;
|
||||
}
|
||||
if (validatorFactory != null) {
|
||||
_validatorFactory = validatorFactory;
|
||||
} else {
|
||||
_validatorFactory = getDefaultValidatorFactory();
|
||||
}
|
||||
if (_validatorFactory != null)
|
||||
_validator = _validatorFactory.getValidator();
|
||||
addDefaultValidationGroups();
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic-type constructor
|
||||
* Returns an Exception if a Validator could not be created.
|
||||
* @param validatorFactory an instance to the validatorFactory
|
||||
* @param mode validation mode enum as string value
|
||||
*/
|
||||
public ValidatorImpl(Object validatorFactory,
|
||||
String mode) {
|
||||
if (validatorFactory != null && validatorFactory instanceof
|
||||
ValidatorFactory) {
|
||||
_validatorFactory = (ValidatorFactory)validatorFactory;
|
||||
} else {
|
||||
_validatorFactory = getDefaultValidatorFactory();
|
||||
}
|
||||
_mode = Enum.valueOf(ValidationMode.class, mode);
|
||||
if (_validatorFactory != null)
|
||||
_validator = _validatorFactory.getValidator();
|
||||
addDefaultValidationGroups();
|
||||
if (validatorFactory != null) {
|
||||
if (validatorFactory instanceof ValidatorFactory) {
|
||||
_validatorFactory = (ValidatorFactory)validatorFactory;
|
||||
} else {
|
||||
// TODO: Add a localized exception
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Common setup code factored out of the constructors
|
||||
*/
|
||||
private void initialize() {
|
||||
// only try setting up a validator if mode is not NONE
|
||||
if (_mode != ValidationMode.NONE) {
|
||||
if (_validatorFactory == null) {
|
||||
_validatorFactory = getDefaultValidatorFactory();
|
||||
}
|
||||
if (_validatorFactory != null) {
|
||||
_validator = _validatorFactory.getValidator();
|
||||
} else {
|
||||
// TODO: Add a localized exception
|
||||
throw new RuntimeException("No default ValidatorFactory");
|
||||
}
|
||||
|
||||
// throw an exception if we have no Validator
|
||||
if (_validator == null) {
|
||||
// TODO: Add a localized exception
|
||||
throw new RuntimeException("No Validator provider");
|
||||
}
|
||||
|
||||
// add in default validation groups, which can be over-ridden later
|
||||
addDefaultValidationGroups();
|
||||
} else {
|
||||
// TODO: Add a localized exception
|
||||
throw new RuntimeException("No Validator should be created based " +
|
||||
"on the supplied Validation Mode.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a validation group for the specific property. The properties map
|
||||
* to a specific lifecycle event. To disable validation for a group, set
|
||||
|
@ -126,9 +175,11 @@ public class ValidatorImpl extends AbstractValidator {
|
|||
if (event != null) {
|
||||
_validationGroups.put(event, vgs);
|
||||
return;
|
||||
} else {
|
||||
// TODO: Add a localized exception
|
||||
throw new IllegalArgumentException("There were no events found " +
|
||||
"for the supplied group name.");
|
||||
}
|
||||
// TODO: Add a localized exception
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,7 +212,7 @@ public class ValidatorImpl extends AbstractValidator {
|
|||
* @return returns true if validating for this particular event
|
||||
*/
|
||||
public boolean isValidating(Integer event) {
|
||||
return _validationGroups.get(event) != null;
|
||||
return (_validationGroups.get(event) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,8 +326,12 @@ public class ValidatorImpl extends AbstractValidator {
|
|||
|
||||
// Get the default validator factory
|
||||
private ValidatorFactory getDefaultValidatorFactory() {
|
||||
ValidatorFactory factory =
|
||||
Validation.buildDefaultValidatorFactory();
|
||||
ValidatorFactory factory = null;
|
||||
try {
|
||||
factory = Validation.buildDefaultValidatorFactory();
|
||||
} catch (javax.validation.ValidationException e) {
|
||||
// no validation providers found
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
|
|
@ -195,4 +195,8 @@ invalid-orderBy: This is not a valid OrderBy annotation. The property or \
|
|||
for "{0}".
|
||||
dynamic-agent: OpenJPA dynamically loaded the class enhancer. Any classes \
|
||||
that were not enhanced at build time will be enhanced when the are \
|
||||
loaded by the JVM
|
||||
loaded by the JVM.
|
||||
vlem-creation-warn: Failed to create the optional Validation Provider.
|
||||
vlem-creation-error: A fatal error occurred while trying to \
|
||||
create the required Validation Provider.
|
||||
|
||||
|
|
Loading…
Reference in New Issue