de.kernwelt.gpxtcx.Main.java Source code

Java tutorial

Introduction

Here is the source code for de.kernwelt.gpxtcx.Main.java

Source

/*
 * Copyright (c) 2011-2015 Thomas Kern
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

package de.kernwelt.gpxtcx;

import com.jgoodies.looks.plastic.Plastic3DLookAndFeel;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.swing.*;
import javax.xml.bind.DatatypeConverter;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.text.ParseException;
import java.util.Date;

public class Main {
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            private Document gpxDoc;
            private Tcx trackPoints;
            private MainFrame frame;
            private Date gpxStartTime;
            private Date tcxStartTime;
            private long tcxTimeOffset = 0;

            public void run() {
                try {

                    try {
                        UIManager.setLookAndFeel(new Plastic3DLookAndFeel());
                    } catch (Exception e) {
                    }

                    frame = new MainFrame();
                    frame.getSaveBtn().setEnabled(false);
                    frame.getBtnAlignTime().setEnabled(false);

                    frame.getReadGpxBtn().addActionListener(new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {

                            File gpxFile = Util.getFile(frame, false, ".gpx");
                            if (gpxFile != null) {
                                try {

                                    gpxDoc = Util.parse(gpxFile);

                                    gpxStartTime = getStartTime();
                                    if (gpxStartTime == null) {
                                        Util.showErrorMessage(frame,
                                                "Error reading file " + gpxFile.getAbsolutePath());
                                    } else {
                                        frame.getGpxStartTime().setText(gpxStartTime.toString());
                                        Util.fixSchema(gpxDoc);
                                        frame.getGpxFileField().setText(gpxFile.getAbsolutePath());
                                    }
                                } catch (Exception e1) {
                                    Util.showErrorMessage(frame, "Error reading file " + gpxFile.getAbsolutePath());
                                }
                            }
                            checkEnabledButtons();
                        }
                    });

                    frame.getReadTcxBtn().addActionListener(new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            File tcxFile = Util.getFile(frame, false, ".tcx");
                            if (tcxFile != null) {
                                try {
                                    trackPoints = new Tcx();
                                    trackPoints.createTrackPoints(tcxFile);
                                    tcxStartTime = trackPoints.getStartTime();
                                    frame.getTcxStartTime().setText(tcxStartTime.toString());
                                    frame.getTcxFileField().setText(tcxFile.getAbsolutePath());
                                } catch (Exception e2) {
                                    Util.showErrorMessage(frame, "Error reading file " + tcxFile.getAbsolutePath());
                                }
                                checkEnabledButtons();
                            }
                        }
                    });

                    frame.getSaveBtn().addActionListener(new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            final File mergedFile = Util.getFile(frame, true, ".gpx");
                            if (mergedFile != null) {

                                boolean doCreate = true;
                                if (mergedFile.exists()) {
                                    doCreate = Util.showYesNoMessage(frame, "File already exists. Overwrite?");
                                }
                                if (doCreate) {
                                    Blocker.setBusy(frame, true);
                                    SwingWorker worker = new SwingWorker<Boolean, Void>() {
                                        @Override
                                        public Boolean doInBackground() throws Exception {
                                            create(mergedFile);
                                            return true;
                                        }

                                        @Override
                                        public void done() {
                                            Blocker.setBusy(frame, false);
                                            try {
                                                get();
                                                Util.showInfoMessage(frame, "Merged file '"
                                                        + mergedFile.getAbsolutePath() + "' saved successfully!");
                                            } catch (InterruptedException ignore) {
                                                // ignored
                                            } catch (java.util.concurrent.ExecutionException e) {
                                                Throwable cause = e.getCause();
                                                String err = null;
                                                if (cause != null) {
                                                    err = cause.getMessage();
                                                } else {
                                                    err = e.getMessage();
                                                }
                                                Util.showErrorMessage(frame, err);
                                            }
                                        }
                                    };

                                    worker.execute();
                                }
                            }
                        }
                    });

                    frame.getBtnAlignTime().addActionListener(new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {

                            try {
                                tcxTimeOffset = gpxStartTime.getTime() - tcxStartTime.getTime();
                                frame.getTcxStartTime().setText(frame.getGpxStartTime().getText());
                            } catch (Exception e3) {
                                Util.showErrorMessage(frame, "Can't align timebase.");
                            }
                        }
                    });

                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            /**
             * Enable/disable buttons
             */
            private void checkEnabledButtons() {
                boolean enabled = frame.getGpxFileField().getText().length() > 0
                        && frame.getTcxFileField().getText().length() > 0;
                frame.getSaveBtn().setEnabled(enabled);
                frame.getBtnAlignTime().setEnabled(enabled);
            }

            /**
             * Get time of the first track point frm GPX file
             *
             * @return time as a string
             */
            private Date getStartTime() {
                NodeList sections = gpxDoc.getElementsByTagName("trkpt");
                int nTr = sections.getLength();
                for (int i = 0; i < nTr; i++) {

                    Element trackPt = (Element) sections.item(i);
                    Node timeNode = Util.getChildByName(trackPt, "time");
                    if (timeNode != null) {
                        return DatatypeConverter.parseDateTime(timeNode.getFirstChild().getNodeValue()).getTime();
                    }
                }
                return null;
            }

            /**
             * Merge extension data into GPX
             *
             * @param outputFile
             * @throws TransformerConfigurationException
             * @throws TransformerException
             * @throws ParseException
             * @throws FileNotFoundException
             */
            private void create(File outputFile) throws TransformerConfigurationException, TransformerException,
                    ParseException, FileNotFoundException {
                Document mergedDoc = (Document) gpxDoc.cloneNode(true);
                NodeList sections = mergedDoc.getElementsByTagName("trkpt");
                int nTr = sections.getLength();
                for (int i = 0; i < nTr; i++) {

                    Element trackPt = (Element) sections.item(i);
                    Node timeNode = Util.getChildByName(trackPt, "time");
                    if (timeNode != null) {
                        String st = timeNode.getFirstChild().getNodeValue();
                        long time = Util.toTime(st);
                        int heartRate = trackPoints.getHeartRateForTime(time + tcxTimeOffset);
                        if (heartRate > 0) {
                            Element extension = mergedDoc.createElement("gpxx:TrackPointExtension");
                            Element hr = mergedDoc.createElement("gpxx:hr");
                            hr.appendChild(mergedDoc.createTextNode(String.valueOf(heartRate)));
                            extension.appendChild(hr);
                            trackPt.appendChild(extension);
                        }
                    }
                }

                TransformerFactory tf = TransformerFactory.newInstance();

                Transformer transformer = tf.newTransformer();
                transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
                transformer.setOutputProperty(OutputKeys.METHOD, "xml");
                transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
                // we want to pretty format the XML output
                // transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
                // "2");
                transformer.setOutputProperty(OutputKeys.INDENT, "yes");

                BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outputFile));

                DOMSource source = new DOMSource(mergedDoc);
                StreamResult result = new StreamResult(out);
                transformer.transform(source, result);
                try {
                    out.close();
                } catch (IOException ex) {
                    // ignore
                }
            }
        });
    }
}