Package com.joshondesign.arduinox

Source Code of com.joshondesign.arduinox.Global

package com.joshondesign.arduinox;

import com.joshondesign.arduino.common.Device;
import com.joshondesign.arduino.common.Util;
import com.joshondesign.xml.Doc;
import com.joshondesign.xml.Elem;
import com.joshondesign.xml.XMLParser;
import gnu.io.CommPortIdentifier;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author josh
*/
public class Global {
    private static Global _global;
    private List<Sketch> sketches = new ArrayList<>();
    private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    private Map<Sketch,EditorWindow> windows = new HashMap<>();
    private final List<SerialPort> ports;
    private final List<Device> devices;
    private Device extracore;
    private File toolchainDir;
    private static final String TOOLCHAIN_DIR = "TOOLCHAIN_DIR";
    private static final String RECENT_SKETCHES = "RECENT_SKETCHES";
    private static final String OPEN_SKETCHES = "OPEN_SKETCHES";
    private static final String COMPILER_COMMANDS_SHOWN = "COMPILER_COMMANDS_SHOWN";
   
    public static void main(String ... args) throws IOException {
        Properties props = new Properties();
        props.setProperty("asdf", "asdfasdf");
        Util.p("===");
        for(Entry e : props.entrySet()) {
            Util.p("key = " + e.getKey() + " " + e.getValue() );
        }
        props.storeToXML(new FileOutputStream("foo.xml"), "foo");
        props.clear();
        props = new Properties();
        Util.p("===");
        for(Entry e : props.entrySet()) {
            Util.p("key = " + e.getKey() + " " + e.getValue() );
        }
        props.loadFromXML(new FileInputStream("foo.xml"));
        Util.p("===");
        for(Entry e : props.entrySet()) {
            Util.p("key = " + e.getKey() + " " + e.getValue() );
        }
    }
   
    public static final int SERIAL_RATE_INTS[] = {
        300,1200,2400,4800,9600,14400,
        19200,28800,38400,57600,115200
    };
   
    public static final String SERIAL_RATE_STRINGS[] = {
        "300","1200","2400","4800","9600","14400",
        "19200","28800","38400","57600","115200"
    };
    private List<String> recentSketches;
    private Set<String> recentUniqueSketches = new HashSet<>();
    private final List<Example> examples;
    private boolean compilerCommandsShown;


    private Global() {
        setupToolchainPath();
        recentSketches = new ArrayList<>();
        this.ports = scanForSerialPorts();
        this.devices = scanForDevices();
        this.examples = scanForExamples();
    }
    private void init() {
        loadSettings();
    }
   
   

    static Global getGlobal() {
        if(_global == null) {
            _global = new Global();
            _global.init();
        }
        return _global;
    }

    void addSketch(Sketch sketch) {
        this.sketches.add(sketch);
        String path = sketch.getDirectory().getAbsolutePath();
        if(!recentUniqueSketches.contains(path)) {
            this.recentSketches.add(path);
            this.recentUniqueSketches.add(path);
        }
        pcs.firePropertyChange("sketches", sketches, sketch);
    }
   
    void removeSketch(Sketch sketch) {
        this.sketches.remove(sketch);
        pcs.firePropertyChange("sketches", sketches, null);
    }

    Iterable<Sketch> getSketches() {
        return sketches;
    }

    EditorWindow getWindowForSketch(Sketch sketch) {
        return windows.get(sketch);
    }

    void setWindowForSketch(Sketch sketch, EditorWindow frame) {
        this.windows.put(sketch,frame);
    }

    void addPropertyChangeListener(String property, PropertyChangeListener listener) {
        this.pcs.addPropertyChangeListener(property,listener);
    }
   
    private List<SerialPort> scanForSerialPorts() {
       
        List<SerialPort> ports = new ArrayList<>();
        try {
       
        //get all ports
        for (Enumeration enumeration = CommPortIdentifier.getPortIdentifiers(); enumeration.hasMoreElements();) {
            CommPortIdentifier port = (CommPortIdentifier) enumeration.nextElement();
            SerialPort pt = new SerialPort();
            pt.portName = port.getName();
            pt.shortName = pt.portName;
            ports.add(pt);
        }
       
        //filter out dupes
        if(Util.isMacOSX()) {
            Map<String,SerialPort> map = new HashMap<>();
            for(SerialPort port : ports) {
                String shortName = port.portName;
                if(port.portName.startsWith("/dev/tty")) {
                    shortName = port.portName.replaceFirst("/dev/tty.", "");
                }
                if(port.portName.startsWith("/dev/cu")) {
                    shortName = port.portName.replaceFirst("/dev/cu.", "");
                }
                port.shortName = shortName;
                map.put(shortName,port);
            }
           
            ports.clear();
            ports.addAll(map.values());
        }
       
        //remove manually blocked items (such as bluetooth)
        Iterator<SerialPort> it = ports.iterator();
        while(it.hasNext()) {
            SerialPort port = it.next();
            if(port.shortName.toLowerCase().contains("bluetooth")) it.remove();
        }
       
        for(SerialPort port : ports) {
            Util.p("final port = " + port.portName + " short = " + port.shortName);
        }
       
        } catch (Throwable thr) {
            thr.printStackTrace();
        }
        //sort by name
        //if only one, use it.
        return ports;
    }

