diff --git a/build.gradle b/build.gradle index c339f8a..bff64f6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'java' +apply plugin: 'eclipse' apply plugin: 'maven' group = 'com.github.boukefalos' @@ -16,9 +17,13 @@ repositories { maven { url 'https://github.com/Boukefalos/jlibusb/raw/mvn-repo/' } + mavenCentral(); } dependencies { + compile 'org.slf4j:slf4j-api:1.+' + compile 'org.slf4j:slf4j-log4j12:1.+' + compile 'org.picocontainer:picocontainer:2.15' compile 'com.github.boukefalos:jlibusb:0.5.7' } diff --git a/src/main/java/com/github/boukefalos/ibuddy/Loader.java b/src/main/java/com/github/boukefalos/ibuddy/Loader.java new file mode 100644 index 0000000..79f70bf --- /dev/null +++ b/src/main/java/com/github/boukefalos/ibuddy/Loader.java @@ -0,0 +1,68 @@ +package com.github.boukefalos.ibuddy; + +import java.io.IOException; +import java.util.Properties; + +import org.picocontainer.DefaultPicoContainer; +import org.picocontainer.MutablePicoContainer; +import org.picocontainer.Parameter; +import org.picocontainer.parameters.ConstantParameter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.boukefalos.ibuddy.exception.LoaderException; +import com.github.boukefalos.ibuddy.implementation.Local; +import com.github.boukefalos.ibuddy.implementation.Remote; +import com.github.boukefalos.ibuddy.server.Server; + +public class Loader { + protected static Logger logger = LoggerFactory.getLogger(Loader.class); + protected static MutablePicoContainer pico; + + public static iBuddy getiBuddy() throws LoaderException { + if (!setup()) { + throw new LoaderException(); + } + return pico.getComponent(iBuddy.class); + } + + public static Server getServer() throws LoaderException { + if (!setup()) { + throw new LoaderException(); + } + return pico.getComponent(Server.class); + } + + protected static boolean setup() { + if (pico == null) { + /* Read properties file */ + Properties properties = new Properties(); + try { + properties.load(Loader.class.getClassLoader().getResourceAsStream("ibuddy.properties")); + } catch (IOException e) { + e.printStackTrace(); + logger.error("Failed to load properties file", e); + return false; + } + + /* Initialise container */ + pico = new DefaultPicoContainer(); + + /* Add implementation */ + if (properties.getProperty("implementation").equals("local")) { + /* Local */ + pico.addComponent(Local.class); + } else { + /* Remote */ + pico.addComponent(Remote.class, Remote.class, new Parameter[]{ + new ConstantParameter(properties.getProperty("remote.host")), + new ConstantParameter(Integer.valueOf(properties.getProperty("remote.port")))}); + } + + /* Add server */ + pico.addComponent(Server.class, Server.class, new Parameter[]{ + new ConstantParameter(Integer.valueOf(properties.getProperty("server.port")))}); + } + return true; + } +} diff --git a/src/main/java/com/github/boukefalos/ibuddy/exception/LoaderException.java b/src/main/java/com/github/boukefalos/ibuddy/exception/LoaderException.java new file mode 100644 index 0000000..2157b9a --- /dev/null +++ b/src/main/java/com/github/boukefalos/ibuddy/exception/LoaderException.java @@ -0,0 +1,6 @@ +package com.github.boukefalos.ibuddy.exception; + +public class LoaderException extends Exception { + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/com/github/boukefalos/ibuddy/exception/ServerException.java b/src/main/java/com/github/boukefalos/ibuddy/exception/ServerException.java new file mode 100644 index 0000000..3ca48f0 --- /dev/null +++ b/src/main/java/com/github/boukefalos/ibuddy/exception/ServerException.java @@ -0,0 +1,6 @@ +package com.github.boukefalos.ibuddy.exception; + +public class ServerException extends Exception { + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/com/github/boukefalos/ibuddy/exception/iBuddyException.java b/src/main/java/com/github/boukefalos/ibuddy/exception/iBuddyException.java new file mode 100644 index 0000000..20b155b --- /dev/null +++ b/src/main/java/com/github/boukefalos/ibuddy/exception/iBuddyException.java @@ -0,0 +1,7 @@ +package com.github.boukefalos.ibuddy.exception; + + +public class iBuddyException extends Exception { + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/com/github/boukefalos/ibuddy/iBuddy.java b/src/main/java/com/github/boukefalos/ibuddy/iBuddy.java new file mode 100644 index 0000000..02f57ce --- /dev/null +++ b/src/main/java/com/github/boukefalos/ibuddy/iBuddy.java @@ -0,0 +1,9 @@ +package com.github.boukefalos.ibuddy; + +import com.github.boukefalos.ibuddy.exception.iBuddyException; + +public interface iBuddy { + public void sendHeadRed(boolean headRed) throws iBuddyException; + public void sendHeadGreen(boolean headGreen) throws iBuddyException; + public void sendHeadBlue(boolean headBlue) throws iBuddyException; +} diff --git a/src/main/java/com/github/boukefalos/ibuddy/implementation/Local.java b/src/main/java/com/github/boukefalos/ibuddy/implementation/Local.java new file mode 100644 index 0000000..86c5f5d --- /dev/null +++ b/src/main/java/com/github/boukefalos/ibuddy/implementation/Local.java @@ -0,0 +1,42 @@ +package com.github.boukefalos.ibuddy.implementation; + +import org.jraf.jlibibuddy.IBuddy; +import org.jraf.jlibibuddy.IBuddyException; + +import com.github.boukefalos.ibuddy.iBuddy; +import com.github.boukefalos.ibuddy.exception.iBuddyException; + +public class Local implements iBuddy { + IBuddy IBuddy; + + @SuppressWarnings("static-access") + public Local() { + IBuddy = IBuddy.getIBuddy(); + } + + public void sendHeadRed(boolean headRed) throws iBuddyException { + try { + IBuddy.sendHeadRed(headRed); + } catch (IBuddyException e) { + throw new iBuddyException(); + } + } + + public void sendHeadGreen(boolean headGreen) throws iBuddyException { + try { + IBuddy.sendHeadGreen(headGreen); + } catch (IBuddyException e) { + throw new iBuddyException(); + } + + } + + public void sendHeadBlue(boolean headBlue) throws iBuddyException { + try { + IBuddy.sendHeadBlue(headBlue); + } catch (IBuddyException e) { + throw new iBuddyException(); + } + + } +} diff --git a/src/main/java/com/github/boukefalos/ibuddy/implementation/Remote.java b/src/main/java/com/github/boukefalos/ibuddy/implementation/Remote.java new file mode 100644 index 0000000..040b757 --- /dev/null +++ b/src/main/java/com/github/boukefalos/ibuddy/implementation/Remote.java @@ -0,0 +1,69 @@ +package com.github.boukefalos.ibuddy.implementation; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.boukefalos.ibuddy.iBuddy; + +public class Remote implements iBuddy { + protected Logger logger = LoggerFactory.getLogger(getClass()); + + protected DatagramSocket udpSocket; + protected InetAddress inetAddress; + protected int port; + + public Remote(String host, int port) throws UnknownHostException{ + inetAddress = InetAddress.getByName(host); + this.port = port; + } + + public void sendHeadRed(boolean headRed) { + send("RED"); + } + + public void sendHeadGreen(boolean headGreen) { + send("GREEN"); + } + + public void sendHeadBlue(boolean headBlue) { + send("BLUE"); + } + + protected void send(String request) { + send(request.getBytes()); + } + + protected void send(byte[] buffer) { + try { + setup(); + DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length, inetAddress, port); + udpSocket.send(datagramPacket); + } catch (IOException e) { + logger.error("Failed to send buffer", e); + } + } + + protected boolean setup() { + if (udpSocket == null) { + try { + udpSocket = new DatagramSocket(); + } catch (SocketException e) { + logger.error("Failed to create socket", e); + return false; + } + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { + udpSocket.close(); + } + }); + } + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/github/boukefalos/ibuddy/server/Server.java b/src/main/java/com/github/boukefalos/ibuddy/server/Server.java new file mode 100644 index 0000000..a24974e --- /dev/null +++ b/src/main/java/com/github/boukefalos/ibuddy/server/Server.java @@ -0,0 +1,64 @@ +package com.github.boukefalos.ibuddy.server; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.SocketException; + +import org.jraf.jlibibuddy.IBuddy; +import org.jraf.jlibibuddy.IBuddy.Color; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.boukefalos.ibuddy.Loader; +import com.github.boukefalos.ibuddy.exception.LoaderException; +import com.github.boukefalos.ibuddy.exception.ServerException; +import com.github.boukefalos.ibuddy.exception.iBuddyException; + +public class Server extends Thread { + protected Logger logger = LoggerFactory.getLogger(getClass()); + protected com.github.boukefalos.ibuddy.iBuddy iBuddy; + protected DatagramSocket diagramSocket; + + public Server(int port) throws ServerException { + try { + iBuddy = Loader.getiBuddy(); + diagramSocket = new DatagramSocket(port); + return; + } catch (LoaderException e) { + logger.error("Failed to load iBuddy", e); + } catch (SocketException e) { + logger.error("Failed to initialize socket", e); + } + throw new ServerException(); + } + + @SuppressWarnings("incomplete-switch") + public void run() { + while (true) { + byte[] buffer = new byte[1024]; + DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length); + try { + diagramSocket.receive(datagramPacket); + } catch (IOException e) { + logger.error("Failed to receive packet", e); + } + String received = new String(datagramPacket.getData(), datagramPacket.getOffset(), datagramPacket.getLength()); + try { + Color color = IBuddy.Color.valueOf(received); + switch (color) { + case RED: + iBuddy.sendHeadRed(true); + case GREEN: + iBuddy.sendHeadGreen(true); + case BLUE: + iBuddy.sendHeadBlue(true); + } + } catch (IllegalArgumentException e) { + logger.error("No such command", e); + } catch (iBuddyException e) { + logger.error("Failed to send command to iBuddy", e); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/test/TestClient.java b/src/main/java/test/TestClient.java new file mode 100644 index 0000000..f6ad60c --- /dev/null +++ b/src/main/java/test/TestClient.java @@ -0,0 +1,12 @@ +package test; +import com.github.boukefalos.ibuddy.Loader; + +public class TestClient { + public static void main(String[] args) { + try { + Loader.getiBuddy().sendHeadGreen(true); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/test/TestOriginal.java b/src/main/java/test/TestOriginal.java new file mode 100644 index 0000000..7115931 --- /dev/null +++ b/src/main/java/test/TestOriginal.java @@ -0,0 +1,30 @@ +package test; +import org.jraf.jlibibuddy.IBuddy; +import org.jraf.jlibibuddy.IBuddy.Color; +import org.jraf.jlibibuddy.IBuddyException; +import org.jraf.jlibibuddy.IBuddyUtils; + +public class TestOriginal { + public static void main(String[] args) { + IBuddy iBuddy = IBuddy.getIBuddy(); + try { + while (true) { + iBuddy.sendAllOff(); + for (Color color : IBuddy.Color.values()) { + iBuddy.sendHeart(false); + iBuddy.sendHeadColor(color); + Thread.sleep(100); + iBuddy.sendHeart(true); + Thread.sleep(500); + } + iBuddy.sendAllOff(); + Thread.sleep(2000); + IBuddyUtils.flap(iBuddy, 400, 6); + } + } catch (IBuddyException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/test/TestServer.java b/src/main/java/test/TestServer.java new file mode 100644 index 0000000..e049f62 --- /dev/null +++ b/src/main/java/test/TestServer.java @@ -0,0 +1,12 @@ +package test; +import com.github.boukefalos.ibuddy.Loader; + +public class TestServer { + public static void main(String[] args) { + try { + Loader.getServer().start(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/resources/ibuddy.properties b/src/main/resources/ibuddy.properties new file mode 100644 index 0000000..d3b723a --- /dev/null +++ b/src/main/resources/ibuddy.properties @@ -0,0 +1,4 @@ +remote.host=localhost +remote.port=8883 +server.port=8883 +implementation=remote \ No newline at end of file diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 0000000..f8a8ad4 --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,4 @@ +log4j.rootLogger=TRACE, CA +log4j.appender.CA=org.apache.log4j.ConsoleAppender +log4j.appender.CA.layout=org.apache.log4j.PatternLayout +log4j.appender.CA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n \ No newline at end of file