I Have a JSF-2.2 web app on a WildFly 8.1 app server shiping Hibernate-validator 5.1
I want to set some constrainst programmaticaly using the fluent API, because they depends on the case for example a min and max of a #Size constraint could vary or a field could be #NotNull or not...
so I try to programmaticaly configure constraints such as describe here : http://docs.jboss.org/hibernate/validator/5.0/reference/en-US/html_single/#section-programmatic-api
I do somthing like that to try (in a EJB #Singleton #Startup):
HibernateValidatorConfiguration configuration = Validation
.byProvider( HibernateValidator.class )
.configure();
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
.type( Car.class )
.property( "manufacturer", FIELD )
.constraint( new NotNullDef() )
.property( "licensePlate", FIELD )
.ignoreAnnotations()
.constraint( new NotNullDef() )
.constraint( new SizeDef().min( 2 ).max( 14 ) );
Validator validator = configuration.addMapping( constraintMapping )
.buildValidatorFactory()
.getValidator();
But then JSF don't use this new constraints mapping.
I can submit forms without problem even if I break the constraints programmaticaly set
I don't know how to configure the Validator or ValidatorFactory JSF is using or how to provide to JSF an other Validator or ValidatorFactory...
Or may be It's more about configuring WildFly server, something to do in a config file or JNDI, I don't have a clue...
EDIT
I try to bind new Validator and validator factory in JNDI
But I can't because "Naming context is read-only"
Hashtable jndiProperties = new Hashtable();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
Context context = new InitialContext(jndiProperties);
context.bind("java:comp/Validator", factory.getValidator());
context.bind("java:comp/ValidatorFactory", factory);
Thank you Hardy
As you proposed I post Hibenate Validator improvement
https://hibernate.atlassian.net/browse/HV-955
There is no way atm to do what you are after. Hibernate Validator has indeed the programmatic mapping, but it is a Hibernate Validator specific feature. There is no way to bootstrap this functionality in a Bean Validation way. I am saying this, since the only way to customize your ValidatorFactory and hence Validator instance within the container is via validation.xml. And there is no mechanism for the fluent API in this configuration file.
Your JNDI idea is in principal good, but as you say, it is only read only.
validation.xml allows for vendor specific properties though. One could imagine a property like org.hibernate.validator.config_factory=acme.MyConfig. The value of the property would point to a fully specified class which would contain some sort of factory method which returns the programmatic mapping to be added to the configuration. Unfortunately, such a property does not yet exist. You could open an issue here though ;-)
Related
In my module, in OSGI component declarationIi need to use a property which will be in my portal-ext.properties, like that :
#Component(
immediate = true,
property = {
"dispatcher=FORWARD",
"dispatcher=REQUEST",
"servlet-context-name=",
"servlet-filter-name=Detail UC Filter",
"url-pattern=/web/guest/" + PropsUtil.get("myPath") + "/*"
}
But i get the compilation error : " The value for annotation attribute Component.property must be a constant expression". How can i do to use a property here?
But i get the compilation error : " The value for annotation attribute Component.property must be a constant expression". How can i do to use a property here?
The entry:
"url-pattern=/web/guest/" + PropsUtil.get("myPath") + "/*"
is the problem. This is because annotations can only have values that are compile-time constants. Obviously this property is not a compile time constant as its value depends on calling a method.
If you want to supply property values at runtime then you can do this in OSGi using Configuration Admin. All Declarative Services components are configurable by default, using a pid which is either:
User configured by setting #Component(configurationPid="foo")
User configured by setting #Component(name="bar")
Defaulted using the fully qualified class name of the component implementation
When you supply a configuration dictionary to Configuration Admin which matches the pid for your DS component then it will be bound to the component.
Your component properties will be merged with the configuration dictionary (with the configuration overriding the static properties). This can be received by your component using an #Activate method
If your component is registered as a service then your service properties will also be updated.
If your component has a #Modified method then these changes will be dynamic, otherwise your component instance will be deactivated and discarded, and a new instance created and activated.
You can force your component not to activate until a configuration has been provided by setting your component's configuration policy. This is useful when you have a property that needs to exist, but can't be known until runtime.
#Component(configurationPolicy=ConfigurationPolicy.REQUIRE)
You can set any of these properties using a config admin configuration.
So one approach is to have a separate component that writes a configuration for this component.
You can use configurationPolicy = ConfigurationPolicy.REQUIRE to prevent the component to become activated before this configuration is present.
Another approach is to use a component factory. See this blog from Scott.
This question is on best practice and if possible.
I need to know if I can dynamically change the base of ldap context source within code?
With my ldap bean wired with the following
<ldap:context-source
url="ldap://<url>"
base="dc=example,dc=local"
username="<user>#example.local"
password="<pass>"
/>
can I in code change the context source to another base depending on a given dynamically changing parameter?
For instance if i want to change base to dc=example2,dc=local .
If I was programmatically setting up LdapContextSource this would be no problem.
So this was simpler and easier than I thought.
All i had to do was go ahead and create
LdapContextSource ctxSrc = new LdapContextSource();
ctxSrc.setUrl("ldap://<url>");
ctxSrc.setBase("dc=example,dc=local");
ctxSrc.setUserDn("<user>#example.local");
ctxSrc.setPassword("<pass>");
ctxSrc.afterPropertiesSet(); // this method should be called.
LdapTemplate tmpl = new LdapTemplate(ctxSrc);
setLdapTemplate(tmpl);
and base my LdapContextSource values on the properties that in my case is a dynamic source.
I was thinking that there was something more Spring like to do .
Using Weld 1.1.13.Final in test with Arquillian....
Let's say I inject into a field something volatile. Something like a property subject to change that I want the bean owning the injection point to receive change events. Thought about creating a CDI extension.
Caught ProcessAnnotatedType event and looking for all fields that have an custom annotation on field injection points:
<T> void pat(#Observes ProcessAnnotatedType<T> event, BeanManager bm) {
final AnnotatedType<T> target = event.getAnnotatedType();
for (AnnotatedField<? super T> field : target.getFields())
if (field.isAnnotationPresent(Value.class)) { // ignore that I don't check #Inject here for the moment
CtClass wrapper = pool.get(target.getJavaClass().getName());
ConstPool cp = wrapper.getClassFile().getConstPool();
CtMethod m = CtNewMethod.make(....)
....
wrapper.addMethod(m);
event.setAnnotatedType(bm.createAnnotatedType(wrapper.toClass()));
}
}
Had even grabbed thereafter all the injection points for fields and replaced the underlying WeldField with a new Field corresponding the "wrapper" type. Otherwise bean validation fails.
But this only works for stuff setup during startup not when for example Arquillian uses the Bean Manager to initialize a class that injects one of my "wraps". Things fail since the Bean Resolver uses the Type as a hash key to find beans.
Basically I don't think I can "mask" a class that is annotated (made into a bean) by the CDI with an extra method to receive custom events. Would have been cool but a Type is a Type (i.e. no idea how to proxy or fake the equals/hashCode).
Got it. Turns out the compute value function (google extension) inside the TypeSafeBeanResolver resolver (at least the CDI Weld implementation) is smart. If I just extend the class:
CtClass wrapper = pool.makeClass(target.getJavaClass().getName()+"Proxy");
wrapper.setSuperclass(pool.get(target.getJavaClass().getName()));
.....
final AnnotatedType<T> other = bm.createAnnotatedType(wrapper
.toClass());
then everything works fine. Tested capturing an event in a bean. Will post the code on a Gist with a comment.
Is there a way we can use ObjectContext with DbContext's ModelBuilder? We don't want to use POCO because we have customized property code that does not modify entire object in update, but only update modified properties. Also we have lots of serialisation and auditing code that uses EntityObject.
Since poco does create a proxy with EntityObject, we want our classes to be derived from EntityObject. We don't want proxy. We also heavily use CreateSourceQuery. The only problem is EDMX file and its big connection string syntax web.config.
Is there any way I can get rid of EDMX file? It will be useful as we can dynamically compile new class based on reverse engineering database.
I would also like to use DbContext with EntityObject instead of poco.
Internal Logic
Access Modified Properties in Save Changes which is available in ObjectStateEntry and Save them onto Audit with Old and New Values
Most of times we need to only check for Any condition on Navigation Property for example
User.EmailAddresses.CreateSourceQuery()
.Any( x=> x.EmailAddress == givenAddress);
Access Property Attributes, such as XmlIgnore etc, we rely heavily on attributes defined on the properties.
A proxy for a POCO is a dynamically created class which derives from (inherits) a POCO. It adds functionality previously found in EntityObject, namely lazy loading and change tracking, as long as a POCO meets requirements. A POCO or its proxy does not contain an EntityObject as the question suggests, but rather a proxy contains functionality of EntityObject. You cannot (AFAIK) use ModelBuilder with EntityObject derivatives and you cannot get to an underlying EntityObject from a POCO or a proxy, since there isn't one as such.
I don't know what features of ObjectContext does your existing serialisation and auditing code use, but you can get to ObjectContext from a DbContext by casting a DbContext to a IObjectContextAdapter and accessing IObjectContextAdapter.ObjectContext property.
EDIT:
1. Access Modified Properties in Save Changes which is available in ObjectStateEntry and Save them onto Audit with Old and New Values
You can achieve this with POCOs by using DbContext.ChangeTracker. First you call DbContext.ChangeTracker.DetectChanges to detect the changes (if you use proxies this is not needed, but can't hurt) and then you use DbCotnext.Entries.Where(e => e.State != EntityState.Unchanged && e.State != EntityState.Detached) to get DbEntityEntry list of changed entities for auditing. Each DbEntityEntry has OriginalValues and CurrentValues and the actual Entity is in property Entity.
You also have access to ObjectStateEntry, see below.
2. Most of times we need to only check for Any condition on Navigation Property for example:
User.EmailAddresses.CreateSourceQuery().Any( x=> x.EmailAddress == givenAddress);
You can use CreateSourceQuery() with DbContext by utilizing IObjectContextAdapter as described previously. When you have ObjectContext you can get to the source query for a related end like this:
public static class DbContextUtils
{
public static ObjectQuery<TMember> CreateSourceQuery<TEntity, TMember>(this IObjectContextAdapter adapter, TEntity entity, Expression<Func<TEntity, ICollection<TMember>>> memberSelector) where TMember : class
{
var objectStateManager = adapter.ObjectContext.ObjectStateManager;
var objectStateEntry = objectStateManager.GetObjectStateEntry(entity);
var relationshipManager = objectStateManager.GetRelationshipManager(entity);
var entityType = (EntityType)objectStateEntry.EntitySet.ElementType;
var navigationProperty = entityType.NavigationProperties[(memberSelector.Body as MemberExpression).Member.Name];
var relatedEnd = relationshipManager.GetRelatedEnd(navigationProperty.RelationshipType.FullName, navigationProperty.ToEndMember.Name);
return ((EntityCollection<TMember>)relatedEnd).CreateSourceQuery();
}
}
This method uses no dynamic code and is strongly typed since it uses expressions. You use it like this:
myDbContext.CreateSourceQuery(invoice, i => i.details);
i am new at grails spring security, and i wanted to know if it is possible to enable/disable security of in my app thru an xml entry.
rather than having
grails.plugins.springsecurity.active = true
I d like to read the value from a bean that i declared in my resources.xml file.
grails.plugins.springsecurity.active = com.myorg.util.BeanUtil.getBean("repositorySettings").getIsSecured()
Using this approach throws errors. is there a way that i can accomplish this, and read the true/false value from a bean in the resources.xml
It's somewhat possible. resources.xml and resources.groovy are loaded after the plugin is, but parsed before. So you can put code in resources.groovy that will run while it's being parsed, before the plugin loads the config, and determines whether it's enabled. But you can't use a bean for that since it wouldn't be ready until it's too late. This wouldn't be possible in resources.xml since that's just XML but resources.groovy allows Groovy code and bean definitions:
import com.pbbi.mimgr.util.BeanUtil
beans = {
def grailsApplication = springConfig.unrefreshedApplicationContext.grailsApplication
def securityConfig = grailsApplication.config.grails.plugins.springsecurity
securityConfig.active = BeanUtil.getBean('repositorySettings').isSecured
}
If BeanUtil accesses the ApplicationContext then this won't work. But if it's accessing singletons that aren't Spring beans it should be fine.