    List<SerialPort> getPorts() {
        return this.ports;
    }

    SerialPort getPortForPath(String portName) {
        for(SerialPort port : this.ports) {
            if(port.portName.equals(portName)) {
                return port;
            }
        }
        return null;
    }

    private List<Example> scanForExamples() {
        List<Example> examples = new ArrayList<>();
        try {
            File exdir = new File(getResourcesDir(),"examples/");
            Util.p("basedir = " + exdir.getCanonicalPath());
            scanForExamples(exdir,examples);
        } catch (Throwable thr) {
            thr.printStackTrace();
        }
        return examples;
    }
   
   
    private List<Device> scanForDevices() {
        List<Device> devices  = new ArrayList<>();
        try {
            File basedir = getResourcesDir();
            if(basedir == null) {
                Util.p("resources dir is null!");
                return devices;
            }
            Util.p("resources dir = " + basedir.getCanonicalPath());
            if(!basedir.exists()) {
                Util.p("resources dir doesn't exist!");
                return devices;
            }
            for(File xml : new File(basedir,"hardware/boards/").listFiles()) {
                Util.p("parsing: " + xml.getCanonicalPath());
                try {
                    Doc doc = XMLParser.parse(xml);
                    Elem e = doc.xpathElement("/board");
                    Device d = new Device();
                    d.name = e.attr("name");
                    d.protocol = e.attr("protocol");
                    d.maximum_size = Integer.parseInt(e.attr("maximum-size"));
                    d.upload_speed = Integer.parseInt(e.attr("upload-speed"));
                    d.low_fuses = parseHex(e.attr("low-fuses"));
                    d.high_fuses = parseHex(e.attr("high-fuses"));
                    d.extended_fuses = parseHex(e.attr("extended-fuses"));
                    d.path = e.attr("path");
                    d.file = e.attr("file");
                    d.unlock_bits = parseHex(e.attr("unlock-bits"));
                    d.lock_bits = parseHex(e.attr("lock-bits"));
                    d.mcu = e.attr("mcu");
                    d.f_cpu = e.attr("f-cpu");
                    d.core = e.attr("core");
                    d.variant = e.attr("variant");
                    devices.add(d);
                } catch (Exception ex) {
                    Logger.getLogger(Global.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } catch (Throwable ex2) {
            ex2.printStackTrace();
        }
       
        return devices;
    }
   
    List<Device> getDevices() {
        return this.devices;
    }
   
    File getToolchainDir() {
        return toolchainDir;
    }

    void setToolchainDir(File arduinoPath) {
        this.toolchainDir = arduinoPath;
    }
   
    File getDocumentsDir() {
        return new File(System.getProperty("user.home"),"Documents/Arduino");
    }

    public void saveSettings() {
        try {
            Util.p("========= saving settings");
            Properties props = new Properties();
           
            StringBuffer sb2 = new StringBuffer();
            for(Sketch sketch : getSketches()) {
                sb2.append(sketch.getDirectory().getAbsolutePath());
                sb2.append(",");
            }
            props.setProperty(OPEN_SKETCHES, sb2.toString());
           
           
            StringBuffer sb = new StringBuffer();
            for(String s : recentSketches) {
                sb.append(s);
                sb.append(",");
            }
            props.setProperty(RECENT_SKETCHES, sb.toString());
            props.setProperty(COMPILER_COMMANDS_SHOWN, Boolean.toString(isCompilerCommandsShown()));
           
           
            props.store(new FileOutputStream("settings.props"), "foo");           
            props.storeToXML(new FileOutputStream("settings.xml"), "ArduinoX Settings", "UTF-8");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private void loadSettings() {
        try {
            Properties props = new Properties();
            props.loadFromXML(new FileInputStream("settings.xml"));
            Util.p("Loaded settings: " + props.keySet().size());

            recentUniqueSketches.clear();
            if(props.containsKey(RECENT_SKETCHES)) {
                String[] s = props.getProperty(RECENT_SKETCHES).split(",");
                for(String ss : s) {
                    //first, skip the dupes
                    if(recentUniqueSketches.contains(ss)) continue;
                   
                    recentUniqueSketches.add(ss);
                    recentSketches.add(ss);
                }
            }
           
            Set<String> os = new HashSet<>();
            if(props.containsKey(OPEN_SKETCHES)) {
                String[] s = props.getProperty(OPEN_SKETCHES).split(",");
                for(String ss : s) {
                    if(!os.contains(ss)) {
                        os.add(ss);
                        Actions.openNewSketch(new File(ss));
                    }
                }
            }
           
            if(props.containsKey(COMPILER_COMMANDS_SHOWN)) {
                compilerCommandsShown = Boolean.parseBoolean(props.getProperty(COMPILER_COMMANDS_SHOWN, "true"));
            }
           
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    Device getDeviceForName(String deviceName) {
        for(Device d : devices) {
            if(d.getName().equals(deviceName)) return d;
        }
        return null;
    }

    Iterable<File> getRecentSketches() {
        List<File> files = new ArrayList<>();
        for(String skdir : recentSketches) {
            files.add(new File(skdir));
        }
        return files;
    }

    private int parseHex(String attr) {
        if(attr == null || attr.trim().equals("")) {
            throw new IllegalArgumentException("The value '" + attr + "' is not a valid hex number");
        }
        if(attr.toLowerCase().startsWith("0x")) {
            attr = attr.substring(2);
        }
        return Integer.parseInt(attr,16);
    }

    private void scanForExamples(File basedir, List<Example> examples) {
        for(File file : basedir.listFiles()) {
            if(file.getName().toLowerCase().equals("example.xml")) {
                examples.add(parseExample(file));
            }
            if(file.isDirectory()) {
                scanForExamples(file,examples);
            }
        }
    }

    private Example parseExample(File file) {
        try {
            Doc doc = XMLParser.parse(file);
            Elem e = doc.xpathElement("/example");
            Example ex = new Example();
            ex.name = e.attr("name");
            for(Elem k : e.xpath("keyword")) {
                ex.keywords.add(k.text().toLowerCase());
                //Util.p("added keyword: " + k.text().toLowerCase());
            }
            ex.description = e.xpathString("description/text()");
            ex.directory = file.getParentFile();
            //Util.p("parsed example: " + ex.name);
            return ex;
        } catch (Exception ex) {
            Logger.getLogger(Global.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    List<Example> findExamplesByText(String text) {
        List<Example> results = new ArrayList<>();
        for(Example ex : examples) {
            if(ex.name.toLowerCase().contains(text.toLowerCase())) {
                results.add(ex);
                continue;
            }
            if(ex.keywords.contains(text.toLowerCase())) {
                results.add(ex);
                continue;
            }
        }
        return results;
    }

    List<Example> getExamples() {
        return this.examples;
    }

    private File getResourcesDir() {
        String resourcesprop = System.getProperty("com.joshondesign.arduinox.resourcespath");
        if(resourcesprop != null) {
            return new File(resourcesprop);
        }
        return new File(toolchainDir,"resources");
    }

    int getOpenSketchCount() {
        return this.sketches.size();
    }


    private void p(Properties props) {
        for(Entry e : props.entrySet()) {
            Util.p("key = " + e.getKey() + " value = " + e.getValue());
        }
    }

    boolean isCompilerCommandsShown() {
        return compilerCommandsShown;
    }

    void setCompilerCommandsShown(boolean selected) {
        this.compilerCommandsShown = selected;
    }

    private void setupToolchainPath() {
        Util.p("the toolchain path = " + System.getProperty("com.joshondesign.arduinox.toolchainpath"));
        String toolchainPath = System.getProperty("com.joshondesign.arduinox.toolchainpath");
        if("uselibrary".equals(toolchainPath)) {
            String librarypath = System.getProperty("java.library.path");
            File contentsDir = new File(librarypath).getParentFile();
            toolchainPath = new File(contentsDir,"toolchain").getAbsolutePath();
        }
        if(toolchainPath == null) {
            toolchainPath = System.getProperty("user.dir");
        }
        //Util.p("final toochain path = " + toolchainPath);
        this.setToolchainDir(new File(toolchainPath));
    }

}
TOP

Related Classes of com.joshondesign.arduinox.Global

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.