package de.blau.android.tasks;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import com.google.gson.stream.JsonReader;
import android.content.Context;
import android.util.Log;
import de.blau.android.App;
import de.blau.android.R;
import de.blau.android.osm.Node;
import de.blau.android.osm.OsmElement;
import de.blau.android.osm.OsmElementFactory;
import de.blau.android.osm.Relation;
import de.blau.android.osm.StorageDelegator;
import de.blau.android.osm.Way;
import de.blau.android.util.DateFormatter;
/**
* A bug in the OpenStreetBugs database, or a prospective new bug.
* @author Andrew Gregory
*/
public class OsmoseBug extends Task implements Serializable {
private static final String DEBUG_TAG = OsmoseBug.class.getSimpleName();
private static final int LEVEL_ERROR=1;
private static final int LEVEL_WARNING=2;
private static final int LEVEL_MINOR_ISSUE=3;
/**
* Date pattern used to parse the update date from a Osmose bug.
*/
private static final String DATE_PATTERN_OSMOSE_BUG_UPDATED_AT = "yyyy-MM-dd HH:mm:ss z";
/**
*
*/
private static final long serialVersionUID = 2L;
private int item;
private int source;
private int bugclass; // class
private String elems;
private int subclass;
private String title;
private String subtitle;
private int level;
private Date update;
private String username;
public static ArrayList<OsmoseBug> parseBugs(InputStream is) throws IOException, NumberFormatException {
ArrayList<OsmoseBug> result = new ArrayList<OsmoseBug>();
JsonReader reader = new JsonReader(new InputStreamReader(is));
try {
// key object
String key = null;
reader.beginObject();
while (reader.hasNext()) {
key = reader.nextName(); //
if (key.equals("description")) {
reader.skipValue();
} else if (key.equals("errors")) {
reader.beginArray();
while (reader.hasNext()) {
OsmoseBug bug = new OsmoseBug();
reader.beginArray();
bug.lat = (int)(reader.nextDouble()*1E7D);
bug.lon = (int)(reader.nextDouble()*1E7D);
bug.id = reader.nextLong();
bug.item = reader.nextInt();
bug.source = reader.nextInt();
bug.bugclass = reader.nextInt();
bug.elems = reader.nextString();
bug.subclass = reader.nextInt();
bug.subtitle = reader.nextString();
bug.title = reader.nextString();
bug.level = reader.nextInt();
try {
bug.update = DateFormatter.getDate(
DATE_PATTERN_OSMOSE_BUG_UPDATED_AT,
reader.nextString());
} catch (java.text.ParseException pex) {
bug.update = new Date();
}
bug.username = reader.nextString();
reader.endArray();
result.add(bug);
}
reader.endArray();
}
}
reader.endObject();
} catch (IOException ioex) {
Log.d(DEBUG_TAG,"Ignoring " + ioex);
} finally {
try {
reader.close();
} catch (IOException ioex) {
Log.d(DEBUG_TAG,"Ignoring " + ioex);
}
}
return result;
}
/**
* Used for when parsing API output
*/
private OsmoseBug() {
open();
}
/**
* Get a string descriptive of the bug. This is intended to be used as a
* short bit of text representative of the bug.
* @return The first comment of the bug.
*/
@Override
public String getDescription() {
return "Osmose: " + (subtitle.length() != 0 ? subtitle : title );
}
@Override
/**
* Get the timestamp of the most recent change.
* @return The timestamp of the most recent change.
*/
public Date getLastUpdate() {
return update;
}
/**
* THis returns fake elements with version -1 for objects not downloaded
* @return
*/
public ArrayList<OsmElement> getElements() {
ArrayList<OsmElement> result = new ArrayList<OsmElement>();
String[] elements = elems.split("_");
StorageDelegator storageDelegator = App.getDelegator();
for (String e:elements) {
try {
if (elems.startsWith("way")) {
OsmElement osm = storageDelegator.getOsmElement(Way.NAME, Long.valueOf(e.substring(3)));
if (osm == null) {
osm = OsmElementFactory.createWay(Long.valueOf(e.substring(3)), -1, (byte) -1);
}
result.add(osm);
} else if (elems.startsWith("node")) {
OsmElement osm = storageDelegator.getOsmElement(Node.NAME, Long.valueOf(e.substring(4)));
if (osm == null) {
osm = OsmElementFactory.createNode(Long.valueOf(e.substring(4)), -1, (byte) -1, 0, 0);
}
result.add(osm);
} else if (elems.startsWith("relation")) {
OsmElement osm = storageDelegator.getOsmElement(Relation.NAME, Long.valueOf(e.substring(8)));
if (osm == null) {
osm = OsmElementFactory.createRelation(Long.valueOf(e.substring(8)), -1, (byte) -1);
}
result.add(osm);
}
}
catch(Exception ex) {
Log.d(DEBUG_TAG,"couldn't retrieve element " + elems + " " + ex);
}
}
return result;
}
public String getLongDescription(Context context, boolean withElements) {
String result = "Osmose: " + level2string(context) + "<br><br>" + (subtitle.length() != 0 ? subtitle : title ) + "<br>";
if (withElements) {
for (OsmElement osm:getElements()) {
if (osm.getOsmVersion() >= 0) {
result = result + "<br>" + osm.getName() + " (" + context.getString(R.string.openstreetbug_not_downloaded) + ") #" + osm.getOsmId();
} else {
result = result + "<br>" + osm.getName() + " " + osm.getDescription(false);
}
result = result + "<br><br>";
}
}
result = result + context.getString(R.string.openstreetbug_last_updated) + ": " + update
+ " " + context.getString(R.string.id) + ": " + id;
return result;
}
private String level2string(Context context) {
switch (level) {
case LEVEL_ERROR: return context.getString(R.string.error);
case LEVEL_WARNING: return context.getString(R.string.warning);
case LEVEL_MINOR_ISSUE: return context.getString(R.string.minor_issue);
default: return context.getString(R.string.unknown_error_level);
}
}
public String bugFilterKey() {
switch (level) {
case LEVEL_ERROR: return "OSMOSE_ERROR";
case LEVEL_WARNING: return "OSMOSE_WARNING";
case LEVEL_MINOR_ISSUE: return "OSMOSE_MINOR_ISSUE";
default: return "?";
}
}
public int getLevel() {
return level;
}
}