I am currently developing a system that uses XStream to create objects from XML. An example object would be
#XStreamAlias("TestClass")
public class TestClass{
#XStreamAlias("format")
private String format;
public String getFormat(){
return format;
}
public void setFormat(String format){
this.format = format;
}
}
This class has one field, a format field, and the XML from which it would be constructed would look like:
<TestClass>
<format>foo</format>
</TestClass>
Now I would like to instantiate different instances of this class, with a specific format. For instance I would like a TestClass object with format foo and one with format bar. But instead of producing
<TestClass>
<format>foo</format>
</TestClass>
<TestClass>
<format>bar</format>
</TestClass>
I want to use an alias system of some sort so that the above XML would not be necessary but instead I could use
<TestClassFoo />
<TestClassBar />
where of course the name does not need to include the format specified.
I see that there has to be a custom converter, but I again do not want to hard code every alias, but instead load these from XML as well (yes, it get complicated). The result of this would be to create shortcut templates for different XML objects, which can be configured dynamically.
If your goal is more compact XML, why not use #XStreamAsAttribute so you will get output like <TestClass format="foo"/>? Otherwise, yes, you are going to have to write a custom converter to do exactly what you want.
Related
I went through some of the samples that have used libraries to generate bean classes from JSON, XML etc. What I would like to know is, whether there's a way to dynamically generate a java bean class, with the parameters I give?
For example if I give an array of Strings as arguments which would represent the properties of the Pojo class for now, how can I generate the POJO?
Arguments: {"field1", "field2", "field3"}
Generate POJO would be:
public class TestBean {
private String field1;
TestBean() {
}
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
}
It should be the same for field2 and field3 as well.
Here I'm assuming that all the properties above are String and the class name is constant for now. Is there any way I can achieve this? Thanks in advance.
The problem with generating an actual Java class at runtime is that there is no way you can access it using standard Java syntax as the compiler doesn't know about it.
In practice therefore, most people just use a map in this circumstance. The only case I can think where you would need to generate a real class is where there is some other code you can't change that requires a Java object and inspects it dynamically using reflection or otherwise.
If you don't need this you are better off using a map, or possibly some utility class designed to emulate a Java Bean.
The Apache BeanUtils package provides the DynaBean interface to implement dynamic Java Beans. That said, the classes are only recognised as beans if accessed from the rest of the BeanUtils package.
There are several subclasses depending on what you want, for example, LazyDynaBean:
DynaBean myBean = new LazyDynaBean();
myBean.set("myProperty", "myValue");
I know that there are easy ways of binding for example an XML file to a bean. In contrast to that, I am looking for a library that allows me to specify some regex for parsing an entire file. I am thinking of something like:
#FileFormat("${value1};${value2};${num}")
class FileBean {
private String value1;
private String value2;
private Integer num;
// Getters and setters...
}
public List<FileBean> read(File file) {
return SomeUtility.read(file, FileBean.class);
}
public void write(File file, List<FileBean> list) {
SomeUtility.read(list, new File("./target"));
}
with a file containing data in the format of ${value1};${value2};${num} such as:
foo;bar;123
bar;foo;494
Does somebody know if such a library that does what I suggest for SomeUtility exists already? I am bound to a number of third-party file formats for data exchange. Would be great if there was something sufficiently generic. (I know this resembles CSV but I am looking for something more flexible.)
Well, there is now: https://github.com/raphw/declarative-parser
This tool allows to define a parser declaratively by annotations.
In an android application I'm developing I need to get a json file containing some data to reconstruct the lines of code of a java class.
Is there any java/javascript library that allows to convert/parse a java class (that doesn't just have fields, but also methods defined inside it) in JSON format, and vice-versa?
EDIT: I'd also need to keep track of the whole project's structure (something like antlr?)
EDIT2: My bad, I wanted to store a java class code into a JSON object to represent it, I was also thinking to create my own json object, this way, by parsing the Java code and finding methods, classes, parameters.
{
"file": "PATH/TO/.java",
"language": "java",
"from": 0,
"to": 255,
"classes": [
"Test:2"
//...
],
"lines": [
[
"public class Test{"
//...
]
]
}
But if a good starting point is present, that would be great.
The trouble is that existing tools (such as GWT) are "only" able to create functioning JS code that is meant to be executed in browsers. But it does not necessarily resemble the original Java class. Your use case sounds quite different. It looks like you want to represent Java source code as JSON data and you don't need/want to execute it.
I fear you may have to create your own tool for that, that meets your specific requirements. I also fear that this tool must be able to parse the Java code because using simple regexes for extracting the data won't help here much because of nested types (interfaces, classes, enums) and also because a single Java file may contain multiple type declarations (even though not encouraged, but it is possible).
Here are a few links for Java parsers:
http://code.google.com/p/javaparser/ (unfortunately only Java 1.5)
http://www.ibm.com/developerworks/opensource/library/os-ast/ (discusses the Eclipse Java parser which is very robust and probably most suitable for your requirement)
You could also create your own parser using ANTLR as you suggest. The latest ANTLR version has some visitor pattern you need to implement in Java, as far as I know. You could implement a visitor that successively constructs your JSON output.
However, you really should use Eclipse's ASTParser for that, because you can easily iterate all methods of your class and get their implementation code as String.
You can use jackson library - http://jackson.codehaus.org/: http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
Use GSON: "GOOGLE for JSON" it's a google open source JSON Library, it can convert Java Object t o JSON object and vice-versa
You have Gson package that convert Json String to Java object and vice versa.
MyClass.java
public class MyClass {
private String mStr = "";
public String getStr() {
return mStr;
}
public void setStr(String mStr) {
this.mStr = mStr;
}
}
Main.java
public class Main {
public static void main(String[] args) {
String jsonString = "{ \"mStr\": \"foo\" }";
Gson mGson = new Gson();
MyClass res = mGson.fromJson(jsonString, MyClass.class);
System.out.println(res.getStr());
}
}
Output: foo
[Edit 1]
You can't store to Json class structure, only data
[Edit 2]
From your fix I understand followed thing:
This Json String represents behavior what to do with "text" file , suppose, you download from server. But no mater what inside Json String 1st of all you need to convert it to Object in Java (if you want to use Java) and after that according to rules (took from Json String) write any logic. For sure java code is able to generate Java files. Your example tells you:
to get text from line ... to line,
create file named xxxx.java
copy it to ...
So use my example above, create class, lets say Launcher:
public class Launcher{
private String file;
private String language;
private int from;
private int to;
private List<String> classes;
private List<SomeOtherClass> lines;
....
}
I want to save a Java class named MyClass into a text file and I want to use JSON to encode the class for file writing purposes instead of implementing the Serializable interface. Moreover, to save the class I want to use the Google's Gson library and in particular the JsonWriter class. The MyClass class is, for instance, defined as follows:
public class MyClass{
String html;
public MyClass(){}
}
As shown in the example above, MyClass has a String field named html, that obviously must contain HTML code.
Can I save the class into a text file by using JSON via the JsonWriter or I should encode or do something similar with the html field (e.g. a call to an URLEncode-like function) before to give it to JsonWriter?
Since escaping new lines / quotes etc can make this a little tricky, why not just use XStream to convert the object to XML and wrap the HTML in a CDATA section ? Json has no equivalent for a CDATA section.
I have a bunch of third-party Java classes that use different property names for what are essentially the same property:
public class Foo {
public String getReferenceID();
public void setReferenceID(String id);
public String getFilename();
public void setFilename(String fileName);
}
public class Bar {
public String getRefID();
public void setRefID(String id);
public String getFileName();
public void setFileName(String fileName);
}
I'd like to be able to address these in a canonicalized form, so that I can treat them polymorphically, and so that I can do stuff with Apache BeanUtils like:
PropertyUtils.copyProperties(object1,object2);
Clearly it would be trivial to write an Adapter for each class ...
public class CanonicalizedBar implements CanonicalizedBazBean {
public String getReferenceID() {
return this.delegate.getRefID();
}
// etc.
}
But I wonder is there something out there more generalized and dynamic? Something that would take a one-to-many map of property name equivalences, and a delegate class, and produce the Adapter?
I've never used it, but I think you're looking for Dozer:
Dozer is a Java Bean to Java Bean mapper that recursively copies data
from one object to another. Typically, these Java Beans will be of
different complex types.
Dozer supports simple property mapping, complex type mapping,
bi-directional mapping, implicit-explicit mapping, as well as
recursive mapping. This includes mapping collection attributes that
also need mapping at the element level.
Dozer not only supports mapping between attribute names, but also
automatically converting between types. Most conversion scenarios are
supported out of the box, but Dozer also allows you to specify custom
conversions via XML.
First Option is Dozer.
Second option is Smooks Framework
with a tweak. It will be beneficial to use Smook's Graphical mapper.
Another option would be XStream with custom Mapper.
maybe something like that:
public class CanonicalizedBar implements CanonicalizedBazBean {
public String getReferenceID() {
Method m = this.delegate.getClass().getDeclaredMethod("getReferenceID");
if(m == null)
m = this.delegate.getClass().getDeclaredMethod("getRefID");
...
return m.invoke();
}
// etc.
}
Although, I personally have never used it. I noticed that a project called orika is noted as having the best performance and the ability to automatically understand many such mappings.
At any rate it also supports custom mappings and uses generated code to implicitly define the adapters.
You can also define a custom mapper, that is if you know how to canonize the member names you can use that knowledge to build a mapping that is true for all your objects. for instance:
DefaultFieldMapper myDefaultMapper = new DefaultFieldMapper() {
public String suggestMapping(String propertyName, Type<?> fromPropertyType) {
// split word according to camel case (apache commons lang)
String[] words= StringUtils.splitByCharacterTypeCamelCase(propertyName);
if(words[0].length() > 6) {
// trim first camel-cased word of propery name to 3 letters
words[0]= words[0].substring(0,2);
return StringUtils.join(words);
} else {
// remains unchanged
return propertyName;
}
}
}
mapperFactory.registerDefaultFieldMapper(myDefaultMapper );
I haven't done much with it but you may be able to use Aspect Oriented Programming to do this.
What you should be able to do I think is add a method to each of the classes that internally calls the real method. See this article about half way down it talks about mixins.
AspectJ is probably the most popular implementation.