|
@@ -0,0 +1,416 @@
|
|
|
+package Connection;
|
|
|
+import java.awt.BorderLayout;
|
|
|
+import java.awt.Component;
|
|
|
+import java.awt.Dimension;
|
|
|
+import java.awt.FlowLayout;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
+import java.io.IOException;
|
|
|
+import java.net.HttpURLConnection;
|
|
|
+import java.net.MalformedURLException;
|
|
|
+import java.net.URL;
|
|
|
+import java.text.NumberFormat;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.Future;
|
|
|
+import java.util.concurrent.ScheduledExecutorService;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+import javax.swing.BorderFactory;
|
|
|
+import javax.swing.ImageIcon;
|
|
|
+import javax.swing.JButton;
|
|
|
+import javax.swing.JCheckBox;
|
|
|
+import javax.swing.JFormattedTextField;
|
|
|
+import javax.swing.JFrame;
|
|
|
+import javax.swing.JLabel;
|
|
|
+import javax.swing.JOptionPane;
|
|
|
+import javax.swing.JPanel;
|
|
|
+import javax.swing.JScrollPane;
|
|
|
+import javax.swing.JSplitPane;
|
|
|
+import javax.swing.JTextArea;
|
|
|
+import javax.swing.text.NumberFormatter;
|
|
|
+
|
|
|
+import api.Algorithm;
|
|
|
+import classes.AbstractCpsObject;
|
|
|
+import classes.CpsUpperNode;
|
|
|
+import classes.HolonObject;
|
|
|
+import ui.controller.Control;
|
|
|
+/**
|
|
|
+ * Easy Connection via Http Request. Repeat Request with a delay.
|
|
|
+ *
|
|
|
+ * @author tom
|
|
|
+ *
|
|
|
+ */
|
|
|
+public class ConnectPhysical implements Algorithm{
|
|
|
+ //Holeg
|
|
|
+ private Control control;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //Gui
|
|
|
+ private JPanel content = new JPanel();
|
|
|
+ private JTextArea textArea;
|
|
|
+ JLabel rotorLabel;
|
|
|
+ JLabel room1Label;
|
|
|
+ JLabel room2Label;
|
|
|
+
|
|
|
+ //
|
|
|
+ Future<?> future;
|
|
|
+ private boolean lessInformation = false;
|
|
|
+ private int delay = 1000;
|
|
|
+ JLabel warningLabel;
|
|
|
+
|
|
|
+ public enum HolonObjectStatus{
|
|
|
+ Connected , NotSelected, ObjectDeleted
|
|
|
+ }
|
|
|
+
|
|
|
+ public class PhysicalLinkWrapper{
|
|
|
+ public HolonObject hObject;
|
|
|
+ public HolonObjectStatus status;
|
|
|
+ public String postAddress;
|
|
|
+
|
|
|
+ PhysicalLinkWrapper(HolonObject hObject, HolonObjectStatus status, String postAddress){
|
|
|
+ this.hObject = hObject;
|
|
|
+ this.status = status;
|
|
|
+ this.postAddress = postAddress;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //Object to look at
|
|
|
+ PhysicalLinkWrapper rotor = new PhysicalLinkWrapper(null, HolonObjectStatus.NotSelected, "/rotor/");
|
|
|
+ PhysicalLinkWrapper room1 = new PhysicalLinkWrapper(null, HolonObjectStatus.NotSelected, "/room1/");
|
|
|
+ PhysicalLinkWrapper room2 = new PhysicalLinkWrapper(null, HolonObjectStatus.NotSelected, "/room2/");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public static void main(String[] args)
|
|
|
+ {
|
|
|
+ JFrame newFrame = new JFrame("exampleWindow");
|
|
|
+ ConnectPhysical instance = new ConnectPhysical();
|
|
|
+ newFrame.setContentPane(instance.getAlgorithmPanel());
|
|
|
+ newFrame.pack();
|
|
|
+ newFrame.setVisible(true);
|
|
|
+ newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public ConnectPhysical() {
|
|
|
+ content.setLayout(new BorderLayout());
|
|
|
+
|
|
|
+ textArea = new JTextArea();
|
|
|
+ textArea.setEditable(false);
|
|
|
+ JScrollPane scrollPane = new JScrollPane(textArea);
|
|
|
+ JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
|
|
|
+ createOptionPanel() , scrollPane);
|
|
|
+ splitPane.setResizeWeight(0.0);
|
|
|
+ content.add(splitPane, BorderLayout.CENTER);
|
|
|
+ content.setPreferredSize(new Dimension(800,800));
|
|
|
+ }
|
|
|
+
|
|
|
+ private Component createOptionPanel() {
|
|
|
+ JPanel optionPanel = new JPanel(new BorderLayout());
|
|
|
+ JScrollPane scrollPane = new JScrollPane(createParameterPanel());
|
|
|
+ scrollPane.setBorder(BorderFactory.createTitledBorder("Settings"));
|
|
|
+ optionPanel.add(scrollPane, BorderLayout.CENTER);
|
|
|
+ optionPanel.add(createButtonPanel(), BorderLayout.PAGE_END);
|
|
|
+ return optionPanel;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Component createParameterPanel() {
|
|
|
+ JPanel parameterPanel = new JPanel(null);
|
|
|
+ parameterPanel.setPreferredSize(new Dimension(510,300));
|
|
|
+
|
|
|
+
|
|
|
+ JLabel lessInformationLabel = new JLabel("Less information in Console:");
|
|
|
+ lessInformationLabel.setBounds(200, 150, 200, 20);
|
|
|
+ parameterPanel.add(lessInformationLabel);
|
|
|
+
|
|
|
+ JCheckBox lessInformationCheckBox = new JCheckBox();
|
|
|
+ lessInformationCheckBox.setSelected(false);
|
|
|
+ lessInformationCheckBox.setBounds(400, 150, 25, 20);
|
|
|
+ lessInformationCheckBox.addActionListener(actionEvent -> {
|
|
|
+ lessInformation = lessInformationCheckBox.isSelected();
|
|
|
+ });
|
|
|
+ parameterPanel.add(lessInformationCheckBox);
|
|
|
+
|
|
|
+
|
|
|
+ JLabel delayLabel = new JLabel("Delay:");
|
|
|
+ delayLabel.setBounds(200, 180, 50, 20);
|
|
|
+ parameterPanel.add(delayLabel);
|
|
|
+
|
|
|
+ JLabel delayUnitLabel = new JLabel("[ms]");
|
|
|
+ delayUnitLabel.setBounds(300, 180, 50, 20);
|
|
|
+ parameterPanel.add(delayUnitLabel);
|
|
|
+
|
|
|
+ warningLabel = new JLabel(stringToHtml(stringWithColor("You need to Stop and Run again to affect delay change.", "red")));
|
|
|
+ warningLabel.setBounds(200, 210, 400, 20);
|
|
|
+ warningLabel.setVisible(false);
|
|
|
+ parameterPanel.add(warningLabel);
|
|
|
+
|
|
|
+ //Integer formatter
|
|
|
+ NumberFormat format = NumberFormat.getIntegerInstance();
|
|
|
+ format.setGroupingUsed(false);
|
|
|
+ format.setParseIntegerOnly(true);
|
|
|
+ NumberFormatter integerFormatter = new NumberFormatter(format);
|
|
|
+ integerFormatter.setMinimum(0);
|
|
|
+ integerFormatter.setCommitsOnValidEdit(true);
|
|
|
+
|
|
|
+
|
|
|
+ JFormattedTextField delayTextField = new JFormattedTextField(integerFormatter);
|
|
|
+ delayTextField.setValue(delay);
|
|
|
+ delayTextField.setToolTipText("Only positive Integer.");
|
|
|
+ delayTextField.addPropertyChangeListener(actionEvent -> {
|
|
|
+ delay = Integer.parseInt(delayTextField.getValue().toString());
|
|
|
+ if(future != null && !future.isCancelled()) {
|
|
|
+ println("You need to Stop and Run again to affect this change.");
|
|
|
+ warningLabel.setVisible(true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ delayTextField.setBounds(250, 180, 50, 20);
|
|
|
+ parameterPanel.add(delayTextField);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ rotorLabel = new JLabel(stringToHtml("Rotor Status: " + statusToString(rotor.status)));
|
|
|
+ rotorLabel.setBounds(200, 60, 220, 30);
|
|
|
+ parameterPanel.add(rotorLabel);
|
|
|
+
|
|
|
+ room1Label = new JLabel(stringToHtml("Room1 Status: " + statusToString(room1.status)));
|
|
|
+ room1Label.setBounds(200, 90, 220, 30);
|
|
|
+ parameterPanel.add(room1Label);
|
|
|
+
|
|
|
+ room2Label = new JLabel(stringToHtml("Room2 Status: " + statusToString(room2.status)));
|
|
|
+ room2Label.setBounds(200, 120, 220, 30);
|
|
|
+ parameterPanel.add(room2Label);
|
|
|
+
|
|
|
+ JButton selectRotorButton = new JButton("Select");
|
|
|
+ selectRotorButton.setBounds(420,65, 90, 20);
|
|
|
+ selectRotorButton.addActionListener(actionEvent -> this.selectGroupNode(rotor));
|
|
|
+ parameterPanel.add(selectRotorButton);
|
|
|
+
|
|
|
+ JButton selectRoom1Button = new JButton("Select");
|
|
|
+ selectRoom1Button.setBounds(420,95, 90, 20);
|
|
|
+ selectRoom1Button.addActionListener(actionEvent -> this.selectGroupNode(room1));
|
|
|
+ parameterPanel.add(selectRoom1Button);
|
|
|
+
|
|
|
+ JButton selectRoom2Button = new JButton("Select");
|
|
|
+ selectRoom2Button.setBounds(420,125, 90, 20);
|
|
|
+ selectRoom2Button.addActionListener(actionEvent -> this.selectGroupNode(room2));
|
|
|
+ parameterPanel.add(selectRoom2Button);
|
|
|
+
|
|
|
+ return parameterPanel;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private String stringToHtml(String string) {
|
|
|
+ return "<html>" + string + "</html>";
|
|
|
+ }
|
|
|
+
|
|
|
+ private String statusToString(HolonObjectStatus status) {
|
|
|
+ switch(status) {
|
|
|
+ case Connected:
|
|
|
+ return stringWithColor("Connected", "green");
|
|
|
+ case NotSelected:
|
|
|
+ return stringWithColor("Not selected", "red");
|
|
|
+ case ObjectDeleted:
|
|
|
+ return stringWithColor("Object deleted", "red");
|
|
|
+ default:
|
|
|
+ return "";
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private String stringWithColor(String string, String color) {
|
|
|
+ return "<font color='"+color + "'>" + string + "</font>";
|
|
|
+ }
|
|
|
+
|
|
|
+ private void updateStatusLabels() {
|
|
|
+ rotorLabel.setText(stringToHtml("Rotor Status: " + statusToString(rotor.status)));
|
|
|
+ room1Label.setText(stringToHtml("Room1 Status: " + statusToString(room1.status)));
|
|
|
+ room2Label.setText(stringToHtml("Room2 Status: " + statusToString(room2.status)));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private Component createButtonPanel() {
|
|
|
+ JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
|
|
+ JButton clearButton = new JButton("Clear Console");
|
|
|
+ clearButton.addActionListener(actionEvent -> clear());
|
|
|
+ buttonPanel.add(clearButton);
|
|
|
+ JButton stopButton = new JButton("Stop");
|
|
|
+ stopButton.addActionListener(actionEvent -> stop());
|
|
|
+ buttonPanel.add(stopButton);
|
|
|
+ JButton runButton = new JButton("Run");
|
|
|
+ runButton.addActionListener(actionEvent -> initSchedule());
|
|
|
+ buttonPanel.add(runButton);
|
|
|
+ return buttonPanel;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void stop() {
|
|
|
+ if(future!= null) {
|
|
|
+ if(future.isCancelled()) {
|
|
|
+ println("Is cancelled.");
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ future.cancel(true);
|
|
|
+ println("Stopped sending Requests on localhost:2019 ...");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ println("Not started jet.");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void initSchedule() {
|
|
|
+ if(future != null && !future.isCancelled()) {
|
|
|
+ println("Is running.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ warningLabel.setVisible(false);
|
|
|
+ println("Starting sending Requests on localhost:2019");
|
|
|
+ final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
|
|
|
+ final Runnable beeper = new Runnable() {
|
|
|
+ //RepeatedMethod
|
|
|
+ public void run() {
|
|
|
+ if(lessInformation)print(".");
|
|
|
+ checkWrapper(rotor);
|
|
|
+ checkWrapper(room1);
|
|
|
+ checkWrapper(room2);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void checkWrapper(PhysicalLinkWrapper wrapper) {
|
|
|
+ if(wrapper.status == HolonObjectStatus.Connected) checkConnected(wrapper);
|
|
|
+ else if(!lessInformation)println(wrapper.postAddress +" is not connected.");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void checkConnected(PhysicalLinkWrapper wrapper) {
|
|
|
+ if(wrapper.hObject == null) {
|
|
|
+ wrapper.status = HolonObjectStatus.ObjectDeleted;
|
|
|
+ updateStatusLabels();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if(wrapper.hObject.getNumberOfElements() > 0) {
|
|
|
+ int value = Math.round(((float)wrapper.hObject.getNumberOfActiveElements()/(float) wrapper.hObject.getNumberOfElements())*(float) 100);
|
|
|
+ sendRequest(wrapper, value);
|
|
|
+
|
|
|
+ }else {
|
|
|
+ sendRequest(wrapper, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sendRequest(PhysicalLinkWrapper wrapper, int value) {
|
|
|
+ if(!lessInformation)println("Send " + "http://localhost:2019" + wrapper.postAddress + value);
|
|
|
+ doHttpUrlConnectionAction("http://localhost:2019" + wrapper.postAddress + value);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Send A Request to a URL.
|
|
|
+ *
|
|
|
+ * @param desiredUrl
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private void doHttpUrlConnectionAction(String desiredUrl)
|
|
|
+ {
|
|
|
+ URL url = null;
|
|
|
+
|
|
|
+ // create the HttpURLConnection
|
|
|
+ try {
|
|
|
+ url = new URL(desiredUrl);
|
|
|
+
|
|
|
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
|
|
+
|
|
|
+ // just want to do an HTTP GET here
|
|
|
+ connection.setRequestMethod("GET");
|
|
|
+
|
|
|
+ // give it 15 seconds to respond
|
|
|
+ connection.setReadTimeout(1000);
|
|
|
+ connection.connect();
|
|
|
+ } catch (MalformedURLException e) {
|
|
|
+ println("MalformedURLException");
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (IOException e) {
|
|
|
+ println("IOException: Connection refused");
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ future = executorService.scheduleAtFixedRate(beeper, 0, delay, TimeUnit.MILLISECONDS);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private void addObjectToList(List<AbstractCpsObject> listToSearch, List<HolonObject> listToAdd){
|
|
|
+ for (AbstractCpsObject aCps : listToSearch) {
|
|
|
+ if (aCps instanceof HolonObject) listToAdd.add((HolonObject) aCps);
|
|
|
+ else if(aCps instanceof CpsUpperNode) {
|
|
|
+ addObjectToList(((CpsUpperNode)aCps).getNodes(),listToAdd);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //SelectGroupNode
|
|
|
+ private void selectGroupNode(PhysicalLinkWrapper wrapper) {
|
|
|
+ List<HolonObject> holonObjectList = new ArrayList<HolonObject>();
|
|
|
+ addObjectToList(control.getModel().getObjectsOnCanvas(),holonObjectList);
|
|
|
+ Object[] possibilities = holonObjectList.stream().map(aCps -> new Handle<HolonObject>(aCps)).toArray();
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ Handle<HolonObject> selected = (Handle<HolonObject>) JOptionPane.showInputDialog(content, "Select HolonObject:", "HolonObject?", JOptionPane.OK_OPTION,new ImageIcon(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)) , possibilities, "");
|
|
|
+ if(selected != null) {
|
|
|
+ println("Selected: " + selected);
|
|
|
+ wrapper.hObject = selected.object;
|
|
|
+ wrapper.status = HolonObjectStatus.Connected;
|
|
|
+ updateStatusLabels();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ private class Handle<T>{
|
|
|
+ public T object;
|
|
|
+ Handle(T object){
|
|
|
+ this.object = object;
|
|
|
+ }
|
|
|
+ public String toString() {
|
|
|
+ return object.toString();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public JPanel getAlgorithmPanel() {
|
|
|
+ return content;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void setController(Control control) {
|
|
|
+ this.control = control;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void clear() {
|
|
|
+ textArea.setText("");
|
|
|
+ }
|
|
|
+ private void print(String message) {
|
|
|
+ textArea.append(message);
|
|
|
+ }
|
|
|
+ private void println(String message) {
|
|
|
+ textArea.append(message + "\n");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|