Commit 68ef471f authored by Nastuzzi Samy's avatar Nastuzzi Samy

Merge branch 'release/v0.11.9'

parents cc1b1898 a87144ef
......@@ -4,6 +4,7 @@
<modules>
<module fileurl="file://$PROJECT_DIR$/PayUTC.iml" filepath="$PROJECT_DIR$/PayUTC.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
<module fileurl="file://$PROJECT_DIR$/jessy.iml" filepath="$PROJECT_DIR$/jessy.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="fr.utc.simde.jessy"
android:versionCode="33"
android:versionName="0.11.0">
android:versionCode="42"
android:versionName="0.11.9">
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.INTERNET" />
......
......@@ -177,14 +177,14 @@ public abstract class ArticleGroupActivity extends BaseActivity {
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ArticleGroupActivity.this);
alertDialogBuilder
.setTitle(R.string.configuration)
.setView(popupView)
.setCancelable(false)
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int id) {
config.setCanCancel(true);
}
});
.setTitle(R.string.configuration)
.setView(popupView)
.setCancelable(false)
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int id) {
config.setCanCancel(true);
}
});
dialog.createDialog(alertDialogBuilder);
}
......
......@@ -6,6 +6,7 @@ import android.app.AlarmManager;
import android.app.DownloadManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
......@@ -102,8 +103,17 @@ public abstract class BaseActivity extends InternetActivity {
});
}
protected void hasRights(final String title, final String[] rightList, final Runnable runnable) { hasRights(title, rightList, false, runnable);}
protected void hasRights(final String title, final String[] rightList, final boolean needToBeSuper, final Runnable runnable) {
protected void hasRights(final String title, final String[] rightList, final Runnable runnablePos) { hasRights(title, rightList, false, runnablePos);}
protected void hasRights(final String title, final String[] rightList, final boolean needToBeSuper, final Runnable runnablePos) {
hasRights(title, rightList, false, runnablePos, new Runnable() {
@Override
public void run() {
dialog.errorDialog(BaseActivity.this, title, nemopaySession.forbidden(rightList, needToBeSuper));
}
});
}
protected void hasRights(final String title, final String[] rightList, final Runnable runnablePos, final Runnable runnableNeg) { hasRights(title, rightList, false, runnablePos, runnableNeg);}
protected void hasRights(final String title, final String[] rightList, final boolean needToBeSuper, final Runnable runnablePos, final Runnable runnableNeg) {
dialog.startLoading(BaseActivity.this, getString(R.string.information_collection), getString(R.string.user_rights_list_collecting));
new Thread() {
@Override
......@@ -125,6 +135,18 @@ public abstract class BaseActivity extends InternetActivity {
if (!needToBeSuper) {
for (JsonNode foundation : myRightList) {
if (rightList.length == 0 && foundation.size() > 75) {
runOnUiThread(new Runnable() {
@Override
public void run() {
dialog.stopLoading();
runnablePos.run();
}
});
return;
}
for (JsonNode myRight : foundation) {
if (rights.contains(myRight.textValue()) && !sameRights.contains(myRight.textValue()))
sameRights.add(myRight.textValue());
......@@ -137,7 +159,7 @@ public abstract class BaseActivity extends InternetActivity {
@Override
public void run() {
dialog.stopLoading();
runnable.run();
runnablePos.run();
}
});
else {
......@@ -145,7 +167,7 @@ public abstract class BaseActivity extends InternetActivity {
@Override
public void run() {
dialog.stopLoading();
dialog.errorDialog(BaseActivity.this, title, nemopaySession.forbidden(rightList, needToBeSuper));
runnableNeg.run();
}
});
}
......@@ -166,34 +188,26 @@ public abstract class BaseActivity extends InternetActivity {
}
protected void restartApp(final Activity activity) {
try {
PackageManager pm = getPackageManager();
Intent mStartActivity = pm.getLaunchIntentForPackage(
getPackageName()
);
mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int mPendingIntentId = 223344;
PendingIntent mPendingIntent = PendingIntent.getActivity(activity, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);
} catch (Exception e) {
Log.e(LOG_TAG, e.getMessage());
}
startMainActivity(activity);
}
protected void startMainActivity(final Activity activity) {
disconnect();
if (activity instanceof MainActivity)
((MainActivity) activity).launch();
else {
disconnect();
Intent intent = new Intent(activity, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
finish();
activity.startActivity(intent);
Intent intent = new Intent(activity, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
finish();
activity.startActivity(intent);
}
}
protected void startFoundationListActivity(final Activity activity) {
if (!nemopaySession.isConnected())
restartApp(activity);
if (config.getFoundationId() != -1) {
startSellActivity(activity);
return;
......@@ -248,14 +262,24 @@ public abstract class BaseActivity extends InternetActivity {
}
public void startSellActivity(final Activity activity) {
if (!nemopaySession.isConnected())
restartApp(activity);
startArticleGroupActivity(activity, new Intent(activity, SellActivity.class));
}
public void startEditActivity(final Activity activity) {
if (!nemopaySession.isConnected())
restartApp(activity);
config.setInCategory(true); // Do not allow keyboard modification (not supported yet)
startArticleGroupActivity(activity, new Intent(activity, EditActivity.class));
}
public void startArticleGroupActivity(final Activity activity, final Intent intent) {
if (!nemopaySession.isConnected())
restartApp(activity);
dialog.startLoading(activity, activity.getResources().getString(R.string.information_collection), getString(R.string.location_list_collecting));
new Thread() {
......@@ -471,6 +495,9 @@ public abstract class BaseActivity extends InternetActivity {
}
protected void startBuyerInfoActivity(final Activity activity, final String badgeId) {
if (!nemopaySession.isConnected())
restartApp(activity);
dialog.startLoading(activity, activity.getResources().getString(R.string.information_collection), activity.getResources().getString(R.string.buyer_info_collecting));
final Intent intent = new Intent(activity, BuyerInfoActivity.class);
......@@ -533,6 +560,9 @@ public abstract class BaseActivity extends InternetActivity {
}
protected void startCardManagementActivity(final Activity activity) {
if (!nemopaySession.isConnected())
restartApp(activity);
hasRights(getString(R.string.user_rights_list_collecting), new String[]{"GESUSERS"}, true, new Runnable() {
@Override
public void run() {
......@@ -542,20 +572,15 @@ public abstract class BaseActivity extends InternetActivity {
}
protected void startQRCodeReaderActivity(final Activity activity) {
if (!nemopaySession.isConnected())
restartApp(activity);
if (haveCameraPermission())
startActivity(new Intent(activity, QRCodeReaderActivity.class));
else
dialog.errorDialog(BaseActivity.this, getString(R.string.qrcode), getString(R.string.need_camera_permission));
}
protected void delKey() {
SharedPreferences.Editor edit = sharedPreferences.edit();
edit.remove("key");
edit.apply();
unregister(BaseActivity.this);
}
protected void setNemopayKey(final String key) {
if (key.equals(""))
return;
......
......@@ -145,7 +145,20 @@ public class EditActivity extends ArticleGroupActivity {
switchCotisant.setChecked(config.getPrintCotisant());
swtich18.setChecked(config.getPrint18());
configButton.setVisibility(View.GONE);
configButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View view) {
hasRights(getString(R.string.configurate), new String[]{
"STAFF",
"GESAPPLICATIONS"
}, new Runnable() {
@Override
public void run() {
configDialog();
}
});
}
});
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(EditActivity.this);
alertDialogBuilder
......@@ -311,7 +324,7 @@ public class EditActivity extends ArticleGroupActivity {
StringBuilder builder = new StringBuilder(dest);
builder.replace(dstart, dend, source
.subSequence(start, end).toString());
if (!builder.toString().matches("(([1-9]{1})([0-9]{0,"+(maxDigitsBeforeDecimalPoint-1)+"})?)?(\\.[0-9]{0,"+maxDigitsAfterDecimalPoint+"})?")) {
if (!builder.toString().matches("((([1-9]{1})([0-9]{0,"+(maxDigitsBeforeDecimalPoint-1)+"})?)|0)?(\\.[0-9]{0,"+maxDigitsAfterDecimalPoint+"})?")) {
if (source.length() == 0)
return dest.subSequence(dstart, dend);
return "";
......@@ -444,7 +457,7 @@ public class EditActivity extends ArticleGroupActivity {
.setTitle(R.string.configuration)
.setView(popupView)
.setCancelable(false)
.setPositiveButton(R.string.reload, new DialogInterface.OnClickListener() {
.setPositiveButton(R.string.register, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int id) {
if (!nameInput.getText().toString().equals("") && (radioVariablePrice.isChecked() || !priceInput.getText().toString().equals(""))) {
dialog.startLoading(EditActivity.this, getString(R.string.article_edit), getString(R.string.article_editing));
......
......@@ -50,50 +50,7 @@ public class MainActivity extends BaseActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPreferences = getSharedPreferences("payutc", Activity.MODE_PRIVATE);
nemopaySession = new NemopaySession(MainActivity.this);
ginger = new Ginger(MainActivity.this);
casConnexion = new CASConnexion(nemopaySession);
config = new Config(sharedPreferences);
setNemopayKey(sharedPreferences.getString("key", ""));
ginger.setKey(sharedPreferences.getString("key_ginger", ""));
appImg = findViewById(R.id.img_payutc);
appNameText = findViewById(R.id.text_app_name);
appConfigText = findViewById(R.id.text_app_config);
appRegisteredText = findViewById(R.id.text_app_registered);
usernameButton = findViewById(R.id.button_username);
casConnexionDialog = false;
appImg.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
config.reset();
restartApp(MainActivity.this);
return false;
}
});
appRegisteredText.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
optionDialog();
return false;
}
});
usernameButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
casDialog();
}
});
setConfig();
checkUpdate(false);
launch();
}
@Override
......@@ -108,6 +65,8 @@ public class MainActivity extends BaseActivity {
if (!key.equals(""))
setNemopayKey(key);
}
checkUpdate(false);
}
@Override
......@@ -128,6 +87,8 @@ public class MainActivity extends BaseActivity {
@Override
protected void enableInternetDialog(final Context context) {
Toast.makeText(context, R.string.internet_not_available, Toast.LENGTH_SHORT).show();
appRegisteredText.setText(R.string.app_not_connected);
appRegisteredText.setOnLongClickListener(null);
dialog.infoDialog(MainActivity.this, getString(R.string.connection), getString(R.string.internet_accessibility), new DialogInterface.OnClickListener() {
@Override
......@@ -166,6 +127,53 @@ public class MainActivity extends BaseActivity {
((TextView) findViewById(R.id.text_app_registered)).setText(R.string.app_not_registred);
}
protected void launch() {
sharedPreferences = getSharedPreferences("payutc", Activity.MODE_PRIVATE);
nemopaySession = new NemopaySession(MainActivity.this);
ginger = new Ginger(MainActivity.this);
casConnexion = new CASConnexion(nemopaySession);
config = new Config(sharedPreferences);
setNemopayKey(sharedPreferences.getString("key", ""));
ginger.setKey(sharedPreferences.getString("key_ginger", ""));
appImg = findViewById(R.id.img_payutc);
appNameText = findViewById(R.id.text_app_name);
appConfigText = findViewById(R.id.text_app_config);
appRegisteredText = findViewById(R.id.text_app_registered);
usernameButton = findViewById(R.id.button_username);
casConnexionDialog = false;
appImg.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
config.reset();
restartApp(MainActivity.this);
return false;
}
});
appRegisteredText.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
optionDialog();
return false;
}
});
usernameButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
casDialog();
}
});
setConfig();
checkUpdate(false);
}
protected void setConfig() {
if (config.getFoundationId() != -1) {
appNameText.setText(config.getFoundationName());
......
......@@ -183,7 +183,7 @@ public class SellActivity extends ArticleGroupActivity {
configButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View view) {
hasRights(getString(R.string.configurate_by_default), new String[]{
hasRights(getString(R.string.configurate), new String[]{
"STAFF",
"GESAPPLICATIONS"
}, new Runnable() {
......
......@@ -84,8 +84,14 @@ public abstract class ArticlesAdapter extends BaseAdapter {
this.clickViewList[position].setAlpha(0.0f);
}
else {
this.clickViewList[position].setText(this.nbrList[position] % 100 == 0 ? Integer.toString(this.nbrList[position] / 100) : Float.toString(this.nbrList[position] / 100.0f));
this.clickViewList[position].setAlpha(1.0f);
if (this.articleList.get(position).get("variable_price").booleanValue()) {
this.clickViewList[position].setText(this.nbrList[position] % 100 == 0 ? Integer.toString(this.nbrList[position] / 100) : Float.toString(this.nbrList[position] / 100.0f) + "€");
this.clickViewList[position].setBackgroundColor(Color.argb(255, 150, 200, 150));
}
else
this.clickViewList[position].setText(this.nbrList[position] % 100 == 0 ? Integer.toString(this.nbrList[position] / 100) : Float.toString(this.nbrList[position] / 100.0f));
}
}
......@@ -97,7 +103,7 @@ public abstract class ArticlesAdapter extends BaseAdapter {
String text;
if (articleList.get(position).get("variable_price").booleanValue())
text = articleList.get(position).get("name").textValue() + ": " + activity.getString(R.string.price_variable);
text = articleList.get(position).get("name").textValue() + ": " + (getNbr(position) == 0 ? activity.getString(R.string.price_variable) : Float.toString(getNbr(position) / 100.0f) + '$');
else if (articleList.get(position).has("quantity"))
text = Integer.toString(articleList.get(position).get("quantity").intValue()) + "x " + articleList.get(position).get("name").textValue() + ": " + Integer.toString(articleList.get(position).get("quantity").intValue()) + "x " + String.format("%.2f", new Float(articleList.get(position).get("price").intValue()) / 100.00f) + "€";
else
......
......@@ -48,8 +48,12 @@ public class ListAdapater extends ArticlesAdapter {
if (article.get("id").intValue() == -1)
priceText.setVisibility(View.GONE);
else {
if (article.get("variable_price").booleanValue())
priceText.setText("PV: " + String.format("%.2f", new Float(articleList.get(position).get("price").intValue()) / 100.00f) + "€");
if (article.get("variable_price").booleanValue()) {
if (articleList.get(position).has("quantity"))
priceText.setText(String.format("%.2f", articleList.get(position).get("price").intValue() * articleList.get(position).get("quantity").intValue() / 100.00f) + "€");
else
priceText.setText(R.string.price_variable);
}
else
priceText.setText((article.has("quantity") ? Integer.toString(article.get("quantity").intValue()) + "x " : "") + String.format("%.2f", new Float(articleList.get(position).get("price").intValue()) / 100.00f) + "€");
}
......
......@@ -89,7 +89,7 @@ public class SellFragment extends ArticleGroupFragment {
StringBuilder builder = new StringBuilder(dest);
builder.replace(dstart, dend, source
.subSequence(start, end).toString());
if (!builder.toString().matches("(([1-9]{1})([0-9]{0,"+(maxDigitsBeforeDecimalPoint-1)+"})?)?(\\.[0-9]{0,"+maxDigitsAfterDecimalPoint+"})?")) {
if (!builder.toString().matches("((([1-9]{1})([0-9]{0,"+(maxDigitsBeforeDecimalPoint-1)+"})?)|0)?(\\.[0-9]{0,"+maxDigitsAfterDecimalPoint+"})?")) {
if (source.length() == 0)
return dest.subSequence(dstart, dend);
return "";
......
package fr.utc.simde.jessy.responses;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Created by Samy on 10/11/2017.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class APIResponse {
protected String id;
protected String username;
protected String type;
protected Integer fun_id;
protected long expires_at;
protected long creation_date;
protected boolean paid;
protected boolean validated;
protected long expires_at;
public String getId() { return this.id; }
public String getUsername() { return this.username; }
public String getType() { return this.type; }
public Integer getFoundationId() { return this.fun_id; }
public long getExpiresAt() { return this.expires_at; }
public long getCreatedAt() { return this.creation_date; }
public boolean isPaid() { return this.paid; }
public boolean isValidated() { return this.validated; }
public long getCreation_date() { return this.creation_date; }
public long getExpires_at() { return this.expires_at; }
}
package fr.utc.simde.jessy.responses;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.List;
......@@ -10,10 +10,19 @@ import java.util.List;
* Created by Samy on 10/11/2017.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class BottomatikResponse extends APIResponse {
protected String _id;
protected Integer fun_id;
protected boolean paid;
protected boolean validated;
protected List<List<String>> articles;
public String get_id() { return this._id; }
public Integer getFun_id() { return this.fun_id; }
public boolean isPaid() { return this.paid; }
public boolean isValidated() { return this.validated; }
public List<List<String>> getArticles() { return this.articles; }
public List<List<Integer>> getArticleList() {
List<List<Integer>> articleList = new ArrayList<List<Integer>>();
......
......@@ -17,12 +17,12 @@ public class GingerResponse {
protected boolean is_cotisant;
protected String badge_uid;
public String getUsername() { return login; }
public String getLastname() { return nom; }
public String getFirstname() { return prenom; }
public String getEmail() { return mail; }
public String getLogin() { return login; }
public String getNom() { return nom; }
public String getPrenom() { return prenom; }
public String getMail() { return mail; }
public String getType() { return type; }
public boolean getIsAdult() { return is_adulte; }
public boolean getIsContributer() { return is_cotisant; }
public String getBadgeId() { return badge_uid; }
public boolean getIs_adulte() { return is_adulte; }
public boolean getIs_cotisant() { return is_cotisant; }
public String getBadge_uid() { return badge_uid; }
}
......@@ -12,6 +12,10 @@ public class QRCodeResponse {
protected String id;
protected String system;
public void setUsername(String username) { this.username = username; }
public void setId(String id) { this.id = id; }
public void setSystem(String system) { this.system = system; }
public String getUsername() { return this.username; }
public String getId() { return this.id; }
public String getSystem() { return this.system; }
......
package fr.utc.simde.jessy.responses;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Created by Samy on 10/11/2017.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class ComedmusResponse extends APIResponse {
public class ReservationResponse extends APIResponse {
protected Integer reservation_id;
protected String seance;
public Integer getReservationId() { return this.reservation_id; }
public Integer getReservation_id() { return this.reservation_id; }
public String getSeance() { return this.seance; }
}
......@@ -26,6 +26,7 @@ public class API {
private String notFound;
private String badRequest;
private String internalError;
private String goneRequest;
private String errorRequest;
public API(final Activity activity, final String name, final String url) {
......@@ -40,6 +41,7 @@ public class API {
this.badRequest = activity.getString(R.string.bad_request);
this.internalError = activity.getString(R.string.internal_error);
this.errorRequest = activity.getString(R.string.error_request);
this.goneRequest = activity.getString(R.string.gone_request);
}
public void setKey(final String key) { this.key = key; }
......@@ -96,13 +98,14 @@ public class API {
else if (responseCode == 403)
throw new Exception(this.noRight);
else if (responseCode == 404)
throw new Exception(this.name + " " + this.notFound);
throw new Exception(this.serviceText + " " + this.name + " " + this.notFound);
else if (responseCode == 400)
throw new Exception(this.name + " " + this.badRequest);
else if (responseCode == 500 || responseCode == 503) {
throw new Exception(this.name + " " + this.internalError);
}
throw new Exception(this.serviceText + " " + this.name + " " + this.badRequest);
else if (responseCode == 500 || responseCode == 503)
throw new Exception(this.serviceText + " " + this.name + " " + this.internalError);
else if (responseCode == 410)
throw new Exception(this.serviceText + " " + this.name + " " + this.goneRequest);
else
throw new Exception(this.name + " " + this.errorRequest + " " + responseCode);
throw new Exception(this.serviceText + " " + this.name + " " + this.errorRequest + " " + responseCode);
}
}
......@@ -36,7 +36,7 @@ public class CASConnexion {
request.addPost("username", username);
request.addPost("password", password);
if (request.post() == 201)
if (request.post(false) == 201)
this.location = request.getHeader("Location");
else
throw new Exception("Not Connected");
......@@ -72,7 +72,7 @@ public class CASConnexion {
HTTPRequest request = new HTTPRequest(this.location);
request.addPost("service", service);
if (request.post() == 200)
if (request.post(false) == 200)
this.ticket = request.getResponse();
else
throw new RuntimeException("Service not added");
......
......@@ -85,13 +85,14 @@ public class HTTPRequest {
return getResponseCode();
}
public int post() {
public int post() { return post(true); }
public int post(final Boolean sendJSON) {
String get = null;
String post = null;
try {
get = get2String(this.getArgs);
post = post2String(this.postArgs);
post = post2String(this.postArgs, sendJSON);
}
catch (Exception e) {
Log.e(LOG_TAG, "error: " + e.getMessage());
......@@ -102,7 +103,7 @@ public class HTTPRequest {
try {
this.request = (HttpURLConnection) (new URL(this.url + get)).openConnection();
this.request.setRequestMethod("POST");
this.request.setRequestProperty("Content-Type", "application/json");
this.request.setRequestProperty("Content-Type", sendJSON ? "application/json" : "application/x-www-form-urlencoded");
this.request.setRequestProperty("charset", "utf-8");
this.request.setRequestProperty("Cookie", getCookiesHeader());
this.request.setUseCaches(false);
......@@ -293,8 +294,16 @@ public class HTTPRequest {
return data;
}
protected String post2String(Map<String, Object> args) throws UnsupportedEncodingException {
return map2JsonNode(args).toString();
protected String post2String(Map<String, Object> args, boolean inJSON) throws Exception {
if (inJSON)
return map2JsonNode(args).toString();
String data = "";