Changeset 1169 in josm for trunk/src/org/openstreetmap/josm/io
- Timestamp:
- 2008-12-23T15:07:05+01:00 (18 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/io
- Files:
-
- 19 edited
-
BoundingBoxDownloader.java (modified) (1 diff)
-
DiffResultReader.java (modified) (6 diffs)
-
GpxReader.java (modified) (1 diff)
-
GpxWriter.java (modified) (6 diffs)
-
MirroredInputStream.java (modified) (1 diff)
-
MultiPartFormOutputStream.java (modified) (2 diffs)
-
MyHttpHandler.java (modified) (1 diff)
-
NmeaReader.java (modified) (1 diff)
-
OsmConnection.java (modified) (1 diff)
-
OsmIdReader.java (modified) (1 diff)
-
OsmReader.java (modified) (15 diffs)
-
OsmServerLocationReader.java (modified) (1 diff)
-
OsmServerObjectReader.java (modified) (1 diff)
-
OsmServerReader.java (modified) (2 diffs)
-
OsmServerWriter.java (modified) (26 diffs)
-
OsmTransferException.java (modified) (1 diff)
-
OsmWriter.java (modified) (1 diff)
-
ProgressInputStream.java (modified) (1 diff)
-
XmlWriter.java (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java
r999 r1169 15 15 public class BoundingBoxDownloader extends OsmServerReader { 16 16 17 /**18 * The boundings of the desired map data.19 */20 private final double lat1;21 private final double lon1;22 private final double lat2;23 private final double lon2;17 /** 18 * The boundings of the desired map data. 19 */ 20 private final double lat1; 21 private final double lon1; 22 private final double lat2; 23 private final double lon2; 24 24 25 public BoundingBoxDownloader(double lat1, double lon1, double lat2, double lon2) {26 this.lat1 = lat1;27 this.lon1 = lon1;28 this.lat2 = lat2;29 this.lon2 = lon2;30 // store the bounding box in the preferences so it can be31 // re-used across invocations of josm32 Main.pref.put("osm-download.bounds", lat1+";"+lon1+";"+lat2+";"+lon2);33 }25 public BoundingBoxDownloader(double lat1, double lon1, double lat2, double lon2) { 26 this.lat1 = lat1; 27 this.lon1 = lon1; 28 this.lat2 = lat2; 29 this.lon2 = lon2; 30 // store the bounding box in the preferences so it can be 31 // re-used across invocations of josm 32 Main.pref.put("osm-download.bounds", lat1+";"+lon1+";"+lat2+";"+lon2); 33 } 34 34 35 /**36 * Retrieve raw gps waypoints from the server API.37 * @return A list of all primitives retrieved. Currently, the list of lists38 * contain only one list, since the server cannot distinguish between39 * ways.40 */41 public GpxData parseRawGps() throws IOException, SAXException {42 Main.pleaseWaitDlg.progress.setValue(0);43 Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));44 try {45 String url = "trackpoints?bbox="+lon1+","+lat1+","+lon2+","+lat2+"&page=";35 /** 36 * Retrieve raw gps waypoints from the server API. 37 * @return A list of all primitives retrieved. Currently, the list of lists 38 * contain only one list, since the server cannot distinguish between 39 * ways. 40 */ 41 public GpxData parseRawGps() throws IOException, SAXException { 42 Main.pleaseWaitDlg.progress.setValue(0); 43 Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server...")); 44 try { 45 String url = "trackpoints?bbox="+lon1+","+lat1+","+lon2+","+lat2+"&page="; 46 46 47 boolean done = false;48 GpxData result = null;49 for (int i = 0;!done;++i) {50 Main.pleaseWaitDlg.currentAction.setText(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000)));51 InputStream in = getInputStream(url+i, Main.pleaseWaitDlg);52 if (in == null)53 break;54 GpxData currentGpx = new GpxReader(in, null).data;55 if (result == null) {56 result = currentGpx;57 } else if (currentGpx.hasTrackPoints()) {58 result.mergeFrom(currentGpx);59 } else{60 done = true;61 }62 in.close();63 activeConnection = null;64 }65 result.fromServer = true;66 return result;67 } catch (IllegalArgumentException e) {68 // caused by HttpUrlConnection in case of illegal stuff in the response69 if (cancel)70 return null;71 throw new SAXException("Illegal characters within the HTTP-header response", e);72 } catch (IOException e) {73 if (cancel)74 return null;75 throw e;76 } catch (SAXException e) {77 throw e;78 } catch (Exception e) {79 if (cancel)80 return null;81 if (e instanceof RuntimeException)82 throw (RuntimeException)e;83 throw new RuntimeException(e);84 }85 }47 boolean done = false; 48 GpxData result = null; 49 for (int i = 0;!done;++i) { 50 Main.pleaseWaitDlg.currentAction.setText(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000))); 51 InputStream in = getInputStream(url+i, Main.pleaseWaitDlg); 52 if (in == null) 53 break; 54 GpxData currentGpx = new GpxReader(in, null).data; 55 if (result == null) { 56 result = currentGpx; 57 } else if (currentGpx.hasTrackPoints()) { 58 result.mergeFrom(currentGpx); 59 } else{ 60 done = true; 61 } 62 in.close(); 63 activeConnection = null; 64 } 65 result.fromServer = true; 66 return result; 67 } catch (IllegalArgumentException e) { 68 // caused by HttpUrlConnection in case of illegal stuff in the response 69 if (cancel) 70 return null; 71 throw new SAXException("Illegal characters within the HTTP-header response", e); 72 } catch (IOException e) { 73 if (cancel) 74 return null; 75 throw e; 76 } catch (SAXException e) { 77 throw e; 78 } catch (Exception e) { 79 if (cancel) 80 return null; 81 if (e instanceof RuntimeException) 82 throw (RuntimeException)e; 83 throw new RuntimeException(e); 84 } 85 } 86 86 87 /**88 * Read the data from the osm server address.89 * @return A data set containing all data retrieved from that url90 */91 public DataSet parseOsm() throws SAXException, IOException {92 try {93 Main.pleaseWaitDlg.progress.setValue(0);94 Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));95 final InputStream in = getInputStream("map?bbox="+lon1+","+lat1+","+lon2+","+lat2, Main.pleaseWaitDlg);96 if (in == null)97 return null;98 Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data..."));99 final DataSet data = OsmReader.parseDataSet(in, null, Main.pleaseWaitDlg);100 in.close();101 activeConnection = null;102 return data;103 } catch (IOException e) {104 if (cancel)105 return null;106 throw e;107 } catch (SAXException e) {108 throw e;109 } catch (Exception e) {110 if (cancel)111 return null;112 if (e instanceof RuntimeException)113 throw (RuntimeException)e;114 throw new RuntimeException(e);115 }116 }87 /** 88 * Read the data from the osm server address. 89 * @return A data set containing all data retrieved from that url 90 */ 91 public DataSet parseOsm() throws SAXException, IOException { 92 try { 93 Main.pleaseWaitDlg.progress.setValue(0); 94 Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server...")); 95 final InputStream in = getInputStream("map?bbox="+lon1+","+lat1+","+lon2+","+lat2, Main.pleaseWaitDlg); 96 if (in == null) 97 return null; 98 Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data...")); 99 final DataSet data = OsmReader.parseDataSet(in, null, Main.pleaseWaitDlg); 100 in.close(); 101 activeConnection = null; 102 return data; 103 } catch (IOException e) { 104 if (cancel) 105 return null; 106 throw e; 107 } catch (SAXException e) { 108 throw e; 109 } catch (Exception e) { 110 if (cancel) 111 return null; 112 if (e instanceof RuntimeException) 113 throw (RuntimeException)e; 114 throw new RuntimeException(e); 115 } 116 } 117 117 } -
trunk/src/org/openstreetmap/josm/io/DiffResultReader.java
r1071 r1169 41 41 */ 42 42 public class DiffResultReader implements Visitor { 43 43 44 44 /** 45 45 * mapping from old id to new id/version … … 47 47 private Map<String, Long[]> versions = new HashMap<String, Long[]>(); 48 48 private Collection<OsmPrimitive> processed; 49 private Map<OsmPrimitive,Long> newIdMap; 49 private Map<OsmPrimitive,Long> newIdMap; 50 50 51 /** 51 /** 52 52 * List of protocol versions that will be accepted on reading 53 53 */ 54 54 55 55 private class Parser extends DefaultHandler { 56 56 … … 81 81 * elemet found there is returned. 82 82 */ 83 public static void parseDiffResult(InputStream source, Collection<OsmPrimitive> osm, Collection<OsmPrimitive> processed, Map<OsmPrimitive,Long> newIdMap, PleaseWaitDialog pleaseWaitDlg) 83 public static void parseDiffResult(InputStream source, Collection<OsmPrimitive> osm, Collection<OsmPrimitive> processed, Map<OsmPrimitive,Long> newIdMap, PleaseWaitDialog pleaseWaitDlg) 84 84 throws SAXException, IOException { 85 85 … … 107 107 } 108 108 } 109 109 110 110 public void visit(Node n) { 111 111 String key = "node:" + (newIdMap.containsKey(n) ? newIdMap.get(n) : n.id); … … 127 127 w.id = nv[0]; w.version = nv[1].intValue(); 128 128 } 129 } 129 } 130 130 } 131 131 public void visit(Relation r) { … … 137 137 r.id = nv[0]; r.version = nv[1].intValue(); 138 138 } 139 } 139 } 140 140 } 141 141 } -
trunk/src/org/openstreetmap/josm/io/GpxReader.java
r1122 r1169 35 35 */ 36 36 public class GpxReader { 37 // TODO: implement GPX 1.0 parsing38 39 /**40 * The resulting gpx data41 */42 public GpxData data;43 public enum state { init, metadata, wpt, rte, trk, ext, author, link, trkseg }44 45 private class Parser extends DefaultHandler {46 47 private GpxData currentData;48 private GpxTrack currentTrack;49 private Collection<WayPoint> currentTrackSeg;50 private GpxRoute currentRoute;51 private WayPoint currentWayPoint;52 53 private state currentState = state.init;54 55 private GpxLink currentLink;56 private Stack<state> states;57 58 private StringBuffer accumulator = new StringBuffer();59 60 @Override public void startDocument() {61 accumulator = new StringBuffer();62 states = new Stack<state>();63 currentData = new GpxData();64 } 65 66 private double parseCoord(String s) {67 try {68 return Double.parseDouble(s);69 } catch (NumberFormatException ex) {70 return Double.NaN;71 }72 }73 74 private LatLon parseLatLon(Attributes atts) {75 return new LatLon(76 parseCoord(atts.getValue("lat")),77 parseCoord(atts.getValue("lon")));78 }79 80 @Override public void startElement(String namespaceURI, String qName, String rqName, Attributes atts) throws SAXException {81 switch(currentState) {82 case init:83 if (qName.equals("metadata")) {84 states.push(currentState);85 currentState = state.metadata;86 } else if (qName.equals("wpt")) {87 states.push(currentState);88 currentState = state.wpt;89 currentWayPoint = new WayPoint(parseLatLon(atts));90 } else if (qName.equals("rte")) {91 states.push(currentState);92 currentState = state.rte;93 currentRoute = new GpxRoute();94 } else if (qName.equals("trk")) {95 states.push(currentState);96 currentState = state.trk;97 currentTrack = new GpxTrack();98 } else if (qName.equals("extensions")) {99 states.push(currentState);100 currentState = state.ext;101 }102 break;103 case author:104 if (qName.equals("link")) {105 states.push(currentState);106 currentState = state.link;107 currentLink = new GpxLink(atts.getValue("href"));108 }109 break;110 case trk:111 if (qName.equals("trkseg")) {112 states.push(currentState);113 currentState = state.trkseg;114 currentTrackSeg = new ArrayList<WayPoint>();115 } else if (qName.equals("link")) {116 states.push(currentState);117 currentState = state.link;118 currentLink = new GpxLink(atts.getValue("href"));119 } else if (qName.equals("extensions")) {120 states.push(currentState);121 currentState = state.ext;122 }123 break;124 case metadata:125 if (qName.equals("author")) {126 states.push(currentState);127 currentState = state.author;128 } else if (qName.equals("extensions")) {129 states.push(currentState);130 currentState = state.ext;131 }132 break;133 case trkseg:134 if (qName.equals("trkpt")) {135 states.push(currentState);136 currentState = state.wpt;137 currentWayPoint = new WayPoint(parseLatLon(atts));138 }139 break;140 case wpt:141 if (qName.equals("link")) {142 states.push(currentState);143 currentState = state.link;144 currentLink = new GpxLink(atts.getValue("href"));145 } else if (qName.equals("extensions")) {146 states.push(currentState);147 currentState = state.ext;148 }149 break;150 case rte:151 if (qName.equals("link")) {152 states.push(currentState);153 currentState = state.link;154 currentLink = new GpxLink(atts.getValue("href"));155 } else if (qName.equals("rtept")) {156 states.push(currentState);157 currentState = state.wpt;158 currentWayPoint = new WayPoint(parseLatLon(atts));159 } else if (qName.equals("extensions")) {160 states.push(currentState);161 currentState = state.ext;162 }163 break;164 default:165 }166 accumulator.setLength(0);167 }168 169 @Override public void characters(char[] ch, int start, int length) {170 accumulator.append(ch, start, length);171 }172 173 private Map<String, Object> getAttr() {174 switch (currentState) {175 case rte: return currentRoute.attr;176 case metadata: return currentData.attr;177 case wpt: return currentWayPoint.attr;178 case trk: return currentTrack.attr;179 default: return null;180 }181 }182 183 @Override public void endElement(String namespaceURI, String qName, String rqName) {184 switch (currentState) {185 case metadata:186 if (qName.equals("name") || qName.equals("desc") ||187 qName.equals("time") || qName.equals("keywords")) {188 currentData.attr.put(qName, accumulator.toString());189 } else if (qName.equals("metadata")) {190 currentState = states.pop();191 }192 //TODO: parse copyright, bounds, extensions193 break;194 case author:195 if (qName.equals("author")) {196 currentState = states.pop();197 } else if (qName.equals("name") || qName.equals("email")) {198 currentData.attr.put("author" + qName, accumulator.toString());199 } else if (qName.equals("link")) {200 currentData.attr.put("authorlink", currentLink);201 }202 break;203 case link:204 if (qName.equals("text")) {205 currentLink.text = accumulator.toString();206 } else if (qName.equals("type")) {207 currentLink.type = accumulator.toString();208 } else if (qName.equals("link")) {209 // <link>URL</link>210 if (currentLink.uri == null)211 currentLink.uri = accumulator.toString();212 213 currentState = states.pop();214 }215 if (currentState == state.author) {216 currentData.attr.put("authorlink", currentLink);217 } else if (currentState != state.link) {218 Map<String, Object> attr = getAttr();219 if (!attr.containsKey("link")) {220 attr.put("link", new LinkedList<GpxLink>());221 }222 ((Collection<GpxLink>) attr.get("link")).add(currentLink);223 }224 break;225 case wpt:226 if (qName.equals("ele") || qName.equals("magvar")227 || qName.equals("geoidheight") || qName.equals("name")228 || qName.equals("sym") || qName.equals("type")) {229 currentWayPoint.attr.put(qName, accumulator.toString());230 } else if (qName.equals("time")) {231 currentWayPoint.attr.put(qName, accumulator.toString());232 currentWayPoint.setTime();233 } else if (qName.equals("cmt") || qName.equals("desc")) {234 currentWayPoint.attr.put(qName, accumulator.toString());235 currentWayPoint.setGarminCommentTime(qName);236 } else if (qName.equals("rtept")) {237 currentState = states.pop();238 currentRoute.routePoints.add(currentWayPoint);239 } else if (qName.equals("trkpt")) {240 currentState = states.pop();241 currentTrackSeg.add(currentWayPoint);242 } else if (qName.equals("wpt")) {243 currentState = states.pop();244 currentData.waypoints.add(currentWayPoint);245 }246 break;247 case trkseg:248 if (qName.equals("trkseg")) {249 currentState = states.pop();250 currentTrack.trackSegs.add(currentTrackSeg);251 }252 break;253 case trk:254 if (qName.equals("trk")) {255 currentState = states.pop();256 currentData.tracks.add(currentTrack);257 } else if (qName.equals("name") || qName.equals("cmt")258 || qName.equals("desc") || qName.equals("src")259 || qName.equals("type") || qName.equals("number")) {260 currentTrack.attr.put(qName, accumulator.toString());261 }262 break;263 case ext:264 if (qName.equals("extensions")) {265 currentState = states.pop();266 }267 break;268 default:269 if (qName.equals("wpt")) {270 currentState = states.pop();271 } else if (qName.equals("rte")) {272 currentState = states.pop();273 currentData.routes.add(currentRoute);274 }275 }276 }277 278 @Override public void endDocument() throws SAXException {279 if (!states.empty()) {280 throw new SAXException(tr("Parse error: invalid document structure for gpx document"));281 }282 data = currentData;283 }284 }285 286 /**287 * Parse the input stream and store the result in trackData and markerData288 * 289 * @param relativeMarkerPath The directory to use as relative path for all <wpt>290 * marker tags. Maybe <code>null</code>, in which case no relative urls are constructed for the markers.291 */292 public GpxReader(InputStream source, File relativeMarkerPath) throws SAXException, IOException {293 294 Parser parser = new Parser();295 InputSource inputSource = new InputSource(new InputStreamReader(source, "UTF-8"));296 try {297 SAXParserFactory factory = SAXParserFactory.newInstance();298 factory.setNamespaceAware(true);299 factory.newSAXParser().parse(inputSource, parser);300 } catch (ParserConfigurationException e) {301 e.printStackTrace(); // broken SAXException chaining302 throw new SAXException(e);303 }304 }37 // TODO: implement GPX 1.0 parsing 38 39 /** 40 * The resulting gpx data 41 */ 42 public GpxData data; 43 public enum state { init, metadata, wpt, rte, trk, ext, author, link, trkseg } 44 45 private class Parser extends DefaultHandler { 46 47 private GpxData currentData; 48 private GpxTrack currentTrack; 49 private Collection<WayPoint> currentTrackSeg; 50 private GpxRoute currentRoute; 51 private WayPoint currentWayPoint; 52 53 private state currentState = state.init; 54 55 private GpxLink currentLink; 56 private Stack<state> states; 57 58 private StringBuffer accumulator = new StringBuffer(); 59 60 @Override public void startDocument() { 61 accumulator = new StringBuffer(); 62 states = new Stack<state>(); 63 currentData = new GpxData(); 64 } 65 66 private double parseCoord(String s) { 67 try { 68 return Double.parseDouble(s); 69 } catch (NumberFormatException ex) { 70 return Double.NaN; 71 } 72 } 73 74 private LatLon parseLatLon(Attributes atts) { 75 return new LatLon( 76 parseCoord(atts.getValue("lat")), 77 parseCoord(atts.getValue("lon"))); 78 } 79 80 @Override public void startElement(String namespaceURI, String qName, String rqName, Attributes atts) throws SAXException { 81 switch(currentState) { 82 case init: 83 if (qName.equals("metadata")) { 84 states.push(currentState); 85 currentState = state.metadata; 86 } else if (qName.equals("wpt")) { 87 states.push(currentState); 88 currentState = state.wpt; 89 currentWayPoint = new WayPoint(parseLatLon(atts)); 90 } else if (qName.equals("rte")) { 91 states.push(currentState); 92 currentState = state.rte; 93 currentRoute = new GpxRoute(); 94 } else if (qName.equals("trk")) { 95 states.push(currentState); 96 currentState = state.trk; 97 currentTrack = new GpxTrack(); 98 } else if (qName.equals("extensions")) { 99 states.push(currentState); 100 currentState = state.ext; 101 } 102 break; 103 case author: 104 if (qName.equals("link")) { 105 states.push(currentState); 106 currentState = state.link; 107 currentLink = new GpxLink(atts.getValue("href")); 108 } 109 break; 110 case trk: 111 if (qName.equals("trkseg")) { 112 states.push(currentState); 113 currentState = state.trkseg; 114 currentTrackSeg = new ArrayList<WayPoint>(); 115 } else if (qName.equals("link")) { 116 states.push(currentState); 117 currentState = state.link; 118 currentLink = new GpxLink(atts.getValue("href")); 119 } else if (qName.equals("extensions")) { 120 states.push(currentState); 121 currentState = state.ext; 122 } 123 break; 124 case metadata: 125 if (qName.equals("author")) { 126 states.push(currentState); 127 currentState = state.author; 128 } else if (qName.equals("extensions")) { 129 states.push(currentState); 130 currentState = state.ext; 131 } 132 break; 133 case trkseg: 134 if (qName.equals("trkpt")) { 135 states.push(currentState); 136 currentState = state.wpt; 137 currentWayPoint = new WayPoint(parseLatLon(atts)); 138 } 139 break; 140 case wpt: 141 if (qName.equals("link")) { 142 states.push(currentState); 143 currentState = state.link; 144 currentLink = new GpxLink(atts.getValue("href")); 145 } else if (qName.equals("extensions")) { 146 states.push(currentState); 147 currentState = state.ext; 148 } 149 break; 150 case rte: 151 if (qName.equals("link")) { 152 states.push(currentState); 153 currentState = state.link; 154 currentLink = new GpxLink(atts.getValue("href")); 155 } else if (qName.equals("rtept")) { 156 states.push(currentState); 157 currentState = state.wpt; 158 currentWayPoint = new WayPoint(parseLatLon(atts)); 159 } else if (qName.equals("extensions")) { 160 states.push(currentState); 161 currentState = state.ext; 162 } 163 break; 164 default: 165 } 166 accumulator.setLength(0); 167 } 168 169 @Override public void characters(char[] ch, int start, int length) { 170 accumulator.append(ch, start, length); 171 } 172 173 private Map<String, Object> getAttr() { 174 switch (currentState) { 175 case rte: return currentRoute.attr; 176 case metadata: return currentData.attr; 177 case wpt: return currentWayPoint.attr; 178 case trk: return currentTrack.attr; 179 default: return null; 180 } 181 } 182 183 @Override public void endElement(String namespaceURI, String qName, String rqName) { 184 switch (currentState) { 185 case metadata: 186 if (qName.equals("name") || qName.equals("desc") || 187 qName.equals("time") || qName.equals("keywords")) { 188 currentData.attr.put(qName, accumulator.toString()); 189 } else if (qName.equals("metadata")) { 190 currentState = states.pop(); 191 } 192 //TODO: parse copyright, bounds, extensions 193 break; 194 case author: 195 if (qName.equals("author")) { 196 currentState = states.pop(); 197 } else if (qName.equals("name") || qName.equals("email")) { 198 currentData.attr.put("author" + qName, accumulator.toString()); 199 } else if (qName.equals("link")) { 200 currentData.attr.put("authorlink", currentLink); 201 } 202 break; 203 case link: 204 if (qName.equals("text")) { 205 currentLink.text = accumulator.toString(); 206 } else if (qName.equals("type")) { 207 currentLink.type = accumulator.toString(); 208 } else if (qName.equals("link")) { 209 // <link>URL</link> 210 if (currentLink.uri == null) 211 currentLink.uri = accumulator.toString(); 212 213 currentState = states.pop(); 214 } 215 if (currentState == state.author) { 216 currentData.attr.put("authorlink", currentLink); 217 } else if (currentState != state.link) { 218 Map<String, Object> attr = getAttr(); 219 if (!attr.containsKey("link")) { 220 attr.put("link", new LinkedList<GpxLink>()); 221 } 222 ((Collection<GpxLink>) attr.get("link")).add(currentLink); 223 } 224 break; 225 case wpt: 226 if (qName.equals("ele") || qName.equals("magvar") 227 || qName.equals("geoidheight") || qName.equals("name") 228 || qName.equals("sym") || qName.equals("type")) { 229 currentWayPoint.attr.put(qName, accumulator.toString()); 230 } else if (qName.equals("time")) { 231 currentWayPoint.attr.put(qName, accumulator.toString()); 232 currentWayPoint.setTime(); 233 } else if (qName.equals("cmt") || qName.equals("desc")) { 234 currentWayPoint.attr.put(qName, accumulator.toString()); 235 currentWayPoint.setGarminCommentTime(qName); 236 } else if (qName.equals("rtept")) { 237 currentState = states.pop(); 238 currentRoute.routePoints.add(currentWayPoint); 239 } else if (qName.equals("trkpt")) { 240 currentState = states.pop(); 241 currentTrackSeg.add(currentWayPoint); 242 } else if (qName.equals("wpt")) { 243 currentState = states.pop(); 244 currentData.waypoints.add(currentWayPoint); 245 } 246 break; 247 case trkseg: 248 if (qName.equals("trkseg")) { 249 currentState = states.pop(); 250 currentTrack.trackSegs.add(currentTrackSeg); 251 } 252 break; 253 case trk: 254 if (qName.equals("trk")) { 255 currentState = states.pop(); 256 currentData.tracks.add(currentTrack); 257 } else if (qName.equals("name") || qName.equals("cmt") 258 || qName.equals("desc") || qName.equals("src") 259 || qName.equals("type") || qName.equals("number")) { 260 currentTrack.attr.put(qName, accumulator.toString()); 261 } 262 break; 263 case ext: 264 if (qName.equals("extensions")) { 265 currentState = states.pop(); 266 } 267 break; 268 default: 269 if (qName.equals("wpt")) { 270 currentState = states.pop(); 271 } else if (qName.equals("rte")) { 272 currentState = states.pop(); 273 currentData.routes.add(currentRoute); 274 } 275 } 276 } 277 278 @Override public void endDocument() throws SAXException { 279 if (!states.empty()) { 280 throw new SAXException(tr("Parse error: invalid document structure for gpx document")); 281 } 282 data = currentData; 283 } 284 } 285 286 /** 287 * Parse the input stream and store the result in trackData and markerData 288 * 289 * @param relativeMarkerPath The directory to use as relative path for all <wpt> 290 * marker tags. Maybe <code>null</code>, in which case no relative urls are constructed for the markers. 291 */ 292 public GpxReader(InputStream source, File relativeMarkerPath) throws SAXException, IOException { 293 294 Parser parser = new Parser(); 295 InputSource inputSource = new InputSource(new InputStreamReader(source, "UTF-8")); 296 try { 297 SAXParserFactory factory = SAXParserFactory.newInstance(); 298 factory.setNamespaceAware(true); 299 factory.newSAXParser().parse(inputSource, parser); 300 } catch (ParserConfigurationException e) { 301 e.printStackTrace(); // broken SAXException chaining 302 throw new SAXException(e); 303 } 304 } 305 305 } -
trunk/src/org/openstreetmap/josm/io/GpxWriter.java
r1164 r1169 97 97 for (WayPoint pnt : data.waypoints) { 98 98 wayPoint(pnt, WAY_POINT); 99 } 100 } 101 99 } 100 } 101 102 102 private void writeRoutes() { 103 103 for (GpxRoute rte : data.routes) { … … 110 110 } 111 111 } 112 112 113 113 private void writeTracks() { 114 114 for (GpxTrack trk : data.tracks) { … … 140 140 indent += " "; 141 141 } 142 142 143 143 private void inline(String tag, String attributes) { 144 144 out.println(indent + "<" + tag + " " + attributes + " />"); … … 155 155 } 156 156 157 /** 157 /** 158 158 * if content not null, open tag, write encoded content, and close tag 159 159 * else do nothing. … … 168 168 } 169 169 170 /** 170 /** 171 171 * output link 172 172 */ … … 180 180 } 181 181 182 /** 182 /** 183 183 * output a point 184 184 */ -
trunk/src/org/openstreetmap/josm/io/MirroredInputStream.java
r999 r1169 20 20 */ 21 21 public class MirroredInputStream extends InputStream { 22 InputStream fs = null;22 InputStream fs = null; 23 23 24 public MirroredInputStream(String name) throws IOException25 {26 this(name, null, -1L);27 }24 public MirroredInputStream(String name) throws IOException 25 { 26 this(name, null, -1L); 27 } 28 28 29 public MirroredInputStream(String name, long maxTime) throws IOException30 {31 this(name, null, maxTime);32 }29 public MirroredInputStream(String name, long maxTime) throws IOException 30 { 31 this(name, null, maxTime); 32 } 33 33 34 public MirroredInputStream(String name, String destDir, long maxTime) throws IOException35 {36 URL url;37 File file = null;38 try39 {40 url = new URL(name);41 if(url.getProtocol().equals("file"))42 {43 file = new File(name.substring("file:/".length()));44 if(!file.exists())45 file = new File(name.substring("file://".length()));46 }47 else48 file = checkLocal(url, destDir, maxTime);49 }50 catch(java.net.MalformedURLException e)51 {52 if(name.startsWith("resource://"))53 {54 fs = getClass().getResourceAsStream(55 name.substring("resource:/".length()));56 return;57 }58 else59 file = new File(name);60 }61 if(file == null)62 throw new IOException();63 fs = new FileInputStream(file);64 }34 public MirroredInputStream(String name, String destDir, long maxTime) throws IOException 35 { 36 URL url; 37 File file = null; 38 try 39 { 40 url = new URL(name); 41 if(url.getProtocol().equals("file")) 42 { 43 file = new File(name.substring("file:/".length())); 44 if(!file.exists()) 45 file = new File(name.substring("file://".length())); 46 } 47 else 48 file = checkLocal(url, destDir, maxTime); 49 } 50 catch(java.net.MalformedURLException e) 51 { 52 if(name.startsWith("resource://")) 53 { 54 fs = getClass().getResourceAsStream( 55 name.substring("resource:/".length())); 56 return; 57 } 58 else 59 file = new File(name); 60 } 61 if(file == null) 62 throw new IOException(); 63 fs = new FileInputStream(file); 64 } 65 65 66 private File checkLocal(URL url, String destDir, long maxTime)67 {68 String localPath = Main.pref.get("mirror." + url);69 File file = null;70 if(localPath != null && localPath.length() > 0)71 {72 String[] lp = localPath.split(";");73 file = new File(lp[1]);74 if(maxTime <= 0)75 maxTime = Main.pref.getInteger("mirror.maxtime", 7*24*60*60);76 if(System.currentTimeMillis() - Long.parseLong(lp[0]) < maxTime*1000)77 {78 if(file.exists())79 {80 return file;81 }82 }83 }84 if(destDir == null)85 destDir = Main.pref.getPreferencesDir();66 private File checkLocal(URL url, String destDir, long maxTime) 67 { 68 String localPath = Main.pref.get("mirror." + url); 69 File file = null; 70 if(localPath != null && localPath.length() > 0) 71 { 72 String[] lp = localPath.split(";"); 73 file = new File(lp[1]); 74 if(maxTime <= 0) 75 maxTime = Main.pref.getInteger("mirror.maxtime", 7*24*60*60); 76 if(System.currentTimeMillis() - Long.parseLong(lp[0]) < maxTime*1000) 77 { 78 if(file.exists()) 79 { 80 return file; 81 } 82 } 83 } 84 if(destDir == null) 85 destDir = Main.pref.getPreferencesDir(); 86 86 87 File destDirFile = new File(destDir);88 if(!destDirFile.exists() )89 destDirFile.mkdirs();87 File destDirFile = new File(destDir); 88 if(!destDirFile.exists() ) 89 destDirFile.mkdirs(); 90 90 91 localPath = "mirror_" + new File(url.getPath()).getName();92 destDirFile = new File(destDir, localPath + ".tmp");93 BufferedOutputStream bos = null;94 BufferedInputStream bis = null;95 try96 {97 URLConnection conn = url.openConnection();98 conn.setConnectTimeout(5000);99 bis = new BufferedInputStream(conn.getInputStream());100 bos = new BufferedOutputStream( new FileOutputStream(destDirFile));101 byte[] buffer = new byte[4096];102 int length;103 while((length = bis.read(buffer)) > -1)104 bos.write(buffer, 0, length);105 }106 catch(IOException ioe)107 {108 if(file != null)109 return file;110 else111 return null;112 }113 finally114 {115 if(bis != null)116 {117 try118 {119 bis.close();120 }121 catch (IOException e)122 {123 e.printStackTrace();124 }125 }126 if(bos != null)127 {128 try129 {130 bos.close();131 }132 catch (IOException e)133 {134 e.printStackTrace();135 }136 }137 file = new File(destDir, localPath);138 destDirFile.renameTo(file);139 Main.pref.put("mirror." + url, System.currentTimeMillis() + ";" + file);140 }91 localPath = "mirror_" + new File(url.getPath()).getName(); 92 destDirFile = new File(destDir, localPath + ".tmp"); 93 BufferedOutputStream bos = null; 94 BufferedInputStream bis = null; 95 try 96 { 97 URLConnection conn = url.openConnection(); 98 conn.setConnectTimeout(5000); 99 bis = new BufferedInputStream(conn.getInputStream()); 100 bos = new BufferedOutputStream( new FileOutputStream(destDirFile)); 101 byte[] buffer = new byte[4096]; 102 int length; 103 while((length = bis.read(buffer)) > -1) 104 bos.write(buffer, 0, length); 105 } 106 catch(IOException ioe) 107 { 108 if(file != null) 109 return file; 110 else 111 return null; 112 } 113 finally 114 { 115 if(bis != null) 116 { 117 try 118 { 119 bis.close(); 120 } 121 catch (IOException e) 122 { 123 e.printStackTrace(); 124 } 125 } 126 if(bos != null) 127 { 128 try 129 { 130 bos.close(); 131 } 132 catch (IOException e) 133 { 134 e.printStackTrace(); 135 } 136 } 137 file = new File(destDir, localPath); 138 destDirFile.renameTo(file); 139 Main.pref.put("mirror." + url, System.currentTimeMillis() + ";" + file); 140 } 141 141 142 return file;143 }144 public int available() throws IOException145 { return fs.available(); }146 public void close() throws IOException147 { fs.close(); }148 public int read() throws IOException149 { return fs.read(); }150 public int read(byte[] b) throws IOException151 { return fs.read(b); }152 public int read(byte[] b, int off, int len) throws IOException153 { return fs.read(b,off, len); }154 public long skip(long n) throws IOException155 { return fs.skip(n); }142 return file; 143 } 144 public int available() throws IOException 145 { return fs.available(); } 146 public void close() throws IOException 147 { fs.close(); } 148 public int read() throws IOException 149 { return fs.read(); } 150 public int read(byte[] b) throws IOException 151 { return fs.read(b); } 152 public int read(byte[] b, int off, int len) throws IOException 153 { return fs.read(b,off, len); } 154 public long skip(long n) throws IOException 155 { return fs.skip(n); } 156 156 } -
trunk/src/org/openstreetmap/josm/io/MultiPartFormOutputStream.java
r627 r1169 3 3 4 4 License 5 5 6 6 Copyright 1994-2007 Sun Microsystems, Inc. All Rights Reserved. 7 Redistribution and use in source and binary forms, with or without modification, 7 Redistribution and use in source and binary forms, with or without modification, 8 8 are permitted provided that the following conditions are met: 9 10 * Redistribution of source code must retain the above copyright notice, this list 9 10 * Redistribution of source code must retain the above copyright notice, this list 11 11 of conditions and the following disclaimer. 12 12 13 * Redistribution in binary form must reproduce the above copyright notice, this 14 list of conditions and the following disclaimer in the documentation and/or other 13 * Redistribution in binary form must reproduce the above copyright notice, this 14 list of conditions and the following disclaimer in the documentation and/or other 15 15 materials provided with the distribution. 16 16 17 18 Neither the name of Sun Microsystems, Inc. or the names of contributors may be used to 19 endorse or promote products derived from this software without specific prior written 17 18 Neither the name of Sun Microsystems, Inc. or the names of contributors may be used to 19 endorse or promote products derived from this software without specific prior written 20 20 permission. 21 22 This software is provided "AS IS," without a warranty of any kind. ALL EXPRESS OR IMPLIED 23 CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 24 FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, 25 INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS 26 A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT 27 WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, 28 INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND 29 REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS 21 22 This software is provided "AS IS," without a warranty of any kind. ALL EXPRESS OR IMPLIED 23 CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 24 FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, 25 INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS 26 A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT 27 WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, 28 INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND 29 REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS 30 30 SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 31 32 You acknowledge that this software is not designed, licensed or intended for use in the 33 design, construction, operation or maintenance of any nuclear facility. 31 32 You acknowledge that this software is not designed, licensed or intended for use in the 33 design, construction, operation or maintenance of any nuclear facility. 34 34 */ 35 35 … … 44 44 import java.net.URLConnection; 45 45 46 46 47 47 /** 48 * <code>MultiPartFormOutputStream</code> is used to write 49 * "multipart/form-data" to a <code>java.net.URLConnection</code> for 50 * POSTing. This is primarily for file uploading to HTTP servers. 51 * 48 * <code>MultiPartFormOutputStream</code> is used to write 49 * "multipart/form-data" to a <code>java.net.URLConnection</code> for 50 * POSTing. This is primarily for file uploading to HTTP servers. 51 * 52 52 * @since JDK1.3 53 53 */ 54 54 public class MultiPartFormOutputStream extends OsmConnection { 55 /**56 * The line end characters.57 */58 private static final String NEWLINE = "\r\n";59 60 /**61 * The boundary prefix.62 */63 private static final String PREFIX = "--";64 65 /**66 * The output stream to write to.67 */68 private DataOutputStream out = null;69 70 /**71 * The multipart boundary string.72 */73 private String boundary = null;74 75 /**76 * Creates a new <code>MultiPartFormOutputStream</code> object using77 * the specified output stream and boundary. The boundary is required78 * to be created before using this method, as described in the79 * description for the <code>getContentType(String)</code> method.80 * The boundary is only checked for <code>null</code> or empty string,81 * but it is recommended to be at least 6 characters. (Or use the82 * static createBoundary() method to create one.)83 * 84 * @param os the output stream85 * @param boundary the boundary86 * @see #createBoundary()87 * @see #getContentType(String)88 */89 public MultiPartFormOutputStream(OutputStream os, String boundary) {90 if(os == null) {91 throw new IllegalArgumentException("Output stream is required.");92 }93 if(boundary == null || boundary.length() == 0) {94 throw new IllegalArgumentException("Boundary stream is required.");95 }96 this.out = new DataOutputStream(os);97 this.boundary = boundary;98 initAuthentication();99 }100 101 /**102 * Writes an boolean field value.103 * 104 * @param name the field name (required)105 * @param value the field value106 * @throws java.io.IOException on input/output errors107 */108 public void writeField(String name, boolean value)109 throws java.io.IOException {110 writeField(name, new Boolean(value).toString());111 }112 113 /**114 * Writes an double field value.115 * 116 * @param name the field name (required)117 * @param value the field value118 * @throws java.io.IOException on input/output errors119 */120 public void writeField(String name, double value)121 throws java.io.IOException {122 writeField(name, Double.toString(value));123 }124 125 /**126 * Writes an float field value.127 * 128 * @param name the field name (required)129 * @param value the field value130 * @throws java.io.IOException on input/output errors131 */132 public void writeField(String name, float value)133 throws java.io.IOException {134 writeField(name, Float.toString(value));135 }136 137 /**138 * Writes an long field value.139 * 140 * @param name the field name (required)141 * @param value the field value142 * @throws java.io.IOException on input/output errors143 */144 public void writeField(String name, long value)145 throws java.io.IOException {146 writeField(name, Long.toString(value));147 }148 149 /**150 * Writes an int field value.151 * 152 * @param name the field name (required)153 * @param value the field value154 * @throws java.io.IOException on input/output errors155 */156 public void writeField(String name, int value)157 throws java.io.IOException {158 writeField(name, Integer.toString(value));159 }160 161 /**162 * Writes an short field value.163 * 164 * @param name the field name (required)165 * @param value the field value166 * @throws java.io.IOException on input/output errors167 */168 public void writeField(String name, short value)169 throws java.io.IOException {170 writeField(name, Short.toString(value));171 }172 173 /**174 * Writes an char field value.175 * 176 * @param name the field name (required)177 * @param value the field value178 * @throws java.io.IOException on input/output errors179 */180 public void writeField(String name, char value)181 throws java.io.IOException {182 writeField(name, new Character(value).toString());183 }184 185 /**186 * Writes an string field value. If the value is null, an empty string187 * is sent ("").188 * 189 * @param name the field name (required)190 * @param value the field value191 * @throws java.io.IOException on input/output errors192 */193 public void writeField(String name, String value)194 throws java.io.IOException {195 if(name == null) {196 throw new IllegalArgumentException("Name cannot be null or empty.");197 }198 if(value == null) {199 value = "";200 }201 /*202 --boundary\r\n203 Content-Disposition: form-data; name="<fieldName>"\r\n204 \r\n205 <value>\r\n206 */207 // write boundary208 out.writeBytes(PREFIX);209 out.writeBytes(boundary);210 out.writeBytes(NEWLINE);211 // write content header212 out.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"");213 out.writeBytes(NEWLINE);214 out.writeBytes(NEWLINE);215 // write content216 out.writeBytes(value);217 out.writeBytes(NEWLINE);218 out.flush();219 }220 221 /**222 * Writes a file's contents. If the file is null, does not exists, or223 * is a directory, a <code>java.lang.IllegalArgumentException</code>224 * will be thrown.225 * 226 * @param name the field name227 * @param mimeType the file content type (optional, recommended)228 * @param file the file (the file must exist)229 * @throws java.io.IOException on input/output errors230 */231 public void writeFile(String name, String mimeType, java.io.File file)232 throws java.io.IOException {233 if(file == null) {234 throw new IllegalArgumentException("File cannot be null.");235 }236 if(!file.exists()) {237 throw new IllegalArgumentException("File does not exist.");238 }239 if(file.isDirectory()) {240 throw new IllegalArgumentException("File cannot be a directory.");241 }242 writeFile(name, mimeType, file.getCanonicalPath(), new FileInputStream(file));243 }244 245 /**246 * Writes a input stream's contents. If the input stream is null, a247 * <code>java.lang.IllegalArgumentException</code> will be thrown.248 * 249 * @param name the field name250 * @param mimeType the file content type (optional, recommended)251 * @param fileName the file name (required)252 * @param is the input stream253 * @throws java.io.IOException on input/output errors254 */255 public void writeFile(String name, String mimeType,256 String fileName, InputStream is)257 throws java.io.IOException {258 if(is == null) {259 throw new IllegalArgumentException("Input stream cannot be null.");260 }261 if(fileName == null || fileName.length() == 0) {262 throw new IllegalArgumentException("File name cannot be null or empty.");263 }264 /*265 --boundary\r\n266 Content-Disposition: form-data; name="<fieldName>"; filename="<filename>"\r\n267 Content-Type: <mime-type>\r\n268 \r\n269 <file-data>\r\n270 */271 // write boundary272 out.writeBytes(PREFIX);273 out.writeBytes(boundary);274 out.writeBytes(NEWLINE);275 // write content header276 out.writeBytes("Content-Disposition: form-data; name=\"" + name +277 "\"; filename=\"" + fileName + "\"");278 out.writeBytes(NEWLINE);279 if(mimeType != null) {280 out.writeBytes("Content-Type: " + mimeType);281 out.writeBytes(NEWLINE);282 }283 out.writeBytes(NEWLINE);284 // write content285 byte[] data = new byte[1024];286 int r = 0;287 while((r = is.read(data, 0, data.length)) != -1) {288 out.write(data, 0, r);289 }290 // close input stream, but ignore any possible exception for it291 try {292 is.close();293 } catch(Exception e) {}294 out.writeBytes(NEWLINE);295 out.flush();296 }297 298 /**299 * Writes the given bytes. The bytes are assumed to be the contents300 * of a file, and will be sent as such. If the data is null, a301 * <code>java.lang.IllegalArgumentException</code> will be thrown.302 * 303 * @param name the field name304 * @param mimeType the file content type (optional, recommended)305 * @param fileName the file name (required)306 * @param data the file data307 * @throws java.io.IOException on input/output errors308 */309 public void writeFile(String name, String mimeType,310 String fileName, byte[] data)311 throws java.io.IOException {312 if(data == null) {313 throw new IllegalArgumentException("Data cannot be null.");314 }315 if(fileName == null || fileName.length() == 0) {316 throw new IllegalArgumentException("File name cannot be null or empty.");317 }318 /*319 --boundary\r\n320 Content-Disposition: form-data; name="<fieldName>"; filename="<filename>"\r\n321 Content-Type: <mime-type>\r\n322 \r\n323 <file-data>\r\n324 */325 // write boundary326 out.writeBytes(PREFIX);327 out.writeBytes(boundary);328 out.writeBytes(NEWLINE);329 // write content header330 out.writeBytes("Content-Disposition: form-data; name=\"" + name +331 "\"; filename=\"" + fileName + "\"");332 out.writeBytes(NEWLINE);333 if(mimeType != null) {334 out.writeBytes("Content-Type: " + mimeType);335 out.writeBytes(NEWLINE);336 }337 out.writeBytes(NEWLINE);338 // write content339 out.write(data, 0, data.length);340 out.writeBytes(NEWLINE);341 out.flush();342 }343 344 /**345 * Flushes the stream. Actually, this method does nothing, as the only346 * write methods are highly specialized and automatically flush.347 */348 public void flush() {349 // out.flush();350 }351 352 /**353 * Closes the stream. <br/>354 * <br/>355 * <b>NOTE:</b> This method <b>MUST</b> be called to finalize the356 * multipart stream.357 * 358 * @throws java.io.IOException on input/output errors359 */360 public void close() throws java.io.IOException {361 // write final boundary362 out.writeBytes(PREFIX);363 out.writeBytes(boundary);364 out.writeBytes(PREFIX);365 out.writeBytes(NEWLINE);366 out.flush();367 out.close();368 }369 370 /**371 * Gets the multipart boundary string being used by this stream.372 * 373 * @return the boundary374 */375 public String getBoundary() {376 return this.boundary;377 }378 379 /**380 * Creates a new <code>java.net.URLConnection</code> object from the381 * specified <code>java.net.URL</code>. This is a convenience method382 * which will set the <code>doInput</code>, <code>doOutput</code>,383 * <code>useCaches</code> and <code>defaultUseCaches</code> fields to384 * the appropriate settings in the correct order.385 * 386 * @return a <code>java.net.URLConnection</code> object for the URL387 * @throws java.io.IOException on input/output errors388 */389 public static URLConnection createConnection(URL url)390 throws java.io.IOException {391 URLConnection urlConn = url.openConnection();392 if(urlConn instanceof HttpURLConnection) {393 HttpURLConnection httpConn = (HttpURLConnection)urlConn;394 httpConn.setRequestMethod("POST");395 }396 urlConn.setDoInput(true);397 urlConn.setDoOutput(true);398 urlConn.setUseCaches(false);399 urlConn.setDefaultUseCaches(false);400 return urlConn;401 }402 403 /**404 * Creates a multipart boundary string by concatenating 20 hyphens (-)405 * and the hexadecimal (base-16) representation of the current time in406 * milliseconds.407 * 408 * @return a multipart boundary string409 * @see #getContentType(String)410 */411 public static String createBoundary() {412 return "--------------------" +413 Long.toString(System.currentTimeMillis(), 16);414 }415 416 /**417 * Gets the content type string suitable for the418 * <code>java.net.URLConnection</code> which includes the multipart419 * boundary string. <br/>420 * <br/>421 * This method is static because, due to the nature of the422 * <code>java.net.URLConnection</code> class, once the output stream423 * for the connection is acquired, it's too late to set the content424 * type (or any other request parameter). So one has to create a425 * multipart boundary string first before using this class, such as426 * with the <code>createBoundary()</code> method.427 * 428 * @param boundary the boundary string429 * @return the content type string430 * @see #createBoundary()431 */432 public static String getContentType(String boundary) {433 return "multipart/form-data; boundary=" + boundary;434 }55 /** 56 * The line end characters. 57 */ 58 private static final String NEWLINE = "\r\n"; 59 60 /** 61 * The boundary prefix. 62 */ 63 private static final String PREFIX = "--"; 64 65 /** 66 * The output stream to write to. 67 */ 68 private DataOutputStream out = null; 69 70 /** 71 * The multipart boundary string. 72 */ 73 private String boundary = null; 74 75 /** 76 * Creates a new <code>MultiPartFormOutputStream</code> object using 77 * the specified output stream and boundary. The boundary is required 78 * to be created before using this method, as described in the 79 * description for the <code>getContentType(String)</code> method. 80 * The boundary is only checked for <code>null</code> or empty string, 81 * but it is recommended to be at least 6 characters. (Or use the 82 * static createBoundary() method to create one.) 83 * 84 * @param os the output stream 85 * @param boundary the boundary 86 * @see #createBoundary() 87 * @see #getContentType(String) 88 */ 89 public MultiPartFormOutputStream(OutputStream os, String boundary) { 90 if(os == null) { 91 throw new IllegalArgumentException("Output stream is required."); 92 } 93 if(boundary == null || boundary.length() == 0) { 94 throw new IllegalArgumentException("Boundary stream is required."); 95 } 96 this.out = new DataOutputStream(os); 97 this.boundary = boundary; 98 initAuthentication(); 99 } 100 101 /** 102 * Writes an boolean field value. 103 * 104 * @param name the field name (required) 105 * @param value the field value 106 * @throws java.io.IOException on input/output errors 107 */ 108 public void writeField(String name, boolean value) 109 throws java.io.IOException { 110 writeField(name, new Boolean(value).toString()); 111 } 112 113 /** 114 * Writes an double field value. 115 * 116 * @param name the field name (required) 117 * @param value the field value 118 * @throws java.io.IOException on input/output errors 119 */ 120 public void writeField(String name, double value) 121 throws java.io.IOException { 122 writeField(name, Double.toString(value)); 123 } 124 125 /** 126 * Writes an float field value. 127 * 128 * @param name the field name (required) 129 * @param value the field value 130 * @throws java.io.IOException on input/output errors 131 */ 132 public void writeField(String name, float value) 133 throws java.io.IOException { 134 writeField(name, Float.toString(value)); 135 } 136 137 /** 138 * Writes an long field value. 139 * 140 * @param name the field name (required) 141 * @param value the field value 142 * @throws java.io.IOException on input/output errors 143 */ 144 public void writeField(String name, long value) 145 throws java.io.IOException { 146 writeField(name, Long.toString(value)); 147 } 148 149 /** 150 * Writes an int field value. 151 * 152 * @param name the field name (required) 153 * @param value the field value 154 * @throws java.io.IOException on input/output errors 155 */ 156 public void writeField(String name, int value) 157 throws java.io.IOException { 158 writeField(name, Integer.toString(value)); 159 } 160 161 /** 162 * Writes an short field value. 163 * 164 * @param name the field name (required) 165 * @param value the field value 166 * @throws java.io.IOException on input/output errors 167 */ 168 public void writeField(String name, short value) 169 throws java.io.IOException { 170 writeField(name, Short.toString(value)); 171 } 172 173 /** 174 * Writes an char field value. 175 * 176 * @param name the field name (required) 177 * @param value the field value 178 * @throws java.io.IOException on input/output errors 179 */ 180 public void writeField(String name, char value) 181 throws java.io.IOException { 182 writeField(name, new Character(value).toString()); 183 } 184 185 /** 186 * Writes an string field value. If the value is null, an empty string 187 * is sent (""). 188 * 189 * @param name the field name (required) 190 * @param value the field value 191 * @throws java.io.IOException on input/output errors 192 */ 193 public void writeField(String name, String value) 194 throws java.io.IOException { 195 if(name == null) { 196 throw new IllegalArgumentException("Name cannot be null or empty."); 197 } 198 if(value == null) { 199 value = ""; 200 } 201 /* 202 --boundary\r\n 203 Content-Disposition: form-data; name="<fieldName>"\r\n 204 \r\n 205 <value>\r\n 206 */ 207 // write boundary 208 out.writeBytes(PREFIX); 209 out.writeBytes(boundary); 210 out.writeBytes(NEWLINE); 211 // write content header 212 out.writeBytes("Content-Disposition: form-data; name=\"" + name + "\""); 213 out.writeBytes(NEWLINE); 214 out.writeBytes(NEWLINE); 215 // write content 216 out.writeBytes(value); 217 out.writeBytes(NEWLINE); 218 out.flush(); 219 } 220 221 /** 222 * Writes a file's contents. If the file is null, does not exists, or 223 * is a directory, a <code>java.lang.IllegalArgumentException</code> 224 * will be thrown. 225 * 226 * @param name the field name 227 * @param mimeType the file content type (optional, recommended) 228 * @param file the file (the file must exist) 229 * @throws java.io.IOException on input/output errors 230 */ 231 public void writeFile(String name, String mimeType, java.io.File file) 232 throws java.io.IOException { 233 if(file == null) { 234 throw new IllegalArgumentException("File cannot be null."); 235 } 236 if(!file.exists()) { 237 throw new IllegalArgumentException("File does not exist."); 238 } 239 if(file.isDirectory()) { 240 throw new IllegalArgumentException("File cannot be a directory."); 241 } 242 writeFile(name, mimeType, file.getCanonicalPath(), new FileInputStream(file)); 243 } 244 245 /** 246 * Writes a input stream's contents. If the input stream is null, a 247 * <code>java.lang.IllegalArgumentException</code> will be thrown. 248 * 249 * @param name the field name 250 * @param mimeType the file content type (optional, recommended) 251 * @param fileName the file name (required) 252 * @param is the input stream 253 * @throws java.io.IOException on input/output errors 254 */ 255 public void writeFile(String name, String mimeType, 256 String fileName, InputStream is) 257 throws java.io.IOException { 258 if(is == null) { 259 throw new IllegalArgumentException("Input stream cannot be null."); 260 } 261 if(fileName == null || fileName.length() == 0) { 262 throw new IllegalArgumentException("File name cannot be null or empty."); 263 } 264 /* 265 --boundary\r\n 266 Content-Disposition: form-data; name="<fieldName>"; filename="<filename>"\r\n 267 Content-Type: <mime-type>\r\n 268 \r\n 269 <file-data>\r\n 270 */ 271 // write boundary 272 out.writeBytes(PREFIX); 273 out.writeBytes(boundary); 274 out.writeBytes(NEWLINE); 275 // write content header 276 out.writeBytes("Content-Disposition: form-data; name=\"" + name + 277 "\"; filename=\"" + fileName + "\""); 278 out.writeBytes(NEWLINE); 279 if(mimeType != null) { 280 out.writeBytes("Content-Type: " + mimeType); 281 out.writeBytes(NEWLINE); 282 } 283 out.writeBytes(NEWLINE); 284 // write content 285 byte[] data = new byte[1024]; 286 int r = 0; 287 while((r = is.read(data, 0, data.length)) != -1) { 288 out.write(data, 0, r); 289 } 290 // close input stream, but ignore any possible exception for it 291 try { 292 is.close(); 293 } catch(Exception e) {} 294 out.writeBytes(NEWLINE); 295 out.flush(); 296 } 297 298 /** 299 * Writes the given bytes. The bytes are assumed to be the contents 300 * of a file, and will be sent as such. If the data is null, a 301 * <code>java.lang.IllegalArgumentException</code> will be thrown. 302 * 303 * @param name the field name 304 * @param mimeType the file content type (optional, recommended) 305 * @param fileName the file name (required) 306 * @param data the file data 307 * @throws java.io.IOException on input/output errors 308 */ 309 public void writeFile(String name, String mimeType, 310 String fileName, byte[] data) 311 throws java.io.IOException { 312 if(data == null) { 313 throw new IllegalArgumentException("Data cannot be null."); 314 } 315 if(fileName == null || fileName.length() == 0) { 316 throw new IllegalArgumentException("File name cannot be null or empty."); 317 } 318 /* 319 --boundary\r\n 320 Content-Disposition: form-data; name="<fieldName>"; filename="<filename>"\r\n 321 Content-Type: <mime-type>\r\n 322 \r\n 323 <file-data>\r\n 324 */ 325 // write boundary 326 out.writeBytes(PREFIX); 327 out.writeBytes(boundary); 328 out.writeBytes(NEWLINE); 329 // write content header 330 out.writeBytes("Content-Disposition: form-data; name=\"" + name + 331 "\"; filename=\"" + fileName + "\""); 332 out.writeBytes(NEWLINE); 333 if(mimeType != null) { 334 out.writeBytes("Content-Type: " + mimeType); 335 out.writeBytes(NEWLINE); 336 } 337 out.writeBytes(NEWLINE); 338 // write content 339 out.write(data, 0, data.length); 340 out.writeBytes(NEWLINE); 341 out.flush(); 342 } 343 344 /** 345 * Flushes the stream. Actually, this method does nothing, as the only 346 * write methods are highly specialized and automatically flush. 347 */ 348 public void flush() { 349 // out.flush(); 350 } 351 352 /** 353 * Closes the stream. <br/> 354 * <br/> 355 * <b>NOTE:</b> This method <b>MUST</b> be called to finalize the 356 * multipart stream. 357 * 358 * @throws java.io.IOException on input/output errors 359 */ 360 public void close() throws java.io.IOException { 361 // write final boundary 362 out.writeBytes(PREFIX); 363 out.writeBytes(boundary); 364 out.writeBytes(PREFIX); 365 out.writeBytes(NEWLINE); 366 out.flush(); 367 out.close(); 368 } 369 370 /** 371 * Gets the multipart boundary string being used by this stream. 372 * 373 * @return the boundary 374 */ 375 public String getBoundary() { 376 return this.boundary; 377 } 378 379 /** 380 * Creates a new <code>java.net.URLConnection</code> object from the 381 * specified <code>java.net.URL</code>. This is a convenience method 382 * which will set the <code>doInput</code>, <code>doOutput</code>, 383 * <code>useCaches</code> and <code>defaultUseCaches</code> fields to 384 * the appropriate settings in the correct order. 385 * 386 * @return a <code>java.net.URLConnection</code> object for the URL 387 * @throws java.io.IOException on input/output errors 388 */ 389 public static URLConnection createConnection(URL url) 390 throws java.io.IOException { 391 URLConnection urlConn = url.openConnection(); 392 if(urlConn instanceof HttpURLConnection) { 393 HttpURLConnection httpConn = (HttpURLConnection)urlConn; 394 httpConn.setRequestMethod("POST"); 395 } 396 urlConn.setDoInput(true); 397 urlConn.setDoOutput(true); 398 urlConn.setUseCaches(false); 399 urlConn.setDefaultUseCaches(false); 400 return urlConn; 401 } 402 403 /** 404 * Creates a multipart boundary string by concatenating 20 hyphens (-) 405 * and the hexadecimal (base-16) representation of the current time in 406 * milliseconds. 407 * 408 * @return a multipart boundary string 409 * @see #getContentType(String) 410 */ 411 public static String createBoundary() { 412 return "--------------------" + 413 Long.toString(System.currentTimeMillis(), 16); 414 } 415 416 /** 417 * Gets the content type string suitable for the 418 * <code>java.net.URLConnection</code> which includes the multipart 419 * boundary string. <br/> 420 * <br/> 421 * This method is static because, due to the nature of the 422 * <code>java.net.URLConnection</code> class, once the output stream 423 * for the connection is acquired, it's too late to set the content 424 * type (or any other request parameter). So one has to create a 425 * multipart boundary string first before using this class, such as 426 * with the <code>createBoundary()</code> method. 427 * 428 * @param boundary the boundary string 429 * @return the content type string 430 * @see #createBoundary() 431 */ 432 public static String getContentType(String boundary) { 433 return "multipart/form-data; boundary=" + boundary; 434 } 435 435 } -
trunk/src/org/openstreetmap/josm/io/MyHttpHandler.java
r655 r1169 26 26 proxyPort = port; 27 27 } 28 28 29 29 protected java.net.URLConnection openConnection(URL u, Proxy p) 30 30 throws IOException { -
trunk/src/org/openstreetmap/josm/io/NmeaReader.java
r1167 r1169 28 28 public class NmeaReader { 29 29 30 /** Handler for the different types that NMEA speaks. */31 public static enum NMEA_TYPE {32 33 /** RMC = recommended minimum sentence C. */34 GPRMC("$GPRMC"),35 /** GPS positions. */36 GPGGA("$GPGGA"),37 /** SA = satellites active. */38 GPGSA("$GPGSA"),39 /** Course over ground and ground speed */40 GPVTG("$GPVTG");41 42 private final String type;43 44 NMEA_TYPE(String type) {45 this.type = type;46 }47 48 public String getType() {49 return this.type;50 }51 52 public boolean equals(String type) {53 return this.type.equals(type);54 }55 }56 57 // GPVTG58 public static enum GPVTG {59 COURSE(1),COURSE_REF(2), // true course60 COURSE_M(3), COURSE_M_REF(4), // magnetic course61 SPEED_KN(5), SPEED_KN_UNIT(6), // speed in knots62 SPEED_KMH(7), SPEED_KMH_UNIT(8), // speed in km/h63 REST(9); // version-specific rest64 65 public final int position;66 67 GPVTG(int position) {68 this.position = position;69 }70 }71 72 // The following only applies to GPRMC73 public static enum GPRMC {74 TIME(1),75 /** Warning from the receiver (A = data ok, V = warning) */76 RECEIVER_WARNING(2),77 WIDTH_NORTH(3), WIDTH_NORTH_NAME(4), // Latitude, NS78 LENGTH_EAST(5), LENGTH_EAST_NAME(6), // Longitude, EW79 SPEED(7), COURSE(8), DATE(9), // Speed in knots80 MAGNETIC_DECLINATION(10), UNKNOWN(11), // magnetic declination81 /**82 * Mode (A = autonom; D = differential; E = estimated; N = not valid; S83 * = simulated)84 *85 * @since NMEA 2.386 */87 MODE(12);88 89 public final int position;90 91 GPRMC(int position) {92 this.position = position;93 }94 }95 96 // The following only applies to GPGGA97 public static enum GPGGA {98 TIME(1), LATITUDE(2), LATITUDE_NAME(3), LONGITUDE(4), LONGITUDE_NAME(5),99 /**100 * Quality (0 = invalid, 1 = GPS, 2 = DGPS, 6 = estimanted (@since NMEA101 * 2.3))102 */103 QUALITY(6), SATELLITE_COUNT(7),104 HDOP(8), // HDOP (horizontal dilution of precision)105 HEIGHT(9), HEIGHT_UNTIS(10), // height above NN (above geoid)106 HEIGHT_2(11), HEIGHT_2_UNTIS(12), // height geoid - height ellipsoid (WGS84)107 GPS_AGE(13),// Age of differential GPS data108 REF(14); // REF station109 110 public final int position;111 GPGGA(int position) {112 this.position = position;113 }114 }115 116 public static enum GPGSA {117 AUTOMATIC(1),118 FIX_TYPE(2), // 1 = not fixed, 2 = 2D fixed, 3 = 3D fixed)119 // PRN numbers for max 12 satellites120 PRN_1(3), PRN_2(4), PRN_3(5), PRN_4(6), PRN_5(7), PRN_6(8),121 PRN_7(9), PRN_8(10), PRN_9(11), PRN_10(12), PRN_11(13), PRN_12(14),122 PDOP(15), // PDOP (precision)123 HDOP(16), // HDOP (horizontal precision)124 VDOP(17), ; // VDOP (vertical precision)125 126 public final int position;127 GPGSA(int position) {128 this.position = position;129 }130 }131 132 public GpxData data;30 /** Handler for the different types that NMEA speaks. */ 31 public static enum NMEA_TYPE { 32 33 /** RMC = recommended minimum sentence C. */ 34 GPRMC("$GPRMC"), 35 /** GPS positions. */ 36 GPGGA("$GPGGA"), 37 /** SA = satellites active. */ 38 GPGSA("$GPGSA"), 39 /** Course over ground and ground speed */ 40 GPVTG("$GPVTG"); 41 42 private final String type; 43 44 NMEA_TYPE(String type) { 45 this.type = type; 46 } 47 48 public String getType() { 49 return this.type; 50 } 51 52 public boolean equals(String type) { 53 return this.type.equals(type); 54 } 55 } 56 57 // GPVTG 58 public static enum GPVTG { 59 COURSE(1),COURSE_REF(2), // true course 60 COURSE_M(3), COURSE_M_REF(4), // magnetic course 61 SPEED_KN(5), SPEED_KN_UNIT(6), // speed in knots 62 SPEED_KMH(7), SPEED_KMH_UNIT(8), // speed in km/h 63 REST(9); // version-specific rest 64 65 public final int position; 66 67 GPVTG(int position) { 68 this.position = position; 69 } 70 } 71 72 // The following only applies to GPRMC 73 public static enum GPRMC { 74 TIME(1), 75 /** Warning from the receiver (A = data ok, V = warning) */ 76 RECEIVER_WARNING(2), 77 WIDTH_NORTH(3), WIDTH_NORTH_NAME(4), // Latitude, NS 78 LENGTH_EAST(5), LENGTH_EAST_NAME(6), // Longitude, EW 79 SPEED(7), COURSE(8), DATE(9), // Speed in knots 80 MAGNETIC_DECLINATION(10), UNKNOWN(11), // magnetic declination 81 /** 82 * Mode (A = autonom; D = differential; E = estimated; N = not valid; S 83 * = simulated) 84 * 85 * @since NMEA 2.3 86 */ 87 MODE(12); 88 89 public final int position; 90 91 GPRMC(int position) { 92 this.position = position; 93 } 94 } 95 96 // The following only applies to GPGGA 97 public static enum GPGGA { 98 TIME(1), LATITUDE(2), LATITUDE_NAME(3), LONGITUDE(4), LONGITUDE_NAME(5), 99 /** 100 * Quality (0 = invalid, 1 = GPS, 2 = DGPS, 6 = estimanted (@since NMEA 101 * 2.3)) 102 */ 103 QUALITY(6), SATELLITE_COUNT(7), 104 HDOP(8), // HDOP (horizontal dilution of precision) 105 HEIGHT(9), HEIGHT_UNTIS(10), // height above NN (above geoid) 106 HEIGHT_2(11), HEIGHT_2_UNTIS(12), // height geoid - height ellipsoid (WGS84) 107 GPS_AGE(13),// Age of differential GPS data 108 REF(14); // REF station 109 110 public final int position; 111 GPGGA(int position) { 112 this.position = position; 113 } 114 } 115 116 public static enum GPGSA { 117 AUTOMATIC(1), 118 FIX_TYPE(2), // 1 = not fixed, 2 = 2D fixed, 3 = 3D fixed) 119 // PRN numbers for max 12 satellites 120 PRN_1(3), PRN_2(4), PRN_3(5), PRN_4(6), PRN_5(7), PRN_6(8), 121 PRN_7(9), PRN_8(10), PRN_9(11), PRN_10(12), PRN_11(13), PRN_12(14), 122 PDOP(15), // PDOP (precision) 123 HDOP(16), // HDOP (horizontal precision) 124 VDOP(17), ; // VDOP (vertical precision) 125 126 public final int position; 127 GPGSA(int position) { 128 this.position = position; 129 } 130 } 131 132 public GpxData data; 133 133 134 134 // private final static SimpleDateFormat GGATIMEFMT = 135 135 // new SimpleDateFormat("HHmmss.SSS"); 136 private final static SimpleDateFormat RMCTIMEFMT =137 new SimpleDateFormat("ddMMyyHHmmss.SSS");138 139 // functons for reading the error stats140 public NMEAParserState ps;141 142 public int getParserUnknown() {143 return ps.unknown;144 }145 public int getParserZeroCoordinates() {146 return ps.zero_coord;147 }148 public int getParserChecksumErrors() {149 return ps.checksum_errors;150 }151 public int getParserMalformed() {152 return ps.malformed;153 }154 public int getNumberOfCoordinates() {155 return ps.success;156 }157 158 public NmeaReader(InputStream source, File relativeMarkerPath) {159 160 // create the data tree161 data = new GpxData();162 GpxTrack currentTrack = new GpxTrack();163 data.tracks.add(currentTrack);164 165 try {166 BufferedReader rd =167 new BufferedReader(new InputStreamReader(source));168 169 StringBuffer sb = new StringBuffer(1024);170 int loopstart_char = rd.read();171 if(loopstart_char == -1) {// zero size file172 //TODO tell user about the problem?173 return;174 }175 sb.append((char)loopstart_char);176 ps = new NMEAParserState();177 ps.p_Date="010100"; // TODO date problem178 while(true) {179 // don't load unparsable files completely to memory180 if(sb.length()>=1020) sb.delete(0, sb.length()-1);181 int c = rd.read();182 if(c=='$') {183 ParseNMEASentence(sb.toString(), ps);184 sb.delete(0, sb.length());185 sb.append('$');186 } else if(c == -1) {187 // EOF: add last WayPoint if it works out188 ParseNMEASentence(sb.toString(),ps);189 break;190 } else sb.append((char)c);191 }192 rd.close();193 Object[] wparr = ps.waypoints.toArray();194 currentTrack.trackSegs.add(ps.waypoints);195 data.recalculateBounds();196 197 } catch (final IOException e) {198 // TODO tell user about the problem?199 }200 }201 private class NMEAParserState {202 protected Collection<WayPoint> waypoints = new ArrayList<WayPoint>();203 protected String p_Time;204 protected String p_Date;205 protected WayPoint p_Wp;206 207 protected int success = 0; // number of successfully parsend sentences208 protected int malformed = 0;209 protected int checksum_errors = 0;210 protected int unknown = 0;211 protected int zero_coord = 0;212 }213 214 // Parses split up sentences into WayPoints which are stored215 // in the collection in the NMEAParserState object.216 // Returns true if the input made sence, false otherwise.217 private boolean ParseNMEASentence(String s, NMEAParserState ps) {218 try {219 if(s.equals("")) throw(null);220 221 // checksum check:222 // the bytes between the $ and the * are xored;223 // if there is no * or other meanities it will throw224 // and result in a malformed packet.225 String[] chkstrings = s.split("\\*");226 byte[] chb = chkstrings[0].getBytes();227 int chk=0;228 for(int i = 1; i < chb.length; i++) chk ^= chb[i];229 if(Integer.parseInt(chkstrings[1].substring(0,2),16) != chk) {230 //System.out.println("Checksum error");231 ps.checksum_errors++;232 ps.p_Wp=null;233 return false;234 }235 // now for the content236 String[] e = chkstrings[0].split(",");237 String accu;238 239 WayPoint currentwp = ps.p_Wp;240 String currentDate = ps.p_Date;241 242 // handle the packet content243 if(e[0].equals("$GPGGA")) {244 // Position245 LatLon latLon = parseLatLon(246 e[GPGGA.LATITUDE_NAME.position],247 e[GPGGA.LONGITUDE_NAME.position],248 e[GPGGA.LATITUDE.position],249 e[GPGGA.LONGITUDE.position]250 );251 if(latLon==null) throw(null); // malformed252 253 if((latLon.lat()==0.0) && (latLon.lon()==0.0)) {254 ps.zero_coord++;255 return false;256 }257 258 // time259 accu = e[GPGGA.TIME.position];260 Date d = RMCTIMEFMT.parse(currentDate+accu, new ParsePosition(0));261 if (d == null) throw(null); // malformed262 263 if((ps.p_Time==null) || (currentwp==null) || !ps.p_Time.equals(accu)) {264 // this node is newer than the previous, create a new waypoint.265 // no matter if previous WayPoint was null, we got something266 // better now.267 ps.p_Time=accu;268 currentwp = new WayPoint(latLon);269 }270 if(!currentwp.attr.containsKey("time")) {271 // As this sentence has no complete time only use it272 // if there is no time so far273 String gpxdate = WayPoint.GPXTIMEFMT.format(d);274 currentwp.attr.put("time", gpxdate);275 }276 // elevation277 accu=e[GPGGA.HEIGHT_UNTIS.position];278 if(accu.equals("M")) {279 // Ignore heights that are not in meters for now280 accu=e[GPGGA.HEIGHT.position];281 if(!accu.equals("")) {282 Double.parseDouble(accu);283 // if it throws it's malformed; this should only happen if the284 // device sends nonstandard data.285 if(!accu.equals("")) currentwp.attr.put("ele", accu);286 }287 }288 // number of sattelites289 accu=e[GPGGA.SATELLITE_COUNT.position];290 int sat = 0;291 if(!accu.equals("")) {292 sat = Integer.parseInt(accu);293 currentwp.attr.put("sat", accu);294 }295 // h-dilution296 accu=e[GPGGA.HDOP.position];297 if(!accu.equals("")) {298 Double.parseDouble(accu);299 currentwp.attr.put("hdop", accu);300 }301 // fix302 accu=e[GPGGA.QUALITY.position];303 if(!accu.equals("")) {304 int fixtype = Integer.parseInt(accu);305 switch(fixtype) {306 case 0:307 currentwp.attr.put("fix", "none");308 break;309 case 1:310 if(sat < 4) currentwp.attr.put("fix", "2d");311 else currentwp.attr.put("fix", "3d");312 break;313 case 2:314 currentwp.attr.put("fix", "dgps");315 break;316 default:317 break;318 }319 }320 } else if(e[0].equals("$GPVTG")) {321 // COURSE322 accu = e[GPVTG.COURSE_REF.position];323 if(accu.equals("T")) {324 // other values than (T)rue are ignored325 accu = e[GPVTG.COURSE.position];326 if(!accu.equals("")) {327 Double.parseDouble(accu);328 currentwp.attr.put("course", accu);329 }330 }331 // SPEED332 accu = e[GPVTG.SPEED_KMH_UNIT.position];333 if(accu.startsWith("K")) {334 accu = e[GPVTG.SPEED_KMH.position];335 if(!accu.equals("")) {336 double speed = Double.parseDouble(accu);337 speed /= 3.6; // speed in m/s338 currentwp.attr.put("speed", Double.toString(speed));339 }340 }341 } else if(e[0].equals("$GPGSA")) {342 // vdop343 accu=e[GPGSA.VDOP.position];344 if(!accu.equals("")) {345 Double.parseDouble(accu);346 currentwp.attr.put("vdop", accu);347 }348 // hdop349 accu=e[GPGSA.HDOP.position];350 if(!accu.equals("")) {351 Double.parseDouble(accu);352 currentwp.attr.put("hdop", accu);353 }354 // pdop355 accu=e[GPGSA.PDOP.position];356 if(!accu.equals("")) {357 Double.parseDouble(accu);358 currentwp.attr.put("pdop", accu);359 }360 }361 else if(e[0].equals("$GPRMC")) {362 // coordinates363 LatLon latLon = parseLatLon(364 e[GPRMC.WIDTH_NORTH_NAME.position],365 e[GPRMC.LENGTH_EAST_NAME.position],366 e[GPRMC.WIDTH_NORTH.position],367 e[GPRMC.LENGTH_EAST.position]368 );369 if(latLon==null) throw(null);370 if((latLon.lat()==0.0) && (latLon.lon()==0.0)) {371 ps.zero_coord++;372 return false;373 }374 // time375 currentDate = e[GPRMC.DATE.position];376 String time = e[GPRMC.TIME.position];377 378 Date d = RMCTIMEFMT.parse(currentDate+time, new ParsePosition(0));379 if (d == null) throw(null);380 381 if((ps.p_Time==null) || (currentwp==null) || !ps.p_Time.equals(time)) {382 // this node is newer than the previous, create a new waypoint.383 ps.p_Time=time;384 currentwp = new WayPoint(latLon);385 }386 // time: this sentence has complete time so always use it.387 String gpxdate = WayPoint.GPXTIMEFMT.format(d);388 currentwp.attr.put("time", gpxdate);389 // speed390 accu = e[GPRMC.SPEED.position];391 if(!accu.equals("") && !currentwp.attr.containsKey("speed")) {392 double speed = Double.parseDouble(accu);393 speed *= 0.514444444; // to m/s394 currentwp.attr.put("speed", Double.toString(speed));395 }396 // course397 accu = e[GPRMC.COURSE.position];398 if(!accu.equals("") && !currentwp.attr.containsKey("course")) {399 Double.parseDouble(accu);400 currentwp.attr.put("course", accu);401 }402 403 // TODO fix?404 // * Mode (A = autonom; D = differential; E = estimated; N = not valid; S405 // * = simulated)406 // *407 // * @since NMEA 2.3408 //409 //MODE(12);410 } else {411 ps.unknown++;412 return false;413 }414 ps.p_Date = currentDate;415 if(ps.p_Wp != currentwp) {416 if(ps.p_Wp!=null) {417 ps.p_Wp.setTime();418 }419 ps.p_Wp = currentwp;420 ps.waypoints.add(currentwp);421 ps.success++;422 return true;423 }424 return true;425 426 } catch(Exception x) {427 // out of bounds and such428 //System.out.println("Malformed line: "+s.toString().trim());429 ps.malformed++;430 ps.p_Wp=null;431 return false;432 }433 }434 435 private LatLon parseLatLon(String ew, String ns, String dlat, String dlon)436 throws NumberFormatException {437 String widthNorth = dlat.trim();438 String lengthEast = dlon.trim();439 440 // return a zero latlon instead of null so it is logged as zero coordinate441 // instead of malformed sentence442 if(widthNorth.equals("")&&lengthEast.equals("")) return new LatLon(0.0,0.0);443 444 // The format is xxDDLL.LLLL445 // xx optional whitespace446 // DD (int) degres447 // LL.LLLL (double) latidude448 int latdegsep = widthNorth.indexOf('.') - 2;449 if (latdegsep < 0) return null;450 451 int latdeg = Integer.parseInt(widthNorth.substring(0, latdegsep));452 double latmin = Double.parseDouble(widthNorth.substring(latdegsep));453 double lat = latdeg + latmin / 60;454 if ("S".equals(ns)) {455 if(!ew.equals("N")) return null;456 lat = -lat;457 }458 459 int londegsep = lengthEast.indexOf('.') - 2;460 if (londegsep < 0) return null;461 462 int londeg = Integer.parseInt(lengthEast.substring(0, londegsep));463 double lonmin = Double.parseDouble(lengthEast.substring(londegsep));464 double lon = londeg + lonmin / 60;465 if ("W".equals(ew)) {466 if(!ew.equals("E")) return null;467 lon = -lon;468 }469 return new LatLon(lat, lon);470 }136 private final static SimpleDateFormat RMCTIMEFMT = 137 new SimpleDateFormat("ddMMyyHHmmss.SSS"); 138 139 // functons for reading the error stats 140 public NMEAParserState ps; 141 142 public int getParserUnknown() { 143 return ps.unknown; 144 } 145 public int getParserZeroCoordinates() { 146 return ps.zero_coord; 147 } 148 public int getParserChecksumErrors() { 149 return ps.checksum_errors; 150 } 151 public int getParserMalformed() { 152 return ps.malformed; 153 } 154 public int getNumberOfCoordinates() { 155 return ps.success; 156 } 157 158 public NmeaReader(InputStream source, File relativeMarkerPath) { 159 160 // create the data tree 161 data = new GpxData(); 162 GpxTrack currentTrack = new GpxTrack(); 163 data.tracks.add(currentTrack); 164 165 try { 166 BufferedReader rd = 167 new BufferedReader(new InputStreamReader(source)); 168 169 StringBuffer sb = new StringBuffer(1024); 170 int loopstart_char = rd.read(); 171 if(loopstart_char == -1) {// zero size file 172 //TODO tell user about the problem? 173 return; 174 } 175 sb.append((char)loopstart_char); 176 ps = new NMEAParserState(); 177 ps.p_Date="010100"; // TODO date problem 178 while(true) { 179 // don't load unparsable files completely to memory 180 if(sb.length()>=1020) sb.delete(0, sb.length()-1); 181 int c = rd.read(); 182 if(c=='$') { 183 ParseNMEASentence(sb.toString(), ps); 184 sb.delete(0, sb.length()); 185 sb.append('$'); 186 } else if(c == -1) { 187 // EOF: add last WayPoint if it works out 188 ParseNMEASentence(sb.toString(),ps); 189 break; 190 } else sb.append((char)c); 191 } 192 rd.close(); 193 Object[] wparr = ps.waypoints.toArray(); 194 currentTrack.trackSegs.add(ps.waypoints); 195 data.recalculateBounds(); 196 197 } catch (final IOException e) { 198 // TODO tell user about the problem? 199 } 200 } 201 private class NMEAParserState { 202 protected Collection<WayPoint> waypoints = new ArrayList<WayPoint>(); 203 protected String p_Time; 204 protected String p_Date; 205 protected WayPoint p_Wp; 206 207 protected int success = 0; // number of successfully parsend sentences 208 protected int malformed = 0; 209 protected int checksum_errors = 0; 210 protected int unknown = 0; 211 protected int zero_coord = 0; 212 } 213 214 // Parses split up sentences into WayPoints which are stored 215 // in the collection in the NMEAParserState object. 216 // Returns true if the input made sence, false otherwise. 217 private boolean ParseNMEASentence(String s, NMEAParserState ps) { 218 try { 219 if(s.equals("")) throw(null); 220 221 // checksum check: 222 // the bytes between the $ and the * are xored; 223 // if there is no * or other meanities it will throw 224 // and result in a malformed packet. 225 String[] chkstrings = s.split("\\*"); 226 byte[] chb = chkstrings[0].getBytes(); 227 int chk=0; 228 for(int i = 1; i < chb.length; i++) chk ^= chb[i]; 229 if(Integer.parseInt(chkstrings[1].substring(0,2),16) != chk) { 230 //System.out.println("Checksum error"); 231 ps.checksum_errors++; 232 ps.p_Wp=null; 233 return false; 234 } 235 // now for the content 236 String[] e = chkstrings[0].split(","); 237 String accu; 238 239 WayPoint currentwp = ps.p_Wp; 240 String currentDate = ps.p_Date; 241 242 // handle the packet content 243 if(e[0].equals("$GPGGA")) { 244 // Position 245 LatLon latLon = parseLatLon( 246 e[GPGGA.LATITUDE_NAME.position], 247 e[GPGGA.LONGITUDE_NAME.position], 248 e[GPGGA.LATITUDE.position], 249 e[GPGGA.LONGITUDE.position] 250 ); 251 if(latLon==null) throw(null); // malformed 252 253 if((latLon.lat()==0.0) && (latLon.lon()==0.0)) { 254 ps.zero_coord++; 255 return false; 256 } 257 258 // time 259 accu = e[GPGGA.TIME.position]; 260 Date d = RMCTIMEFMT.parse(currentDate+accu, new ParsePosition(0)); 261 if (d == null) throw(null); // malformed 262 263 if((ps.p_Time==null) || (currentwp==null) || !ps.p_Time.equals(accu)) { 264 // this node is newer than the previous, create a new waypoint. 265 // no matter if previous WayPoint was null, we got something 266 // better now. 267 ps.p_Time=accu; 268 currentwp = new WayPoint(latLon); 269 } 270 if(!currentwp.attr.containsKey("time")) { 271 // As this sentence has no complete time only use it 272 // if there is no time so far 273 String gpxdate = WayPoint.GPXTIMEFMT.format(d); 274 currentwp.attr.put("time", gpxdate); 275 } 276 // elevation 277 accu=e[GPGGA.HEIGHT_UNTIS.position]; 278 if(accu.equals("M")) { 279 // Ignore heights that are not in meters for now 280 accu=e[GPGGA.HEIGHT.position]; 281 if(!accu.equals("")) { 282 Double.parseDouble(accu); 283 // if it throws it's malformed; this should only happen if the 284 // device sends nonstandard data. 285 if(!accu.equals("")) currentwp.attr.put("ele", accu); 286 } 287 } 288 // number of sattelites 289 accu=e[GPGGA.SATELLITE_COUNT.position]; 290 int sat = 0; 291 if(!accu.equals("")) { 292 sat = Integer.parseInt(accu); 293 currentwp.attr.put("sat", accu); 294 } 295 // h-dilution 296 accu=e[GPGGA.HDOP.position]; 297 if(!accu.equals("")) { 298 Double.parseDouble(accu); 299 currentwp.attr.put("hdop", accu); 300 } 301 // fix 302 accu=e[GPGGA.QUALITY.position]; 303 if(!accu.equals("")) { 304 int fixtype = Integer.parseInt(accu); 305 switch(fixtype) { 306 case 0: 307 currentwp.attr.put("fix", "none"); 308 break; 309 case 1: 310 if(sat < 4) currentwp.attr.put("fix", "2d"); 311 else currentwp.attr.put("fix", "3d"); 312 break; 313 case 2: 314 currentwp.attr.put("fix", "dgps"); 315 break; 316 default: 317 break; 318 } 319 } 320 } else if(e[0].equals("$GPVTG")) { 321 // COURSE 322 accu = e[GPVTG.COURSE_REF.position]; 323 if(accu.equals("T")) { 324 // other values than (T)rue are ignored 325 accu = e[GPVTG.COURSE.position]; 326 if(!accu.equals("")) { 327 Double.parseDouble(accu); 328 currentwp.attr.put("course", accu); 329 } 330 } 331 // SPEED 332 accu = e[GPVTG.SPEED_KMH_UNIT.position]; 333 if(accu.startsWith("K")) { 334 accu = e[GPVTG.SPEED_KMH.position]; 335 if(!accu.equals("")) { 336 double speed = Double.parseDouble(accu); 337 speed /= 3.6; // speed in m/s 338 currentwp.attr.put("speed", Double.toString(speed)); 339 } 340 } 341 } else if(e[0].equals("$GPGSA")) { 342 // vdop 343 accu=e[GPGSA.VDOP.position]; 344 if(!accu.equals("")) { 345 Double.parseDouble(accu); 346 currentwp.attr.put("vdop", accu); 347 } 348 // hdop 349 accu=e[GPGSA.HDOP.position]; 350 if(!accu.equals("")) { 351 Double.parseDouble(accu); 352 currentwp.attr.put("hdop", accu); 353 } 354 // pdop 355 accu=e[GPGSA.PDOP.position]; 356 if(!accu.equals("")) { 357 Double.parseDouble(accu); 358 currentwp.attr.put("pdop", accu); 359 } 360 } 361 else if(e[0].equals("$GPRMC")) { 362 // coordinates 363 LatLon latLon = parseLatLon( 364 e[GPRMC.WIDTH_NORTH_NAME.position], 365 e[GPRMC.LENGTH_EAST_NAME.position], 366 e[GPRMC.WIDTH_NORTH.position], 367 e[GPRMC.LENGTH_EAST.position] 368 ); 369 if(latLon==null) throw(null); 370 if((latLon.lat()==0.0) && (latLon.lon()==0.0)) { 371 ps.zero_coord++; 372 return false; 373 } 374 // time 375 currentDate = e[GPRMC.DATE.position]; 376 String time = e[GPRMC.TIME.position]; 377 378 Date d = RMCTIMEFMT.parse(currentDate+time, new ParsePosition(0)); 379 if (d == null) throw(null); 380 381 if((ps.p_Time==null) || (currentwp==null) || !ps.p_Time.equals(time)) { 382 // this node is newer than the previous, create a new waypoint. 383 ps.p_Time=time; 384 currentwp = new WayPoint(latLon); 385 } 386 // time: this sentence has complete time so always use it. 387 String gpxdate = WayPoint.GPXTIMEFMT.format(d); 388 currentwp.attr.put("time", gpxdate); 389 // speed 390 accu = e[GPRMC.SPEED.position]; 391 if(!accu.equals("") && !currentwp.attr.containsKey("speed")) { 392 double speed = Double.parseDouble(accu); 393 speed *= 0.514444444; // to m/s 394 currentwp.attr.put("speed", Double.toString(speed)); 395 } 396 // course 397 accu = e[GPRMC.COURSE.position]; 398 if(!accu.equals("") && !currentwp.attr.containsKey("course")) { 399 Double.parseDouble(accu); 400 currentwp.attr.put("course", accu); 401 } 402 403 // TODO fix? 404 // * Mode (A = autonom; D = differential; E = estimated; N = not valid; S 405 // * = simulated) 406 // * 407 // * @since NMEA 2.3 408 // 409 //MODE(12); 410 } else { 411 ps.unknown++; 412 return false; 413 } 414 ps.p_Date = currentDate; 415 if(ps.p_Wp != currentwp) { 416 if(ps.p_Wp!=null) { 417 ps.p_Wp.setTime(); 418 } 419 ps.p_Wp = currentwp; 420 ps.waypoints.add(currentwp); 421 ps.success++; 422 return true; 423 } 424 return true; 425 426 } catch(Exception x) { 427 // out of bounds and such 428 //System.out.println("Malformed line: "+s.toString().trim()); 429 ps.malformed++; 430 ps.p_Wp=null; 431 return false; 432 } 433 } 434 435 private LatLon parseLatLon(String ew, String ns, String dlat, String dlon) 436 throws NumberFormatException { 437 String widthNorth = dlat.trim(); 438 String lengthEast = dlon.trim(); 439 440 // return a zero latlon instead of null so it is logged as zero coordinate 441 // instead of malformed sentence 442 if(widthNorth.equals("")&&lengthEast.equals("")) return new LatLon(0.0,0.0); 443 444 // The format is xxDDLL.LLLL 445 // xx optional whitespace 446 // DD (int) degres 447 // LL.LLLL (double) latidude 448 int latdegsep = widthNorth.indexOf('.') - 2; 449 if (latdegsep < 0) return null; 450 451 int latdeg = Integer.parseInt(widthNorth.substring(0, latdegsep)); 452 double latmin = Double.parseDouble(widthNorth.substring(latdegsep)); 453 double lat = latdeg + latmin / 60; 454 if ("S".equals(ns)) { 455 if(!ew.equals("N")) return null; 456 lat = -lat; 457 } 458 459 int londegsep = lengthEast.indexOf('.') - 2; 460 if (londegsep < 0) return null; 461 462 int londeg = Integer.parseInt(lengthEast.substring(0, londegsep)); 463 double lonmin = Double.parseDouble(lengthEast.substring(londegsep)); 464 double lon = londeg + lonmin / 60; 465 if ("W".equals(ew)) { 466 if(!ew.equals("E")) return null; 467 lon = -lon; 468 } 469 return new LatLon(lat, lon); 470 } 471 471 } -
trunk/src/org/openstreetmap/josm/io/OsmConnection.java
r763 r1169 34 34 public class OsmConnection { 35 35 36 public static class OsmParseException extends Exception {37 public OsmParseException() {super();}38 public OsmParseException(String message, Throwable cause) {super(message, cause);}39 public OsmParseException(String message) {super(message);}40 public OsmParseException(Throwable cause) {super(cause);}41 }36 public static class OsmParseException extends Exception { 37 public OsmParseException() {super();} 38 public OsmParseException(String message, Throwable cause) {super(message, cause);} 39 public OsmParseException(String message) {super(message);} 40 public OsmParseException(Throwable cause) {super(cause);} 41 } 42 42 43 protected boolean cancel = false;44 protected HttpURLConnection activeConnection;43 protected boolean cancel = false; 44 protected HttpURLConnection activeConnection; 45 45 46 private static OsmAuth authentication = new OsmAuth();47 /**48 * Initialize the http defaults and the authenticator.49 */50 static {51 //TODO: refactor this crap (maybe just insert the damn auth http-header by yourself)52 try {53 HttpURLConnection.setFollowRedirects(true);54 Authenticator.setDefault(authentication);46 private static OsmAuth authentication = new OsmAuth(); 47 /** 48 * Initialize the http defaults and the authenticator. 49 */ 50 static { 51 //TODO: refactor this crap (maybe just insert the damn auth http-header by yourself) 52 try { 53 HttpURLConnection.setFollowRedirects(true); 54 Authenticator.setDefault(authentication); 55 55 } catch (SecurityException e) { 56 56 } 57 }57 } 58 58 59 /**60 * The authentication class handling the login requests.61 */62 private static class OsmAuth extends Authenticator {63 /**64 * Set to true, when the autenticator tried the password once.65 */66 boolean passwordtried = false;67 /**68 * Whether the user cancelled the password dialog69 */70 boolean authCancelled = false;59 /** 60 * The authentication class handling the login requests. 61 */ 62 private static class OsmAuth extends Authenticator { 63 /** 64 * Set to true, when the autenticator tried the password once. 65 */ 66 boolean passwordtried = false; 67 /** 68 * Whether the user cancelled the password dialog 69 */ 70 boolean authCancelled = false; 71 71 72 @Override protected PasswordAuthentication getPasswordAuthentication() {73 String username = Main.pref.get("osm-server.username");74 String password = Main.pref.get("osm-server.password");75 if (passwordtried || username.equals("") || password.equals("")) {76 JPanel p = new JPanel(new GridBagLayout());77 if (!username.equals("") && !password.equals(""))78 p.add(new JLabel(tr("Incorrect password or username.")), GBC.eop());79 p.add(new JLabel(tr("Username")), GBC.std().insets(0,0,10,0));80 JTextField usernameField = new JTextField(username, 20);81 p.add(usernameField, GBC.eol());82 p.add(new JLabel(tr("Password")), GBC.std().insets(0,0,10,0));83 JPasswordField passwordField = new JPasswordField(password, 20);84 p.add(passwordField, GBC.eol());85 JLabel warning = new JLabel(tr("Warning: The password is transferred unencrypted."));86 warning.setFont(warning.getFont().deriveFont(Font.ITALIC));87 p.add(warning, GBC.eop());72 @Override protected PasswordAuthentication getPasswordAuthentication() { 73 String username = Main.pref.get("osm-server.username"); 74 String password = Main.pref.get("osm-server.password"); 75 if (passwordtried || username.equals("") || password.equals("")) { 76 JPanel p = new JPanel(new GridBagLayout()); 77 if (!username.equals("") && !password.equals("")) 78 p.add(new JLabel(tr("Incorrect password or username.")), GBC.eop()); 79 p.add(new JLabel(tr("Username")), GBC.std().insets(0,0,10,0)); 80 JTextField usernameField = new JTextField(username, 20); 81 p.add(usernameField, GBC.eol()); 82 p.add(new JLabel(tr("Password")), GBC.std().insets(0,0,10,0)); 83 JPasswordField passwordField = new JPasswordField(password, 20); 84 p.add(passwordField, GBC.eol()); 85 JLabel warning = new JLabel(tr("Warning: The password is transferred unencrypted.")); 86 warning.setFont(warning.getFont().deriveFont(Font.ITALIC)); 87 p.add(warning, GBC.eop()); 88 88 89 JCheckBox savePassword = new JCheckBox(tr("Save user and password (unencrypted)"), !username.equals("") && !password.equals(""));90 p.add(savePassword, GBC.eop());89 JCheckBox savePassword = new JCheckBox(tr("Save user and password (unencrypted)"), !username.equals("") && !password.equals("")); 90 p.add(savePassword, GBC.eop()); 91 91 92 int choice = JOptionPane.showConfirmDialog(Main.parent, p, tr("Enter Password"), JOptionPane.OK_CANCEL_OPTION);93 if (choice == JOptionPane.CANCEL_OPTION) {94 authCancelled = true;95 return null;96 }97 username = usernameField.getText();98 password = String.valueOf(passwordField.getPassword());99 if (savePassword.isSelected()) {100 Main.pref.put("osm-server.username", username);101 Main.pref.put("osm-server.password", password);102 }103 if (username.equals(""))104 return null;105 }106 passwordtried = true;107 return new PasswordAuthentication(username, password.toCharArray());108 }109 }92 int choice = JOptionPane.showConfirmDialog(Main.parent, p, tr("Enter Password"), JOptionPane.OK_CANCEL_OPTION); 93 if (choice == JOptionPane.CANCEL_OPTION) { 94 authCancelled = true; 95 return null; 96 } 97 username = usernameField.getText(); 98 password = String.valueOf(passwordField.getPassword()); 99 if (savePassword.isSelected()) { 100 Main.pref.put("osm-server.username", username); 101 Main.pref.put("osm-server.password", password); 102 } 103 if (username.equals("")) 104 return null; 105 } 106 passwordtried = true; 107 return new PasswordAuthentication(username, password.toCharArray()); 108 } 109 } 110 110 111 /**112 * Must be called before each connection attemp to initialize the authentication.113 */114 protected final void initAuthentication() {115 authentication.authCancelled = false;116 authentication.passwordtried = false;117 }111 /** 112 * Must be called before each connection attemp to initialize the authentication. 113 */ 114 protected final void initAuthentication() { 115 authentication.authCancelled = false; 116 authentication.passwordtried = false; 117 } 118 118 119 /**120 * @return Whether the connection was cancelled.121 */122 protected final boolean isAuthCancelled() {123 return authentication.authCancelled;124 }119 /** 120 * @return Whether the connection was cancelled. 121 */ 122 protected final boolean isAuthCancelled() { 123 return authentication.authCancelled; 124 } 125 125 126 public void cancel() {127 Main.pleaseWaitDlg.currentAction.setText(tr("Aborting..."));128 cancel = true;129 if (activeConnection != null) {130 activeConnection.setConnectTimeout(100);131 activeConnection.setReadTimeout(100);132 try {133 Thread.sleep(100);134 } catch (InterruptedException ex) {}135 activeConnection.disconnect();136 }137 }126 public void cancel() { 127 Main.pleaseWaitDlg.currentAction.setText(tr("Aborting...")); 128 cancel = true; 129 if (activeConnection != null) { 130 activeConnection.setConnectTimeout(100); 131 activeConnection.setReadTimeout(100); 132 try { 133 Thread.sleep(100); 134 } catch (InterruptedException ex) {} 135 activeConnection.disconnect(); 136 } 137 } 138 138 139 protected void addAuth(HttpURLConnection con) throws CharacterCodingException {140 CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();141 String auth = Main.pref.get("osm-server.username") + ":" + Main.pref.get("osm-server.password");142 ByteBuffer bytes = encoder.encode(CharBuffer.wrap(auth));143 con.addRequestProperty("Authorization", "Basic "+Base64.encode(bytes));144 }139 protected void addAuth(HttpURLConnection con) throws CharacterCodingException { 140 CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder(); 141 String auth = Main.pref.get("osm-server.username") + ":" + Main.pref.get("osm-server.password"); 142 ByteBuffer bytes = encoder.encode(CharBuffer.wrap(auth)); 143 con.addRequestProperty("Authorization", "Basic "+Base64.encode(bytes)); 144 } 145 145 } -
trunk/src/org/openstreetmap/josm/io/OsmIdReader.java
r627 r1169 21 21 /** 22 22 * Read only the ids and classes of an stream. 23 * 23 * 24 24 * @author Imi 25 25 */ 26 26 public class OsmIdReader extends DefaultHandler { 27 27 28 private boolean cancel;29 Map<Long, String> entries = new HashMap<Long, String>();30 private Reader in;28 private boolean cancel; 29 Map<Long, String> entries = new HashMap<Long, String>(); 30 private Reader in; 31 31 32 @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {33 if (qName.equals("node") || qName.equals("way") || qName.equals("relation")) {34 try {35 entries.put(Long.valueOf(atts.getValue("id")), qName);36 } catch (Exception e) {37 e.printStackTrace();38 throw new SAXException(tr("Error during parse."));39 }40 }32 @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { 33 if (qName.equals("node") || qName.equals("way") || qName.equals("relation")) { 34 try { 35 entries.put(Long.valueOf(atts.getValue("id")), qName); 36 } catch (Exception e) { 37 e.printStackTrace(); 38 throw new SAXException(tr("Error during parse.")); 39 } 40 } 41 41 } 42 42 43 public Map<Long, String> parseIds(InputStream in) throws IOException, SAXException {43 public Map<Long, String> parseIds(InputStream in) throws IOException, SAXException { 44 44 this.in = new InputStreamReader(in, "UTF-8"); 45 try {46 SAXParserFactory.newInstance().newSAXParser().parse(new InputSource(this.in), this);45 try { 46 SAXParserFactory.newInstance().newSAXParser().parse(new InputSource(this.in), this); 47 47 } catch (ParserConfigurationException e) { 48 if (!cancel) {49 e.printStackTrace(); // broken SAXException chaining50 throw new SAXException(e);51 }48 if (!cancel) { 49 e.printStackTrace(); // broken SAXException chaining 50 throw new SAXException(e); 51 } 52 52 } catch (SAXException e) { 53 if (!cancel)54 throw e;55 } 56 return entries;57 }58 59 public void cancel() {60 cancel = true;61 if (in != null)53 if (!cancel) 54 throw e; 55 } 56 return entries; 57 } 58 59 public void cancel() { 60 cancel = true; 61 if (in != null) 62 62 try {in.close();} catch (IOException e) {} 63 }63 } 64 64 } -
trunk/src/org/openstreetmap/josm/io/OsmReader.java
r1071 r1169 106 106 private Map<OsmPrimitiveData, Collection<Long>> ways = new HashMap<OsmPrimitiveData, Collection<Long>>(); 107 107 108 /** 108 /** 109 109 * Data structure for relation objects 110 110 */ 111 111 private Map<OsmPrimitiveData, Collection<RelationMemberData>> relations = new HashMap<OsmPrimitiveData, Collection<RelationMemberData>>(); 112 112 113 /** 113 /** 114 114 * List of protocol versions that will be accepted on reading 115 115 */ … … 133 133 generator = atts.getValue("generator"); 134 134 135 135 136 136 } else if (qName.equals("bound")) { 137 137 // old style bounds. 138 138 // TODO: remove this around 1st October 2008. 139 // - this is a bit of a hack; since we still write out old style bound objects, 139 // - this is a bit of a hack; since we still write out old style bound objects, 140 140 // we don't want to load them both. so when writing, we add a "note" tag the our 141 141 // old-style bound, and when reading, ignore those with a "note". … … 172 172 ds.dataSources.add(src); 173 173 } 174 174 175 175 // ---- PARSING NODES AND WAYS ---- 176 176 177 177 } else if (qName.equals("node")) { 178 178 current = new Node(new LatLon(getDouble(atts, "lat"), getDouble(atts, "lon"))); … … 192 192 list.add(id); 193 193 194 // ---- PARSING RELATIONS ---- 194 // ---- PARSING RELATIONS ---- 195 195 196 196 } else if (qName.equals("relation")) { … … 207 207 emd.type=atts.getValue("type"); 208 208 emd.relationMember.role = atts.getValue("role"); 209 209 210 210 if (emd.id == 0) 211 211 throw new SAXException(tr("Incomplete <member> specification with ref=0")); 212 212 213 213 list.add(emd); 214 214 215 215 // ---- PARSING TAGS (applicable to all objects) ---- 216 216 217 217 } else if (qName.equals("tag")) { 218 218 current.put(atts.getValue("k"), atts.getValue("v")); … … 231 231 } 232 232 } 233 234 /** 233 234 /** 235 235 * Constructor initializes list of allowed protocol versions. 236 236 */ … … 239 239 allowedVersions.add(Main.pref.get("osm-server.version", "0.5")); 240 240 // now also add all compatible versions 241 String[] additionalVersions = 241 String[] additionalVersions = 242 242 Main.pref.get("osm-server.additional-versions", "").split("/,/"); 243 243 if (additionalVersions.length == 1 && additionalVersions[0].length() == 0) 244 244 additionalVersions = new String[] {}; 245 allowedVersions.addAll(Arrays.asList(additionalVersions)); 245 allowedVersions.addAll(Arrays.asList(additionalVersions)); 246 246 } 247 247 … … 267 267 current.timestamp = time; 268 268 } 269 269 270 270 // user attribute added in 0.4 API 271 271 String user = atts.getValue("user"); … … 274 274 current.user = User.get(user); 275 275 } 276 276 277 277 // visible attribute added in 0.4 API 278 278 String visible = atts.getValue("visible"); … … 342 342 adder.visit(w); 343 343 } 344 344 345 345 } 346 346 … … 348 348 * Return the Way object with the given id, or null if it doesn't 349 349 * exist yet. This method only looks at ways stored in the data set. 350 * 350 * 351 351 * @param id 352 352 * @return way object or null … … 365 365 * Return the Relation object with the given id, or null if it doesn't 366 366 * exist yet. This method only looks at relations stored in the data set. 367 * 367 * 368 368 * @param id 369 369 * @return relation object or null … … 380 380 381 381 /** 382 * Create relations. This is slightly different than n/s/w because 382 * Create relations. This is slightly different than n/s/w because 383 383 * unlike other objects, relations may reference other relations; it 384 384 * is not guaranteed that a referenced relation will have been created … … 387 387 */ 388 388 private void createRelations() { 389 389 390 390 // pass 1 - create all relations 391 391 for (Entry<OsmPrimitiveData, Collection<RelationMemberData>> e : relations.entrySet()) { … … 399 399 Relation en = findRelation(e.getKey().id); 400 400 if (en == null) throw new Error("Failed to create relation " + e.getKey().id); 401 401 402 402 for (RelationMemberData emd : e.getValue()) { 403 403 RelationMember em = emd.relationMember; -
trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java
r1146 r1169 12 12 13 13 public class OsmServerLocationReader extends OsmServerReader { 14 14 15 15 String url; 16 16 17 17 public OsmServerLocationReader(String url) { 18 18 this.url = url; 19 19 } 20 20 21 21 /** 22 22 * Method to download OSM files from somewhere -
trunk/src/org/openstreetmap/josm/io/OsmServerObjectReader.java
r1146 r1169 20 20 String type; 21 21 boolean full; 22 22 23 23 public OsmServerObjectReader(long id, String type, boolean full) { 24 24 this.id = id; -
trunk/src/org/openstreetmap/josm/io/OsmServerReader.java
r1146 r1169 19 19 /** 20 20 * This DataReader reads directly from the REST API of the osm server. 21 * 21 * 22 22 * It supports plain text transfer as well as gzip or deflate encoded transfers; 23 23 * if compressed transfers are unwanted, set property osm-server.use-compression … … 27 27 */ 28 28 public abstract class OsmServerReader extends OsmConnection { 29 /**30 * Open a connection to the given url and return a reader on the input stream31 * from that connection. In case of user cancel, return <code>null</code>.32 * @param urlStr The exact url to connect to.33 * @param pleaseWaitDlg34 * @return An reader reading the input stream (servers answer) or <code>null</code>.35 */36 protected InputStream getInputStream(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws IOException {37 String version = Main.pref.get("osm-server.version", "0.5");38 urlStr = Main.pref.get("osm-server.url")+"/"+version+"/" + urlStr;29 /** 30 * Open a connection to the given url and return a reader on the input stream 31 * from that connection. In case of user cancel, return <code>null</code>. 32 * @param urlStr The exact url to connect to. 33 * @param pleaseWaitDlg 34 * @return An reader reading the input stream (servers answer) or <code>null</code>. 35 */ 36 protected InputStream getInputStream(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws IOException { 37 String version = Main.pref.get("osm-server.version", "0.5"); 38 urlStr = Main.pref.get("osm-server.url")+"/"+version+"/" + urlStr; 39 39 return getInputStreamRaw(urlStr, pleaseWaitDlg); 40 40 } 41 41 42 42 protected InputStream getInputStreamRaw(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws IOException { 43 44 System.out.println("download: "+urlStr);45 initAuthentication();46 URL url = new URL(urlStr);47 activeConnection = (HttpURLConnection)url.openConnection();48 if (cancel) {49 activeConnection.disconnect();50 return null;51 }52 53 if (Boolean.parseBoolean(Main.pref.get("osm-server.use-compression", "true")))54 activeConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");55 43 56 activeConnection.setConnectTimeout(15000);57 if (isAuthCancelled() && activeConnection.getResponseCode() == 401) 58 return null;59 if (activeConnection.getResponseCode() == 500)60 {61 throw new IOException(tr("Server returned internal error. Try a reduced area or retry after waiting some time."));62 } 63 // System.out.println("got return: "+activeConnection.getResponseCode()); 44 System.out.println("download: "+urlStr); 45 initAuthentication(); 46 URL url = new URL(urlStr); 47 activeConnection = (HttpURLConnection)url.openConnection(); 48 if (cancel) { 49 activeConnection.disconnect(); 50 return null; 51 } 64 52 65 String encoding = activeConnection.getContentEncoding(); 66 InputStream inputStream = new ProgressInputStream(activeConnection, pleaseWaitDlg); 67 if (encoding != null && encoding.equalsIgnoreCase("gzip")) { 68 inputStream = new GZIPInputStream(inputStream); 69 } 70 else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { 71 inputStream = new InflaterInputStream(inputStream, new Inflater(true)); 72 } 73 return inputStream; 74 } 75 53 if (Boolean.parseBoolean(Main.pref.get("osm-server.use-compression", "true"))) 54 activeConnection.setRequestProperty("Accept-Encoding", "gzip, deflate"); 55 56 activeConnection.setConnectTimeout(15000); 57 if (isAuthCancelled() && activeConnection.getResponseCode() == 401) 58 return null; 59 if (activeConnection.getResponseCode() == 500) 60 { 61 throw new IOException(tr("Server returned internal error. Try a reduced area or retry after waiting some time.")); 62 } 63 // System.out.println("got return: "+activeConnection.getResponseCode()); 64 65 String encoding = activeConnection.getContentEncoding(); 66 InputStream inputStream = new ProgressInputStream(activeConnection, pleaseWaitDlg); 67 if (encoding != null && encoding.equalsIgnoreCase("gzip")) { 68 inputStream = new GZIPInputStream(inputStream); 69 } 70 else if (encoding != null && encoding.equalsIgnoreCase("deflate")) { 71 inputStream = new InflaterInputStream(inputStream, new Inflater(true)); 72 } 73 return inputStream; 74 } 75 76 76 public abstract DataSet parseOsm() throws SAXException, IOException; 77 77 78 78 } -
trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java
r1137 r1169 79 79 80 80 long uploadStartTime; 81 81 82 82 public String timeLeft(int progress, int list_size) { 83 83 long now = System.currentTimeMillis(); … … 96 96 return time_left_str; 97 97 } 98 98 99 99 public void uploadOsm(Collection<OsmPrimitive> list) throws SAXException { 100 100 processed = new LinkedList<OsmPrimitive>(); … … 103 103 Main.pleaseWaitDlg.progress.setMaximum(list.size()); 104 104 Main.pleaseWaitDlg.progress.setValue(0); 105 105 106 106 // controls whether or not we open and close a changeset. API 0.6 requires changesets. 107 107 boolean useChangesets = Main.pref.get("osm-server.version", "0.5").equals("0.6"); 108 108 109 109 // controls whether or not we try and uplaod the whole bunch in one go 110 boolean useDiffUploads = Main.pref.getBoolean("osm-server.atomic-upload", 110 boolean useDiffUploads = Main.pref.getBoolean("osm-server.atomic-upload", 111 111 Main.pref.get("osm-server.version", "0.5").equals("0.6")); 112 112 113 113 String comment = null; 114 114 while (useChangesets && comment == null) { 115 comment = JOptionPane.showInputDialog(Main.parent, 115 comment = JOptionPane.showInputDialog(Main.parent, 116 116 tr("Provide a brief comment as to the changes to you are uploading:"), 117 117 tr("Commit comment"), JOptionPane.QUESTION_MESSAGE); … … 131 131 return; 132 132 } 133 133 134 134 try { 135 135 if (useDiffUploads) { … … 166 166 } 167 167 catch (OsmTransferException ex) { 168 dealWithTransferException(ex); 168 dealWithTransferException(ex); 169 169 } 170 170 dealWithTransferException(e); 171 171 } 172 172 } 173 173 174 174 /* FIXME: This code is terrible, please fix it!!!! */ 175 175 … … 183 183 * can fix the issue where hitting cancel doesn't do anything while 184 184 * retrying. - Mv0 Apr 2008 185 * 185 * 186 186 * Cancelling has an effect now, maybe it does not always catch on. Florian Heer, Aug 08 187 187 */ … … 198 198 Main.pref.get("osm-server.url") + 199 199 "/" + version + 200 "/" + "changeset" + 200 "/" + "changeset" + 201 201 "/" + "create"); 202 202 System.out.print("upload to: "+url+ "..." ); … … 205 205 activeConnection.setRequestMethod("PUT"); 206 206 addAuth(activeConnection); 207 207 208 208 activeConnection.setDoOutput(true); 209 209 OutputStream out = activeConnection.getOutputStream(); 210 210 OsmWriter.output(out, changeset); 211 211 out.close(); 212 212 213 213 activeConnection.connect(); 214 214 System.out.println("connected"); … … 224 224 } 225 225 if (retCode != 200 && retCode != 412) { 226 226 227 227 if (retries >= 0) { 228 228 retries--; … … 232 232 return startChangeset(retries, comment); 233 233 } 234 234 235 235 // Look for a detailed error message from the server 236 236 retMsg += "\n" + readString(activeConnection.getInputStream()); … … 262 262 throw new OsmTransferException (e.getMessage()+ " " + e.getClass().getCanonicalName(), e); 263 263 } 264 264 265 265 catch (Exception e) { 266 266 if (cancel) … … 274 274 return true; 275 275 } 276 276 277 277 private void uploadDiff(int retries, Collection<OsmPrimitive> list) throws OsmTransferException { 278 278 279 279 CreateOsmChangeVisitor duv = new CreateOsmChangeVisitor(changeset); 280 280 … … 290 290 String diff = duv.getDocument(); 291 291 System.out.println(diff); 292 292 293 293 Main.pleaseWaitDlg.currentAction.setText(tr("Uploading...")); 294 294 try { … … 299 299 Main.pref.get("osm-server.url") + 300 300 "/" + version + 301 "/" + "changeset" + 301 "/" + "changeset" + 302 302 "/" + changeset.id + 303 303 "/upload" ); … … 307 307 activeConnection.setRequestMethod("POST"); 308 308 addAuth(activeConnection); 309 309 310 310 activeConnection.setDoOutput(true); 311 311 PrintWriter out; … … 317 317 out.print(diff); 318 318 out.close(); 319 319 320 320 activeConnection.connect(); 321 321 System.out.println("connected"); … … 323 323 int retCode = activeConnection.getResponseCode(); 324 324 String retMsg = ""; 325 325 326 326 if (retCode == 200) { 327 327 DiffResultReader.parseDiffResult(activeConnection.getInputStream(), list, processed, duv.getNewIdMap(), Main.pleaseWaitDlg); … … 333 333 System.out.println("retrying ("+retries+" left)"); 334 334 stopChangeset(retries); 335 } else { 335 } else { 336 336 // Look for a detailed error message from the server 337 337 retMsg += "\n" + readString(activeConnection.getInputStream()); … … 372 372 } 373 373 } 374 375 374 375 376 376 private void stopChangeset(int retries) throws OsmTransferException { 377 377 Main.pleaseWaitDlg.currentAction.setText(tr("Closing changeset...")); … … 383 383 Main.pref.get("osm-server.url") + 384 384 "/" + version + 385 "/" + "changeset" + 385 "/" + "changeset" + 386 386 "/" + changeset.id + 387 387 "/close" ); … … 391 391 activeConnection.setRequestMethod("PUT"); 392 392 addAuth(activeConnection); 393 393 394 394 activeConnection.setDoOutput(true); 395 395 OutputStream out = activeConnection.getOutputStream(); 396 396 OsmWriter.output(out, changeset); 397 397 out.close(); 398 398 399 399 activeConnection.connect(); 400 400 System.out.println("connected"); … … 415 415 System.out.println("retrying ("+retries+" left)"); 416 416 stopChangeset(retries); 417 } else { 417 } else { 418 418 // Look for a detailed error message from the server 419 419 retMsg += readString(activeConnection.getInputStream()); 420 420 421 421 // Report our error 422 422 ByteArrayOutputStream o = new ByteArrayOutputStream(); … … 490 490 processed.add(e); 491 491 } 492 492 493 493 /** 494 494 * Read a long from the input stream and return it. … … 540 540 new URL(Main.pref.get("osm-server.url") + 541 541 "/" + version + "/"), 542 urlSuffix + 542 urlSuffix + 543 543 "/" + (osm.id==0 ? "create" : osm.id), 544 544 new MyHttpHandler()); … … 622 622 } 623 623 } 624 624 625 625 private void sendRequest(String requestMethod, String urlSuffix, 626 626 OsmPrimitive osm, boolean addBody) { … … 636 636 } 637 637 } 638 638 639 639 private void dealWithTransferException (OsmTransferException e) { 640 640 Main.pleaseWaitDlg.currentAction.setText(tr("Transfer aborted due to error (will wait for 5 seconds):") + e.getMessage()); -
trunk/src/org/openstreetmap/josm/io/OsmTransferException.java
r784 r1169 4 4 public class OsmTransferException extends Exception { 5 5 6 public OsmTransferException() {7 }6 public OsmTransferException() { 7 } 8 8 9 public OsmTransferException(String message) {10 super(message);11 }9 public OsmTransferException(String message) { 10 super(message); 11 } 12 12 13 public OsmTransferException(Throwable cause) {14 super(cause);15 }13 public OsmTransferException(Throwable cause) { 14 super(cause); 15 } 16 16 17 public OsmTransferException(String message, Throwable cause) {18 super(message, cause);19 }17 public OsmTransferException(String message, Throwable cause) { 18 super(message, cause); 19 } 20 20 21 21 } -
trunk/src/org/openstreetmap/josm/io/OsmWriter.java
r1071 r1169 24 24 public class OsmWriter extends XmlWriter implements Visitor { 25 25 26 /**27 * The counter for new created objects. Starting at -1 and goes down.28 */29 private long newIdCounter = -1;30 /**31 * All newly created ids and their primitive that uses it. This is a back reference32 * map to allow references to use the correnct primitives.33 */34 public HashMap<OsmPrimitive, Long> usedNewIds = new HashMap<OsmPrimitive, Long>();35 36 private final boolean osmConform;37 private final Changeset changeset;38 39 public abstract static class Osm implements OsmWriterInterface {40 public void header(PrintWriter out) {41 out.print("<osm version='");42 out.print(Main.pref.get("osm-server.version", "0.5"));43 out.println("' generator='JOSM'>");44 }45 public void footer(PrintWriter out) {46 out.println("</osm>");47 }48 }49 50 // simple helper to write the object's class to the out stream51 private Visitor typeWriteVisitor = new Visitor() {52 public void visit(Node n) { out.print("node"); }53 public void visit(Way w) { out.print("way"); }54 public void visit(Relation e) { out.print("relation"); }55 };56 57 /**58 * An output writer for function output that writes everything of the given dataset into59 * the xml60 */61 public static final class All extends Osm {62 private final DataSet ds;63 private final boolean osmConform;64 65 /**66 * Construct an writer function67 * @param osmConform <code>true</code>, if the xml should be 100% osm conform. In this68 *case, not all information can be retrieved later (as example, modified state69 *is lost and id's remain 0 instead of decrementing from -1)70 */71 public All(DataSet ds, boolean osmConform) {72 this.ds = ds;73 this.osmConform = osmConform;74 }75 76 public void write(PrintWriter out) {77 Visitor writer = new OsmWriter(out, osmConform, null);78 for (Node n : ds.nodes)79 if (shouldWrite(n))80 writer.visit(n);81 for (Way w : ds.ways)82 if (shouldWrite(w))83 writer.visit(w);84 for (Relation e : ds.relations)85 if (shouldWrite(e))86 writer.visit(e);87 } 88 89 private boolean shouldWrite(OsmPrimitive osm) {90 return osm.id != 0 || !osm.deleted;91 } 92 93 @Override public void header(PrintWriter out) {94 super.header(out);95 for (DataSource s : ds.dataSources) {26 /** 27 * The counter for new created objects. Starting at -1 and goes down. 28 */ 29 private long newIdCounter = -1; 30 /** 31 * All newly created ids and their primitive that uses it. This is a back reference 32 * map to allow references to use the correnct primitives. 33 */ 34 public HashMap<OsmPrimitive, Long> usedNewIds = new HashMap<OsmPrimitive, Long>(); 35 36 private final boolean osmConform; 37 private final Changeset changeset; 38 39 public abstract static class Osm implements OsmWriterInterface { 40 public void header(PrintWriter out) { 41 out.print("<osm version='"); 42 out.print(Main.pref.get("osm-server.version", "0.5")); 43 out.println("' generator='JOSM'>"); 44 } 45 public void footer(PrintWriter out) { 46 out.println("</osm>"); 47 } 48 } 49 50 // simple helper to write the object's class to the out stream 51 private Visitor typeWriteVisitor = new Visitor() { 52 public void visit(Node n) { out.print("node"); } 53 public void visit(Way w) { out.print("way"); } 54 public void visit(Relation e) { out.print("relation"); } 55 }; 56 57 /** 58 * An output writer for function output that writes everything of the given dataset into 59 * the xml 60 */ 61 public static final class All extends Osm { 62 private final DataSet ds; 63 private final boolean osmConform; 64 65 /** 66 * Construct an writer function 67 * @param osmConform <code>true</code>, if the xml should be 100% osm conform. In this 68 * case, not all information can be retrieved later (as example, modified state 69 * is lost and id's remain 0 instead of decrementing from -1) 70 */ 71 public All(DataSet ds, boolean osmConform) { 72 this.ds = ds; 73 this.osmConform = osmConform; 74 } 75 76 public void write(PrintWriter out) { 77 Visitor writer = new OsmWriter(out, osmConform, null); 78 for (Node n : ds.nodes) 79 if (shouldWrite(n)) 80 writer.visit(n); 81 for (Way w : ds.ways) 82 if (shouldWrite(w)) 83 writer.visit(w); 84 for (Relation e : ds.relations) 85 if (shouldWrite(e)) 86 writer.visit(e); 87 } 88 89 private boolean shouldWrite(OsmPrimitive osm) { 90 return osm.id != 0 || !osm.deleted; 91 } 92 93 @Override public void header(PrintWriter out) { 94 super.header(out); 95 for (DataSource s : ds.dataSources) { 96 96 // TODO: remove <bound> output after a grace period (1st October 08) 97 out.print(" <bound note='this tag is deprecated and only provided for backward compatiblity' box='"+98 s.bounds.min.lat()+","+99 s.bounds.min.lon()+","+100 s.bounds.max.lat()+","+101 s.bounds.max.lon()+"' ");102 out.println("origin='"+XmlWriter.encode(s.origin)+"' />");103 out.print(" <bounds minlat='" +104 s.bounds.min.lat()+"' minlon='"+105 s.bounds.min.lon()+"' maxlat='"+106 s.bounds.max.lat()+"' maxlon='"+107 s.bounds.max.lon()+"' ");108 out.println("origin='"+XmlWriter.encode(s.origin)+"' />");109 }110 } 111 }112 113 /**114 * An output writer for functino output that writes only one specific primitive into115 * the xml116 */117 public static final class Single extends Osm {118 private final OsmPrimitive osm;119 private final boolean osmConform;120 private final Changeset changeset;121 122 public Single(OsmPrimitive osm, boolean osmConform, Changeset changeset) {123 this.osm = osm;124 this.osmConform = osmConform;125 this.changeset = changeset;126 }127 128 public void write(PrintWriter out) {129 osm.visit(new OsmWriter(out, osmConform, changeset));130 } 131 }132 133 public OsmWriter(PrintWriter out, boolean osmConform, Changeset changeset) {134 super(out);135 this.osmConform = osmConform;136 this.changeset = changeset;137 }138 139 public void visit(Node n) {140 if (n.incomplete) return;141 addCommon(n, "node");142 out.print(" lat='"+n.coor.lat()+"' lon='"+n.coor.lon()+"'");143 addTags(n, "node", true);144 }145 146 public void visit(Way w) {147 if (w.incomplete) return;148 addCommon(w, "way");149 out.println(">");150 for (Node n : w.nodes)151 out.println(" <nd ref='"+getUsedId(n)+"' />");152 addTags(w, "way", false);153 }154 155 public void visit(Relation e) {156 if (e.incomplete) return;157 addCommon(e, "relation");158 out.println(">");159 for (RelationMember em : e.members) {160 out.print(" <member type='");161 em.member.visit(typeWriteVisitor);162 out.println("' ref='"+getUsedId(em.member)+"' role='" +163 XmlWriter.encode(em.role) + "' />");164 }165 addTags(e, "relation", false);166 }167 168 169 /**170 * Return the id for the given osm primitive (may access the usedId map)171 */172 private long getUsedId(OsmPrimitive osm) {173 if (osm.id != 0)174 return osm.id;175 if (usedNewIds.containsKey(osm))176 return usedNewIds.get(osm);177 usedNewIds.put(osm, newIdCounter);178 return osmConform ? 0 : newIdCounter--;179 }180 181 private void addTags(OsmPrimitive osm, String tagname, boolean tagOpen) {182 if (osm.keys != null) {183 if (tagOpen)184 out.println(">");185 for (Entry<String, String> e : osm.keys.entrySet())186 out.println(" <tag k='"+ XmlWriter.encode(e.getKey()) +187 "' v='"+XmlWriter.encode(e.getValue())+ "' />");188 out.println(" </" + tagname + ">");189 } else if (tagOpen)190 out.println(" />");191 else192 out.println(" </" + tagname + ">");193 }194 195 /**196 * Add the common part as the form of the tag as well as the XML attributes197 * id, action, user, and visible.198 */199 private void addCommon(OsmPrimitive osm, String tagname) {200 out.print(" <"+tagname+" id='"+getUsedId(osm)+"'");201 if (!osmConform) {202 String action = null;203 if (osm.deleted)204 action = "delete";205 else if (osm.modified)206 action = "modify";207 if (action != null)208 out.print(" action='"+action+"'");209 }210 if (osm.timestamp != null) {211 out.print(" timestamp='"+osm.timestamp+"'");212 }213 // user and visible added with 0.4 API214 if (osm.user != null) {215 out.print(" user='"+XmlWriter.encode(osm.user.name)+"'");216 }217 out.print(" visible='"+osm.visible+"'");218 if (osm.version != -1)219 out.print(" version='"+osm.version+"'");220 if (this.changeset != null && this.changeset.id != 0)221 out.print(" changeset='"+this.changeset.id+"'" );222 }97 out.print(" <bound note='this tag is deprecated and only provided for backward compatiblity' box='"+ 98 s.bounds.min.lat()+","+ 99 s.bounds.min.lon()+","+ 100 s.bounds.max.lat()+","+ 101 s.bounds.max.lon()+"' "); 102 out.println("origin='"+XmlWriter.encode(s.origin)+"' />"); 103 out.print(" <bounds minlat='" + 104 s.bounds.min.lat()+"' minlon='"+ 105 s.bounds.min.lon()+"' maxlat='"+ 106 s.bounds.max.lat()+"' maxlon='"+ 107 s.bounds.max.lon()+"' "); 108 out.println("origin='"+XmlWriter.encode(s.origin)+"' />"); 109 } 110 } 111 } 112 113 /** 114 * An output writer for functino output that writes only one specific primitive into 115 * the xml 116 */ 117 public static final class Single extends Osm { 118 private final OsmPrimitive osm; 119 private final boolean osmConform; 120 private final Changeset changeset; 121 122 public Single(OsmPrimitive osm, boolean osmConform, Changeset changeset) { 123 this.osm = osm; 124 this.osmConform = osmConform; 125 this.changeset = changeset; 126 } 127 128 public void write(PrintWriter out) { 129 osm.visit(new OsmWriter(out, osmConform, changeset)); 130 } 131 } 132 133 public OsmWriter(PrintWriter out, boolean osmConform, Changeset changeset) { 134 super(out); 135 this.osmConform = osmConform; 136 this.changeset = changeset; 137 } 138 139 public void visit(Node n) { 140 if (n.incomplete) return; 141 addCommon(n, "node"); 142 out.print(" lat='"+n.coor.lat()+"' lon='"+n.coor.lon()+"'"); 143 addTags(n, "node", true); 144 } 145 146 public void visit(Way w) { 147 if (w.incomplete) return; 148 addCommon(w, "way"); 149 out.println(">"); 150 for (Node n : w.nodes) 151 out.println(" <nd ref='"+getUsedId(n)+"' />"); 152 addTags(w, "way", false); 153 } 154 155 public void visit(Relation e) { 156 if (e.incomplete) return; 157 addCommon(e, "relation"); 158 out.println(">"); 159 for (RelationMember em : e.members) { 160 out.print(" <member type='"); 161 em.member.visit(typeWriteVisitor); 162 out.println("' ref='"+getUsedId(em.member)+"' role='" + 163 XmlWriter.encode(em.role) + "' />"); 164 } 165 addTags(e, "relation", false); 166 } 167 168 169 /** 170 * Return the id for the given osm primitive (may access the usedId map) 171 */ 172 private long getUsedId(OsmPrimitive osm) { 173 if (osm.id != 0) 174 return osm.id; 175 if (usedNewIds.containsKey(osm)) 176 return usedNewIds.get(osm); 177 usedNewIds.put(osm, newIdCounter); 178 return osmConform ? 0 : newIdCounter--; 179 } 180 181 private void addTags(OsmPrimitive osm, String tagname, boolean tagOpen) { 182 if (osm.keys != null) { 183 if (tagOpen) 184 out.println(">"); 185 for (Entry<String, String> e : osm.keys.entrySet()) 186 out.println(" <tag k='"+ XmlWriter.encode(e.getKey()) + 187 "' v='"+XmlWriter.encode(e.getValue())+ "' />"); 188 out.println(" </" + tagname + ">"); 189 } else if (tagOpen) 190 out.println(" />"); 191 else 192 out.println(" </" + tagname + ">"); 193 } 194 195 /** 196 * Add the common part as the form of the tag as well as the XML attributes 197 * id, action, user, and visible. 198 */ 199 private void addCommon(OsmPrimitive osm, String tagname) { 200 out.print(" <"+tagname+" id='"+getUsedId(osm)+"'"); 201 if (!osmConform) { 202 String action = null; 203 if (osm.deleted) 204 action = "delete"; 205 else if (osm.modified) 206 action = "modify"; 207 if (action != null) 208 out.print(" action='"+action+"'"); 209 } 210 if (osm.timestamp != null) { 211 out.print(" timestamp='"+osm.timestamp+"'"); 212 } 213 // user and visible added with 0.4 API 214 if (osm.user != null) { 215 out.print(" user='"+XmlWriter.encode(osm.user.name)+"'"); 216 } 217 out.print(" visible='"+osm.visible+"'"); 218 if (osm.version != -1) 219 out.print(" version='"+osm.version+"'"); 220 if (this.changeset != null && this.changeset.id != 0) 221 out.print(" changeset='"+this.changeset.id+"'" ); 222 } 223 223 } -
trunk/src/org/openstreetmap/josm/io/ProgressInputStream.java
r782 r1169 16 16 public class ProgressInputStream extends InputStream { 17 17 18 private final InputStream in;19 private int readSoFar = 0;20 private int lastDialogUpdate = 0;21 private final URLConnection connection;22 private PleaseWaitDialog pleaseWaitDlg;18 private final InputStream in; 19 private int readSoFar = 0; 20 private int lastDialogUpdate = 0; 21 private final URLConnection connection; 22 private PleaseWaitDialog pleaseWaitDlg; 23 23 24 public class OsmServerException extends IOException {25 private OsmServerException(String e) {26 super(e);27 }28 }24 public class OsmServerException extends IOException { 25 private OsmServerException(String e) { 26 super(e); 27 } 28 } 29 29 30 public ProgressInputStream(URLConnection con, PleaseWaitDialog pleaseWaitDlg) throws IOException, OsmServerException {31 this.connection = con;30 public ProgressInputStream(URLConnection con, PleaseWaitDialog pleaseWaitDlg) throws IOException, OsmServerException { 31 this.connection = con; 32 32 33 try {34 this.in = con.getInputStream();35 } catch (IOException e) {36 if (con.getHeaderField("Error") != null)37 throw new OsmServerException(tr(con.getHeaderField("Error")));38 throw e;39 }33 try { 34 this.in = con.getInputStream(); 35 } catch (IOException e) { 36 if (con.getHeaderField("Error") != null) 37 throw new OsmServerException(tr(con.getHeaderField("Error"))); 38 throw e; 39 } 40 40 41 int contentLength = con.getContentLength();42 this.pleaseWaitDlg = pleaseWaitDlg;43 if (pleaseWaitDlg == null)44 return;45 if (contentLength > 0)46 pleaseWaitDlg.progress.setMaximum(contentLength);47 else48 pleaseWaitDlg.progress.setMaximum(0);49 pleaseWaitDlg.progress.setValue(0);50 }41 int contentLength = con.getContentLength(); 42 this.pleaseWaitDlg = pleaseWaitDlg; 43 if (pleaseWaitDlg == null) 44 return; 45 if (contentLength > 0) 46 pleaseWaitDlg.progress.setMaximum(contentLength); 47 else 48 pleaseWaitDlg.progress.setMaximum(0); 49 pleaseWaitDlg.progress.setValue(0); 50 } 51 51 52 @Override public void close() throws IOException {53 in.close();54 }52 @Override public void close() throws IOException { 53 in.close(); 54 } 55 55 56 @Override public int read(byte[] b, int off, int len) throws IOException {57 int read = in.read(b, off, len);58 if (read != -1)59 advanceTicker(read);60 return read;61 }56 @Override public int read(byte[] b, int off, int len) throws IOException { 57 int read = in.read(b, off, len); 58 if (read != -1) 59 advanceTicker(read); 60 return read; 61 } 62 62 63 @Override public int read() throws IOException {64 int read = in.read();65 if (read != -1)66 advanceTicker(1);67 return read;68 }63 @Override public int read() throws IOException { 64 int read = in.read(); 65 if (read != -1) 66 advanceTicker(1); 67 return read; 68 } 69 69 70 /**71 * Increase ticker (progress counter and displayed text) by the given amount.72 * @param amount73 */74 private void advanceTicker(int amount) {75 if (pleaseWaitDlg == null)76 return;70 /** 71 * Increase ticker (progress counter and displayed text) by the given amount. 72 * @param amount 73 */ 74 private void advanceTicker(int amount) { 75 if (pleaseWaitDlg == null) 76 return; 77 77 78 if (pleaseWaitDlg.progress.getMaximum() == 0 && connection.getContentLength() != -1)79 pleaseWaitDlg.progress.setMaximum(connection.getContentLength());78 if (pleaseWaitDlg.progress.getMaximum() == 0 && connection.getContentLength() != -1) 79 pleaseWaitDlg.progress.setMaximum(connection.getContentLength()); 80 80 81 readSoFar += amount;81 readSoFar += amount; 82 82 83 if (readSoFar / 1024 != lastDialogUpdate) {84 lastDialogUpdate++;85 String progStr = " "+readSoFar/1024+"/";86 progStr += (pleaseWaitDlg.progress.getMaximum()==0) ? "??? KB" : (pleaseWaitDlg.progress.getMaximum()/1024)+" KB";87 pleaseWaitDlg.progress.setValue(readSoFar);83 if (readSoFar / 1024 != lastDialogUpdate) { 84 lastDialogUpdate++; 85 String progStr = " "+readSoFar/1024+"/"; 86 progStr += (pleaseWaitDlg.progress.getMaximum()==0) ? "??? KB" : (pleaseWaitDlg.progress.getMaximum()/1024)+" KB"; 87 pleaseWaitDlg.progress.setValue(readSoFar); 88 88 89 String cur = pleaseWaitDlg.currentAction.getText();90 int i = cur.indexOf(' ');91 if (i != -1)92 cur = cur.substring(0, i) + progStr;93 else94 cur += progStr;95 pleaseWaitDlg.currentAction.setText(cur);96 }97 }89 String cur = pleaseWaitDlg.currentAction.getText(); 90 int i = cur.indexOf(' '); 91 if (i != -1) 92 cur = cur.substring(0, i) + progStr; 93 else 94 cur += progStr; 95 pleaseWaitDlg.currentAction.setText(cur); 96 } 97 } 98 98 } -
trunk/src/org/openstreetmap/josm/io/XmlWriter.java
r627 r1169 10 10 /** 11 11 * Helper class to use for xml outputting classes. 12 * 12 * 13 13 * @author imi 14 14 */ 15 15 public class XmlWriter { 16 16 17 /**18 * The interface to write the data into an Osm stream19 * @author immanuel.scholz20 */21 public static interface OsmWriterInterface {22 void header(PrintWriter out);23 void write(PrintWriter out);24 void footer(PrintWriter out);25 }17 /** 18 * The interface to write the data into an Osm stream 19 * @author immanuel.scholz 20 */ 21 public static interface OsmWriterInterface { 22 void header(PrintWriter out); 23 void write(PrintWriter out); 24 void footer(PrintWriter out); 25 } 26 26 27 27 28 protected XmlWriter(PrintWriter out) {29 this.out = out;30 }28 protected XmlWriter(PrintWriter out) { 29 this.out = out; 30 } 31 31 32 /**33 * Encode the given string in XML1.0 format.34 * Optimized to fast pass strings that don't need encoding (normal case).35 */36 public static String encode(String unencoded) {37 StringBuilder buffer = null;38 for (int i = 0; i < unencoded.length(); ++i) {39 String encS = XmlWriter.encoding.get(unencoded.charAt(i));40 if (encS != null) {41 if (buffer == null)42 buffer = new StringBuilder(unencoded.substring(0,i));43 buffer.append(encS);44 } else if (buffer != null)45 buffer.append(unencoded.charAt(i));46 }47 return (buffer == null) ? unencoded : buffer.toString();48 }32 /** 33 * Encode the given string in XML1.0 format. 34 * Optimized to fast pass strings that don't need encoding (normal case). 35 */ 36 public static String encode(String unencoded) { 37 StringBuilder buffer = null; 38 for (int i = 0; i < unencoded.length(); ++i) { 39 String encS = XmlWriter.encoding.get(unencoded.charAt(i)); 40 if (encS != null) { 41 if (buffer == null) 42 buffer = new StringBuilder(unencoded.substring(0,i)); 43 buffer.append(encS); 44 } else if (buffer != null) 45 buffer.append(unencoded.charAt(i)); 46 } 47 return (buffer == null) ? unencoded : buffer.toString(); 48 } 49 49 50 /**51 * Write the header and start tag, then call the runnable to add all real tags and finally52 * "closes" the xml by writing the footer.53 */54 public static void output(OutputStream outStream, OsmWriterInterface outputWriter) {55 PrintWriter out;56 try {57 out = new PrintWriter(new OutputStreamWriter(outStream, "UTF-8"));58 } catch (UnsupportedEncodingException e) {59 throw new RuntimeException(e);60 }61 out.println("<?xml version='1.0' encoding='UTF-8'?>");62 outputWriter.header(out);63 outputWriter.write(out);64 outputWriter.footer(out);65 out.flush();66 out.close();67 }50 /** 51 * Write the header and start tag, then call the runnable to add all real tags and finally 52 * "closes" the xml by writing the footer. 53 */ 54 public static void output(OutputStream outStream, OsmWriterInterface outputWriter) { 55 PrintWriter out; 56 try { 57 out = new PrintWriter(new OutputStreamWriter(outStream, "UTF-8")); 58 } catch (UnsupportedEncodingException e) { 59 throw new RuntimeException(e); 60 } 61 out.println("<?xml version='1.0' encoding='UTF-8'?>"); 62 outputWriter.header(out); 63 outputWriter.write(out); 64 outputWriter.footer(out); 65 out.flush(); 66 out.close(); 67 } 68 68 69 /**70 * The output writer to save the values to.71 */72 protected final PrintWriter out;73 final private static HashMap<Character, String> encoding = new HashMap<Character, String>();74 static {75 encoding.put('<', "<");76 encoding.put('>', ">");77 encoding.put('"', """);78 encoding.put('\'', "'");79 encoding.put('&', "&");80 encoding.put('\n', "
");81 encoding.put('\r', "
");82 encoding.put('\t', "	");83 }69 /** 70 * The output writer to save the values to. 71 */ 72 protected final PrintWriter out; 73 final private static HashMap<Character, String> encoding = new HashMap<Character, String>(); 74 static { 75 encoding.put('<', "<"); 76 encoding.put('>', ">"); 77 encoding.put('"', """); 78 encoding.put('\'', "'"); 79 encoding.put('&', "&"); 80 encoding.put('\n', "
"); 81 encoding.put('\r', "
"); 82 encoding.put('\t', "	"); 83 } 84 84 }
Note:
See TracChangeset
for help on using the changeset viewer.
