jsonschema2pojo not generating pojo classes from json string - java

I was following the link Generate Java class from JSON? to create the POJO classes from json string (and not from schema). I am using jsonschema2pojo jar of version 0.4.10 but could not able to generate the POJO class.
My code is as below,
public class App
{
public static void main( String[] args )
{
JCodeModel codeModel = new JCodeModel();
try {
URL source = new URL("file:///C://Users//...//accession.json");
new SchemaMapper().generate(codeModel, "Accession", "com.test", source);
File dir = new File("D://test");
if(dir.exists()){
System.out.println("dir available");
codeModel.build(dir);
}else{
System.out.println("dir not available");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
So accession.json has json string which need to be converted into POJO. Can anybody please help me here.

I had a similar experience using the command-line tool. In my case, it was the result of not correctly specifying the source type (JSONSCHEMA or JSON; default: JSONSCHEMA).
I think your problem is similar: You're using the default (no-args) constructor for SchemaMapper. The following steps should solve the problem:
Subclass org.jsonschema2pojo.DefaultGenerationConfig, overriding getSourceType() to return SourceType.JSON
Use an instance of that subclass for the SchemaMapper(RuleFactory ruleFactory, SchemaGenerator schemaGenerator) constructor (instead of the no-args constructor).

Once I faced the same problem and then I resolved this.
In your code you are using Default Configuration which takes Source Type Jason Schema.
But when You are giving input Jason you have to set this return type in this way :
SourceType.JSON in your Configuration.
class App
{
public static void main( String[] args )
{
JCodeModel codeModel = new JCodeModel();
try {
URL source= new URL("file:///D:/temp.json");
GenerationConfig config = new DefaultGenerationConfig() {
#Override
public boolean isGenerateBuilders() {
return true;
}
public SourceType getSourceType(){
return SourceType.JSON;
}
};
SchemaMapper mapper =new SchemaMapper(new RuleFactory(config, new GsonAnnotator(), new SchemaStore()), new SchemaGenerator());
mapper.generate(codeModel, "Accession", "com.test", source);
File dir = new File("D://");
if(dir.exists()){
System.out.println("dir available");
codeModel.build(dir);
}else{
System.out.println("dir not available");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I hope It will help you..
Good Luck !!

I also struggled a bit with this. I did the following in the end:
Created my own GenerationConfig, overriding getSourceType:
static class MyConfig extends DefaultGenerationConfig {
#Override
public SourceType getSourceType() {
return SourceType.JSON;
}
}
I then initialised the build process as follows:
private void parseFileExample() {
URL source = new URL("file:/tmp/input/blah.json");
JCodeModel codeModel = new JCodeModel();
MyConfig generationConfig = new MyConfig();
RuleFactory ruleFactory = new RuleFactory(generationConfig, new GsonAnnotator(), new SchemaStore());
SchemaGenerator generator = new SchemaGenerator();
SchemaMapper mapper = new SchemaMapper(ruleFactory, generator);
mapper.generate(codeModel, "MyClass", "com.drakedroid", source);
codeModel.build(new File("/tmp/output/"));
}
The trick here was, to use an URL. The mapper.generate didn't work when I passed in just a string.

Thanks #Kapil, your answer helped me.
This program allows us to generate POJO classes according to predefined JSON.
We can also use it at runtime, where JSON response is not known, write the JSON response to the file and read it accordingly using the following code.
public class JSONExample {
public static void main(String... args) {
JCodeModel codeModel = new JCodeModel();
try
{
// In sample.json I have already pasted a JSON
File file=new File("//root//AndroidStudioProjects//MyApplication//sample.json");
URL source = file.toURI().toURL();
GenerationConfig config = new DefaultGenerationConfig() {
#Override
public boolean isGenerateBuilders()
{
return true;
}
public SourceType getSourceType()
{
return SourceType.JSON;
}
};
SchemaMapper mapper = new SchemaMapper(new RuleFactory(config, new Jackson2Annotator(), new SchemaStore()), new SchemaGenerator());
try {
// The ClassName is the main class that will contain references to other generated class files
// com.example is the package name
mapper.generate(codeModel, "ClassName", "com.example", source);
} catch (IOException e) {
e.printStackTrace();
}
try {
// Directory where classes will be genetrated
File file1=new File("//root//AndroidStudioProjects//MyApplication//");
if (file1.exists())
{
System.out.println("dir available");
codeModel.build(file1);
}
else
{
System.out.println("dir not available");
}
System.out.println(""+file1+" Exists "+file1.exists());
} catch (IOException e) {
e.printStackTrace();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

Related

How to load saved item from JSON file in java

I am making an app where user can change theme (dark and light mood) as per his convenience. And the theme that the user chooses will be saved and the saved theme will be there when the app is opened again later.
I have saved the data to file using JSON.
And when the user clicks on the theme change button, the data will be written to the file.
The code of the theme:
private void darkTheme() {
FlatDarkLaf.setup();
UIManager.put("TextField.foreground", new ColorUIResource(Color.WHITE));
UIManager.put("Label.foreground", new ColorUIResource(Color.WHITE));
UIManager.put("Button.foreground", new ColorUIResource(Color.WHITE));
SwingUtilities.updateComponentTreeUI(contentPane);
for(int i=0; i<arList.size(); i++) {
((JLabel)arList.get(i).getRenderer()).setHorizontalAlignment(SwingConstants.CENTER);
}
}
And the Code for the theme change and write to the file button:
btnDark.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String path = "resources/config.cfg";
JSONObject json = new JSONObject();
try {
json.put("Theme", "darkTheme();");
} catch (JSONException ex) {
ex.printStackTrace();
}
try (PrintWriter out = new PrintWriter(new FileWriter(path))) {
out.write(json.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
darkTheme();
}
});
I can read the file but can't Load the save data.
Here the code for read the file:
private void readData() {
try {
String path = "resources/config.cfg";
InputStream is = Button.class.getResourceAsStream(path);
if (is == null) {
throw new NullPointerException("Cannot find resource file " + path);
}
JSONTokener tokener = new JSONTokener(is);
JSONObject object = new JSONObject(tokener);
// object.getString("darkTheme();");
object.getJSONObject("Theme");
}
catch (Exception e) {
}
}
Can anyone please help me how to do this correctly.
Ok Finally I've got a solution by my own and someone's idea.
I have changed the line in btnDark
json.put("Theme", "darkTheme();");
to
json.put("Theme", "Dark");
and in the readData() method I write like this
private void readData() {
String jsonText;
try {
String path = "resources/config.cfg";
jsonText = IOUtils.toString(new FileInputStream(new File(path)));
int i = jsonText.indexOf("{");
jsonText = jsonText.substring(i);
JSONObject ob = new JSONObject(jsonText);
String Theme = ob.getString("Theme");
if(Theme.equals("Dark")) {
darkTheme();
}
else if(Theme.equals("Light")) {
lightTheme();
}
}catch(Exception ex) {
ex.printStackTrace();
}
}
And now it's work perfectly

How to load the correct language (set in config) instead of the language last in an array

I'm creating a little java app and I'm trying to load the yml files based on config.yml lang set (en/it) but I can't find a way to load them, only the last one in an array is loaded which is "it" for me.
I know that my method is probably the worst solution for a language file, I'm open to every method that will help me with the problem. But I prefer an external lang_en/it file instead of internal ones (Or is it better internal?)
After I set the language, the app will self-update every text in every class.
static final Properties props = new Properties();
static WelcomeMessage main = new WelcomeMessage();
static File file = null;
static File folder = null;
static boolean os = main.os.startsWith("Windows");
public static void create() {
String[] lang = {"en", "it"};
for (String s : lang) {
file = new File(WelcomeMessage.user + "/AppData/Roaming/MyApp/lang_" + s + ".yml");
folder = new File(file.getParent());
SetLanguages(s);
}
if (!file.exists()) {
try {
if (os) {
folder.mkdir();
file.createNewFile();
} else {
file = new File(main.user + "/Library/Application Support/MyApp/config.yml");
folder.mkdir();
file.createNewFile();
}
} catch (Exception e) {
System.out.println(e + " " + file);
}
}
}
public static void SetLanguages(String lang) {
if (lang.equals("en")) {
store("Settings.Save", "Save");
store("Settings.ConfigPath", "Config Path");
store("Settings.Language", "Language");
store("Settings.Title", "Settings");
} else if (lang.equals("it")) {
store("Settings.Save", "Salva");
store("Settings.ConfigPath", "Percorso config");
store("Settings.Language", "Lingua");
store("Settings.Title", "Impostazioni");
}
}
public static String get(String value) {
String key = null;
try {
FileInputStream in = new FileInputStream(file);
props.load(in);
key = props.getProperty(value);
in.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
return key;
}
public static void store(String value, String key) {
try {
FileOutputStream out = new FileOutputStream(file);
props.setProperty(value, key);
props.store(out, null);
out.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
}
This is how I get a text from yml:
path.setText(Language.get("Settings.ConfigPath"));
language.setText(Language.get("Settings.Language"));
f.setTitle(Language.get("Settings.Title"));
save.setText(Language.get("Settings.Save"));
And this my Language.get(key)
public static String get(String value) {
String key = null;
try {
FileInputStream in = new FileInputStream(file);
props.load(in);
key = props.getProperty(value);
in.close();
} catch (Exception fnf) {
System.out.println(fnf);
}
return key;
}
I suggest the following changes:
Create a Settings class to hold the properties save, configPath, language and title. Even better if this class uses an immutable builder pattern, because once set, the properties will never change.
Create a SettingsFactory class with method getSettings(language). This class shall also have a field Map<String, Settings>. In the constructor (or a static block), first check if a file exists on the disk, and if yes, load it into the map. If not, populate the map, one entry for each language, and persist to the disk.
getSettings would simply return the value from the map corresponding to the given language.
The format of the file written to the disk is a different matter. You say YAML, but I'm not seeing any YAML specific code in your snippet. If you don't know how to write a map to YAML, open a different question.

Freemarker encoding wrong

I have project it's jetty server which use freemarker. I use russian letters in my templates and receive ?. All subjects i have read before didn't help me.
I use in my code
.setContentType("text/html;charset=utf-8");
.setCharacterEncoding("UTF-8");
all my files is utf-8.
My Freemarker page genertor servlet
public class PageGenerator {
private static PageGenerator pageGenerator;
private Configuration cfg;
public static PageGenerator instance() {
if (pageGenerator == null)
pageGenerator = new PageGenerator();
return pageGenerator;
}
public String getPage(String filename, Map<String, Object> data) {
Writer stream = new StringWriter();
try {
Template template = cfg.getTemplate(filename);
template.process(data, stream);
} catch (IOException | TemplateException e) {
e.printStackTrace();
}
return stream.toString();
}
private PageGenerator() {
cfg = setCfg();
}
private Configuration setCfg(){
cfg = new Configuration(Configuration.VERSION_2_3_20);
try {
cfg.setDirectoryForTemplateLoading(new File("templates/"));
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
} catch (IOException e) {
e.printStackTrace();
}
return cfg;
}
}
But in brouser my page in windows-1252 encoding.
Thanks for idea ddekany I used debag mode and find out that Class Response that extends HttpServletResponse has "magic" method .setCharacterEncoding() which set Character Encoding in response stream

Java Dynammic Class loading inside webapp

I made a java project, the project only contais this class:
package test.processor;
public abstract class Processor {
public abstract void loadData(String objectId);
public abstract void processData();
public abstract void saveData(String objectId);
}
The project is exported as a jar file (processor.jar)
Then I made another project that imports processor.jar and there is a class that extends Processor:
package test.process;
import test.processor.Processor;
public class Process extends Processor{
#Override
public void loadData(String objectId) {
System.out.println("LOAD DATAAAAAAAAAAAA");
}
#Override
public void processData() {
System.out.println("PROCESS DATAAAAAAAAAAAA");
}
#Override
public void saveData(String objectId) {
System.out.println("SAVE DATAAAAAAAAAAAA");
}
}
This project is also exported as jar (plugin.jar).
Finally, I coded something to load the plugins dynamically:
import test.processor.Processor;
public class Test {
public void testPlugins(){
Processor plugin = (Processor) loadJar(
"C:\\Users\\...\\Desktop\\plugin.jar",
"test.process.Process");
processor.loadData("dada");
}
private Object loadJar(String jar, String className){
File jarFile = new File(jar);
Object instance = null;
try {
URL jarpath = jarFile.toURI().toURL();
String jarUrl = "jar:" + jarpath + "!/";
URL urls[] = { new URL(jarUrl) };
URLClassLoader child = new URLClassLoader(urls);
Class classToLoad = Class.forName(nomeClasse, true, child);
instance = classToLoad.newInstance();
} catch (Exception ex) {
ex.printStackTrace();
}
return instance;
}
}
If I run that code inside a main method it works correctly, once I try to run it in the server there is a problem when loading the class, I get a ClassNotFoundException (Processor).
I tried putting the jar in the tomcat/lib, project/WEB-INF/lib and nothing changed.
Any idea of what Im doing wrong?
I didn't solve it the way I wanted, but I solved it:
First I tried loading the process.jar manually:
private Object loadJars(String processJar, String pluginJar, String className){
File processJarFile = new File(processJar);
File pluginJarFile = new File(pluginJar);
Object instance = null;
try {
URL processJarPath = processJarFile.toURI().toURL();
String processJarUrl = "jar:" + processJarPath + "!/";
URL pluginJarPath = pluginJarFile.toURI().toURL();
String pluginJarUrl = "jar:" + pluginJarPath + "!/";
URL urls[] = { new URL(processJarUrl), new URL(pluginJarUrl) };
URLClassLoader child = new URLClassLoader(urls);
Class classToLoad = Class.forName(nomeClasse, true, child);
instance = classToLoad.newInstance();
} catch (Exception ex) {
ex.printStackTrace();
}
return instance;
}
That loads the Process class correctly, the problem happens in the testPlugins mehod, once it tries to cast to Processor (ClassCastException, can't cast Process to Processor):
public void testPlugins(){
Processor plugin = (Processor) loadJars("C:\\Users\\...\\Desktop\\processor.jar",
"C:\\Users\\...\\Desktop\\plugin.jar",
"test.process.Process");
processor.loadData("dada");
}
Still need to read a lot about classloading but I guess the problem is that it doesn't recognize the Processor loaded from C:\Users\...\Desktop\processor.jar as the same as the Processor loaded from the webapp context or it "forgets" Process extends Processor.
I was in a hurry so I didn't have time to research, to solve the problem I invoked the methods using reflection:
public void modifiedTestPlugins(){
Object plugin = loadJar("C:\\Users\\...\\Desktop\\processor.jar",
"C:\\Users\\...\\Desktop\\plugin.jar",
"test.process.Process");
try {
Method processData = findMethod(obj.getClass(), "processData");
//here I invoke the processData method, it prints: PROCESS DATAAAAAAAAAAAA
loadData.invoke(processData, new Object[]{});
} catch (Exception e) {
e.printStackTrace();
}
}
private static Method findMethod(Class clazz, String methodName) throws Exception {
Method[] methods = clazz.getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals(methodName))
return methods[i];
}
return null;
}

JAXB is not generating the required schema for a class that contains generated Java classes?

I have this class
#XmlRootElement
public class GpsDataRequest{
//definition of variables
#XmlElement(required=true, type=GpxType.class)
public GpxType getGpxRoot() {
return gpxRoot;
}
#XmlElement(required=true, type=JourneyXML.class)
public JourneyXML getJourneyPlanRoot() {
return journeyPlanRoot;
}
#XmlElement(required=true)
public String getSecurityToken() {
return securityToken;
}
#XmlElement(required=true)
public UUID getUuid() {
return uuid;
}
}
When i generate the schema using this code:
public class SchemaGenerator {
public static void main(String[] args)
{
try {
JAXBContext context=
JAXBContext.newInstance(GpsDataRequest.class);
SchemaOutputResolver sor =new DemoSchemaOutputResolver();
context.generateSchema(sor);
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static class DemoSchemaOutputResolver extends SchemaOutputResolver {
#Override
public Result createOutput(String namespaceUri, String suggestedFileName)
throws IOException {
// create new file
File file = new File("request.xsd");
// create stream result
StreamResult result = new StreamResult(file);
// set system id
result.setSystemId(file.toURI().toURL().toString());
// return result
return result;
}
}
}
All I get is the XSD of the GpxType class only. Why is that?
Just to let you know, GpxType and JourneyXML are generated from XSD files.
How to enforce this to generate the appropriate XSD I need?
Try changing your createOutput method to not always write to the request.xsd file. I believe there are multiple namespaces in your model and therefore multiple XML schemas are being generated.
#Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
// create new file
File file = new File(suggestedFileName);
// create stream result
StreamResult result = new StreamResult(file);
// set system id
result.setSystemId(file.toURI().toURL().toString());
// return result
return result;
}

Categories

Resources