Java tutorial
/* * Copyright 2012-2014 Coronastreet Networks * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License */ package org.coronastreet.gpxconverter; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringWriter; import java.util.Iterator; import java.util.List; import javax.swing.JTextArea; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; import org.apache.xml.serialize.OutputFormat; import org.apache.xml.serialize.XMLSerializer; import org.json.JSONObject; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; @SuppressWarnings("deprecation") public class Strava { private int apiVersion = 2; private String authenticationURL = "http://www.strava.com/api/v" + apiVersion + "/authentication/login"; private String uploadURL = "http://www.strava.com/api/v" + apiVersion + "/upload"; private String email; private String password; private String tripName; private String authToken; private String activityType; private Document outDoc; private String rideStartTime; private String deviceType; private boolean hasAltimeter = false; private JTextArea statusTextArea; private List<Trkpt> trackPoints; public Strava() { } private String convertDoc() { OutputFormat format = new OutputFormat(outDoc); format.setIndenting(true); StringWriter stringOut = new StringWriter(); XMLSerializer serializer = new XMLSerializer(stringOut, format); try { serializer.serialize(outDoc); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return stringOut.toString(); } public boolean processData() { boolean success = false; //load the output template loadOutFile(); setIdAndStartTime(); setDeviceType(); // Add the track data we imported to the output document if (addTrackData()) { success = true; } // Spit out the TCX file //printOutFile(); success = true; return success; } private void setIdAndStartTime() { NodeList nl = outDoc.getElementsByTagName("Activity"); NodeList nl2 = ((Element) nl.item(0)).getElementsByTagName("Id"); if (nl2 != null && nl2.getLength() > 0) { Element el = (Element) nl2.item(0); el.appendChild(outDoc.createTextNode(rideStartTime)); } NodeList nl3 = ((Element) nl.item(0)).getElementsByTagName("Lap"); if (nl3 != null && nl3.getLength() > 0) { Element el = (Element) nl3.item(0); el.setAttribute("StartTime", rideStartTime); } } private Element createTrackPointElement(Trkpt tp) { Element eTrackpoint = outDoc.createElement("Trackpoint"); //create time element and time text node and attach it to the trackpoint Element eTime = outDoc.createElement("Time"); eTime.appendChild(outDoc.createTextNode(tp.getTime())); eTrackpoint.appendChild(eTime); //create elevation element and elevation text node and attach it to the trackpoint Element eElevation = outDoc.createElement("AltitudeMeters"); eElevation.appendChild(outDoc.createTextNode(tp.getElevation())); eTrackpoint.appendChild(eElevation); //create Speed Sensor element and attach it to the trackpoint Element eSensorState = outDoc.createElement("SensorState"); eSensorState.appendChild(outDoc.createTextNode("Absent")); eTrackpoint.appendChild(eSensorState); // Create Lat/Long and add them to Position Element ePosition = outDoc.createElement("Position"); Element eLatitudeDegrees = outDoc.createElement("LatitudeDegrees"); eLatitudeDegrees.appendChild(outDoc.createTextNode(tp.getLat())); Element eLongitudeDegrees = outDoc.createElement("LongitudeDegrees"); eLongitudeDegrees.appendChild(outDoc.createTextNode(tp.getLon())); ePosition.appendChild(eLongitudeDegrees); ePosition.appendChild(eLatitudeDegrees); eTrackpoint.appendChild(ePosition); //create HeartRate and add it to the trackpoint Element eHR = outDoc.createElement("HeartRateBpm"); eHR.setAttribute("xsi:type", "HeartRateInBeatsPerMinute_t"); Element eHRValue = outDoc.createElement("Value"); eHRValue.appendChild(outDoc.createTextNode(tp.getHr())); eHR.appendChild(eHRValue); eTrackpoint.appendChild(eHR); //create Cadence element text node and add it to the trackpoint Element eCad = outDoc.createElement("Cadence"); eCad.appendChild(outDoc.createTextNode(tp.getCad())); eTrackpoint.appendChild(eCad); //create Temperature element text node and add it to the trackpoint Element eTemp = outDoc.createElement("Temperature"); eTemp.appendChild(outDoc.createTextNode(tp.getTemp())); eTrackpoint.appendChild(eTemp); return eTrackpoint; } private void setDeviceType() { // Strava only recognizes Garmin devices for Altimeter stuff // Everything else shows up as "Mobile" if (hasAltimeter) { deviceType = "Garmin Edge 800"; } else { deviceType = "Garmin Edge 200"; } NodeList nl = outDoc.getElementsByTagName("Activity"); NodeList nl1 = ((Element) nl.item(0)).getElementsByTagName("Creator"); NodeList nl2 = ((Element) nl1.item(0)).getElementsByTagName("Name"); if (nl2 != null && nl2.getLength() > 0) { Element el = (Element) nl2.item(0); el.appendChild(outDoc.createTextNode(deviceType)); } } private boolean addTrackData() { boolean success = false; // Get the Track element Element track = null; Element docEle = outDoc.getDocumentElement(); // GRabbing the track node. in theory, the node list should always return 1 NodeList nl = docEle.getElementsByTagName("Track"); if (nl != null && nl.getLength() > 0) { track = (Element) nl.item(0); } int trkCounter = 0; Iterator<Trkpt> it = trackPoints.iterator(); while (it.hasNext()) { Trkpt t = (Trkpt) it.next(); Element tp = createTrackPointElement(t); //dumpNode(tp); track.appendChild(tp); trkCounter++; } log("Added " + trkCounter + " trackpoints to the template."); if (trkCounter >= 1) { success = true; } return success; } public void upload() { HttpClient httpClient = HttpClientBuilder.create().build(); if (doLogin()) { try { HttpPost request = new HttpPost(uploadURL); JSONObject activityObject = new JSONObject(); activityObject.put("token", authToken); activityObject.put("type", "TCX"); activityObject.put("activity_type", activityType); activityObject.put("activity_name", tripName); String xmlData = convertDoc(); activityObject.put("data", xmlData); StringEntity params = new StringEntity(activityObject.toString()); //statusLog("Sending Entity: " + activityObject.toString()); request.addHeader("content-type", "application/json"); request.setEntity(params); HttpResponse response = httpClient.execute(request); if (response.getStatusLine().getStatusCode() != 200) { log("Failed to Upload"); HttpEntity entity = response.getEntity(); if (entity != null) { String output = EntityUtils.toString(entity); log(output); } } HttpEntity entity = response.getEntity(); if (entity != null) { String output = EntityUtils.toString(entity); //log(output); JSONObject userInfo = new JSONObject(output); log("Successful Uploaded. ID is " + userInfo.get("upload_id")); } } catch (Exception ex) { // handle exception here } finally { httpClient.getConnectionManager().shutdown(); } } else { log("Failed to upload!"); } } protected boolean doLogin() { boolean ret = false; HttpClient httpClient = HttpClientBuilder.create().build(); log("Authenticating athlete..."); try { HttpPost request = new HttpPost(authenticationURL); String jsonString = "{\"email\":\"" + email + "\",\"password\":\"" + password + "\"} "; StringEntity params = new StringEntity(jsonString); //log("Sending Entity: " + jsonString); request.addHeader("content-type", "application/json"); request.setEntity(params); HttpResponse response = httpClient.execute(request); if (response.getStatusLine().getStatusCode() != 200) { log("Failed to Login."); HttpEntity entity = response.getEntity(); if (entity != null) { //String output = EntityUtils.toString(entity); //log(output); } } HttpEntity entity = response.getEntity(); if (entity != null) { String output = EntityUtils.toString(entity); //statusLog(output); JSONObject userInfo = new JSONObject(output); JSONObject athleteInfo = userInfo.getJSONObject("athlete"); log("Logged in as " + athleteInfo.get("name")); authToken = (String) userInfo.get("token"); if (authToken.length() > 0) { ret = true; } } else { log("Something went wrong!"); } } catch (Exception ex) { // handle exception here ex.printStackTrace(); } finally { httpClient.getConnectionManager().shutdown(); } return ret; } private void loadOutFile() { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { DocumentBuilder db = dbf.newDocumentBuilder(); log("Loading TCX template file."); outDoc = db .parse(this.getClass().getResourceAsStream("/org/coronastreet/gpxconverter/tcxtemplate.xml")); } catch (ParserConfigurationException pce) { pce.printStackTrace(); } catch (SAXException se) { se.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } } @SuppressWarnings("unused") private void dumpNode(JSONObject o) { log(o.toString(2)); } private void log(String s) { this.statusTextArea.append("STRAVA: " + s + "\n"); this.statusTextArea.repaint(1); } @SuppressWarnings("unused") private void log(InputStream is) { try { BufferedReader rd = new BufferedReader(new InputStreamReader(is)); String line = ""; while ((line = rd.readLine()) != null) { log(line); } } catch (Exception e) { e.printStackTrace(); } } public List<Trkpt> getTrackPoints() { return trackPoints; } public void setTrackPoints(List<Trkpt> trackPoints) { this.trackPoints = trackPoints; } public JTextArea getStatusTextArea() { return statusTextArea; } public void setStatusTextArea(JTextArea statusTextArea) { this.statusTextArea = statusTextArea; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getTripName() { return tripName; } public void setTripName(String tripName) { this.tripName = tripName; } public String getActivityType() { return activityType; } public void setActivityType(String at) { this.activityType = at; } public String getRideStartTime() { return rideStartTime; } public void setRideStartTime(String rideStartTime) { this.rideStartTime = rideStartTime; } public void setHasAltimeter(boolean hasAltimeter) { this.hasAltimeter = hasAltimeter; } }