Java tutorial
/******************************************************************************* * Copyright (C) 2005, 2010 Wolfgang Schramm and Contributors * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA *******************************************************************************/ package net.tourbook.device.polartrainer; import java.util.ArrayList; import java.util.HashMap; import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.tourbook.chart.ChartLabel; import net.tourbook.data.TimeData; import net.tourbook.data.TourData; import net.tourbook.data.TourMarker; import net.tourbook.data.TourType; import net.tourbook.database.TourDatabase; import net.tourbook.device.InvalidDeviceSAXException; import net.tourbook.importdata.DeviceData; import net.tourbook.importdata.TourbookDevice; import net.tourbook.preferences.TourTypeColorDefinition; import net.tourbook.util.StatusUtil; import net.tourbook.util.Util; import org.eclipse.osgi.util.NLS; import org.joda.time.DateTime; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import de.byteholder.geoclipse.map.UI; /** * This sax handler performs data import for the following scema: * * <pre> * <xs:schema version="1.0" * xmlns:xs="http://www.w3.org/2001/XMLSchema" * targetNamespace="http://www.polarpersonaltrainer.com" * xmlns="http://www.polarpersonaltrainer.com" * elementFormDefault="qualified" * attributeFormDefault="unqualified"> * * <xs:annotation> * <xs:appinfo>Polar Personaltrainer.com data export</xs:appinfo> * <xs:documentation xml:lang="en"> * XML Schema for validating data objects exported from Polar Personaltrainer.com * * <b>ALL UNITS ARE ASSUMED METRIC.</b> * </xs:documentation> * </xs:annotation> * </pre> */ public class PolarTrainerSAXHandler extends DefaultHandler { private static final String DEVICE_NAME_POLAR_PERSONALTRAINER = "Polar Personal Trainer"; //$NON-NLS-1$ /** * <pre> * <xs:enumeration value="HEARTRATE"/> * <xs:enumeration value="SPEED"/> * <xs:enumeration value="CADENCE"/> * <xs:enumeration value="ALTITUDE"/> * <xs:enumeration value="POWER"/> * <xs:enumeration value="POWER_PI"/> * <xs:enumeration value="POWER_LRB"/> * <xs:enumeration value="AIR_PRESSURE"/> * <xs:enumeration value="RUN_CADENCE"/> * <xs:enumeration value="TEMPERATURE"/> * </pre> * * value <code>DISTANCE</code> is available but not documented in */ private static final String SAMPLE_TYPE_ALTITUDE = "ALTITUDE"; //$NON-NLS-1$ private static final String SAMPLE_TYPE_CADENCE = "CADENCE"; //$NON-NLS-1$ private static final String SAMPLE_TYPE_DISTANCE = "DISTANCE"; //$NON-NLS-1$ private static final String SAMPLE_TYPE_HEARTRATE = "HEARTRATE"; //$NON-NLS-1$ private static final String SAMPLE_TYPE_SPEED = "SPEED"; //$NON-NLS-1$ private static final String SAMPLE_TYPE_TEMPERATURE = "TEMPERATURE"; //$NON-NLS-1$ // private static final String SAMPLE_TYPE_POWER = "POWER"; // private static final String SAMPLE_TYPE_POWER_PI = "POWER_PI"; // private static final String SAMPLE_TYPE_POWER_LRB = "POWER_LRB"; // private static final String SAMPLE_TYPE_AIR_PRESSURE = "AIR_PRESSURE"; // private static final String SAMPLE_TYPE_RUN_CADENCE = "RUN_CADENCE"; // private static final String PATTERN_HHMMSS = "(\\d{0,2}):*(\\d{0,2}):*(\\d{0,2}).*"; //$NON-NLS-1$ private static final String PATTERN_DATE_TIME = "(\\d{4})-(\\d{2})-(\\d{2})\\s(\\d{2}):(\\d{2}):(\\d{2})\\.\\d{1}"; //$NON-NLS-1$ // private static final Pattern _patternHHMMSS = Pattern.compile(PATTERN_HHMMSS, Pattern.DOTALL); private static final Pattern _patternDateTime = Pattern.compile(PATTERN_DATE_TIME, Pattern.DOTALL); // private static final String TAG_ROOT = "polar-exercise-data"; //$NON-NLS-1$ private static final String TAG_ROOT_XMLNS = "xmlns"; //$NON-NLS-1$ private static final String TAG_ROOT_XMLNS_POLARTRAINER = "http://www.polarpersonaltrainer.com"; //$NON-NLS-1$ private static final String TAG_ROOT_VERSION = "version"; //$NON-NLS-1$ private static final String TAG_ROOT_VERSION_1 = "1.0"; //$NON-NLS-1$ // private static final String TAG_EXERCISE = "exercise"; //$NON-NLS-1$ private static final String TAG_EXERCISE_CREATED = "created"; //$NON-NLS-1$ private static final String TAG_EXERCISE_TIME = "time"; //$NON-NLS-1$ private static final String TAG_EXERCISE_NAME = "name"; //$NON-NLS-1$ private static final String TAG_EXERCISE_SPORT = "sport"; //$NON-NLS-1$ // private static final String TAG_RESULT = "result"; //$NON-NLS-1$ private static final String TAG_RESULT_DURATION = "duration"; //$NON-NLS-1$ private static final String TAG_RESULT_CALORIES = "calories"; //$NON-NLS-1$ private static final String TAG_RESULT_RECORDING_RATE = "recording-rate"; //$NON-NLS-1$ // private static final String TAG_LAPS = "laps"; //$NON-NLS-1$ private static final String TAG_LAP = "lap"; //$NON-NLS-1$ private static final String TAG_LAP_DURATION = "duration"; //$NON-NLS-1$ private static final String TAG_LAP_DISTANCE = "distance"; //$NON-NLS-1$ // private static final String TAG_SAMPLES = "samples"; //$NON-NLS-1$ private static final String TAG_SAMPLE = "sample"; //$NON-NLS-1$ private static final String TAG_SAMPLE_TYPE = "type"; //$NON-NLS-1$ private static final String TAG_SAMPLE_VALUES = "values"; //$NON-NLS-1$ // private static final String TAG_USER_SETTINGS = "user-settings"; //$NON-NLS-1$ private static final String TAG_USER_SETTINGS_RESTING = "resting"; //$NON-NLS-1$ // private boolean _isPolarDataValid = false; private int _dataVersion = -1; // private boolean _isInExercise; private boolean _isInExerciseCreated; private boolean _isInExerciseTime; private boolean _isInExerciseName; private boolean _isInExerciseSport; // private boolean _isInResult; private boolean _isInResultCalories; private boolean _isInResultDuration; private boolean _isInResultRecordingRate; // private boolean _isInLaps; private boolean _isInLap; private boolean _isInLapDuration; private boolean _isInLapDistance; // private boolean _isInSamples; private boolean _isInSample; private boolean _isInSampleType; private boolean _isInSampleValues; // private boolean _isInUserSettings; private boolean _isInUserSettingsResting; private TourbookDevice _device; private String _importFilePath; private HashMap<Long, TourData> _tourDataMap; private ArrayList<TourType> _allTourTypes; private boolean _isImported; private boolean _isDebug = false; private boolean _isNewTourType = false; private ArrayList<TimeData> _timeSlices = new ArrayList<TimeData>(); private ArrayList<Lap> _laps = new ArrayList<Lap>(); private Exercise _currentExercise; private Lap _currentLap; private String _currentSampleType; private StringBuilder _characters = new StringBuilder(100); private class Exercise { private String tourTitle; private String sport; private DateTime tourStart; private DateTime dtCreated; private DateTime dtStartTime; private short timeInterval; /** * in kcal */ private int calories = -1; private int restPulse; private int recordingRate; /** * in seconds */ private long duration = -1; private float[] altitudeValues; private float[] cadenceValues; private float[] distanceValues; private float[] pulseValues; private float[] speedValues; private float[] temperatureValues; } private class Lap { private int duration = -1; // <!-- 500 hours max --> private float distance; @Override public String toString() { return "Lap [duration=" + duration + ", distance=" + distance + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } public PolarTrainerSAXHandler(final TourbookDevice device, final String importFileName, final DeviceData deviceData, final HashMap<Long, TourData> tourDataMap) { _device = device; _importFilePath = importFileName; _tourDataMap = tourDataMap; _allTourTypes = TourDatabase.getAllTourTypes(); } @Override public void characters(final char[] chars, final int startIndex, final int length) throws SAXException { if (_isPolarDataValid && (// _isInLapDuration || _isInLapDistance || _isInSampleType || _isInSampleValues || _isInExerciseCreated || _isInExerciseTime || _isInExerciseName || _isInExerciseSport || _isInResultCalories || _isInResultRecordingRate || _isInResultDuration // )) { _characters.append(chars, startIndex, length); } } public void dispose() { _laps.clear(); _timeSlices.clear(); } @Override public void endElement(final String uri, final String localName, final String name) throws SAXException { // System.out.println("</" + name + ">\t" + _isInSample); try { /* * get values */ if (_isInLap) { parseLap02End(name); } else if (_isInSample) { parseSample02End(name); } else if (_isInResult) { parseResult02End(name); } else if (_isInUserSettings) { parseUserSettings02End(name); } else if (_isInExerciseCreated) { _isInExerciseCreated = false; _currentExercise.dtCreated = getDateTime(_characters.toString()); } else if (_isInExerciseTime) { _isInExerciseTime = false; _currentExercise.dtStartTime = getDateTime(_characters.toString()); } else if (_isInExerciseName) { _isInExerciseName = false; _currentExercise.tourTitle = _characters.toString(); } else if (_isInExerciseSport) { _isInExerciseSport = false; _currentExercise.sport = _characters.toString(); } /* * reset state */ if (name.equals(TAG_SAMPLES)) { _isInSamples = false; } else if (name.equals(TAG_SAMPLE)) { _isInSample = false; } else if (name.equals(TAG_LAPS)) { _isInLaps = false; } else if (name.equals(TAG_LAP)) { _isInLap = false; _laps.add(_currentLap); if (_isDebug) { System.out.println("\t" + _currentLap); //$NON-NLS-1$ } } else if (name.equals(TAG_USER_SETTINGS)) { // /polar-exercise-data/calendar-items/exercise/result/user-settings/heart-rate/resting _isInUserSettings = false; } else if (name.equals(TAG_RESULT)) { _isInResult = false; } else if (name.equals(TAG_EXERCISE)) { /* * exercise/tour ends */ _isInExercise = false; finalizeTour(); } } catch (final NumberFormatException e) { StatusUtil.showStatus(e); } } private void finalizeTour() throws InvalidDeviceSAXException { if (finalizeTour10CreateTimeSlices() == false) { _isImported = false; return; } // create data object for each tour final TourData tourData = new TourData(); /* * set tour start date/time */ final DateTime tourStart = _currentExercise.tourStart; tourData.setStartHour((short) tourStart.getHourOfDay()); tourData.setStartMinute((short) tourStart.getMinuteOfHour()); tourData.setStartSecond((short) tourStart.getSecondOfMinute()); tourData.setStartYear((short) tourStart.getYear()); tourData.setStartMonth((short) tourStart.getMonthOfYear()); tourData.setStartDay((short) tourStart.getDayOfMonth()); tourData.setWeek(tourStart); tourData.setDeviceTimeInterval(_currentExercise.timeInterval); tourData.setTemperatureScale(TourbookDevice.TEMPERATURE_SCALE); tourData.importRawDataFile = _importFilePath; tourData.setTourImportFilePath(_importFilePath); tourData.setTourTitle(_currentExercise.tourTitle); tourData.setCalories(_currentExercise.calories); tourData.setRestPulse(_currentExercise.restPulse); tourData.createTimeSeries(_timeSlices, true); finalizeTour20CreateMarkers(tourData); finalizeTour30SetTourType(tourData); tourData.computeAltitudeUpDown(); // after all data are added, the tour id can be created final Long tourId = tourData .createTourId(_device.createUniqueId(tourData, Util.UNIQUE_ID_SUFFIX_POLAR_TRAINER)); // check if the tour is already imported if (_tourDataMap.containsKey(tourId) == false) { tourData.computeTourDrivingTime(); tourData.computeComputedValues(); tourData.setDeviceId(_device.deviceId); tourData.setDeviceName(DEVICE_NAME_POLAR_PERSONALTRAINER); tourData.setDeviceFirmwareVersion(_dataVersion == 1 ? TAG_ROOT_VERSION_1 : UI.EMPTY_STRING); // add new tour to other tours _tourDataMap.put(tourId, tourData); } _isImported = true; } /** * @throws InvalidDeviceSAXException */ private boolean finalizeTour10CreateTimeSlices() throws InvalidDeviceSAXException { _timeSlices.clear(); final float[] altitudeValues = _currentExercise.altitudeValues; final float[] cadenceValues = _currentExercise.cadenceValues; final float[] distanceValues = _currentExercise.distanceValues; final float[] pulseValues = _currentExercise.pulseValues; final float[] speedValues = _currentExercise.speedValues; final float[] temperatureValues = _currentExercise.temperatureValues; final DateTime dtCreated = _currentExercise.dtCreated; final DateTime dtExerciseStartTime = _currentExercise.dtStartTime; final long exerciseDuration = _currentExercise.duration; /* * dtCreated is always available (minOccurs="1"), exercise start time is optional */ DateTime dtStartTime = dtExerciseStartTime; if (dtStartTime == null) { dtStartTime = dtCreated; } final long tourStartTime = dtStartTime.getMillis(); _currentExercise.tourStart = dtStartTime; /* * get value length */ int valueLength = -1; if (altitudeValues != null) { valueLength = altitudeValues.length; } else if (cadenceValues != null) { valueLength = cadenceValues.length; } else if (distanceValues != null) { valueLength = distanceValues.length; } else if (pulseValues != null) { valueLength = pulseValues.length; } else if (speedValues != null) { valueLength = speedValues.length; } else if (temperatureValues != null) { valueLength = temperatureValues.length; } // check if data are available if (valueLength < 1) { // at least one value must be available return false; } final boolean isAltitude = altitudeValues != null; final boolean isCadence = cadenceValues != null; final boolean isDistance = distanceValues != null; final boolean isSpeed = speedValues != null; final boolean isPulse = pulseValues != null; final boolean isTemperature = temperatureValues != null; /* * get time interval */ int timeInterval = _currentExercise.recordingRate; if (timeInterval < 1) { final float interval = (float) exerciseDuration / valueLength; timeInterval = (int) (interval + 0.5); if (timeInterval == 0) { throw new InvalidDeviceSAXException(NLS.bind("Tour time interval cannot be determined in: {0}", //$NON-NLS-1$ _importFilePath)); } } _currentExercise.timeInterval = (short) timeInterval; float absoluteDistance = 0; /* * create slices */ for (int valueIndex = 0; valueIndex < valueLength; valueIndex++) { final TimeData timeSlice = new TimeData(); timeSlice.absoluteTime = tourStartTime + (valueIndex * timeInterval * 1000); if (isAltitude) { timeSlice.absoluteAltitude = altitudeValues[valueIndex]; } if (isCadence) { timeSlice.cadence = (int) cadenceValues[valueIndex]; } if (isDistance) { timeSlice.absoluteDistance = distanceValues[valueIndex]; } else if (isSpeed) { // get distance from speed, speed is not saved it is always computed final float speedMeterSecond = (float) (speedValues[valueIndex] * (1000.0 / 3600)); final float distanceDiff = speedMeterSecond * timeInterval; absoluteDistance += distanceDiff; timeSlice.absoluteDistance = absoluteDistance; } if (isPulse) { timeSlice.pulse = (int) pulseValues[valueIndex]; } if (isTemperature) { timeSlice.temperature = (int) (temperatureValues[valueIndex] * TourbookDevice.TEMPERATURE_SCALE); } _timeSlices.add(timeSlice); } return true; } private void finalizeTour20CreateMarkers(final TourData tourData) { if (_laps.size() == 0) { return; } final int[] timeSerie = tourData.timeSerie; if (timeSerie.length == 0) { return; } final Set<TourMarker> tourMarkers = tourData.getTourMarkers(); final int[] distanceSerie = tourData.distanceSerie; int sumLapDuration = 0; int lapCounter = 1; for (final Lap lap : _laps) { final int lapDuration = lap.duration; int serieIndex = 0; // get serie index for (final int tourRelativeTime : timeSerie) { if (tourRelativeTime >= sumLapDuration + lapDuration) { break; } serieIndex++; } // check array bounds if (serieIndex >= timeSerie.length) { serieIndex = timeSerie.length - 1; } final TourMarker tourMarker = new TourMarker(tourData, ChartLabel.MARKER_TYPE_DEVICE); tourMarker.setLabel(Integer.toString(lapCounter)); tourMarker.setSerieIndex(serieIndex); tourMarker.setTime(sumLapDuration + lapDuration); tourMarker.setVisualPosition(ChartLabel.VISUAL_HORIZONTAL_ABOVE_GRAPH_CENTERED); if (distanceSerie != null) { tourMarker.setDistance(distanceSerie[serieIndex]); } tourMarkers.add(tourMarker); lapCounter++; sumLapDuration += lapDuration; } } /** * Set tour type from category field * * @param tourData */ private void finalizeTour30SetTourType(final TourData tourData) { final String sport = _currentExercise.sport; if (sport == null) { return; } TourType tourType = null; // find tour type in existing tour types for (final TourType mapTourType : _allTourTypes) { if (sport.equalsIgnoreCase(mapTourType.getName())) { tourType = mapTourType; break; } } TourType newSavedTourType = null; if (tourType == null) { // create new tour type final TourType newTourType = new TourType(sport); final TourTypeColorDefinition newColorDefinition = new TourTypeColorDefinition(newTourType, Long.toString(newTourType.getTypeId()), newTourType.getName()); newTourType.setColorBright(newColorDefinition.getDefaultGradientBright()); newTourType.setColorDark(newColorDefinition.getDefaultGradientDark()); newTourType.setColorLine(newColorDefinition.getDefaultLineColor()); // save new entity newSavedTourType = TourDatabase.saveEntity(newTourType, newTourType.getTypeId(), TourType.class); if (newSavedTourType != null) { tourType = newSavedTourType; _allTourTypes.add(tourType); } } tourData.setTourType(tourType); _isNewTourType |= newSavedTourType != null; } /** * Create date/time with the regex: * * <pre> * (\\d{4})-(\\d{2})-(\\d{2})\\s(\\d{2}):(\\d{2}):(\\d{2})\\.\\d{1} * </pre> * * @param dtValue * @return Returns parsed date/time or <code>null</code> when the format is not correct. */ private DateTime getDateTime(final String dtValue) { final Matcher matcherResult = _patternDateTime.matcher(dtValue); if (matcherResult.matches()) { try { int year = 0; int month = 0; int day = 0; int hour = 0; int minute = 0; int seconds = 0; final int groupCount = matcherResult.groupCount(); if (groupCount < 6) { return null; } for (int groupNo = 1; groupNo <= groupCount; groupNo++) { final String stringValue = matcherResult.group(groupNo); if (stringValue == null) { return null; } final int value = Integer.parseInt(stringValue); if (groupNo == 1) { year = value; } else if (groupNo == 2) { month = value; } else if (groupNo == 3) { day = value; } else if (groupNo == 4) { hour = value; } else if (groupNo == 5) { minute = value; } else if (groupNo == 6) { seconds = value; } } return new DateTime(year, month, day, hour, minute, seconds, 0); } catch (final NumberFormatException e) { return null; } } return null; } private float getFloatValue(final String textValue) { try { if (textValue != null) { return Float.parseFloat(textValue); } else { return Float.MIN_VALUE; } } catch (final NumberFormatException e) { return Float.MIN_VALUE; } } /** * Parse hh:mm:ss values with <code>\d{0,2}:*\d{0,2}:*\d{0,2}</code> * * @param hhmmssValue * @return Returns hh:mm:ss value in seconds or <code>-1</code> when hhmmssValue falue cannot be * parsed. */ private long getHHMMSS(final String hhmmssValue) { final Matcher matcherResult = _patternHHMMSS.matcher(hhmmssValue); if (matcherResult.matches()) { try { long returnValue = -1; final int groupCount = matcherResult.groupCount(); if (groupCount < 3) { return -1; } for (int groupNo = 1; groupNo <= groupCount; groupNo++) { final String stringValue = matcherResult.group(groupNo); if (stringValue == null) { return -1; } final long value = Long.parseLong(stringValue); if (groupNo == 1) { returnValue = value * 3600; } else if (groupNo == 2) { returnValue += value * 60; } else if (groupNo == 3) { returnValue += value; } } return returnValue; } catch (final NumberFormatException e) { return -1; } } return -1; } private int getIntValue(final String textValue) { try { if (textValue != null) { return Integer.parseInt(textValue); } else { return Integer.MIN_VALUE; } } catch (final NumberFormatException e) { return Integer.MIN_VALUE; } } private void initNewTour() { _laps.clear(); _currentSampleType = null; _currentExercise = new Exercise(); } /** * @return Returns <code>true</code> when a tour was imported */ public boolean isImported() { return _isImported; } boolean isNewTourType() { return _isNewTourType; } private void parseLap01Start(final String name) { if (name.equals(TAG_LAP_DURATION)) { _isInLapDuration = true; } else if (name.equals(TAG_LAP_DISTANCE)) { _isInLapDistance = true; } else { return; } _characters.delete(0, _characters.length()); } private void parseLap02End(final String name) { if (_isInLapDuration && name.equals(TAG_LAP_DURATION)) { // <duration>02:11:24</duration> _isInLapDuration = false; _currentLap.duration = (int) getHHMMSS(_characters.toString()); } else if (_isInLapDistance && name.equals(TAG_LAP_DISTANCE)) { // <distance>62200.0</distance> _isInLapDistance = false; _currentLap.distance = getFloatValue(_characters.toString()); } } private void parseResult01Start(final String name) { if (name.equals(TAG_RESULT_CALORIES)) { _isInResultCalories = true; } else if (name.equals(TAG_RESULT_RECORDING_RATE)) { _isInResultRecordingRate = true; } else if (name.equals(TAG_RESULT_DURATION)) { _isInResultDuration = true; } else { return; } _characters.delete(0, _characters.length()); } private void parseResult02End(final String name) { if (_isInResultCalories && name.equals(TAG_RESULT_CALORIES)) { _isInResultCalories = false; _currentExercise.calories = getIntValue(_characters.toString()); } else if (_isInResultRecordingRate && name.equals(TAG_RESULT_RECORDING_RATE)) { _isInResultRecordingRate = false; _currentExercise.recordingRate = getIntValue(_characters.toString()); } else if (_isInResultDuration && name.equals(TAG_RESULT_DURATION)) { _isInResultDuration = false; _currentExercise.duration = getHHMMSS(_characters.toString()); } } private void parseSample01Start(final String name) { if (name.equals(TAG_SAMPLE_TYPE)) { _isInSampleType = true; } else if (name.equals(TAG_SAMPLE_VALUES)) { _isInSampleValues = true; } else { return; } _characters.delete(0, _characters.length()); } private void parseSample02End(final String name) { if (_isInSampleType && name.equals(TAG_SAMPLE_TYPE)) { // e.g. <type>TEMPERATURE</type> _isInSampleType = false; final String sampleType = _characters.toString(); if (sampleType.equals(SAMPLE_TYPE_ALTITUDE) || sampleType.equals(SAMPLE_TYPE_CADENCE) || sampleType.equals(SAMPLE_TYPE_DISTANCE) || sampleType.equals(SAMPLE_TYPE_HEARTRATE) || sampleType.equals(SAMPLE_TYPE_SPEED) || sampleType.equals(SAMPLE_TYPE_TEMPERATURE)) { _currentSampleType = sampleType; } else { _currentSampleType = null; } } else if (_isInSampleValues && name.equals(TAG_SAMPLE_VALUES)) { // e.g. <values>15.1,15.1,15.1,15,15,14.9,14.8 ..... 16.9,16.8</values> _isInSampleValues = false; parseSampleValues(_characters.toString()); } } private void parseSampleValues(final String valueString) { if (_currentSampleType == null) { return; } final float[] sampleValues = parseSampleValues10(valueString); if (sampleValues == null) { return; } if (_currentSampleType.equals(SAMPLE_TYPE_ALTITUDE)) { _currentExercise.altitudeValues = sampleValues; } else if (_currentSampleType.equals(SAMPLE_TYPE_CADENCE)) { _currentExercise.cadenceValues = sampleValues; } else if (_currentSampleType.equals(SAMPLE_TYPE_DISTANCE)) { _currentExercise.distanceValues = sampleValues; } else if (_currentSampleType.equals(SAMPLE_TYPE_HEARTRATE)) { _currentExercise.pulseValues = sampleValues; } else if (_currentSampleType.equals(SAMPLE_TYPE_SPEED)) { _currentExercise.speedValues = sampleValues; } else if (_currentSampleType.equals(SAMPLE_TYPE_TEMPERATURE)) { _currentExercise.temperatureValues = sampleValues; } } /** * Get all values from the <sample> tag * * @param valueString * @return Returns samples as floating values. */ private float[] parseSampleValues10(final String valueString) { float[] floatValues = null; try { final ArrayList<String> floatStrings = new ArrayList<String>(); final StringTokenizer tokenizer = new StringTokenizer(valueString, UI.KOMMA); while (tokenizer.hasMoreElements()) { floatStrings.add((String) tokenizer.nextElement()); } final String[] floatValueStrings = floatStrings.toArray(new String[floatStrings.size()]); final int floatValueLength = floatValueStrings.length; floatValues = new float[floatValueLength]; for (int floatIndex = 0; floatIndex < floatValueLength; floatIndex++) { floatValues[floatIndex] = Float.parseFloat(floatValueStrings[floatIndex]); } } catch (final NumberFormatException e) { StatusUtil.showStatus(e); return null; } return floatValues; } private void parseUserSettings01Start(final String name) { if (name.equals(TAG_USER_SETTINGS_RESTING)) { _isInUserSettingsResting = true; } else { return; } _characters.delete(0, _characters.length()); } private void parseUserSettings02End(final String name) { if (_isInUserSettingsResting && name.equals(TAG_USER_SETTINGS_RESTING)) { _isInUserSettingsResting = false; _currentExercise.restPulse = getIntValue(_characters.toString()); } } @Override public void startElement(final String uri, final String localName, final String name, final Attributes attributes) throws SAXException { // System.out.print("<" + name + ">\n"); if (_dataVersion == 1) { /* * xmlns="http://www.polarpersonaltrainer.com" version="1.0" */ if (_isInExercise) { if (_isInLaps && _isInLap) { parseLap01Start(name); } else if (_isInSamples && _isInSample) { parseSample01Start(name); } else if (_isInResult) { parseResult01Start(name); } else if (_isInUserSettings) { parseUserSettings01Start(name); } if (name.equals(TAG_LAPS)) { _isInLaps = true; } else if (name.equals(TAG_LAP)) { // a new lap starts _isInLap = true; _currentLap = new Lap(); } else if (name.equals(TAG_SAMPLES)) { // /polar-exercise-data/calendar-items/exercise/result/samples _isInSamples = true; } else if (name.equals(TAG_SAMPLE)) { // /polar-exercise-data/calendar-items/exercise/result/samples/sample _isInSample = true; } else if (name.equals(TAG_USER_SETTINGS)) { // /polar-exercise-data/calendar-items/exercise/result/user-settings/heart-rate/resting _isInUserSettings = true; } else if (name.equals(TAG_EXERCISE_CREATED)) { // /polar-exercise-data/calendar-items/exercise/created _isInExerciseCreated = true; _characters.delete(0, _characters.length()); } else if (name.equals(TAG_EXERCISE_TIME)) { // /polar-exercise-data/calendar-items/exercise/time _isInExerciseTime = true; _characters.delete(0, _characters.length()); } else if (name.equals(TAG_EXERCISE_NAME)) { // /polar-exercise-data/calendar-items/exercise/name _isInExerciseName = true; _characters.delete(0, _characters.length()); } else if (name.equals(TAG_EXERCISE_SPORT)) { // /polar-exercise-data/calendar-items/exercise/sport _isInExerciseSport = true; _characters.delete(0, _characters.length()); } else if (name.equals(TAG_RESULT)) { // /polar-exercise-data/calendar-items/exercise/result _isInResult = true; } } else if (name.equals(TAG_EXERCISE)) { /* * a new exercise/tour starts */ _isInExercise = true; initNewTour(); } } else if (_dataVersion < 0) { // this must be the first element if (name.equals(TAG_ROOT)) { // check version and root tag in the xml file boolean isPolarTrainer = false; _dataVersion = -1; for (int attrIndex = 0; attrIndex < attributes.getLength(); attrIndex++) { final String attrName = attributes.getQName(attrIndex); final String attrValue = attributes.getValue(attrIndex); if (attrName.equalsIgnoreCase(TAG_ROOT_XMLNS)) { if (attrValue.equalsIgnoreCase(TAG_ROOT_XMLNS_POLARTRAINER)) { isPolarTrainer = true; continue; } } if (attrName.equalsIgnoreCase(TAG_ROOT_VERSION)) { if (attrValue.equalsIgnoreCase(TAG_ROOT_VERSION_1)) { _dataVersion = 1; continue; } } } if (isPolarTrainer && _dataVersion > -1) { _isPolarDataValid = true; return; } } throw new InvalidDeviceSAXException(NLS.bind("Polar xml data are not valid in: {0}", _importFilePath)); //$NON-NLS-1$ } } }