/* AVR8 Burn-O-Mat Copyright (C) 2007 Torsten Brischalle 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, either version 3 of the License, or (at your option) any later version. 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, see <http://www.gnu.org/licenses/ */ package de.lazyzero.kkMulticopterFlashTool.utils; import static lu.tudor.santec.i18n.Translatrix._; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.swing.JOptionPane; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import avr8_burn_o_mat.XmlUtil; import de.lazyzero.kkMulticopterFlashTool.KKMulticopterFlashTool; public class XmlReaderFirmwares { private Vector <Firmware> firmwares = new Vector <Firmware>(); private double actualVersion; private LinkedHashMap<String,String> firmwareRepositories = new LinkedHashMap<String,String>(); private Logger logger = KKMulticopterFlashTool.getLogger(); private String changelog; /** Creates a new instance of FuseReader */ public XmlReaderFirmwares() { } public XmlReaderFirmwares(LinkedHashMap<String,String> firmwareRepositories) { firmwares.removeAllElements(); if (KKMulticopterFlashTool.isOfflineMode()){ String url = "file://"+KKMulticopterFlashTool.getTempFolder()+"firmwares.xml"; this.firmwareRepositories.put("",url); try { readXmlFile(url); } catch (Exception e) { JOptionPane.showMessageDialog(null, _("error.offlineRepository")); e.printStackTrace(); logger.log(Level.WARNING, e.getMessage()); } } else { //from the online repository this.firmwareRepositories = firmwareRepositories; try { Iterator<String> keys = firmwareRepositories.keySet().iterator(); while (keys.hasNext()) { String key = keys.next(); boolean load = false; if (key.equals("tgydaily")) { if (KKMulticopterFlashTool.isShowDailyTGYEnabled()) { load = true; } else { load = false; } } else { load = true; } if (load) { String url = firmwareRepositories.get(key); System.out.println("repository URL: " + url); downloadFirmwareDescription(new URL(url)); readXmlFile(getLocalXMLFile(url.substring(url.lastIndexOf('/')+1))); } } } catch (Exception e) { // try { // System.out.println("repository mirror URL: " + firmwareRepositoryMirrorURL.toString()); // url = this.firmwareRepositoryMirrorURL; // downloadFirmwareDescription(new URL(url)); // readXmlFile(url); // } catch (Exception e2) { // JOptionPane.showMessageDialog(null, _("error.repository")); // } e.printStackTrace(); } } } public Vector<Firmware> getFirmwares() { return firmwares; } public Vector<Firmware> getFirmwares(String controllerName) { System.out.println("Adding firmwares for controller: " + controllerName); if(controllerName.endsWith("p")){ controllerName=controllerName.replace("p", ""); System.out.println(controllerName); } else if (controllerName.endsWith("pa")){ controllerName=controllerName.replace("pa", ""); System.out.println(controllerName); } Vector <Firmware> fw = new Vector<Firmware>(); Enumeration<Firmware> en = firmwares.elements(); while (en.hasMoreElements()) { Firmware firmware = (Firmware) en.nextElement(); if (firmware.getController().contains(controllerName)){ if (KKMulticopterFlashTool.isHideDecprecatedEnabled()) { if (!firmware.isDeprecated()) { fw.add(firmware); System.out.println("add firmware to drop down list " + firmware); } } else { fw.add(firmware); System.out.println("add firmware to drop down list " + firmware); } } } Collections.sort(fw, new Comparator<Firmware>() { @Override public int compare(Firmware o1, Firmware o2) { // TODO Auto-generated method stub return o2.toStringSorting().compareTo(o1.toStringSorting()); } }); return fw; } public void readXmlFile(String uri) throws Exception { //test the connection first if(!KKMulticopterFlashTool.isOfflineMode()) { try { URL url = new URL(uri); if (uri.startsWith("http")) { HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(5000); } } catch (Exception e) { e.printStackTrace(); logger.log(Level.WARNING, e.getMessage()); throw e; } } System.out.println("start to parse: " + uri); // if (System.getProperty("os.name").toLowerCase().contains("windows")) { // uri = uri.substring(7, uri.length()); // } DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(uri); Node node = document.getDocumentElement().getFirstChild(); while (node != null) { if (node.getNodeName().equals("firmware")) { readFirmware(node); } if (node.getNodeName().equals("version")) { readVersion(node); readChangelog(node); } node = node.getNextSibling(); } } private void readChangelog(Node node) { Node nodeChangelog = node.getFirstChild(); changelog = "<ul>"; while (nodeChangelog != null) { if (nodeChangelog.getNodeName().equals("change")) { String line = XmlUtil.getAttr(nodeChangelog, "value"); changelog = changelog.concat("<li>" + line + "</li>"); } nodeChangelog = nodeChangelog.getNextSibling(); } changelog = changelog.concat("<li>and more...</li>"); changelog = changelog.concat("</ul>"); } private void readVersion(Node node) { actualVersion = Double.parseDouble(XmlUtil.getAttr(node, "name")); } private void readFirmware(Node node) throws Exception { Node nodeFirmware = node.getFirstChild(); String author = new String(); String versionname = new String(); String controller = new String(); String md5 = new String(); String eepromMd5 = new String(); String additionalOptions = new String(); String server = new String(); URL url = null; URL zipurl = null; URL eepromUrl = null; URL eepromZipurl = null; String svnUrl = null; String svnEEpromUrl = null; String svnName = null; String svnEEpromName = null; URL commenturl = null; int features = -1; int target = 0; String name = XmlUtil.getAttr(node, "name"); String version = XmlUtil.getAttr(node, "value"); boolean isDeprecated = false; while (nodeFirmware != null) { if (nodeFirmware.getNodeName().equals("author")) { author = XmlUtil.getAttr(nodeFirmware, "name"); } if (nodeFirmware.getNodeName().equals("versionname")) { versionname = XmlUtil.getAttr(nodeFirmware, "name"); } if (nodeFirmware.getNodeName().equals("controller")) { controller = XmlUtil.getAttr(nodeFirmware, "name"); } try { if (nodeFirmware.getNodeName().equals("controller")) { target = Integer.parseInt(XmlUtil.getAttr(nodeFirmware, "target")); } } catch (Exception e) { //if target is missing or NumberformatException the target is set to kk. target = 0; } if (nodeFirmware.getNodeName().equals("file")) { url = new URL(XmlUtil.getAttr(nodeFirmware, "url")); } try { if (nodeFirmware.getNodeName().equals("zipfile")) { zipurl = new URL(XmlUtil.getAttr(nodeFirmware, "url")); } } catch (Exception e) { zipurl = null; } if (nodeFirmware.getNodeName().equals("eepromfile")) { eepromUrl = new URL(XmlUtil.getAttr(nodeFirmware, "url")); } try { if (nodeFirmware.getNodeName().equals("eepromzipfile")) { eepromZipurl = new URL(XmlUtil.getAttr(nodeFirmware, "url")); } } catch (Exception e) { eepromZipurl = null; } try { if (nodeFirmware.getNodeName().equals("svn")) { svnUrl = new String(XmlUtil.getAttr(nodeFirmware, "url")); svnName = new String(XmlUtil.getAttr(nodeFirmware, "name")); } } catch (Exception e) { svnUrl = null; svnName = null; } try { if (nodeFirmware.getNodeName().equals("svn")) { svnEEpromUrl = new String(XmlUtil.getAttr(nodeFirmware, "eepromurl")); svnEEpromName = new String(XmlUtil.getAttr(nodeFirmware, "eepromname")); } } catch (Exception e) { svnEEpromUrl = null; svnEEpromName = null; } try { if (nodeFirmware.getNodeName().equals("commenturl")) { commenturl = new URL(XmlUtil.getAttr(nodeFirmware, "url")); } } catch (Exception e) { commenturl = null; } try { if (nodeFirmware.getNodeName().equals("additionalOptions")) { additionalOptions = XmlUtil.getAttr(nodeFirmware, "option"); } } catch (Exception e) { additionalOptions = new String(); } if (nodeFirmware.getNodeName().equals("md5")) { md5 = new String(XmlUtil.getAttr(nodeFirmware, "value")); } if (nodeFirmware.getNodeName().equals("eeprommd5")) { eepromMd5 = new String(XmlUtil.getAttr(nodeFirmware, "value")); } if (nodeFirmware.getNodeName().equals("features")) { features = Integer.parseInt(XmlUtil.getAttr(nodeFirmware, "value")); } if (nodeFirmware.getNodeName().equals("server")) { server = new String(XmlUtil.getAttr(nodeFirmware, "name")); } if (nodeFirmware.getNodeName().equals("deprecated")) { isDeprecated = Boolean.parseBoolean(XmlUtil.getAttr(nodeFirmware, "value")); } nodeFirmware = nodeFirmware.getNextSibling(); } Firmware firmware = new Firmware(url); firmware.setName(name); firmware.setFileName(url.toString()); firmware.setVersionName(versionname); firmware.setVersion(version); firmware.setController(controller); firmware.setAuthor(author); firmware.setZipURL(zipurl); firmware.setEEpromURL(eepromUrl); firmware.setEEpromZipURL(eepromZipurl); firmware.setSVN(svnUrl); firmware.setSVNname(svnName); firmware.setEEpromSVN(svnEEpromUrl); firmware.setEEpromSVNname(svnEEpromName); firmware.setMD5(md5); firmware.setEEpromMD5(eepromMd5); firmware.setCommentURL(commenturl); firmware.setAdditionalOptions(additionalOptions); firmware.setFeatures(features); firmware.setTargetPlatform(target); firmware.setServer(server); firmware.setDeprecated(isDeprecated); //firmware.getFile(); firmwares.add(firmware); } private File downloadFirmwareDescription(URL url){ String filename = null; String tmpdir = null; String urlPath = url.getPath(); filename = urlPath.substring(urlPath.lastIndexOf("/")+1); System.out.println("Download firmware description file: "+filename); System.out.println("from: " + url); tmpdir = KKMulticopterFlashTool.getTempFolder(); filename = tmpdir + filename; File tmpFile = new File(filename); if ((new File(tmpdir)).mkdir()) System.out.println("tmpdir created"); try { long time = System.currentTimeMillis(); // ZipInputStream in = new ZipInputStream(url.openStream()); BufferedInputStream in = new BufferedInputStream(url.openStream()); FileOutputStream fos = new FileOutputStream(tmpFile); BufferedOutputStream bout = new BufferedOutputStream(fos,1024); byte[] data = new byte[1024]; int x=0; // in.getNextEntry(); while((x=in.read(data,0,1024))>=0) { bout.write(data,0,x); } bout.close(); in.close(); System.out.println("Download finished in milli seconds " + (System.currentTimeMillis()-time)); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //unzip try { long time = System.currentTimeMillis(); int BUFFER = 2048; BufferedOutputStream dest = null; BufferedInputStream is = null; ZipEntry entry; ZipFile zipfile = new ZipFile(filename); @SuppressWarnings("rawtypes") Enumeration e = zipfile.entries(); System.out.println("zip: " + e.hasMoreElements()); while (e.hasMoreElements()) { entry = (ZipEntry) e.nextElement(); System.out.println("Extracting: " + entry); is = new BufferedInputStream(zipfile.getInputStream(entry)); int count; byte data[] = new byte[BUFFER]; FileOutputStream fos = new FileOutputStream(filename.replace(".zip", "")); dest = new BufferedOutputStream(fos, BUFFER); while ((count = is.read(data, 0, BUFFER)) != -1) { dest.write(data, 0, count); } dest.flush(); dest.close(); is.close(); } System.out.println("Download extracted in milli seconds " + (System.currentTimeMillis()-time)); } catch (Exception e) { e.printStackTrace(); } // } // try { // long time = System.currentTimeMillis(); // int BUFFER = 2048; // ZipInputStream zin = new ZipInputStream(url.openStream()); // ZipEntry entry; // while ((entry = zin.getNextEntry()) != null) { // int count; // byte data[] = new byte[BUFFER]; // FileOutputStream fos = new FileOutputStream(entry.getName()); // BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER); // while ((count = zin.read(data, 0, BUFFER)) != -1) { // // System.out.write(x); // dest.write(data, 0, count); // } // dest.flush(); // dest.close(); // // } // zin.close(); // System.out.println("Download extracted in milli seconds " + (System.currentTimeMillis()-time)); // } catch (FileNotFoundException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } catch (IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } System.out.println("Download finished: " + filename); return tmpFile; } public static void main(String[] args) { XmlReaderFirmwares f = new XmlReaderFirmwares(); try { f.readXmlFile("./firmwares.xml"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public LinkedHashMap<String, String> getURL() { return this.firmwareRepositories; } /** * @return the actualVersion */ public double getActualVersion() { return actualVersion; } public String getChangelog() { return changelog; } public void reloadXmlFile(LinkedHashMap<String, String> urls) throws Exception { this.firmwareRepositories = urls; this.firmwares.removeAllElements(); Iterator<String> keys = firmwareRepositories.keySet().iterator(); while (keys.hasNext()) { String key = keys.next(); String url = firmwareRepositories.get(key); boolean load = false; if (key.equals("tgydaily")) { if (KKMulticopterFlashTool.isShowDailyTGYEnabled()) { load = true; } else { load = false; } } else { load = true; } if (load) { downloadFirmwareDescription(new URL(url)); String uri = getLocalXMLFile(url.substring(url.lastIndexOf('/') + 1)); readXmlFile(uri); } } } private String getLocalXMLFile(String file) { String url = file.substring(0, file.length()-4); String uri = KKMulticopterFlashTool.getTempFolder()+url; uri = "file:////".concat(uri); return uri; } }