I have an XML defined which provides a payload path to a serialized XML. I would like to take these parameters and create an object and call a method in a class. What is the best approach to do this in Java?
XML
<RequestObjectType>com.test.model.QueryType</RequestObjectType>
<Class>com.test.api.Query</Class>
<Method>generalQuery</Method>
public void callRequestViaObj(String payloadXML, String payloadType, String api_className, String method){
Class c_payloadType = Class.forName(payloadType);
Class c_apiClass = Class.forName(api_className);
JAXBElement<c_payloadType> elemreq = (JAXBElement<c_payloadType>) JaxbUtils.XMLtoObj( payloadXML, JAXBContext.newInstance(c_payloadType) );
c_payloadType qreq = (c_payloadType) (elemreq.getValue());
//Would like to do something like this...
c_payloadType.newInstance().callMethod(method).with(qreq);
}
have a look at the reflection-api:
http://java.sun.com/developer/technicalArticles/ALT/Reflection/
section "Invoking Methods by Name"
There are many tools that will do this for you. One of them is Castor.
It looks like you just need to tweak the calls that use the reflection API. Try
c_payloadType.newInstance().getMethod(method, qreq.getClass()).invoke(qreq);
This assumes that c_payloadType is an instance of Class<?> and qreq is the argument you want to pass to the method call. I'm not sure if the JAXB code you've written correctly constructs those two objects.
Related
Is it possible to use RestEasy's Path annotation to get the following string:
/items.json
I was thinking something like this: /items{(\.)?format}, where format could be json, xml etc.
I would then have a method with an argument like: #PathParam("format") String format.
Thanks.
I managed to make the following work with my use case: item{format:(\.(json|xml))?}
I chose to make the reg exp restrictive so as not to have to handle unsupported or invalid formats inside the actual service method, but if one prefers a more general approach I think that instead of (json|xml) one can add \S+.
you might want to create two methods, one for the default type and one for the optional types but yes, your logic should work:
#Path(items.{format})
public Response getItems(#PathParam("format") String format) {
}
#Path(items)
public Response getItems() {
return getItems("json");
}
Programming in Java, what's the better way to create resource files to save the messages of the application in different languages?
If I use a properties file, inside the code everytime that I need refer to a message I have to write something like that:
ResourceBundle.getBundle("test.messages.messageFile").getString("Message1")
Exists another form to use messages and generate a code cleaner? Maybe create a class with static constants that refer to this messages?
you can use ResourceBundle, but declare it and use it as a variable.
ResourceBundle languageBundle=ResourceBundle.getbundle("test.messages.messageFile");
//later in your code you can say
languageBundle.getString("Message1");
it would help if you make this variable public static
This is the standard way. But nothing forces you to not store the bundle in a field:
private ResourceBundle messages = ResourceBundle.getBundle("test.messages.messageFile");
...
String message1 = messages.getString("Message1");
You may also encapsulate it into a Messages class that has the following method:
public String getMessage1() {
return messages.getString("Message1");
}
It's all up to you.
you can try Internationalization made easier.
This is based on annotations and gives type safety for argument substitution.
Say I follow the Single Responsibility Principle and I have the following classes.
public class Extractor {
public Container extract(List<Container> list) {
... some extraction
}
}
public class Converter {
public String convert(Container container) {
... some conversion
}
}
As you can see it's following the principle and all the names of the classes/methods tell what they do. Now I have another class that has a method like this.
public class SomeClass {
private Extractor extractor = new Extractor();
private Converter converter = new Converter();
private Queue queue = new Queue();
public void someMethod(List<Container> list) {
Container tmp = extractor.extract(list);
String result = converter.convert(tmp);
queue.add(result);
}
}
As you can see the "someMethod"-Method does call extract, convert and add. My question is now, how do you call such a class/method? It's not actually extracting, converting or adding but it's calling those?
If you name the method after its responsibility what would that be?
Well since you seem to add to a queue and you don't return anything I'd call it addToQueue. The fact that you convert + extract is implementation detail that I don't think needs to be exposed.
What about processAndQueueMessage?
Also (not related), you shouldn't create (using new) the Extractor and Converter in your SomeClass, you should rather inject them (at construction or in setters), and use interfaces to them. That will make it easier to test, and reduce coupling between implementations.
// Assuming Converter and Extractor are interfaces to the actual implementations
public class SomeClass {
private final Extractor extractor ;
private final Converter converter;
private Queue queue = new Queue();
public SomeClass(Extractor extractor, Converter converter) {
this.converter = converter;
this.extractor = extractor;
}
public void someMethod(List<Container> list) {
Container tmp = extractor.extract(list);
String result = converter.convert(tmp);
queue.add(result);
}
}
And you create it using:
final SomeClass myProcessor = new SomeClass(new MyExtractorImplementation(), new MyConverterImplementation());
(Or use a DI container, like Spring or Pico)
What you do is think about the composite meaning of the sequence of method calls, turn that into a concise verb or verb phrase and use that as the name. If you can't come up with a concise name then you could use a generic / neutral name (like "process") or use something completely bogus (like "sploddify").
If you want the name to be really generic, I'd go with addToQueue() or populateQueue() since getting something into that object seems to be the point of the method.
But really at that level I'd call it by what business logic it's trying to accomplish, in which case the name really depends on what it's being used for.
If you can't come up with a good name, it is an indication that your procedural abstraction is rather arbitrary / artificial, and a possible hint that there might be a better way to do it. Or maybe not.
Sounds like some kind of builder class. You get data in one format, convert it and then create some kind of output format. So how about "SomethingSomethingBuilder"?
I'm assuming someone downvoted me because I forgot to provide a good name for the method. Sorry about that.
So this method adds incrementally data into your builder class. I would call it, "Add", "AddData" or "Push" (I'd probably go with push because that has very similar meaning in many standard classes).
Alternative to "Builder" could potentially be "SomeKindOfCreator". Obviously you would name it based on whatever it is your class is actually creating.
Okay, so, here's what I have in code:
public void makeObject(int i){
String s = getString(i); //This returns the name of a class
new s(); //This is what I want to do
}
Can I do this?
No you can't do this, but what you're probably looking for is called 'reflection'.
Look at these series of (free) slides: http://www.slideshare.net/CiaranMcHale/java-reflection-explained-simply especially slide 11, but read the ones before that as well. It will give you an idea of what reflection is and a way to make a class by knowing the name (as a string) and how to instantiate a new instance of that class.
You can also find methods and fields by name, you can even modify existing classes in code.
Edit: for example the following code will return a class by string name
Class cls = Class.ForName("MyPackage.MyClassName");
return cls.NewInstance();
code snippet:
for( String token : tokens )
{
try
{
Url url = as("mycompany", "someapikey").call(shorten(token));
}
}
what do the 'as' and the 'call' mean. Are they keywords in java?
i was browsing and i found this code and i would like to understand what it means.
thank you in advance.
Looks like it's using the bit.ly library to shorten URLs. the for loop is iterating through strings in a collection, tokens. it then creates a shortened URL via the bit.ly library. These aren't keywords in Java, they are just method names.
android bit.ly library: http://code.google.com/p/bitlyj/
No, they are regular methods. The as() method should be in the class this is from (or a superclass), while the call() method is defined for the type returned by as().
It would be helpful to have a link back to the original source where you found this, as more context is often useful.
as and call are not keywords in Java.
It seems that as(String s1, String s2) is a method that returns an object that has a method call(..).
That method call(..) is invoked on the return value of as(..).
Maybe a static import?
For example, if class Foo has a static method as(), you can use
import static Foo.as;
{
//now can do this:
as(); //equal to Foo.as();
}