I have autowired a class as #Autowired(required=true) private CookieDao ewp;
I am trying to use the ewp to call a function ewp.getCookieEntry(id, name );
How do I access the contents of ewp. Since it is a object I get classname#hashcode but after .toString() , I just get the classname.
If ewp is autowired, then is it the same as CookieDao ewp = new CookieDao();? If not, then what is it called and how can I extract it's values?
I believe that you need to annotate your CookieDao with #Repository to the autowired work just fine, for more information have a looks into this answer : Understanding Spring #Autowired usage
Related
I'm new to groovy...
I've made a class. Within this class, I'd like to call an external method : LOG.error, but somehow, groovy is complaining about the method not being part of the class... how should I call that external method ?
class GAPI{
private myvar
public getResult(){
this.myvar="blabla"
LOG.error("test")
}
}
Groovy provides #Slf4j annotation that can add log field to your class, e.g.
#Slf4j
class GAPI{
private myvar
public getResult(){
this.myvar="blabla"
log.error("test")
}
}
Alternatively you can use #Log annotation that adds log field that uses java.util.logging.Logger instead of one provided with Slf4j. However in this case you have to be aware that java.util.logging.Logger uses different API, so there is no log.error() method.
In your example Groovy throws MissingPropertyException, because LOG is not defined in your class. If there is a class LOG with static method error you will have to import this class. But most probably you should just create LOG field (with annotation or manually) and call it to be most explicit (otherwise your code gets unreadable).
There seems be some things missing in the Spring-LDAP ODM annotations. This is a question by way of a feature request, if there is a better way to contribute such requests, please say so.
I'd like to mark an #Attribute as read-only, so it will populate the bean from LDAP for reference, but not persist it back to ldap. I'd suggest adding an attribute read-only to #Attribute, defaulting to false, for the usual case. The default attributes of * misses all the operational attributes, some of which are very useful, and transfers more data than is required, slowing down the ldap query with attributes which will never be used.
An example of this; it would be very useful, for literally read only, such as entryUUID, etag, etc., which you cannot use if you wish to persist only some fields back to ldap, as the bean fails to persist to ldap with an exception when you save the bean. But also would be usefule for general fields which you want to structurally prevent the user from ever updating.
You can get around this by not annotating read-only fields, and then manually populating the read only fields with a separate call. Very messy and kills the query speed.
Also on a related topic, query() coudl have a default list of attributes, which you have already annotated in your classes, something like :
public static String[] getBeanAttributes(Class<?> beanClass) {
ArrayList<String> attrsObj = new ArrayList<>();
for (Field field : beanClass.getDeclaredFields()) {
if (field.isAnnotationPresent(Attribute.class)) {
Attribute attr = field.getAnnotation(Attribute.class);
attrsObj.add(attr.name());
}
}
String[] attrs = attrsObj.toArray(new String[attrsObj.size()]);
return attrs;
}
Above just returns a simple String[] of your declared attributes, to pass to query.attributes() - now i realize that as a static member, query() is built before the bean class is known, but at least there could be a helper function like the above, or a method signature for query attributes() that took a bean Class signature as an argument.
I created LDAP-312 on Jira. Thanks.
I have ValidationMessages_en_US.properties as below
requiredFirstName=First name is required
requiredLastName=Last name is required
requiredEmailAddress=Email Address is required
...
...
What I would like to do is parameterize the field name in this. So something like this
requiredField={field} is required
So that there will be only one message and I can pass in the field name. I am using this in bean validations in the jsf environment.
This is where I want to use the values:
public class SomeBean implements Serializable
{
#NotNull(message="{requiredFirstName}" )
private String firstName;
......
.....
Is there a way to do this?
Thanks
There is no way to achieve this with the current Bean Validation specification or reference implementation (Hibernate Validator). You can interpolate the validated value and the constraint parameters and with Validator 5.1 you will also be able to add custom variables via HibernateConstraintValidatorContext (see also https://hibernate.atlassian.net/browse/HV-701). However, that does not help you yet to identify your fields and set the right 'field' value.
I think i understood how CDI works and in order to dive deep in it, i would like to try using it with something real world example. I am stuck with one thing where i need your help to make me understand. I would really appreciate your help in this regard.
I have my own workflow framework developed using Java reflection API and XML configurations where based on specific type of "source" and "eventName" i load appropriate Module class and invoke "process" method on that. Everything is working fine in our project.
I got excited with CDI feature and wanted to give it try with workflow framework where i am planning inject Module class instead of loading them using Reflection etc...
Just to give you an idea, I will try to keep things simple here.
"Message.java" is a kind of Transfer Object which carries "Source" and "eventName", so that we can load module appropriately.
public class Message{
private String source;
private String eventName;
}
Module configurations are as below
<modules>
<module>
<source>A</source>
<eventName>validate</eventName>
<moduleClass>ValidatorModule</moduleClass>
</module>
<module>
<source>B</source>
<eventName>generate</eventName>
<moduleClass>GeneratorModule</moduleClass>
</module>
</modules>
ModuleLoader.java
public class ModuleLoader {
public void loadAndProcess(Message message){
String source=message.getSource();
String eventName=message.getEventName();
//Load Module based on above values.
}
}
Question
Now , if i want to implement same via CDI to inject me a Module (in ModuleLoader class), I can write Factory class with #Produce method , which can do that. BUT my question is,
a) how can pass Message Object to #Produce method to do lookup based on eventName and source ?
Can you please provide me suggestions ?
Thanks in advance.
This one is a little tricky because CDI doesn't work the same way as your custom solution (if I understand it correctly). CDI must have all the list of dependencies and resolutions for those dependencies at boot time, where your solution sounds like it finds everything at runtime where things may change. That being said there are a couple of things you could try.
You could try injecting an InjectionPoint as a parameter to a producer method and returning the correct object, or creating the correct type.
There's also creating your own extension of doing this and creating dependencies and wiring them all up in the extension (take a look at ProcessInjectionTarget, ProcessAnnotatedType, and 'AfterBeanDiscovery` events. These two quickstarts may also help get some ideas going.
I think you may be going down the wrong path regarding a producer. Instead it more than likely would be much better to use an observer especially based on what you've described.
I'm making the assumption that the "Message" transfer object is used abstractly like a system wide event where basically you fire the event and you would like some handler defined in your XML framework you've created to determine the correct manager for the event, instantiate it (if need be), and then call the class passing it the event.
#ApplicationScoped
public class MyMessageObserver {
public void handleMessageEvent(#Observes Message message) {
//Load Module based on above values and process the event
}
}
Now let's assume you want to utilize your original interface (I'll guess it looks like):
public interface IMessageHandler {
public void handleMessage(final Message message);
}
#ApplicationScoped
public class EventMessageHandler implements IMessageHandler {
#Inject
private Event<Message> messageEvent;
public void handleMessage(Message message) {
messageEvent.fire(message);
}
}
Then in any legacy class you want to use it:
#Inject
IMessageHandler handler;
This will allow you to do everything you've described.
May be you need somthing like that:
You need the qualifier. Annotation like #Module, which will take two paramters source and eventName; They should be non qualifier values. See docs.
Second you need a producer:
#Produces
#Module
public Module makeAmodule(InjectionPoint ip) {
// load the module, take source and eventName from ip
}
Inject at proper place like that:
#Inject
#Module(source="A", eventName="validate")
Module modulA;
There is only one issue with that solution, those modules must be dependent scope, otherwise system will inject same module regardles of source and eventName.
If you want to use scopes, then you need make source and eventName qualified parameters and:
make an extension for CDI, register programmatically producers
or make producer method for each and every possible combinations of source and eventName (I do not think it is nice)
I have a class marked as CollectionDataContract which has a enum member. When I place an object of this class in Appfabric, I am through. When I get it back from App fabric, it does not deserialize the enum member. But I am not sure if the enum has been missed out in Serialization part itself.
Please do help.
If you need more information let me know.
Thanks.
[CollectionDataContract]
public partial class RuleConditionList : List<IRuleCondition>, IRuleCondition
{
public LogicalOperator Operator;
}
where LogicalOperator is an enum
I think there is a problem when serializing/deserializing your object. AppFabric uses the NetDataContractSerializer class for serialization before storing the items in the cache.
You can use the NetDataContractSerializer on any type which are marked with the DataContractAttribute or SerializableAttribute, or types that implement the ISerializable interface.
So depending and your object, there should be something wrong like a private type, a private field, a missing attibute, ...
Edit
You should add DataMember to your field.
[DataMember]
public LogicalOperator Operator;
Any data member in a class marked with Collection data contract cannot be serialized by NetdataContractSerializer which is the serailization technique used by App fabric for storing data.
To make things work we have two options:
Make a wrapper for RuleConditionList
Instead of Inheriting from List, make it as a property and change the attribute as DataContract.