Revert "bug fix"

This reverts commit 93db8c4c
This commit is contained in:
simon 2020-10-15 12:40:16 +03:00
parent 93db8c4c0e
commit 4cb48a38a9
16 changed files with 28 additions and 2200 deletions

View file

@ -56,55 +56,6 @@ public class NetworkUtils {
return e.getMessage(); return e.getMessage();
} }
} }
public static String sendPostDataRequest(String urlText, InputStream data){
try {
log.info("POST : " + urlText);
HttpURLConnection conn = getHttpURLConnection(urlText);
conn.setDoInput(true);
conn.setDoOutput(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept","*/*");
conn.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
OutputStream ous = conn.getOutputStream();
ous.write(("--" + BOUNDARY + "\r\n").getBytes());
ous.write(("content-disposition: form-data; name=\"" + "file" + "\"; filename=\"" + "image1" + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
Algorithms.streamCopy(data,ous);
ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
ous.flush();
log.info("Response code and message : " + conn.getResponseCode() + " " + conn.getResponseMessage());
if(conn.getResponseCode() != 200){
return conn.getResponseMessage();
}
StringBuilder responseBody = new StringBuilder();
InputStream is = conn.getInputStream();
responseBody.setLength(0);
if (is != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8")); //$NON-NLS-1$
String s;
boolean first = true;
while ((s = in.readLine()) != null) {
if(first){
first = false;
} else {
responseBody.append("\n"); //$NON-NLS-1$
}
responseBody.append(s);
}
is.close();
}
Algorithms.closeStream(is);
Algorithms.closeStream(data);
Algorithms.closeStream(ous);
return responseBody.toString();
} catch (IOException e) {
log.error(e.getMessage(), e);
return e.getMessage();
}
}
private static final String BOUNDARY = "CowMooCowMooCowCowCow"; //$NON-NLS-1$ private static final String BOUNDARY = "CowMooCowMooCowCowCow"; //$NON-NLS-1$
public static String uploadFile(String urlText, File fileToUpload, String userNamePassword, public static String uploadFile(String urlText, File fileToUpload, String userNamePassword,
OsmOAuthAuthorizationClient client, OsmOAuthAuthorizationClient client,

Binary file not shown.

View file

@ -34,20 +34,17 @@ import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.graphics.drawable.DrawableCompat;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect; import net.osmand.data.QuadRect;
import net.osmand.osm.PoiCategory; import net.osmand.osm.PoiCategory;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.ActivityResultListener;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.mapcontextmenu.builders.cards.AbstractCard; import net.osmand.plus.mapcontextmenu.builders.cards.AbstractCard;
@ -56,7 +53,6 @@ import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask;
import net.osmand.plus.mapcontextmenu.builders.cards.NoImagesCard; import net.osmand.plus.mapcontextmenu.builders.cards.NoImagesCard;
import net.osmand.plus.mapcontextmenu.controllers.TransportStopController; import net.osmand.plus.mapcontextmenu.controllers.TransportStopController;
import net.osmand.plus.osmedit.utils.SecUtils;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.transport.TransportStopRoute; import net.osmand.plus.transport.TransportStopRoute;
@ -66,9 +62,7 @@ import net.osmand.plus.widgets.TextViewEx;
import net.osmand.plus.widgets.tools.ClickableSpanTouchListener; import net.osmand.plus.widgets.tools.ClickableSpanTouchListener;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -83,7 +77,7 @@ public class MenuBuilder {
public static final float SHADOW_HEIGHT_TOP_DP = 17f; public static final float SHADOW_HEIGHT_TOP_DP = 17f;
public static final int TITLE_LIMIT = 60; public static final int TITLE_LIMIT = 60;
protected static final String[] arrowChars = new String[] {"=>", " - "}; protected static final String[] arrowChars = new String[]{"=>"," - "};
protected MapActivity mapActivity; protected MapActivity mapActivity;
protected MapContextMenu mapContextMenu; protected MapContextMenu mapContextMenu;
@ -109,8 +103,6 @@ public class MenuBuilder {
private String preferredMapLang; private String preferredMapLang;
private String preferredMapAppLang; private String preferredMapAppLang;
private boolean transliterateNames; private boolean transliterateNames;
private static final int PICK_IMAGE = 1231;
private static final Log LOG = PlatformUtil.getLog(MenuBuilder.class);
public interface CollapseExpandListener { public interface CollapseExpandListener {
void onCollapseExpand(boolean collapsed); void onCollapseExpand(boolean collapsed);
@ -220,59 +212,10 @@ public class MenuBuilder {
if (showOnlinePhotos) { if (showOnlinePhotos) {
buildNearestPhotosRow(view); buildNearestPhotosRow(view);
} }
buildUploadImagesRow(view);
buildPluginRows(view); buildPluginRows(view);
// buildAfter(view); // buildAfter(view);
} }
public void buildUploadImagesRow(View view) {
if (mapContextMenu != null) {
//TODO to strings
String title = "Upload images";
buildRow(view, R.drawable.ic_action_note_dark, null, title, 0, false,
null, false, 0, false, new OnClickListener() {
@Override
public void onClick(View view) {
mapActivity.registerActivityResultListener(new ActivityResultListener(PICK_IMAGE,
new ActivityResultListener.OnActivityResultListener() {
@Override
public void onResult(int resultCode, Intent resultData) {
InputStream inputStream = null;
try {
inputStream = mapActivity.getContentResolver().openInputStream(resultData.getData());
} catch (FileNotFoundException e) {
LOG.error(e);
}
handleSelectedImage(inputStream);
}
}));
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
mapActivity.startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);
}
}, false);
}
}
private void handleSelectedImage(final InputStream image) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try{
String url = "https://test.openplacereviews.org/api/ipfs/image";
String response = NetworkUtils.sendPostDataRequest(url, image);
//TODO
(new SecUtils()).main(new String[0]);
}
catch (Exception e){
e.printStackTrace();
}
}
});
t.start();
}
private boolean showTransportRoutes() { private boolean showTransportRoutes() {
return showLocalTransportRoutes() || showNearbyTransportRoutes(); return showLocalTransportRoutes() || showNearbyTransportRoutes();
} }
@ -311,7 +254,7 @@ public class MenuBuilder {
protected boolean needBuildPlainMenuItems() { protected boolean needBuildPlainMenuItems() {
return true; return true;
} }
protected boolean needBuildCoordinatesRow() { protected boolean needBuildCoordinatesRow() {
return true; return true;
} }
@ -339,7 +282,7 @@ public class MenuBuilder {
protected void buildNearestWikiRow(View view) { protected void buildNearestWikiRow(View view) {
if (processNearestWiki() && nearestWiki.size() > 0) { if (processNearestWiki() && nearestWiki.size() > 0) {
buildRow(view, R.drawable.ic_action_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", 0, buildRow(view, R.drawable.ic_action_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size()+")", 0,
true, getCollapsableWikiView(view.getContext(), true), true, getCollapsableWikiView(view.getContext(), true),
false, 0, false, null, false); false, 0, false, null, false);
} }
@ -379,9 +322,9 @@ public class MenuBuilder {
locationData.remove(PointDescription.LOCATION_LIST_HEADER); locationData.remove(PointDescription.LOCATION_LIST_HEADER);
CollapsableView cv = getLocationCollapsableView(locationData); CollapsableView cv = getLocationCollapsableView(locationData);
buildRow(view, R.drawable.ic_action_get_my_location, null, title, 0, true, cv, false, 1, buildRow(view, R.drawable.ic_action_get_my_location, null, title, 0, true, cv, false, 1,
false, null, false); false, null, false);
} }
private void startLoadingImages() { private void startLoadingImages() {
if (onlinePhotoCardsRow == null) { if (onlinePhotoCardsRow == null) {
return; return;
@ -436,7 +379,7 @@ public class MenuBuilder {
} }
} }
protected void buildDescription(View view) { protected void buildDescription(View view){
} }
protected void buildAfter(View view) { protected void buildAfter(View view) {
@ -452,8 +395,8 @@ public class MenuBuilder {
} }
public View buildRow(View view, int iconId, String buttonText, String text, int textColor, public View buildRow(View view, int iconId, String buttonText, String text, int textColor,
boolean collapsable, final CollapsableView collapsableView, boolean collapsable, final CollapsableView collapsableView,
boolean needLinks, int textLinesLimit, boolean isUrl, OnClickListener onClickListener, boolean matchWidthDivider) { boolean needLinks, int textLinesLimit, boolean isUrl, OnClickListener onClickListener, boolean matchWidthDivider) {
return buildRow(view, iconId == 0 ? null : getRowIcon(iconId), buttonText, text, textColor, null, collapsable, collapsableView, return buildRow(view, iconId == 0 ? null : getRowIcon(iconId), buttonText, text, textColor, null, collapsable, collapsableView,
needLinks, textLinesLimit, isUrl, onClickListener, matchWidthDivider); needLinks, textLinesLimit, isUrl, onClickListener, matchWidthDivider);
} }
@ -537,7 +480,7 @@ public class MenuBuilder {
textPrefixView.setLayoutParams(llTextParams); textPrefixView.setLayoutParams(llTextParams);
textPrefixView.setTypeface(FontCache.getRobotoRegular(view.getContext())); textPrefixView.setTypeface(FontCache.getRobotoRegular(view.getContext()));
textPrefixView.setTextSize(12); textPrefixView.setTextSize(12);
textPrefixView.setTextColor(app.getResources().getColor(light ? R.color.text_color_secondary_light : R.color.text_color_secondary_dark)); textPrefixView.setTextColor(app.getResources().getColor(light ? R.color.text_color_secondary_light: R.color.text_color_secondary_dark));
textPrefixView.setMinLines(1); textPrefixView.setMinLines(1);
textPrefixView.setMaxLines(1); textPrefixView.setMaxLines(1);
textPrefixView.setText(textPrefix); textPrefixView.setText(textPrefix);
@ -583,7 +526,7 @@ public class MenuBuilder {
textViewSecondary.setLayoutParams(llTextSecondaryParams); textViewSecondary.setLayoutParams(llTextSecondaryParams);
textViewSecondary.setTypeface(FontCache.getRobotoRegular(view.getContext())); textViewSecondary.setTypeface(FontCache.getRobotoRegular(view.getContext()));
textViewSecondary.setTextSize(14); textViewSecondary.setTextSize(14);
textViewSecondary.setTextColor(app.getResources().getColor(light ? R.color.text_color_secondary_light : R.color.text_color_secondary_dark)); textViewSecondary.setTextColor(app.getResources().getColor(light ? R.color.text_color_secondary_light: R.color.text_color_secondary_dark));
textViewSecondary.setText(secondaryText); textViewSecondary.setText(secondaryText);
llText.addView(textViewSecondary); llText.addView(textViewSecondary);
} }
@ -638,7 +581,7 @@ public class MenuBuilder {
} }
if (collapsableView.getContentView().getParent() != null) { if (collapsableView.getContentView().getParent() != null) {
((ViewGroup) collapsableView.getContentView().getParent()) ((ViewGroup) collapsableView.getContentView().getParent())
.removeView(collapsableView.getContentView()); .removeView(collapsableView.getContentView());
} }
baseView.addView(collapsableView.getContentView()); baseView.addView(collapsableView.getContentView());
} }
@ -798,8 +741,8 @@ public class MenuBuilder {
} }
public void addPlainMenuItem(int iconId, String text, boolean needLinks, boolean isUrl, public void addPlainMenuItem(int iconId, String text, boolean needLinks, boolean isUrl,
boolean collapsable, CollapsableView collapsableView, boolean collapsable, CollapsableView collapsableView,
OnClickListener onClickListener) { OnClickListener onClickListener) {
plainMenuItems.add(new PlainMenuItem(iconId, null, text, needLinks, isUrl, collapsable, collapsableView, onClickListener)); plainMenuItems.add(new PlainMenuItem(iconId, null, text, needLinks, isUrl, collapsable, collapsableView, onClickListener));
} }
@ -1021,7 +964,7 @@ public class MenuBuilder {
button.setTypeface(FontCache.getRobotoRegular(context)); button.setTypeface(FontCache.getRobotoRegular(context));
int bg; int bg;
if (selected) { if (selected) {
bg = light ? R.drawable.context_menu_controller_bg_light_selected : R.drawable.context_menu_controller_bg_dark_selected; bg = light ? R.drawable.context_menu_controller_bg_light_selected: R.drawable.context_menu_controller_bg_dark_selected;
} else if (showAll) { } else if (showAll) {
bg = light ? R.drawable.context_menu_controller_bg_light_show_all : R.drawable.context_menu_controller_bg_dark_show_all; bg = light ? R.drawable.context_menu_controller_bg_light_show_all : R.drawable.context_menu_controller_bg_dark_show_all;
} else { } else {
@ -1078,7 +1021,7 @@ public class MenuBuilder {
private List<Amenity> getAmenities(QuadRect rect, PoiUIFilter wikiPoiFilter) { private List<Amenity> getAmenities(QuadRect rect, PoiUIFilter wikiPoiFilter) {
return wikiPoiFilter.searchAmenities(rect.top, rect.left, return wikiPoiFilter.searchAmenities(rect.top, rect.left,
rect.bottom, rect.right, -1, null); rect.bottom, rect.right, -1, null);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View file

@ -18,7 +18,6 @@ import net.osmand.osm.edit.Entity.EntityType;
import net.osmand.osm.edit.EntityInfo; import net.osmand.osm.edit.EntityInfo;
import net.osmand.osm.edit.Node; import net.osmand.osm.edit.Node;
import net.osmand.osm.edit.Way; import net.osmand.osm.edit.Way;
import net.osmand.osm.io.Base64;
import net.osmand.osm.io.NetworkUtils; import net.osmand.osm.io.NetworkUtils;
import net.osmand.osm.io.OsmBaseStorage; import net.osmand.osm.io.OsmBaseStorage;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
@ -31,8 +30,10 @@ import org.apache.commons.logging.Log;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;
import java.io.*; import java.io.ByteArrayInputStream;
import java.net.HttpURLConnection; import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.HashMap; import java.util.HashMap;
@ -107,16 +108,14 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
boolean doAuthenticate) { boolean doAuthenticate) {
log.info("Sending request " + url); //$NON-NLS-1$ log.info("Sending request " + url); //$NON-NLS-1$
try { try {
OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(ctx); if (doAuthenticate){
if (doAuthenticate) { OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(ctx);
if (client.isValidToken()) { Response response = client.performRequest(url,requestMethod,requestBody);
Response response = client.performRequest(url, requestMethod, requestBody); return response.getBody();
return response.getBody(); }
} else { else {
return performBasicAuthRequest(url, requestMethod, requestBody, userOperation); OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(ctx);
} Response response = client.performRequestWithoutAuth(url,requestMethod,requestBody);
} else {
Response response = client.performRequestWithoutAuth(url, requestMethod, requestBody);
return response.getBody(); return response.getBody();
} }
} catch (NullPointerException e) { } catch (NullPointerException e) {
@ -140,64 +139,11 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
log.error(userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$ log.error(userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$
showWarning(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template) showWarning(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation)); + ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation));
} catch (Exception e) {
log.error(userOperation + " " + ctx.getString(R.string.failed_op), e); //$NON-NLS-1$
showWarning(MessageFormat.format(ctx.getResources().getString(R.string.shared_string_action_template)
+ ": " + ctx.getResources().getString(R.string.shared_string_unexpected_error), userOperation));
} }
return null; return null;
} }
private String performBasicAuthRequest(String url, String requestMethod, String requestBody, String userOperation) throws IOException {
HttpURLConnection connection = NetworkUtils.getHttpURLConnection(url);
connection.setConnectTimeout(15000);
connection.setRequestMethod(requestMethod);
connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx)); //$NON-NLS-1$
StringBuilder responseBody = new StringBuilder();
String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$
connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
connection.setDoInput(true);
if (requestMethod.equals("PUT") || requestMethod.equals("POST") || requestMethod.equals("DELETE")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
connection.setDoOutput(true);
connection.setRequestProperty("Content-type", "text/xml"); //$NON-NLS-1$ //$NON-NLS-2$
OutputStream out = connection.getOutputStream();
if (requestBody != null) {
BufferedWriter bwr = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"), 1024); //$NON-NLS-1$
bwr.write(requestBody);
bwr.flush();
}
out.close();
}
connection.connect();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
String msg = userOperation
+ " " + ctx.getString(R.string.failed_op) + " : " + connection.getResponseMessage(); //$NON-NLS-1$//$NON-NLS-2$
log.error(msg);
showWarning(msg);
} else {
log.info("Response : " + connection.getResponseMessage()); //$NON-NLS-1$
// populate return fields.
responseBody.setLength(0);
InputStream i = connection.getInputStream();
if (i != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256); //$NON-NLS-1$
String s;
boolean f = true;
while ((s = in.readLine()) != null) {
if (!f) {
responseBody.append("\n"); //$NON-NLS-1$
} else {
f = false;
}
responseBody.append(s);
}
}
return responseBody.toString();
}
return null;
}
public long openChangeSet(String comment) { public long openChangeSet(String comment) {
long id = -1; long id = -1;
StringWriter writer = new StringWriter(256); StringWriter writer = new StringWriter(256);

View file

@ -1,16 +0,0 @@
package net.osmand.plus.osmedit.utils;
public class FailedVerificationException extends Exception {
private static final long serialVersionUID = -4936205097177668159L;
public FailedVerificationException(Exception e) {
super(e);
}
public FailedVerificationException(String msg) {
super(msg);
}
}

View file

@ -1,135 +0,0 @@
package net.osmand.plus.osmedit.utils;
import com.google.gson.*;
import net.osmand.plus.osmedit.utils.ops.OpObject;
import net.osmand.plus.osmedit.utils.ops.OpOperation;
import java.io.Reader;
import java.lang.reflect.Type;
import java.util.*;
public class JsonFormatter {
private Gson gson;
private Gson gsonOperationHash;
private Gson gsonFullOutput;
public JsonFormatter() {
GsonBuilder builder = new GsonBuilder();
builder.disableHtmlEscaping();
builder.registerTypeAdapter(OpOperation.class, new OpOperation.OpOperationBeanAdapter(false));
builder.registerTypeAdapter(OpObject.class, new OpObject.OpObjectAdapter(false));
builder.registerTypeAdapter(TreeMap.class, new MapDeserializerDoubleAsIntFix());
gson = builder.create();
builder = new GsonBuilder();
builder.disableHtmlEscaping();
builder.registerTypeAdapter(OpOperation.class, new OpOperation.OpOperationBeanAdapter(false, true));
builder.registerTypeAdapter(OpObject.class, new OpObject.OpObjectAdapter(false));
builder.registerTypeAdapter(TreeMap.class, new MapDeserializerDoubleAsIntFix());
gsonOperationHash = builder.create();
builder = new GsonBuilder();
builder.disableHtmlEscaping();
builder.registerTypeAdapter(OpOperation.class, new OpOperation.OpOperationBeanAdapter(true));
builder.registerTypeAdapter(OpObject.class, new OpObject.OpObjectAdapter(true));
builder.registerTypeAdapter(TreeMap.class, new MapDeserializerDoubleAsIntFix());
gsonFullOutput = builder.create();
}
public static class MapDeserializerDoubleAsIntFix implements JsonDeserializer<TreeMap<String, Object>> {
@Override @SuppressWarnings("unchecked")
public TreeMap<String, Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return (TreeMap<String, Object>) read(json);
}
public Object read(JsonElement in) {
if(in.isJsonArray()){
List<Object> list = new ArrayList<Object>();
JsonArray arr = in.getAsJsonArray();
for (JsonElement anArr : arr) {
list.add(read(anArr));
}
return list;
}else if(in.isJsonObject()){
Map<String, Object> map = new TreeMap<String, Object>();
JsonObject obj = in.getAsJsonObject();
Set<Map.Entry<String, JsonElement>> entitySet = obj.entrySet();
for(Map.Entry<String, JsonElement> entry: entitySet){
map.put(entry.getKey(), read(entry.getValue()));
}
return map;
}else if(in.isJsonPrimitive()){
JsonPrimitive prim = in.getAsJsonPrimitive();
if(prim.isBoolean()){
return prim.getAsBoolean();
}else if(prim.isString()){
return prim.getAsString();
}else if(prim.isNumber()){
Number num = prim.getAsNumber();
// here you can handle double int/long values
// and return any type you want
// this solution will transform 3.0 float to long values
if(Math.ceil(num.doubleValue()) == num.longValue() && (!num.toString().contains(".") || num.toString().split("\\.")[1].length() <= 1))
return num.longValue();
else {
return num.doubleValue();
}
}
}
return null;
}
}
// operations to parse / format related
public OpOperation parseOperation(String opJson) {
return gson.fromJson(opJson, OpOperation.class);
}
public OpObject parseObject(String opJson) {
return gson.fromJson(opJson, OpObject.class);
}
public Object parseBlock(String opJson) {
throw new UnsupportedOperationException("");
}
public JsonElement toJsonElement(Object o) {
return gson.toJsonTree(o);
}
@SuppressWarnings("unchecked")
public TreeMap<String, Object> fromJsonToTreeMap(String json) {
return gson.fromJson(json, TreeMap.class);
}
public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException {
return gson.fromJson(json, classOfT);
}
public String fullObjectToJson(Object o) {
return gsonFullOutput.toJson(o);
}
public String opToJsonNoHash(OpOperation op) {
return gsonOperationHash.toJson(op);
}
public String opToJson(OpOperation op) {
return gson.toJson(op);
}
public String objToJson(OpObject op) {
return gson.toJson(op);
}
}

View file

@ -1,411 +0,0 @@
package net.osmand.plus.osmedit.utils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
//import java.util.Base64;
import java.util.concurrent.ThreadLocalRandom;
import net.osmand.plus.osmedit.utils.ops.OpOperation;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
//import org.bouncycastle.crypto.generators.SCrypt;
//import org.bouncycastle.crypto.prng.FixedSecureRandom;
public class SecUtils {
private static final String SIG_ALGO_SHA1_EC = "SHA1withECDSA";
private static final String SIG_ALGO_NONE_EC = "NonewithECDSA";
public static final String SIG_ALGO_ECDSA = "ECDSA";
public static final String ALGO_EC = "EC";
public static final String EC_256SPEC_K1 = "secp256k1";
public static final String KEYGEN_PWD_METHOD_1 = "EC256K1_S17R8";
public static final String DECODE_BASE64 = "base64";
public static final String HASH_SHA256 = "sha256";
public static final String HASH_SHA1 = "sha1";
public static final String JSON_MSG_TYPE = "json";
public static final String KEY_BASE64 = DECODE_BASE64;
public static void main(String[] args) {
//1) create op, 2) sign op 3) send to server process op
//
KeyPairGenerator keyGen = null ;
SecureRandom random = null;
try {
keyGen = KeyPairGenerator.getInstance(ALGO_EC);
random = SecureRandom.getInstance("SHA1PRNG");
keyGen.initialize(1024, random);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
KeyPair kp = null;
try {
kp = SecUtils.getKeyPair(ALGO_EC,
"base64:PKCS#8:MD4CAQAwEAYHKoZIzj0CAQYFK4EEAAoEJzAlAgEBBCDR+/ByIjTHZgfdnMfP9Ab5s14mMzFX+8DYqUiGmf/3rw=="
, "base64:X.509:MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEOMUiRZwU7wW8L3A1qaJPwhAZy250VaSxJmKCiWdn9EMeubXQgWNT8XUWLV5Nvg7O3sD+1AAQLG5kHY8nOc/AyA==");
} catch (FailedVerificationException e) {
e.printStackTrace();
}
// KeyPair kp = generateECKeyPairFromPassword(KEYGEN_PWD_METHOD_1, "openplacereviews", "");
// KeyPair kp = generateRandomEC256K1KeyPair();
System.out.println(kp.getPrivate().getFormat());
System.out.println(kp.getPrivate().getAlgorithm());
try {
System.out.println(SecUtils.validateKeyPair(ALGO_EC, kp.getPrivate(), kp.getPublic()));
} catch (FailedVerificationException e) {
e.printStackTrace();
}
String pr = encodeKey(KEY_BASE64, kp.getPrivate());
String pk = encodeKey(KEY_BASE64, kp.getPublic());
String algo = kp.getPrivate().getAlgorithm();
System.out.println(String.format("Private key: %s %s\nPublic key: %s %s", kp.getPrivate().getFormat(), pr, kp
.getPublic().getFormat(), pk));
String signMessageTest = "Hello this is a registration message test";
byte[] signature = signMessageWithKey(kp, signMessageTest.getBytes(), SIG_ALGO_SHA1_EC);
System.out.println(String.format("Signed message: %s %s", android.util.Base64.decode(signature, android.util.Base64.DEFAULT),
signMessageTest));
KeyPair nk = null;
try {
nk = getKeyPair(algo, pr, pk);
} catch (FailedVerificationException e) {
e.printStackTrace();
}
// validate
pr = new String(android.util.Base64.decode(nk.getPrivate().getEncoded(), android.util.Base64.DEFAULT));
pk = new String(android.util.Base64.decode(nk.getPublic().getEncoded(), android.util.Base64.DEFAULT));
System.out.println(String.format("Private key: %s %s\nPublic key: %s %s", nk.getPrivate().getFormat(), pr, nk
.getPublic().getFormat(), pk));
System.out.println(validateSignature(nk, signMessageTest.getBytes(), SIG_ALGO_SHA1_EC, signature));
JsonFormatter formatter = new JsonFormatter();
String msg = "{\n" +
" \"type\" : \"sys.signup\",\n" +
" \"signed_by\": \"openplacereviews\",\n" +
" \"create\": [{\n" +
" \"id\": [\"openplacereviews\"],\n" +
" \"name\" : \"openplacereviews\",\n" +
" \"algo\": \"EC\",\n" +
" \"auth_method\": \"provided\",\n" +
" \"pubkey\": \"base64:X.509:MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEn6GkOTN3SYc+OyCYCpqPzKPALvUgfUVNDJ+6eyBlCHI1/gKcVqzHLwaO90ksb29RYBiF4fW/PqHcECNzwJB+QA==\"\n" +
" }]\n" +
" }";
OpOperation opOperation = formatter.parseOperation(msg);
String hash = JSON_MSG_TYPE + ":"
+ SecUtils.calculateHashWithAlgo(SecUtils.HASH_SHA256, null,
formatter.opToJsonNoHash(opOperation));
byte[] hashBytes = SecUtils.getHashBytes(hash);
String signatureTxt = SecUtils.signMessageWithKeyBase64(kp, hashBytes, SecUtils.SIG_ALGO_ECDSA, null);
System.out.println(formatter.opToJsonNoHash(opOperation));
System.out.println(hash);
System.out.println(signatureTxt);
}
public static EncodedKeySpec decodeKey(String key) {
if (key.startsWith(KEY_BASE64 + ":")) {
key = key.substring(KEY_BASE64.length() + 1);
int s = key.indexOf(':');
if (s == -1) {
throw new IllegalArgumentException(String.format("Key doesn't contain algorithm of hashing to verify"));
}
return getKeySpecByFormat(key.substring(0, s),
android.util.Base64.decode(key.substring(s + 1), android.util.Base64.DEFAULT));
}
throw new IllegalArgumentException(String.format("Key doesn't contain algorithm of hashing to verify"));
}
public static String encodeKey(String algo, PublicKey pk) {
if (algo.equals(KEY_BASE64)) {
return SecUtils.KEY_BASE64 + ":" + pk.getFormat() + ":" + encodeBase64(pk.getEncoded());
}
throw new UnsupportedOperationException("Algorithm is not supported: " + algo);
}
public static String encodeKey(String algo, PrivateKey pk) {
if (algo.equals(KEY_BASE64)) {
return SecUtils.KEY_BASE64 + ":" + pk.getFormat() + ":" + encodeBase64(pk.getEncoded());
}
throw new UnsupportedOperationException("Algorithm is not supported: " + algo);
}
public static EncodedKeySpec getKeySpecByFormat(String format, byte[] data) {
switch (format) {
case "PKCS#8":
return new PKCS8EncodedKeySpec(data);
case "X.509":
return new X509EncodedKeySpec(data);
}
throw new IllegalArgumentException(format);
}
public static String encodeBase64(byte[] data) {
return new String(android.util.Base64.decode(data, android.util.Base64.DEFAULT));
}
public static boolean validateKeyPair(String algo, PrivateKey privateKey, PublicKey publicKey)
throws FailedVerificationException {
if (!algo.equals(ALGO_EC)) {
throw new FailedVerificationException("Algorithm is not supported: " + algo);
}
// create a challenge
byte[] challenge = new byte[512];
ThreadLocalRandom.current().nextBytes(challenge);
try {
// sign using the private key
Signature sig = Signature.getInstance(SIG_ALGO_SHA1_EC);
sig.initSign(privateKey);
sig.update(challenge);
byte[] signature = sig.sign();
// verify signature using the public key
sig.initVerify(publicKey);
sig.update(challenge);
boolean keyPairMatches = sig.verify(signature);
return keyPairMatches;
} catch (InvalidKeyException e) {
throw new FailedVerificationException(e);
} catch (NoSuchAlgorithmException e) {
throw new FailedVerificationException(e);
} catch (SignatureException e) {
throw new FailedVerificationException(e);
}
}
public static KeyPair getKeyPair(String algo, String prKey, String pbKey) throws FailedVerificationException {
try {
KeyFactory keyFactory = KeyFactory.getInstance(algo);
PublicKey pb = null;
PrivateKey pr = null;
if (pbKey != null) {
pb = keyFactory.generatePublic(decodeKey(pbKey));
}
if (prKey != null) {
pr = keyFactory.generatePrivate(decodeKey(prKey));
}
return new KeyPair(pb, pr);
} catch (NoSuchAlgorithmException e) {
throw new FailedVerificationException(e);
} catch (InvalidKeySpecException e) {
throw new FailedVerificationException(e);
}
}
public static KeyPair generateKeyPairFromPassword(String algo, String keygenMethod, String salt, String pwd)
throws FailedVerificationException {
if (algo.equals(ALGO_EC)) {
return generateECKeyPairFromPassword(keygenMethod, salt, pwd);
}
throw new UnsupportedOperationException("Unsupported algo keygen method: " + algo);
}
public static KeyPair generateECKeyPairFromPassword(String keygenMethod, String salt, String pwd)
throws FailedVerificationException {
if (keygenMethod.equals(KEYGEN_PWD_METHOD_1)) {
return generateEC256K1KeyPairFromPassword(salt, pwd);
}
throw new UnsupportedOperationException("Unsupported keygen method: " + keygenMethod);
}
// "EC:secp256k1:scrypt(salt,N:17,r:8,p:1,len:256)" algorithm - EC256K1_S17R8
public static KeyPair generateEC256K1KeyPairFromPassword(String salt, String pwd)
throws FailedVerificationException {
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGO_EC);
ECGenParameterSpec ecSpec = new ECGenParameterSpec(EC_256SPEC_K1);
if (pwd.length() < 10) {
throw new IllegalArgumentException("Less than 10 characters produces only 50 bit entropy");
}
byte[] bytes = pwd.getBytes("UTF-8");
//byte[] scrypt = SCrypt.generate(bytes, salt.getBytes("UTF-8"), 1 << 17, 8, 1, 256);
//kpg.initialize(ecSpec, new FixedSecureRandom(scrypt));
return kpg.genKeyPair();
} catch (NoSuchAlgorithmException e) {
throw new FailedVerificationException(e);
} catch (UnsupportedEncodingException e) {
throw new FailedVerificationException(e);
} /* catch (InvalidAlgorithmParameterException e) {
throw new FailedVerificationException(e);
}*/
}
public static KeyPair generateRandomEC256K1KeyPair() throws FailedVerificationException {
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGO_EC);
ECGenParameterSpec ecSpec = new ECGenParameterSpec(EC_256SPEC_K1);
kpg.initialize(ecSpec);
return kpg.genKeyPair();
} catch (NoSuchAlgorithmException e) {
throw new FailedVerificationException(e);
} catch (InvalidAlgorithmParameterException e) {
throw new FailedVerificationException(e);
}
}
public static String signMessageWithKeyBase64(KeyPair keyPair, byte[] msg, String signAlgo, ByteArrayOutputStream out) {
byte[] sigBytes = signMessageWithKey(keyPair, msg, signAlgo);
if(out != null) {
try {
out.write(sigBytes);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
String signature = new String(android.util.Base64.decode(sigBytes, android.util.Base64.DEFAULT));
return signAlgo + ":" + DECODE_BASE64 + ":" + signature;
}
public static byte[] signMessageWithKey(KeyPair keyPair, byte[] msg, String signAlgo) {
try {
Signature sig = Signature.getInstance(getInternalSigAlgo(signAlgo));
sig.initSign(keyPair.getPrivate());
sig.update(msg);
byte[] signatureBytes = sig.sign();
return signatureBytes;
} catch (NoSuchAlgorithmException e) {
//throw new FailedVerificationException(e);
} catch (InvalidKeyException e) {
//throw new FailedVerificationException(e);
} catch (SignatureException e) {
//throw new FailedVerificationException(e);
}
return new byte[0];
}
public static boolean validateSignature(KeyPair keyPair, byte[] msg, String sig) {
if(sig == null || keyPair == null) {
return false;
}
int ind = sig.indexOf(':');
String sigAlgo = sig.substring(0, ind);
return validateSignature(keyPair, msg, sigAlgo, decodeSignature(sig.substring(ind + 1)));
}
public static boolean validateSignature(KeyPair keyPair, byte[] msg, String sigAlgo, byte[] signature) {
if (keyPair == null) {
return false;
}
try {
Signature sig = Signature.getInstance(getInternalSigAlgo(sigAlgo));
sig.initVerify(keyPair.getPublic());
sig.update(msg);
return sig.verify(signature);
} catch (NoSuchAlgorithmException e) {
//throw new FailedVerificationException(e);
} catch (InvalidKeyException e) {
//throw new FailedVerificationException(e);
} catch (SignatureException e) {
//throw new FailedVerificationException(e);
}
return false;
}
private static String getInternalSigAlgo(String sigAlgo) {
return sigAlgo.equals(SIG_ALGO_ECDSA)? SIG_ALGO_NONE_EC : sigAlgo;
}
public static byte[] calculateHash(String algo, byte[] b1, byte[] b2) {
byte[] m = mergeTwoArrays(b1, b2);
if (algo.equals(HASH_SHA256)) {
return DigestUtils.sha256(m);
} else if (algo.equals(HASH_SHA1)) {
return DigestUtils.sha1(m);
}
throw new UnsupportedOperationException();
}
public static byte[] mergeTwoArrays(byte[] b1, byte[] b2) {
byte[] m = b1 == null ? b2 : b1;
if(b2 != null && b1 != null) {
m = new byte[b1.length + b2.length];
System.arraycopy(b1, 0, m, 0, b1.length);
System.arraycopy(b2, 0, m, b1.length, b2.length);
}
return m;
}
public static String calculateHashWithAlgo(String algo, String salt, String msg) {
try {
String hex = Hex.encodeHexString(calculateHash(algo, salt == null ? null : salt.getBytes("UTF-8"),
msg == null ? null : msg.getBytes("UTF-8")));
return algo + ":" + hex;
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
}
public static String calculateHashWithAlgo(String algo, byte[] bts) {
byte[] hash = calculateHash(algo, bts, null);
return formatHashWithAlgo(algo, hash);
}
public static String formatHashWithAlgo(String algo, byte[] hash) {
String hex = Hex.encodeHexString(hash);
return algo + ":" + hex;
}
public static byte[] getHashBytes(String msg) {
if(msg == null || msg.length() == 0) {
// special case for empty hash
return new byte[0];
}
int i = msg.lastIndexOf(':');
String s = i >= 0 ? msg.substring(i + 1) : msg;
try {
return Hex.decodeHex(s);
} catch (DecoderException e) {
throw new IllegalArgumentException(e);
}
}
public static boolean validateHash(String hash, String salt, String msg) {
int s = hash.indexOf(":");
if (s == -1) {
throw new IllegalArgumentException(String.format("Hash %s doesn't contain algorithm of hashing to verify",
s));
}
String v = calculateHashWithAlgo(hash.substring(0, s), salt, msg);
return hash.equals(v);
}
public static byte[] decodeSignature(String digest) {
try {
int indexOf = digest.indexOf(DECODE_BASE64 + ":");
if (indexOf != -1) {
// return Base64.getDecoder().decode(digest.substring(indexOf + DECODE_BASE64.length() + 1).
// getBytes("UTF-8"));
return android.util.Base64.decode(digest.substring(indexOf + DECODE_BASE64.length() + 1)
.getBytes("UTF-8"), android.util.Base64.DEFAULT);
}
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
throw new IllegalArgumentException("Unknown format for signature " + digest);
}
public static String hexify(byte[] bytes) {
if(bytes == null || bytes.length == 0) {
return "";
}
return Hex.encodeHexString(bytes);
}
}

View file

@ -1,530 +0,0 @@
package net.osmand.plus.osmedit.utils.ops;
import com.google.gson.*;
import net.osmand.plus.osmedit.utils.util.JsonObjectUtils;
import net.osmand.plus.osmedit.utils.util.OUtils;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
public class OpObject {
public static final String F_NAME = "name";
public static final String F_ID = "id";
public static final String F_COMMENT = "comment";
public static final String TYPE_OP = "sys.op";
public static final String TYPE_BLOCK = "sys.block";
public static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
// transient info about validation timing etc
public static final String F_EVAL = "eval";
public static final String F_VALIDATION = "validation";
public static final String F_TIMESTAMP_ADDED = "timestamp";
public static final String F_PARENT_TYPE = "parentType";
public static final String F_PARENT_HASH = "parentHash";
public static final String F_CHANGE = "change";
public static final String F_CURRENT = "current";
// voting
public static final String F_OP = "op";
public static final String F_STATE = "state";
public static final String F_OPEN = "open";
public static final String F_FINAL = "final";
public static final String F_VOTE = "vote";
public static final String F_VOTES = "votes";
public static final String F_SUBMITTED_OP_HASH = "submittedOpHash";
public static final String F_USER = "user";
public static final OpObject NULL = new OpObject(true);
public static SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
static {
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
}
protected Map<String, Object> fields = new TreeMap<>();
protected transient Map<String, Object> cacheFields;
protected boolean isImmutable;
protected transient String parentType;
protected transient String parentHash;
protected transient boolean deleted;
public OpObject() {}
public OpObject(boolean deleted) {
this.deleted = deleted;
}
public OpObject(OpObject cp) {
this(cp, false);
}
public OpObject(OpObject cp, boolean copyCacheFields) {
createOpObjectCopy(cp, copyCacheFields);
}
@SuppressWarnings("unchecked")
private OpObject createOpObjectCopy(OpObject opObject, boolean copyCacheFields) {
this.parentType = opObject.parentType;
this.parentHash = opObject.parentHash;
this.deleted = opObject.deleted;
this.fields = (Map<String, Object>) copyingObjects(opObject.fields, copyCacheFields);
if (opObject.cacheFields != null && copyCacheFields) {
this.cacheFields = (Map<String, Object>) copyingObjects(opObject.cacheFields, copyCacheFields);
}
this.isImmutable = false;
return this;
}
public boolean isDeleted() {
return deleted;
}
@SuppressWarnings("unchecked")
private Object copyingObjects(Object object, boolean copyCacheFields) {
if (object instanceof Number) {
return (Number) object;
} else if (object instanceof String) {
return (String) object;
} else if (object instanceof Boolean) {
return (Boolean) object;
} else if (object instanceof List) {
List<Object> copy = new ArrayList<>();
List<Object> list = (List<Object>) object;
for (Object o : list) {
copy.add(copyingObjects(o, copyCacheFields));
}
return copy;
} else if (object instanceof Map) {
Map<Object, Object> copy = new LinkedHashMap<>();
Map<Object, Object> map = (Map<Object, Object>) object;
for (Object o : map.keySet()) {
copy.put(o, copyingObjects(map.get(o), copyCacheFields));
}
return copy;
} else if (object instanceof OpObject) {
return new OpObject((OpObject) object);
} else {
throw new UnsupportedOperationException("Type of object is not supported");
}
}
public void setParentOp(OpOperation op) {
setParentOp(op.type, op.getRawHash());
}
public void setParentOp(String parentType, String parentHash) {
this.parentType = parentType;
this.parentHash = parentHash;
}
public String getParentHash() {
return parentHash;
}
public String getParentType() {
return parentType;
}
public List<String> getId() {
return getStringList(F_ID);
}
public void setId(String id) {
addOrSetStringValue(F_ID, id);;
}
public boolean isImmutable() {
return isImmutable;
}
public OpObject makeImmutable() {
isImmutable = true;
return this;
}
public Object getFieldByExpr(String field) {
if (field.contains(".") || field.contains("[") || field.contains("]")) {
return JsonObjectUtils.getField(this.fields, generateFieldSequence(field));
}
return fields.get(field);
}
/**
* generateFieldSequence("a") - [a]
* generateFieldSequence("a.b") - [a, b]
* generateFieldSequence("a.b.c.de") - [a, b, c, de]
* generateFieldSequence("a.bwerq.c") - [a, bwerq, c]
* generateFieldSequence("a.bwerq...c") - [a, bwerq, c]
* generateFieldSequence("a.bwereq..c..") - [a, bwerq, c]
* generateFieldSequence("a.{b}") - [a, b]
* generateFieldSequence("a.{b.c.de}") - [a, b.c.de]
* generateFieldSequence("a.{b.c.de}") - [a, b.c.de]
* generateFieldSequence("a.{b{}}") - [a, b{}]
* generateFieldSequence("a.{b{}d.q}") - [a, b{}d.q]
*/
private static List<String> generateFieldSequence(String field) {
int STATE_OPEN_BRACE = 1;
int STATE_OPEN = 0;
int state = STATE_OPEN;
int start = 0;
List<String> l = new ArrayList<String>();
for(int i = 0; i < field.length(); i++) {
boolean split = false;
if (i == field.length() - 1) {
if (state == STATE_OPEN_BRACE) {
if(field.charAt(i) == '}') {
split = true;
} else {
throw new IllegalArgumentException("Illegal field expression: " + field);
}
} else {
if(field.charAt(i) != '.') {
i++;
}
split = true;
}
} else {
if (field.charAt(i) == '.' && state == STATE_OPEN) {
split = true;
} else if (field.charAt(i) == '}' && field.charAt(i + 1) == '.' && state == STATE_OPEN_BRACE) {
split = true;
} else if (field.charAt(i) == '{' && state == STATE_OPEN) {
if(start != i) {
throw new IllegalArgumentException("Illegal field expression (wrap {} is necessary): " + field);
}
state = STATE_OPEN_BRACE;
start = i + 1;
}
}
if(split) {
if (i != start) {
l.add(field.substring(start, i));
}
start = i + 1;
state = STATE_OPEN;
}
}
return l;
}
public void setFieldByExpr(String field, Object object) {
if (field.contains(".") || field.contains("[") || field.contains("]")) {
List<String> fieldSequence = generateFieldSequence(field);
if (object == null) {
JsonObjectUtils.deleteField(this.fields, fieldSequence);
} else {
JsonObjectUtils.setField(this.fields, fieldSequence, object);
}
} else if (object == null) {
fields.remove(field);
} else {
fields.put(field, object);
}
}
public Object getCacheObject(String f) {
if(cacheFields == null) {
return null;
}
return cacheFields.get(f);
}
public void putCacheObject(String f, Object o) {
if (isImmutable()) {
if (cacheFields == null) {
cacheFields = new ConcurrentHashMap<String, Object>();
}
cacheFields.put(f, o);
}
}
public void setId(String id, String id2) {
List<String> list = new ArrayList<String>();
list.add(id);
list.add(id2);
putObjectValue(F_ID, list);
}
public String getName() {
return getStringValue(F_NAME);
}
public String getComment() {
return getStringValue(F_COMMENT);
}
public Map<String, Object> getRawOtherFields() {
return fields;
}
@SuppressWarnings("unchecked")
public Map<String, String> getStringMap(String field) {
return (Map<String, String>) fields.get(field);
}
@SuppressWarnings("unchecked")
public Map<String, List<String>> getMapStringList(String field) {
return (Map<String, List<String>>) fields.get(field);
}
@SuppressWarnings("unchecked")
public List<Map<String, String>> getListStringMap(String field) {
return (List<Map<String, String>>) fields.get(field);
}
@SuppressWarnings("unchecked")
public List<Map<String, Object>> getListStringObjMap(String field) {
return (List<Map<String, Object>>) fields.get(field);
}
@SuppressWarnings("unchecked")
public Map<String, Object> getStringObjMap(String field) {
return (Map<String, Object>) fields.get(field);
}
@SuppressWarnings("unchecked")
public <T> T getField(T def, String... fields) {
Map<String, Object> p = this.fields;
for(int i = 0; i < fields.length - 1 ; i++) {
p = (Map<String, Object>) p.get(fields[i]);
if(p == null) {
return def;
}
}
T res = (T) p.get(fields[fields.length - 1]);
if(res == null) {
return def;
}
return res;
}
@SuppressWarnings("unchecked")
public Map<List<String>, Object> getStringListObjMap(String field) {
return (Map<List<String>, Object>) fields.get(field);
}
public long getDate(String field) {
String date = getStringValue(field);
if(OUtils.isEmpty(date)) {
return 0;
}
try {
return dateFormat.parse(date).getTime();
} catch (ParseException e) {
return 0;
}
}
public void setDate(String field, long time) {
putStringValue(field, dateFormat.format(new Date(time)));
}
public Number getNumberValue(String field) {
return (Number) fields.get(field);
}
public int getIntValue(String key, int def) {
Number o = getNumberValue(key);
return o == null ? def : o.intValue();
}
public long getLongValue(String key, long def) {
Number o = getNumberValue(key);
return o == null ? def : o.longValue();
}
public String getStringValue(String field) {
Object o = fields.get(field);
if (o instanceof String || o == null) {
return (String) o;
}
return o.toString();
}
@SuppressWarnings("unchecked")
public List<String> getStringList(String field) {
// cast to list if it is single value
Object o = fields.get(field);
if(o == null || o.toString().isEmpty()) {
return Collections.emptyList();
}
if(o instanceof String) {
return Collections.singletonList(o.toString());
}
return (List<String>) o;
}
public Object getObjectValue(String field) {
return fields.get(field);
}
public void putStringValue(String key, String value) {
checkNotImmutable();
if(value == null) {
fields.remove(key);
} else {
fields.put(key, value);
}
}
/**
* Operates as a single value if cardinality is less than 1
* or as a list of values if it stores > 1 value
* @param key
* @param value
*/
@SuppressWarnings("unchecked")
public void addOrSetStringValue(String key, String value) {
checkNotImmutable();
Object o = fields.get(key);
if(o == null) {
fields.put(key, value);
} else if(o instanceof List) {
((List<String>) o).add(value);
} else {
List<String> list = new ArrayList<String>();
list.add(o.toString());
list.add(value);
fields.put(key, list);
}
}
@SuppressWarnings("unchecked")
public Map<String, Object> getChangedEditFields() {
return (Map<String, Object>) fields.get(F_CHANGE);
}
@SuppressWarnings("unchecked")
public Map<String, Object> getCurrentEditFields() {
return (Map<String, Object>) fields.get(F_CURRENT);
}
public void putObjectValue(String key, Object value) {
checkNotImmutable();
if(value == null) {
fields.remove(key);
} else {
fields.put(key, value);
}
}
public void checkNotImmutable() {
if(isImmutable) {
throw new IllegalStateException("Object is immutable");
}
}
public void checkImmutable() {
if(!isImmutable) {
throw new IllegalStateException("Object is mutable");
}
}
public Object remove(String key) {
checkNotImmutable();
return fields.remove(key);
}
public Map<String, Object> getMixedFieldsAndCacheMap() {
TreeMap<String, Object> mp = new TreeMap<>(fields);
if(cacheFields != null || parentType != null || parentHash != null) {
TreeMap<String, Object> eval = new TreeMap<String, Object>();
if(parentType != null) {
eval.put(F_PARENT_TYPE, parentType);
}
if(parentHash != null) {
eval.put(F_PARENT_HASH, parentHash);
}
if (cacheFields != null) {
Iterator<Entry<String, Object>> it = cacheFields.entrySet().iterator();
while (it.hasNext()) {
Entry<String, Object> e = it.next();
Object v = e.getValue();
if (v instanceof Map || v instanceof String || v instanceof Number) {
eval.put(e.getKey(), v);
}
}
}
if(eval.size() > 0) {
mp.put(F_EVAL, eval);
}
}
return mp;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((fields == null) ? 0 : fields.hashCode());
return result;
}
@Override
public String toString() {
return getClass().getSimpleName() + "[" + fields + "]";
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
OpObject other = (OpObject) obj;
if (fields == null) {
if (other.fields != null)
return false;
} else if (!fields.equals(other.fields))
return false;
return true;
}
public static class OpObjectAdapter implements JsonDeserializer<OpObject>,
JsonSerializer<OpObject> {
private boolean fullOutput;
public OpObjectAdapter(boolean fullOutput) {
this.fullOutput = fullOutput;
}
@Override
public OpObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
OpObject bn = new OpObject();
bn.fields = context.deserialize(json, TreeMap.class);
// remove cache
bn.fields.remove(F_EVAL);
return bn;
}
@Override
public JsonElement serialize(OpObject src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(fullOutput ? src.getMixedFieldsAndCacheMap() : src.fields);
}
}
}

View file

@ -1,281 +0,0 @@
package net.osmand.plus.osmedit.utils.ops;
import com.google.gson.*;
import java.lang.reflect.Type;
import java.util.*;
public class OpOperation extends OpObject {
public static final String F_TYPE = "type";
public static final String F_SIGNED_BY = "signed_by";
public static final String F_HASH = "hash";
public static final String F_SIGNATURE = "signature";
public static final String F_REF = "ref";
public static final String F_CREATE = "create";
public static final String F_DELETE = "delete";
public static final String F_EDIT = "edit";
public static final String F_NAME = "name";
public static final String F_COMMENT = "comment";
private List<OpObject> createdObjects = new LinkedList<OpObject>();
private List<OpObject> editedObjects = new LinkedList<OpObject>();
protected String type;
public OpOperation() {
}
public OpOperation(OpOperation cp, boolean copyCacheFields) {
super(cp, copyCacheFields);
this.type = cp.type;
for(OpObject o : cp.createdObjects) {
this.createdObjects.add(new OpObject(o, copyCacheFields));
}
for(OpObject o : cp.editedObjects) {
this.editedObjects.add(new OpObject(o, copyCacheFields));
}
}
public String getOperationType() {
return type;
}
public void setType(String name) {
checkNotImmutable();
type = name;
updateObjectsRef();
}
protected void updateObjectsRef() {
for(OpObject o : createdObjects) {
o.setParentOp(this);
}
for(OpObject o : editedObjects) {
o.setParentOp(this);
}
}
public String getType() {
return type;
}
public OpOperation makeImmutable() {
isImmutable = true;
for(OpObject o : createdObjects) {
o.makeImmutable();
}
for(OpObject o : editedObjects) {
o.makeImmutable();
}
return this;
}
public void setSignedBy(String value) {
putStringValue(F_SIGNED_BY, value);
}
public void addOtherSignedBy(String value) {
super.addOrSetStringValue(F_SIGNED_BY, value);
}
public List<String> getSignedBy() {
return getStringList(F_SIGNED_BY);
}
public String getHash() {
return getStringValue(F_HASH);
}
public String getRawHash() {
String rw = getStringValue(F_HASH);
// drop algorithm and everything else
if(rw != null) {
rw = rw.substring(rw.lastIndexOf(':') + 1);
}
return rw;
}
public List<String> getSignatureList() {
return getStringList(F_SIGNATURE);
}
public Map<String, List<String>> getRef() {
return getMapStringList(F_REF);
}
@SuppressWarnings("unchecked")
public List<List<String>> getDeleted() {
List<List<String>> l = (List<List<String>>) fields.get(F_DELETE);
if(l == null) {
return Collections.emptyList();
}
return l;
}
public boolean hasDeleted() {
return getDeleted().size() > 0;
}
public void addDeleted(List<String> id) {
if(!fields.containsKey(F_DELETE)) {
ArrayList<List<String>> lst = new ArrayList<>();
lst.add(id);
putObjectValue(F_DELETE, lst);
} else {
getDeleted().add(id);
}
}
public List<OpObject> getCreated() {
return createdObjects;
}
public void addCreated(OpObject o) {
checkNotImmutable();
createdObjects.add(o);
if(type != null) {
o.setParentOp(this);
}
}
public boolean hasCreated() {
return createdObjects.size() > 0;
}
public void addEdited(OpObject o) {
checkNotImmutable();
editedObjects.add(o);
if (type != null) {
o.setParentOp(this);
}
}
public List<OpObject> getEdited() {
return editedObjects;
}
public boolean hasEdited() {
return editedObjects.size() > 0;
}
public String getName() {
return getStringValue(F_NAME);
}
public String getComment() {
return getStringValue(F_COMMENT);
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((createdObjects == null) ? 0 : createdObjects.hashCode());
result = prime * result + ((editedObjects == null) ? 0 : editedObjects.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
OpOperation other = (OpOperation) obj;
if (createdObjects == null) {
if (other.createdObjects != null)
return false;
} else if (!createdObjects.equals(other.createdObjects))
return false;
if (editedObjects == null) {
if (other.editedObjects != null)
return false;
} else if (!editedObjects.equals(other.editedObjects))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
public static class OpOperationBeanAdapter implements JsonDeserializer<OpOperation>,
JsonSerializer<OpOperation> {
// plain serialization to calculate hash
private boolean excludeHashAndSignature;
private boolean fullOutput;
public OpOperationBeanAdapter(boolean fullOutput, boolean excludeHashAndSignature) {
this.excludeHashAndSignature = excludeHashAndSignature;
this.fullOutput = fullOutput;
}
public OpOperationBeanAdapter(boolean fullOutput) {
this.fullOutput = fullOutput;
this.excludeHashAndSignature = false;
}
@Override
public OpOperation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject jsonObj = json.getAsJsonObject();
OpOperation op = new OpOperation();
JsonElement tp = jsonObj.remove(F_TYPE);
if(tp != null) {
String opType = tp.getAsString();
op.type = opType;
} else {
op.type = "";
}
JsonElement createdObjs = jsonObj.remove(F_CREATE);
if(createdObjs != null) {
JsonArray ar = createdObjs.getAsJsonArray();
for(int i = 0; i < ar.size(); i++) {
//op.addCreated(context.deserialize(ar.get(i), OpObject.class));
}
}
JsonElement editedObjs = jsonObj.remove(F_EDIT);
if (editedObjs != null) {
for (JsonElement editElem : editedObjs.getAsJsonArray()) {
//op.addEdited(context.deserialize(editElem, OpObject.class));
}
}
jsonObj.remove(F_EVAL);
op.fields = context.deserialize(jsonObj, TreeMap.class);
return op;
}
@Override
public JsonElement serialize(OpOperation src, Type typeOfSrc, JsonSerializationContext context) {
TreeMap<String, Object> tm = new TreeMap<>(fullOutput ? src.getMixedFieldsAndCacheMap() : src.fields);
if(excludeHashAndSignature) {
tm.remove(F_SIGNATURE);
tm.remove(F_HASH);
}
tm.put(F_TYPE, src.type);
if (src.hasEdited()) {
tm.put(F_EDIT, context.serialize(src.editedObjects));
}
if(src.hasCreated()) {
tm.put(F_CREATE, context.serialize(src.createdObjects));
}
return context.serialize(tm);
}
}
}

View file

@ -1,171 +0,0 @@
package net.osmand.plus.osmedit.utils.ops;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
public class PerformanceMetrics {
private static final PerformanceMetrics inst = new PerformanceMetrics();
public static final int METRICS_COUNT = 2;
public static PerformanceMetrics i() {
return inst;
}
private final Map<String, PerformanceMetric> metrics = new ConcurrentHashMap<String, PerformanceMetric>();
private final AtomicInteger ids = new AtomicInteger();
private final PerformanceMetric DISABLED = new PerformanceMetric(-1, "<disabled>");
private boolean enabled = true;
private PerformanceMetric overhead;
private PerformanceMetrics() {
overhead = getByKey("_overhead");
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Map<String, PerformanceMetric> getMetrics() {
return metrics;
}
public PerformanceMetric getMetric(String prefix, String key) {
if(!enabled) {
return DISABLED;
}
return getMetric(prefix + "." + key);
}
public void reset(int c) {
for(PerformanceMetric p : metrics.values()) {
p.reset(c);
}
}
public PerformanceMetric getMetric(String key) {
if(!enabled) {
return DISABLED;
}
long s = System.nanoTime();
PerformanceMetric pm = getByKey(key);
overhead.capture(System.nanoTime() - s);
return pm;
}
private PerformanceMetric getByKey(String key) {
PerformanceMetric pm = metrics.get(key);
if(pm == null) {
pm = new PerformanceMetric(ids.incrementAndGet(), key);
metrics.put(key, pm);
}
return pm;
}
public final class PerformanceMetric {
final String name;
final int id;
String description;
AtomicInteger invocations = new AtomicInteger();
AtomicLong totalDuration = new AtomicLong();
AtomicInteger invocationsA = new AtomicInteger();
AtomicLong totalDurationA = new AtomicLong();
AtomicInteger invocationsB = new AtomicInteger();
AtomicLong totalDurationB = new AtomicLong();
private PerformanceMetric(int id, String name) {
this.id = id;
this.name = name;
}
public Metric start() {
if(id == -1) {
return Metric.EMPTY;
}
return new Metric(this);
}
public String getName() {
return name;
}
public void setDescription(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void reset(int c) {
if(c == 1) {
invocationsA.set(0);
totalDurationA.set(0);
} else if(c == 2) {
totalDurationB.set(0);
invocationsB.set(0);
}
}
public int getInvocations(int c) {
if(c == 1) {
return invocationsA.get();
} else if(c == 2) {
return invocationsB.get();
}
return invocations.get();
}
public long getDuration(int c) {
if(c == 1) {
return totalDurationA.get();
} else if(c == 2) {
return totalDurationB.get();
}
return totalDuration.get();
}
public int getId() {
return id;
}
long capture(long d) {
invocations.incrementAndGet();
totalDuration.addAndGet(d);
invocationsA.incrementAndGet();
totalDurationA.addAndGet(d);
invocationsB.incrementAndGet();
totalDurationB.addAndGet(d);
return d;
}
}
public static final class Metric {
long start;
PerformanceMetric m;
boolean e;
public static final Metric EMPTY = new Metric(true);
private Metric(PerformanceMetric m) {
start = System.nanoTime();
this.m = m;
}
private Metric(boolean empty) {
e = empty;
}
public long capture() {
if(e) {
return 0;
}
return m.capture(System.nanoTime() - start);
}
}
}

View file

@ -1,25 +0,0 @@
package net.osmand.plus.osmedit.utils.util;
public interface DBConstants {
public static final String SCHEMA_NAME = "public";
// Tables
public static final String BLOCK_TABLE = "blocks";
public static final String LOGINS_TABLE = "logins";
public static final String USERS_TABLE = "users";
public static final String QUEUE_TABLE = "queue";
public static final String ROLES_TABLE = "roles";
public static final String TABLES_TABLE = "tables";
public static final String OP_DEFINITIONS_TABLE = "op_definitions";
public static final String EXECUTED_OPERATIONS_TABLE = "operations";
}

View file

@ -1,275 +0,0 @@
package net.osmand.plus.osmedit.utils.util;
import java.util.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Class uses for work with Json Object represent as Map.
*/
public class JsonObjectUtils {
private static final int GET_OPERATION = 0;
private static final int SET_OPERATION = 1;
private static final int DELETE_OPERATION = 2;
protected static final Log LOGGER = LogFactory.getLog(JsonObjectUtils.class);
private static class OperationAccess {
private final int operation;
private final Object value;
private OperationAccess(int op, Object v) {
this.operation = op;
this.value = v;
}
}
/**
* Retrieve value from jsonMap by field sequence.
* @param jsonMap source json object deserialized in map
* @param fieldSequence Sequence to field value.
* Example: person.car.number have to be ["person", "car[2]", "number"]
* @return Field value
*/
public static Object getField(Map<String, Object> jsonMap, String[] fieldSequence) {
return accessField(jsonMap, fieldSequence, new OperationAccess(GET_OPERATION, null));
}
/**
* Set value to json field (path to field presented as sequence of string)
*
* @param jsonMap source json object deserialized in map
* @param fieldSequence Sequence to field value.
* * Example: person.car.number have to be ["person", "car[2]", "number"]
* @param field field value
* @return
*/
public static Object setField(Map<String, Object> jsonMap, List<String> fieldSequence, Object field) {
return setField(jsonMap, fieldSequence.toArray(new String[fieldSequence.size()]), field);
}
/**
* Set value to json field (path to field presented as sequence of string)
*
* @param jsonObject source json object deserialized in map
* @param fieldSequence Sequence to field value.
* * Example: person.car.number have to be ["person", "car[2]", "number"]
* @param field field value
* @return
*/
public static Object setField(Map<String, Object> jsonObject, String[] fieldSequence, Object field) {
return accessField(jsonObject, fieldSequence, new OperationAccess(SET_OPERATION, field));
}
/**
* Retrieve value from jsonMap by field sequence.
*
* @param jsonObject source json object deserialized in map
* @param fieldSequence Sequence to field value.
* Example: person.car.number have to be ["person", "car[2]", "number"]
* @return Field value
*/
public static Object getField(Map<String, Object> jsonObject, List<String> fieldSequence) {
return getField(jsonObject, fieldSequence.toArray(new String[fieldSequence.size()]));
}
/**
* Delete field value from json Map (field path presented as sequence of string)
*
* @param jsonMap source json object deserialized in map
* @param fieldSequence Sequence to field value.
* Example: person.car.number have to be ["person", "car[2]", "number"]
* @return
*/
public static Object deleteField(Map<String, Object> jsonMap, List<String> fieldSequence) {
return accessField(jsonMap, fieldSequence.toArray(new String[fieldSequence.size()]), new OperationAccess(DELETE_OPERATION, null));
}
@SuppressWarnings("unchecked")
private static Object accessField(Map<String, Object> jsonObject, String[] fieldSequence, OperationAccess op) {
if (fieldSequence == null || fieldSequence.length == 0) {
throw new IllegalArgumentException("Field sequence is empty. Set value to root not possible.");
}
String fieldName = null;
Map<String, Object> jsonObjLocal = jsonObject;
List<Object> jsonListLocal = null;
int indexToAccess = -1;
for(int i = 0; i < fieldSequence.length; i++) {
boolean last = i == fieldSequence.length - 1;
fieldName = fieldSequence[i];
int indOpArray = -1;
for(int ic = 0; ic < fieldName.length(); ) {
if(ic > 0 && (fieldName.charAt(ic) == '[' || fieldName.charAt(ic) == ']') &&
fieldName.charAt(ic - 1) == '\\') {
// replace '\[' with '['
fieldName = fieldName.substring(0, ic - 1) + fieldName.substring(ic);
} else if(fieldName.charAt(ic) == '[') {
indOpArray = ic;
break;
} else {
ic++;
}
}
jsonListLocal = null; // reset
if(indOpArray == -1) {
if(!last) {
Map<String, Object> fieldAccess = (Map<String, Object>) jsonObjLocal.get(fieldName);
if(fieldAccess == null) {
if(op.operation == GET_OPERATION) {
// don't modify during get operation
return null;
}
Map<String, Object> newJsonMap = new TreeMap<>();
jsonObjLocal.put(fieldName, newJsonMap);
jsonObjLocal = newJsonMap;
} else {
jsonObjLocal = fieldAccess;
}
}
} else {
String arrayFieldName = fieldName.substring(0, indOpArray);
if(arrayFieldName.contains("]")) {
throw new IllegalArgumentException(String.format("Illegal field array modifier %s", fieldSequence[i]));
}
jsonListLocal = (List<Object>) jsonObjLocal.get(arrayFieldName);
if (jsonListLocal == null) {
if (op.operation == GET_OPERATION) {
// don't modify during get operation
return null;
}
jsonListLocal = new ArrayList<Object>();
jsonObjLocal.put(arrayFieldName, jsonListLocal);
}
while (indOpArray != -1) {
fieldName = fieldName.substring(indOpArray + 1);
int indClArray = fieldName.indexOf("]");
if (indClArray == -1) {
throw new IllegalArgumentException(String.format("Illegal field array modifier %s", fieldSequence[i]));
}
if(indClArray == fieldName.length() - 1) {
indOpArray = -1;
} else if(fieldName.charAt(indClArray + 1) == '[') {
indOpArray = indClArray + 1;
} else {
throw new IllegalArgumentException(String.format("Illegal field array modifier %s", fieldSequence[i]));
}
int index = Integer.parseInt(fieldName.substring(0, indClArray));
if (last && indOpArray == -1) {
indexToAccess = index;
} else {
Object obj = null;
if (index < jsonListLocal.size() && index >= 0) {
obj = jsonListLocal.get(index);
} else if (op.operation == SET_OPERATION && (index == -1 || index == jsonListLocal.size())) {
index = jsonListLocal.size();
jsonListLocal.add(null);
} else {
throw new IllegalArgumentException(
String.format("Illegal access to array at position %d", index));
}
if (obj == null) {
if (op.operation == GET_OPERATION) {
// don't modify during get operation
return null;
}
if (indOpArray == -1) {
obj = new TreeMap<>();
} else {
obj = new ArrayList<Object>();
}
jsonListLocal.set(index, obj);
}
if(indOpArray != -1) {
jsonListLocal = (List<Object>) obj;
} else {
jsonObjLocal = (Map<String, Object>) obj;
jsonListLocal = null;
}
}
}
}
}
if(jsonListLocal != null) {
return accessListField(op, jsonListLocal, indexToAccess);
} else {
return accessObjField(op, jsonObjLocal, fieldName);
}
}
private static Object accessObjField(OperationAccess op, Map<String, Object> jsonObjLocal, String fieldName) {
Object prevValue;
if (op.operation == DELETE_OPERATION) {
prevValue = jsonObjLocal.remove(fieldName);
} else if (op.operation == SET_OPERATION) {
prevValue = jsonObjLocal.put(fieldName, op.value);
} else {
prevValue = jsonObjLocal.get(fieldName);
}
return prevValue;
}
private static Object accessListField(OperationAccess op, List<Object> jsonListLocal, int indexToAccess) {
Object prevValue;
int lastIndex = indexToAccess;
if (op.operation == DELETE_OPERATION) {
if (lastIndex >= jsonListLocal.size() || lastIndex < 0) {
prevValue = null;
} else {
prevValue = jsonListLocal.remove(lastIndex);
}
} else if (op.operation == SET_OPERATION) {
if (lastIndex == jsonListLocal.size() || lastIndex == -1) {
prevValue = null;
jsonListLocal.add(op.value);
} else if (lastIndex >= jsonListLocal.size() || lastIndex < 0) {
throw new IllegalArgumentException(String.format("Illegal access to %d position in array with size %d",
lastIndex, jsonListLocal.size()));
} else {
prevValue = jsonListLocal.set(lastIndex, op.value);
}
} else {
if (lastIndex >= jsonListLocal.size() || lastIndex < 0) {
prevValue = null;
} else {
prevValue = jsonListLocal.get(lastIndex);
}
}
return prevValue;
}
@SuppressWarnings("unchecked")
public static List<Object> getIndexObjectByField(Object obj, List<String> field, List<Object> res) {
if(obj == null) {
return res;
}
if(field.size() == 0) {
if(res == null) {
res = new ArrayList<Object>();
}
res.add(obj);
return res;
}
if (obj instanceof Map) {
String fieldFirst = field.get(0);
Object value = ((Map<String, Object>) obj).get(fieldFirst);
return getIndexObjectByField(value, field.subList(1, field.size()), res);
} else if(obj instanceof Collection) {
for(Object o : ((Collection<Object>)obj)) {
res = getIndexObjectByField(o, field, res);
}
} else {
// we need extract but there no field
LOGGER.warn(String.format("Can't access field %s for object %s", field, obj));
}
return res;
}
}

View file

@ -1,122 +0,0 @@
package net.osmand.plus.osmedit.utils.util;
import java.util.List;
public class OUtils {
public static boolean isEmpty(String s) {
return s == null || s.trim().length() == 0;
}
public static boolean validateSqlIdentifier(String id, StringBuilder errorMessage, String field, String action) {
if(isEmpty(id)) {
errorMessage.append(String.format("Field '%s' is not specified which is necessary to %s", field, action));
return false;
}
if(!isValidJavaIdentifier(id)) {
errorMessage.append(String.format("Value '%s' is not valid for %s to %s", id, field, action));
return false;
}
return true;
}
public static long combine(int x1, int x2) {
long l = Integer.toUnsignedLong(x1);
l = (l << 32) | Integer.toUnsignedLong(x2);
return l;
}
public static int first(long l) {
long s = Integer.MAX_VALUE;
int t = (int) ((l & (s << 32)) >> 32);
if(l < 0) {
t = -t;
}
return t;
}
public static int second(long l) {
int t = (int) (l & Integer.MAX_VALUE);
if ((l & 0x80000000l) != 0) {
t = -t;
}
return t;
}
public static boolean isValidJavaIdentifier(String s) {
if (s.isEmpty()) {
return false;
}
if (!Character.isJavaIdentifierStart(s.charAt(0))) {
return false;
}
for (int i = 1; i < s.length(); i++) {
if (!Character.isJavaIdentifierPart(s.charAt(i))) {
return false;
}
}
return true;
}
public static boolean equals(List<?> s1, List<?> s2) {
if(s1 == null || s1.size() == 0) {
return s2 == null || s2.size() == 0;
}
if(s2 == null || s1.size() != s2.size()) {
return false;
}
for(int i = 0; i < s1.size(); i++) {
Object o1 = s1.get(i);
Object o2 = s2.get(i);
if(o1 == null) {
if(o2 != null) {
return false;
}
} else {
if(!o1.equals(o2)) {
return false;
}
}
}
return true;
}
public static boolean equals(Object s1, Object s2) {
if(s1 == null || s2 == null) {
return s1 == s2;
}
if(s1 instanceof Number && s2 instanceof Number) {
return ((Number) s1).longValue() == ((Number) s2).longValue() &&
((Number) s1).doubleValue() == ((Number) s2).doubleValue();
}
return s1.equals(s2);
}
public static boolean equalsStringValue(Object s1, Object s2) {
if(s1 == null || s2 == null) {
return s1 == s2;
}
return s1.toString().equals(s2.toString());
}
public static long parseLongSilently(String input, long def) {
if (input != null && input.length() > 0) {
try {
return Long.parseLong(input);
} catch (NumberFormatException e) {
return def;
}
}
return def;
}
public static int parseIntSilently(String input, int def) {
if (input != null && input.length() > 0) {
try {
return Integer.parseInt(input);
} catch (NumberFormatException e) {
return def;
}
}
return def;
}
}

View file

@ -1,15 +0,0 @@
package net.osmand.plus.osmedit.utils.util.exception;
public class ConnectionException extends TechnicalException {
private static final long serialVersionUID = 8191498058841215578L;
public ConnectionException(String message, Throwable cause) {
super(message, cause);
}
public ConnectionException(String message) {
super(message);
}
}

View file

@ -1,16 +0,0 @@
package net.osmand.plus.osmedit.utils.util.exception;
public class FailedVerificationException extends Exception {
private static final long serialVersionUID = -4936205097177668159L;
public FailedVerificationException(Exception e) {
super(e);
}
public FailedVerificationException(String msg) {
super(msg);
}
}

View file

@ -1,15 +0,0 @@
package net.osmand.plus.osmedit.utils.util.exception;
public class TechnicalException extends RuntimeException {
private static final long serialVersionUID = 9201898433665734132L;
public TechnicalException(String message, Throwable cause) {
super(message, cause);
}
public TechnicalException(String message) {
super(message);
}
}