
com.sta.cts.JSONGenerator Maven / Gradle / Ivy
package com.sta.cts;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.Date;
import com.sta.mlogger.MLogger;
/**
* Name: JSONGenerator
* Description: .
*
* Comment: ...
*
* Copyright: Copyright (c) 2018, 2019, 2021
* Company: >StA-Soft<
* @author StA
* @version 1.0
*/
public class JSONGenerator implements AutoCloseable
{
/**
* Der BufferedWriter f?r die aktuelle Ziel-JSON-Datei.
*/
private BufferedWriter bw;
/**
* Anzahl der Spalten = Breite der Einr?ckung.
*/
private int sp;
/**
* Aktuelle Spalte in der JSON-Datei.
*/
private int col;
/**
* Angabe, ob das n?chste Element das erste in einem Object oder in einem Array ist
* (true: erstes Element, also kein "," schreiben, false: Folgeelement, also zuvor ein "," schreiben).
*/
private boolean first;
//===========================================================================
/**
* Standard-Constructor: Zum Instantiieren eines JSON-Generators.
*/
public JSONGenerator()
{
}
//===========================================================================
/**
* String pStrg schreiben, ohne CRLF. Dabei wird die Spalte col mitgez?hlt.
* @param pStrg der zu schreibende String
* @exception IOException falls ein Schreibfehler auftritt
*/
protected void write(String pStrg) throws IOException
{
bw.write(pStrg);
col += pStrg.length();
}
/**
* String Strg schreiben, mit CRLF. Dabei wird die Spalte col auf 0 gesetzt.
* @param pStrg der zu schreibende String
* @exception IOException falls ein Schreibfehler auftritt
*/
protected void writeln(String pStrg) throws IOException
{
bw.write(pStrg);
bw.newLine();
col = 0;
}
/**
* Leerzeile schreiben bzw. Zeilenwechsel veranlassen. Dabei wird die Spalte col auf 0 gesetzt.
* @exception IOException falls ein Schreibfehler auftritt
*/
protected void writeln() throws IOException
{
bw.newLine();
col = 0;
}
/**
* Spaces (Einr?ckung) entsprechend sp schreiben.
* @exception IOException falls ein Schreibfehler auftritt
*/
protected void writeSp() throws IOException
{
if (sp != 0)
{
StringBuilder sb = new StringBuilder(); // (sp)
for (int i = 1; i <= sp; i++)
{
sb.append(' ');
}
write(sb.toString());
}
}
/**
* Schreiben von (offenen) Tags beenden (Tags vervollst?ndigen).
*
* - Falls ein Tag ge?ffnet ist (isOpen), wird es geschlossen.
* - Falls dann ln = true, wird mit der n?chsten Zeile fortgesetzt.
*
* @param ln true, falls zus?tzlich ein Zeilenende geschrieben werden soll.
* @exception IOException falls ein Schreibfehler auftritt
*/
protected void flush(boolean ln) throws IOException
{
// if (isOpen)
// {
// write(">");
if (ln)
{
// writeln();
newline();
}
// isOpen = false;
// }
}
/**
* Ruft flush(true) auf.
* @exception IOException falls ein Schreibfehler auftritt
*/
private void flush() throws IOException
{
flush(true);
}
/**
* Sorgt daf?r, da? folgende Schreiboperationen in einer neuen Zeile beginnen.
* Falls col nicht 0 ist, wird ein CRLF geschrieben und col = 0 gesetzt.
* @exception IOException falls ein Schreibfehler auftritt
*/
protected void newline() throws IOException
{
if (col != 0)
{
writeln();
col = 0;
}
}
//---------------------------------------------------------------------------
/**
* Buffered Writer zur "Erstellung" einer JSON-Datei verwenden.
* Die Felder sp und col werden auf 0 gesetzt. Es wird ein JSON-Header
* geschrieben. Das ?bergebene Encoding wird lediglich f?r den JSON-Header
* verwendet, um die korrekte Codierung muss sich der Verwender k?mmern.
* @param pBW BufferedWriter
* @param pEnc Encoding, Standard: "ISO-8859-1" (falls pEnc = null)
* @throws IOException im Fehlerfall
*/
public void createJSON(BufferedWriter pBW, String pEnc) throws IOException
{
bw = pBW;
sp = 0;
col = 0;
first = true;
// isOpen = false;
// writeln("");
}
/**
* Buffered Writer zur "Erstellung" einer JSON-Datei verwenden. Es wird vom
* Standard-Encoding ausgegangen.
* @param pBW BufferedWriter
* @throws IOException im Fehlerfall
*/
public void createJSON(BufferedWriter pBW) throws IOException
{
createJSON(pBW, null);
}
/**
* Initialisierung des JSON-Datei mit Encoding, das Encoding wird dabei zur
* Codierung verwendet.
* @param pOS OutputStream
* @param pEnc Encoding
* @throws IOException im Fehlerfall
*/
public void createJSON(OutputStream pOS, String pEnc) throws IOException
{
pEnc = pEnc != null ? pEnc : "UTF-8"; // Charset.defaultCharset().name();
OutputStreamWriter osw = pEnc != null ? new OutputStreamWriter(pOS, pEnc) : new OutputStreamWriter(pOS);
createJSON(new BufferedWriter(osw), pEnc);
}
/**
* Initialisierung der JSON-Datei, es wird vom Standard-Encoding ausgegangen.
* @param pOS OutputStream
* @throws IOException im Fehlerfall
*/
public void createJSON(OutputStream pOS) throws IOException
{
createJSON(pOS, null);
}
/**
* Erzeugen einer neuen JSON-Datei, mit Encoding, das Encoding wird dabei zur
* Codierung verwendet.
* @param pFileName Name der JSON-Datei.
* @param pEnc Encoding, Standard: "ISO-8859-1" (falls pEnc = null)
* @exception IOException falls die Datei nicht erstellt werden konnte oder
* ein Schreibfehler auftritt
*/
public void createJSON(String pFileName, String pEnc) throws IOException
{
createJSON(new FileOutputStream(pFileName), pEnc);
}
/**
* Erzeugen einer neuen JSON-Datei, es wird vom Standard-Encoding ausgegangen.
* @param pFileName Name der JSON-Datei.
* @exception IOException falls die Datei nicht erstellt werden konnte oder
* ein Schreibfehler auftritt
*/
public void createJSON(String pFileName) throws IOException
{
createJSON(pFileName, null);
}
//---------------------------------------------------------------------------
/**
* Direkte Ausgabe: Text ohne Zeilenumbruch.
* @param pStrg auszugebender Text
* @throws IOException im Fehlerfall
*/
public void directWrite(String pStrg) throws IOException
{
flush(false);
write(pStrg);
}
/**
* Direkte Ausgabe: Text mit Zeilenumbruch.
* @param pStrg auszugebender Text
* @throws IOException im Fehlerfall
*/
public void directWriteLn(String pStrg) throws IOException
{
flush(false);
writeln(pStrg);
}
/**
* Direkte Ausgabe: Zeilenumbruch.
* @throws IOException im Fehlerfall
*/
public void directWriteLn() throws IOException
{
flush(false);
writeln();
}
//---------------------------------------------------------------------------
/**
* Falls es sich nicht um das erste Element in einem Array oder in einem Object handelt, wird ein Komma (",") geschrieben.
* @throws IOException im Fehlerfall
*/
protected void checkFirst() throws IOException
{
if (!first)
{
write(",");
}
}
/**
* Object-Anfang schreiben.
* @throws IOException im Fehlerfall
*/
public void openObject() throws IOException
{
checkFirst();
write("{");
first = true;
}
/**
* Object-Ende schreiben.
* @throws IOException im Fehlerfall
*/
public void closeObject() throws IOException
{
write("}");
first = false;
}
/**
* Array-Anfang schreiben.
* @throws IOException im Fehlerfall
*/
public void openArray() throws IOException
{
checkFirst();
write("[");
first = true;
}
/**
* Array-Ende schreiben.
* @throws IOException im Fehlerfall
*/
public void closeArray() throws IOException
{
write("]");
first = false;
}
/**
* Blatt-Anfang schreiben.
* @param pName Names des Blatts
* @throws IOException im Fehlerfall
*/
public void openLeaf(String pName) throws IOException
{
checkFirst();
write("\"");
write(pName);
write("\"");
write(":");
first = true;
}
/**
* Blatt-Ende schreiben.
* @throws IOException im Fehlerfall
*/
public void closeLeaf() throws IOException
{
first = false;
}
//---------------------------------------------------------------------------
/**
* Tags werden vervollst?ndigt, JSON-Datei wird ge-flush-t und geschlossen.
* Erst danach kann mit createJSON eine neue JSON-Datei erzeugt werden.
* @exception IOException falls ein Schreibfehler auftritt oder die Datei
* nicht geschlossen werden konnte.
*/
public void closeJSON() throws IOException
{
flush();
bw.flush(); // wichtig!
bw.close();
}
@Override
public void close() throws IOException
{
closeJSON();
}
//---------------------------------------------------------------------------
/**
* String mit Maskierung ohne String-Begrenzung (also ohne Anf?hrungszeichen - beidseitig ohne!) schreiben.
* @param pContent der Text
* @throws IOException im Fehlerfall
*/
public void writeString(String pContent) throws IOException
{
StringBuilder sb = new StringBuilder();
int len = pContent.length();
for (int i = 0; i < len; i++)
{
char ch = pContent.charAt(i);
if (ch == '\"')
{
sb.append('\\');
sb.append(ch);
}
else if (ch == '\\')
{
sb.append('\\');
sb.append(ch);
}
else
{
sb.append(ch);
}
}
write(sb.toString());
}
/**
* JSON-Blattelement (im weitesten Sinne) schreiben. Es handelt sich um die Kombination aus Name/Schl?ssel in
* Anf?hrungszeichen und einem Wert, wobei der Wert wahlweise mit (im String-Fall) oder ohne Anf?hrungszeichen (im Number-
* oder Boolean-Fall) geschrieben werden kann. Falls der Wert null ist, wird nichts geschrieben (vgl. putValue).
* @param pName Name/Schl?ssel
* @param pContent der Text f?r den Wert
* @param quote Wert mit (true) oder ohne (false) Anf?hrungszeichen schreiben
* @throws IOException im Fehlerfall
*/
protected void putLeaf(String pName, String pContent, boolean quote) throws IOException
{
/*
if ((pContent != null) && (pContent.length() != 0))
{
openTag(pName);
putContent(pContent);
closeTag(pName);
}
*/
if (pContent != null)
{
openLeaf(pName);
if (quote)
{
write("\"");
}
writeString(pContent);
if (quote)
{
write("\"");
}
closeLeaf();
}
}
/**
* JSON-Blatt schreiben (mit Anf?hrungszeichen f?r den Wert).
* Hierbei handelt es sich um eine Basis-Routine f?r die folgenden
* Spezialf?lle. Das JSON-Blatt wird nur dann erzeugt, wenn der zu schreibende
* Inhalt verschieden von null und verschieden von "" ist.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt, ggf. auch null oder ""
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeaf(String pName, String pContent) throws IOException
{
putLeaf(pName, pContent, true);
}
/**
* String-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als String
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafString(String pName, String pContent) throws IOException
{
putLeaf(pName, pContent, true);
}
/**
* Integer-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Integer
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafInt(String pName, Integer pContent) throws IOException
{
putLeaf(pName, UniTypeConv.convInt2String(pContent), false);
}
/**
* Long-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Integer
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafLong(String pName, Long pContent) throws IOException
{
putLeaf(pName, UniTypeConv.convLong2String(pContent), false);
}
/**
* Float-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Float
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafFloat(String pName, Float pContent) throws IOException
{
putLeaf(pName, UniTypeConv.convFloat2String(pContent), false);
}
/**
* Double-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Double
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafDouble(String pName, Double pContent) throws IOException
{
putLeaf(pName, UniTypeConv.convDouble2String(pContent), false);
}
/**
* Date-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Date (nur Datum)
* @param pMask optionale Maske
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafDate(String pName, Date pContent, String pMask) throws IOException
{
putLeaf(pName, UniTypeConv.convDate2String(pContent, pMask));
}
/**
* Date-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Date (nur Datum)
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafDate(String pName, Date pContent) throws IOException
{
putLeafDate(pName, pContent, null);
}
/**
* Time-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Date (nur Zeitangabe)
* @param pMask optionale Maske
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafTime(String pName, Date pContent, String pMask) throws IOException
{
putLeaf(pName, UniTypeConv.convTime2String(pContent, pMask));
}
/**
* Time-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Date (nur Zeitangabe)
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafTime(String pName, Date pContent) throws IOException
{
putLeafTime(pName, pContent, null);
}
/**
* DateTime-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Date (Datum und Zeitangabe)
* @param pMask optionale Maske
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafDateTime(String pName, Date pContent, String pMask) throws IOException
{
putLeaf(pName, UniTypeConv.convDateTime2String(pContent, pMask));
}
/**
* DateTime-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Date (Datum und Zeitangabe)
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafDateTime(String pName, Date pContent) throws IOException
{
putLeafDateTime(pName, pContent, null);
}
/**
* Boolean-JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt als Boolean
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafBool(String pName, Boolean pContent) throws IOException
{
String s = pContent != null ? pContent ? "true" : "false" : null;
putLeaf(pName, s, false);
}
/**
* JSON-Blatt schreiben.
* @param pName der Name des JSON-Blatt-Tags
* @param pContent der Inhalt
* @throws IOException falls ein Schreibfehler auftritt
*/
public void putLeafObj(String pName, Object pContent) throws IOException
{
if (pContent != null)
{
if (pContent instanceof String)
{
putLeafString(pName, (String) pContent);
}
else if (pContent instanceof Integer)
{
putLeafInt(pName, (Integer) pContent);
}
else if (pContent instanceof Long)
{
putLeafLong(pName, (Long) pContent);
}
else if (pContent instanceof Float)
{
putLeafFloat(pName, (Float) pContent);
}
else if (pContent instanceof Double)
{
putLeafDouble(pName, (Double) pContent);
}
else if (pContent instanceof Boolean)
{
putLeafBool(pName, (Boolean) pContent);
}
else if (pContent instanceof Date)
{
putLeafDateTime(pName, (Date) pContent);
}
else
{
putLeaf(pName, pContent.toString());
}
}
}
/**
* JSON-Wert schreiben. Achtung! Es handelt sich NICHT um ein Blatt, es wird also NUR der Wert selbst geschrieben,
* OHNE Name/Schl?ssel vorweg! Insbesondere wird, falls der Wert null ist, der Text "null" (ohne Anf?hrungszeichen)
* geschrieben.
* @param obj Wert
* @throws IOException im Fehlerfall
*/
public void putValue(Object obj) throws IOException
{
if (obj != null)
{
if (obj instanceof String)
{
checkFirst();
write("\"");
writeString((String) obj);
write("\"");
}
else if (obj instanceof Integer)
{
checkFirst();
write(UniTypeConv.convInt2String((Integer) obj));
}
else if (obj instanceof Long)
{
checkFirst();
write(UniTypeConv.convLong2String((Long) obj));
}
else if (obj instanceof Float)
{
checkFirst();
write(UniTypeConv.convFloat2String((Float) obj));
}
else if (obj instanceof Double)
{
checkFirst();
write(UniTypeConv.convDouble2String((Double) obj));
}
else if (obj instanceof Boolean)
{
checkFirst();
write((Boolean) obj ? "true" : "false");
}
else if (obj.getClass().isArray())
{
openArray();
Object[] oa = (Object[]) obj;
for (int i = 0; i < oa.length; i++)
{
putValue(oa[i]);
}
closeArray();
}
else
{
openObject();
// ...
closeObject();
}
}
else
{
checkFirst();
write("null");
}
first = false;
}
//===========================================================================
/**
* Main-Methode.
* @param args Kommandozeilenargumente
*/
public static void main(String... args)
{
try
{
JSONGenerator jg = new JSONGenerator();
StringWriter sw = new StringWriter();
jg.createJSON(new BufferedWriter(sw));
jg.putLeafString("Strg", "Mein String");
jg.openObject();
jg.putLeafString("Strg2", "Noch ein String");
jg.putLeafInt("Int", 1);
jg.putLeafLong("Long", 2L);
jg.putLeafFloat("Float", 3.4f);
jg.putLeafDouble("Double", 5.6);
jg.putLeafBool("Bool1", true);
jg.putLeafBool("Bool0", false);
jg.putLeafDate("Date", new Date());
jg.putLeafTime("Time", new Date());
jg.putLeafDateTime("DateTime", new Date());
jg.putLeafObj("Object", new Object());
jg.closeObject();
jg.openObject();
jg.putLeafString("Strg2", "Mein String 2");
jg.closeObject();
jg.openArray();
jg.putValue("Mein String 3");
jg.putValue(7);
jg.putValue(8L);
jg.putValue(9.1f);
jg.putValue(2.3);
jg.putValue(true);
jg.putValue(false);
// jg.putValue(new Date());
// jg.putValue(new Object());
jg.putValue(new String[] { "S1", "S2", "S3" });
jg.close();
MLogger.deb(() -> "result:\n" + sw.toString());
}
catch (Exception ex)
{
MLogger.err("", ex);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy