server
Clone or download
Modified Files
/*
Stream-Pi - Free & Open-Source Modular Cross-Platform Programmable Macropad
Copyright (C) 2019-2021 Debayan Sutradhar (rnayabed), Samuel Quiñones (SamuelQuinones)
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.
Written by : Debayan Sutradhar (rnayabed)
*/
package com.stream_pi.server.action;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.ActionType;
import com.stream_pi.action_api.action.PropertySaver;
import com.stream_pi.action_api.action.ServerConnection;
import com.stream_pi.action_api.actionproperty.ServerProperties;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.normalaction.ExternalPlugin;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.StreamPiException;
import com.stream_pi.util.version.Version;
import com.stream_pi.util.xmlconfighelper.XMLConfigHelper;
import org.w3c.dom.NodeList;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import java.io.File;
import java.lang.module.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ServiceLoader;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.w3c.dom.Element;
public class ExternalPlugins
{
private static ExternalPlugins instance = null;
private final Logger logger;
private File configFile;
private Document document;
private static String pluginsLocation = null;
/**
* Singleton class instance getter. Creates new one, when asked for the first time
*
* @return returns instance of NormalActionPlugins (one and only, always)
*/
public static synchronized ExternalPlugins getInstance()
{
if(instance == null)
{
instance = new ExternalPlugins();
}
return instance;
}
/**
* Sets the folder location where the plugin JARs and their dependencies are stored
*
* @param location Folder location
*/
public static void setPluginsLocation(String location)
{
pluginsLocation = location;
}
/**
* Private constructor
*/
private ExternalPlugins()
{
logger = Logger.getLogger(ExternalPlugins.class.getName());
externalPluginsHashmap = new HashMap<>();
}
/**
* init Method
*/
public void init() throws SevereException, MinorException
{
registerPlugins();
initPlugins();
}
/**
* Used to fetch list of all external Plugins
*
* @return List of plugins
*/
public List<ExternalPlugin> getPlugins()
{
return externalPlugins;
}
/**
* Returns a plugin by its module name
*
* @param name Module Name
* @return The plugin. If not found, then null is returned
*/
public ExternalPlugin getPluginByModuleName(String name)
{
logger.info("Plugin being requested : "+name);
Integer index = externalPluginsHashmap.getOrDefault(name, -1);
if(index != -1)
{
return externalPlugins.get(index);
}
return null;
}
private List<ExternalPlugin> externalPlugins = null;
HashMap<String, Integer> externalPluginsHashmap;
/**
* Used to register plugins from plugin location
*/
public void registerPlugins() throws SevereException, MinorException
{
logger.info("Registering external plugins from "+pluginsLocation+" ...");
try
{
configFile = new File(pluginsLocation+"/config.xml");
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
document = docBuilder.parse(configFile);
}
catch (Exception e)
{
e.printStackTrace();
throw new SevereException("Plugins","Error reading plugins config.xml. Cannot continue.");
}
ArrayList<ExternalPlugin> errorModules = new ArrayList<>();
ArrayList<String> errorModuleError = new ArrayList<>();
ArrayList<Action> pluginsConfigs = new ArrayList<>();
NodeList actionsNode = document.getElementsByTagName("actions").item(0).getChildNodes();
for(int i =0;i<actionsNode.getLength();i++)
{
Node eachActionNode = actionsNode.item(i);
if(eachActionNode.getNodeType() != Node.ELEMENT_NODE)
continue;
if(!eachActionNode.getNodeName().equals("action"))
continue;
Element eachActionElement = (Element) eachActionNode;
String name;
Version version;
try
{
name = XMLConfigHelper.getStringProperty(eachActionElement, "module-name");
version = new Version(XMLConfigHelper.getStringProperty(eachActionElement, "version"));
}
catch (Exception e)
{
logger.log(Level.WARNING, "Skipping configuration because invalid ...");
e.printStackTrace();
continue;
}
ServerProperties serverProperties = new ServerProperties();
NodeList serverPropertiesNodeList = eachActionElement.getElementsByTagName("properties").item(0).getChildNodes();
for(int j = 0;j<serverPropertiesNodeList.getLength();j++)
{
Node eachPropertyNode = serverPropertiesNodeList.item(j);
if(eachPropertyNode.getNodeType() != Node.ELEMENT_NODE)
continue;
if(!eachPropertyNode.getNodeName().equals("property"))
continue;
Element eachPropertyElement = (Element) eachPropertyNode;
try
{
Property property = new Property(XMLConfigHelper.getStringProperty(eachPropertyElement, "name"), Type.STRING);
property.setRawValue(XMLConfigHelper.getStringProperty(eachPropertyElement, "value"));
serverProperties.addProperty(property);
}
catch (Exception e)
{
logger.log(Level.WARNING, "Skipping property because invalid ...");
e.printStackTrace();
}
}
Action action = new Action(ActionType.NORMAL);
action.setModuleName(name);
action.setVersion(version);
action.getServerProperties().set(serverProperties);
pluginsConfigs.add(action);
}
logger.info("Size : "+pluginsConfigs.size());
Path pluginsDir = Paths.get(pluginsLocation); // Directory with plugins JARs
try
{
// Search for plugins in the plugins directory
ModuleFinder pluginsFinder = ModuleFinder.of(pluginsDir);
// Find all names of all found plugin modules
List<String> p = pluginsFinder
.findAll()
.stream()
.map(ModuleReference::descriptor)
.map(ModuleDescriptor::name)
.collect(Collectors.toList());
// Create configuration that will resolve plugin modules
// (verify that the graph of modules is correct)
Configuration pluginsConfiguration = ModuleLayer
.boot()
.configuration()
.resolve(pluginsFinder, ModuleFinder.of(), p);
// Create a module layer for plugins
ModuleLayer layer = ModuleLayer
.boot()
.defineModulesWithOneLoader(pluginsConfiguration, ClassLoader.getSystemClassLoader());
logger.info("Loading plugins from jar ...");
// Now you can use the new module layer to find service implementations in it
externalPlugins = ServiceLoader
.load(layer, NormalAction.class).stream()
.map(ServiceLoader.Provider::get)
.collect(Collectors.toList());
logger.info("...Done!");
}
catch (Exception e)
{
e.printStackTrace();
throw new MinorException("Error", "Error loading modules\n"+e.getMessage()+"\nPlease fix the errors. Other plugins wont be loaded.");
}
sortedPlugins = new HashMap<>();
for (ExternalPlugin eachPlugin : externalPlugins)
{
try
{
eachPlugin.setPropertySaver(propertySaver);
eachPlugin.setServerConnection(serverConnection);
eachPlugin.initProperties();
Action foundAction = null;
for (Action action : pluginsConfigs) {
if (action.getModuleName().equals(eachPlugin.getModuleName())
&& action.getVersion().isEqual(eachPlugin.getVersion())) {
foundAction = action;
List<Property> eachPluginStoredProperties = action.getServerProperties().get();
List<Property> eachPluginCodeProperties = eachPlugin.getServerProperties().get();
for (int i =0;i< eachPluginCodeProperties.size(); i++) {
Property eachPluginCodeProperty = eachPluginCodeProperties.get(i);
Property foundProp = null;
for (Property eachPluginStoredProperty : eachPluginStoredProperties) {
if (eachPluginCodeProperty.getName().equals(eachPluginStoredProperty.getName())) {
eachPluginCodeProperty.setRawValue(eachPluginStoredProperty.getRawValue());
foundProp = eachPluginStoredProperty;
}
}
eachPluginCodeProperties.set(i, eachPluginCodeProperty);
if (foundProp != null) {
eachPluginStoredProperties.remove(foundProp);
}
}
eachPlugin.getServerProperties().set(eachPluginCodeProperties);
break;
}
}
if (foundAction != null)
pluginsConfigs.remove(foundAction);
else
{
List<Property> eachPluginStoredProperties = eachPlugin.getServerProperties().get();
for(Property property :eachPluginStoredProperties)
{
if(property.getType() == Type.STRING || property.getType() == Type.INTEGER || property.getType() == Type.DOUBLE)
property.setRawValue(property.getDefaultRawValue());
}
}
if (!sortedPlugins.containsKey(eachPlugin.getCategory())) {
ArrayList<ExternalPlugin> actions = new ArrayList<>();
sortedPlugins.put(eachPlugin.getCategory(), actions);
}
sortedPlugins.get(eachPlugin.getCategory()).add(eachPlugin);
}
catch (Exception e)
{
e.printStackTrace();
errorModules.add(eachPlugin);
errorModuleError.add(e.getMessage());
}
}
try {
saveServerSettings();
} catch (MinorException e) {
e.printStackTrace();
}
logger.log(Level.INFO, "All plugins registered!");
if(errorModules.size() > 0)
{
StringBuilder errors = new StringBuilder("The following action modules could not be loaded:");
for(int i = 0; i<errorModules.size(); i++)
{
externalPlugins.remove(errorModules.get(i));
errors.append("\n * ").append(errorModules.get(i).getModuleName()).append("\n(")
.append(errorModuleError.get(i)).append(")");
}
throw new MinorException("Plugins", errors.toString());
}
for(int i = 0;i<externalPlugins.size();i++)
{
externalPluginsHashmap.put(externalPlugins.get(i).getModuleName(), i);
}
}
/**
* Used to init plugins
*/
public void initPlugins() throws MinorException
{
StringBuilder errors = new StringBuilder("There were errors registering the following plugins. As a result, they have been omitted : ");
boolean isError = false;
for(ExternalPlugin eachPlugin : externalPlugins)
{
try
{
eachPlugin.initAction();
}
catch (Exception e)
{
e.printStackTrace();
isError = true;
errors.append("\n* ")
.append(eachPlugin.getName())
.append(" - ")
.append(eachPlugin.getModuleName())
.append("\n");
if(e instanceof StreamPiException)
errors.append(((MinorException) e).getShortMessage());
errors.append("\n");
}
}
if(isError)
{
throw new MinorException("Plugin init error", errors.toString());
}
}
HashMap<String, ArrayList<ExternalPlugin>> sortedPlugins;
/**
* Gets list of sorted plugins
*
* @return Hashmap with category key, and list of plugins of each category
*/
public HashMap<String, ArrayList<ExternalPlugin>> getSortedPlugins()
{
return sortedPlugins;
}
/**
* @return Gets actions element from the config.xml in plugins folder
*/
private Element getActionsElement()
{
return (Element) document.getElementsByTagName("actions").item(0);
}
/**
* Saves ServerProperties of every plugin in config.xml in plugins folder
*
* @throws MinorException Thrown when failed to save settings
*/
public void saveServerSettings() throws MinorException
{
XMLConfigHelper.removeChilds(getActionsElement());
for(ExternalPlugin normalAction : externalPlugins)
{
Element actionElement = document.createElement("action");
getActionsElement().appendChild(actionElement);
Element moduleNameElement = document.createElement("module-name");
moduleNameElement.setTextContent(normalAction.getModuleName());
actionElement.appendChild(moduleNameElement);
Element versionElement = document.createElement("version");
versionElement.setTextContent(normalAction.getVersion().getText());
actionElement.appendChild(versionElement);
Element propertiesElement = document.createElement("properties");
actionElement.appendChild(propertiesElement);
for(String key : normalAction.getServerProperties().getNames())
{
for(Property eachProperty : normalAction.getServerProperties().getMultipleProperties(key))
{
Element propertyElement = document.createElement("property");
propertiesElement.appendChild(propertyElement);
Element nameElement = document.createElement("name");
nameElement.setTextContent(eachProperty.getName());
propertyElement.appendChild(nameElement);
Element valueElement = document.createElement("value");
valueElement.setTextContent(eachProperty.getRawValue());
propertyElement.appendChild(valueElement);
}
}
}
save();
}
private PropertySaver propertySaver = null;
/**
* Set PropertySaver class
* @param propertySaver instance of PropertySaver
*/
public void setPropertySaver(PropertySaver propertySaver)
{
this.propertySaver = propertySaver;
}
private ServerConnection serverConnection = null;
/**
* Set setServerConnection class
* @param serverConnection instance of ServerConnection
*/
public void setServerConnection(ServerConnection serverConnection)
{
this.serverConnection = serverConnection;
}
/**
* Get plugin from index from list
*
* @param index of plugin
* @return found plugin
*/
public ExternalPlugin getActionFromIndex(int index)
{
return externalPlugins.get(index);
}
/**
* Calls onShutDown method in every plugin
*/
public void shutDownActions()
{
if(externalPlugins != null)
{
for(ExternalPlugin eachPlugin : externalPlugins)
{
try
{
eachPlugin.onShutDown();
}
catch (Exception e)
{
e.printStackTrace();
}
}
externalPlugins.clear();
}
}
/**
* Saves all Server Properties of each Plugin in config.xml in Plugins folder
* @throws MinorException thrown when failed to save
*/
public void save() throws MinorException
{
try
{
Transformer transformer = TransformerFactory.newInstance().newTransformer();
Result output = new StreamResult(configFile);
Source input = new DOMSource(document);
transformer.transform(input, output);
}
catch (Exception e)
{
throw new MinorException("Config", "unable to save server plugins settings");
}
}
}
/*
Stream-Pi - Free & Open-Source Modular Cross-Platform Programmable Macropad
Copyright (C) 2019-2021 Debayan Sutradhar (rnayabed), Samuel Quiñones (SamuelQuinones)
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.
Written by : Debayan Sutradhar (rnayabed)
*/
package com.stream_pi.server.action;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.ActionType;
import com.stream_pi.action_api.action.PropertySaver;
import com.stream_pi.action_api.action.ServerConnection;
import com.stream_pi.action_api.actionproperty.ServerProperties;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.StreamPiException;
import com.stream_pi.util.version.Version;
import com.stream_pi.util.xmlconfighelper.XMLConfigHelper;
import org.w3c.dom.NodeList;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import java.io.File;
import java.lang.module.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ServiceLoader;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.w3c.dom.Element;
public class NormalActionPlugins
{
private static NormalActionPlugins instance = null;
private final Logger logger;
private File configFile;
private Document document;
private static String pluginsLocation = null;
/**
* Singleton class instance getter. Creates new one, when asked for the first time
*
* @return returns instance of NormalActionPlugins (one and only, always)
*/
public static synchronized NormalActionPlugins getInstance()
{
if(instance == null)
{
instance = new NormalActionPlugins();
}
return instance;
}
/**
* Sets the folder location where the plugin JARs and their dependencies are stored
*
* @param location Folder location
*/
public static void setPluginsLocation(String location)
{
pluginsLocation = location;
}
/**
* Private constructor
*/
private NormalActionPlugins()
{
logger = Logger.getLogger(NormalActionPlugins.class.getName());
normalPluginsHashmap = new HashMap<>();
}
/**
* init Method
*/
public void init() throws SevereException, MinorException
{
registerPlugins();
initPlugins();
}
/**
* Used to fetch list of all external Plugins
*
* @return List of plugins
*/
public List<NormalAction> getPlugins()
{
return normalPlugins;
}
/**
* Returns a plugin by its module name
*
* @param name Module Name
* @return The plugin. If not found, then null is returned
*/
public NormalAction getPluginByModuleName(String name)
{
logger.info("Plugin being requested : "+name);
Integer index = normalPluginsHashmap.getOrDefault(name, -1);
if(index != -1)
{
return normalPlugins.get(index);
}
return null;
}
private List<NormalAction> normalPlugins = null;
HashMap<String, Integer> normalPluginsHashmap;
/**
* Used to register plugins from plugin location
*/
public void registerPlugins() throws SevereException, MinorException
{
logger.info("Registering external plugins from "+pluginsLocation+" ...");
try
{
configFile = new File(pluginsLocation+"/config.xml");
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
document = docBuilder.parse(configFile);
}
catch (Exception e)
{
e.printStackTrace();
throw new SevereException("Plugins","Error reading plugins config.xml. Cannot continue.");
}
ArrayList<NormalAction> errorModules = new ArrayList<>();
ArrayList<String> errorModuleError = new ArrayList<>();
ArrayList<Action> pluginsConfigs = new ArrayList<>();
NodeList actionsNode = document.getElementsByTagName("actions").item(0).getChildNodes();
for(int i =0;i<actionsNode.getLength();i++)
{
Node eachActionNode = actionsNode.item(i);
if(eachActionNode.getNodeType() != Node.ELEMENT_NODE)
continue;
if(!eachActionNode.getNodeName().equals("action"))
continue;
Element eachActionElement = (Element) eachActionNode;
String name;
Version version;
try
{
name = XMLConfigHelper.getStringProperty(eachActionElement, "module-name");
version = new Version(XMLConfigHelper.getStringProperty(eachActionElement, "version"));
}
catch (Exception e)
{
logger.log(Level.WARNING, "Skipping configuration because invalid ...");
e.printStackTrace();
continue;
}
ServerProperties serverProperties = new ServerProperties();
NodeList serverPropertiesNodeList = eachActionElement.getElementsByTagName("properties").item(0).getChildNodes();
for(int j = 0;j<serverPropertiesNodeList.getLength();j++)
{
Node eachPropertyNode = serverPropertiesNodeList.item(j);
if(eachPropertyNode.getNodeType() != Node.ELEMENT_NODE)
continue;
if(!eachPropertyNode.getNodeName().equals("property"))
continue;
Element eachPropertyElement = (Element) eachPropertyNode;
try
{
Property property = new Property(XMLConfigHelper.getStringProperty(eachPropertyElement, "name"), Type.STRING);
property.setRawValue(XMLConfigHelper.getStringProperty(eachPropertyElement, "value"));
serverProperties.addProperty(property);
}
catch (Exception e)
{
logger.log(Level.WARNING, "Skipping property because invalid ...");
e.printStackTrace();
}
}
Action action = new Action(ActionType.NORMAL);
action.setModuleName(name);
action.setVersion(version);
action.getServerProperties().set(serverProperties);
pluginsConfigs.add(action);
}
logger.info("Size : "+pluginsConfigs.size());
Path pluginsDir = Paths.get(pluginsLocation); // Directory with plugins JARs
try
{
// Search for plugins in the plugins directory
ModuleFinder pluginsFinder = ModuleFinder.of(pluginsDir);
// Find all names of all found plugin modules
List<String> p = pluginsFinder
.findAll()
.stream()
.map(ModuleReference::descriptor)
.map(ModuleDescriptor::name)
.collect(Collectors.toList());
// Create configuration that will resolve plugin modules
// (verify that the graph of modules is correct)
Configuration pluginsConfiguration = ModuleLayer
.boot()
.configuration()
.resolve(pluginsFinder, ModuleFinder.of(), p);
// Create a module layer for plugins
ModuleLayer layer = ModuleLayer
.boot()
.defineModulesWithOneLoader(pluginsConfiguration, ClassLoader.getSystemClassLoader());
logger.info("Loading plugins from jar ...");
// Now you can use the new module layer to find service implementations in it
normalPlugins = ServiceLoader
.load(layer, NormalAction.class).stream()
.map(ServiceLoader.Provider::get)
.collect(Collectors.toList());
logger.info("...Done!");
}
catch (Exception e)
{
e.printStackTrace();
throw new MinorException("Error", "Error loading modules\n"+e.getMessage()+"\nPlease fix the errors. Other plugins wont be loaded.");
}
sortedPlugins = new HashMap<>();
for (NormalAction eachPlugin : normalPlugins)
{
try
{
eachPlugin.setPropertySaver(propertySaver);
eachPlugin.setServerConnection(serverConnection);
eachPlugin.initProperties();
Action foundAction = null;
for (Action action : pluginsConfigs) {
if (action.getModuleName().equals(eachPlugin.getModuleName())
&& action.getVersion().isEqual(eachPlugin.getVersion())) {
foundAction = action;
List<Property> eachPluginStoredProperties = action.getServerProperties().get();
List<Property> eachPluginCodeProperties = eachPlugin.getServerProperties().get();
for (int i =0;i< eachPluginCodeProperties.size(); i++) {
Property eachPluginCodeProperty = eachPluginCodeProperties.get(i);
Property foundProp = null;
for (Property eachPluginStoredProperty : eachPluginStoredProperties) {
if (eachPluginCodeProperty.getName().equals(eachPluginStoredProperty.getName())) {
eachPluginCodeProperty.setRawValue(eachPluginStoredProperty.getRawValue());
foundProp = eachPluginStoredProperty;
}
}
eachPluginCodeProperties.set(i, eachPluginCodeProperty);
if (foundProp != null) {
eachPluginStoredProperties.remove(foundProp);
}
}
eachPlugin.getServerProperties().set(eachPluginCodeProperties);
break;
}
}
if (foundAction != null)
pluginsConfigs.remove(foundAction);
else
{
List<Property> eachPluginStoredProperties = eachPlugin.getServerProperties().get();
for(Property property :eachPluginStoredProperties)
{
if(property.getType() == Type.STRING || property.getType() == Type.INTEGER || property.getType() == Type.DOUBLE)
property.setRawValue(property.getDefaultRawValue());
}
}
if (!sortedPlugins.containsKey(eachPlugin.getCategory())) {
ArrayList<NormalAction> actions = new ArrayList<>();
sortedPlugins.put(eachPlugin.getCategory(), actions);
}
sortedPlugins.get(eachPlugin.getCategory()).add(eachPlugin);
}
catch (Exception e)
{
e.printStackTrace();
errorModules.add(eachPlugin);
errorModuleError.add(e.getMessage());
}
}
try {
saveServerSettings();
} catch (MinorException e) {
e.printStackTrace();
}
logger.log(Level.INFO, "All plugins registered!");
if(errorModules.size() > 0)
{
StringBuilder errors = new StringBuilder("The following action modules could not be loaded:");
for(int i = 0; i<errorModules.size(); i++)
{
normalPlugins.remove(errorModules.get(i));
errors.append("\n * ").append(errorModules.get(i).getModuleName()).append("\n(")
.append(errorModuleError.get(i)).append(")");
}
throw new MinorException("Plugins", errors.toString());
}
for(int i = 0;i<normalPlugins.size();i++)
{
normalPluginsHashmap.put(normalPlugins.get(i).getModuleName(), i);
}
}
/**
* Used to init plugins
*/
public void initPlugins() throws MinorException
{
StringBuilder errors = new StringBuilder("There were errors registering the following plugins. As a result, they have been omitted : ");
boolean isError = false;
for(NormalAction eachPlugin : normalPlugins)
{
try
{
eachPlugin.initAction();
}
catch (Exception e)
{
e.printStackTrace();
isError = true;
errors.append("\n* ")
.append(eachPlugin.getName())
.append(" - ")
.append(eachPlugin.getModuleName())
.append("\n");
if(e instanceof StreamPiException)
errors.append(((MinorException) e).getShortMessage());
errors.append("\n");
}
}
if(isError)
{
throw new MinorException("Plugin init error", errors.toString());
}
}
HashMap<String, ArrayList<NormalAction>> sortedPlugins;
/**
* Gets list of sorted plugins
*
* @return Hashmap with category key, and list of plugins of each category
*/
public HashMap<String, ArrayList<NormalAction>> getSortedPlugins()
{
return sortedPlugins;
}
/**
* @return Gets actions element from the config.xml in plugins folder
*/
private Element getActionsElement()
{
return (Element) document.getElementsByTagName("actions").item(0);
}
/**
* Saves ServerProperties of every plugin in config.xml in plugins folder
*
* @throws MinorException Thrown when failed to save settings
*/
public void saveServerSettings() throws MinorException
{
XMLConfigHelper.removeChilds(getActionsElement());
for(NormalAction normalAction : normalPlugins)
{
Element actionElement = document.createElement("action");
getActionsElement().appendChild(actionElement);
Element moduleNameElement = document.createElement("module-name");
moduleNameElement.setTextContent(normalAction.getModuleName());
actionElement.appendChild(moduleNameElement);
Element versionElement = document.createElement("version");
versionElement.setTextContent(normalAction.getVersion().getText());
actionElement.appendChild(versionElement);
Element propertiesElement = document.createElement("properties");
actionElement.appendChild(propertiesElement);
for(String key : normalAction.getServerProperties().getNames())
{
for(Property eachProperty : normalAction.getServerProperties().getMultipleProperties(key))
{
Element propertyElement = document.createElement("property");
propertiesElement.appendChild(propertyElement);
Element nameElement = document.createElement("name");
nameElement.setTextContent(eachProperty.getName());
propertyElement.appendChild(nameElement);
Element valueElement = document.createElement("value");
valueElement.setTextContent(eachProperty.getRawValue());
propertyElement.appendChild(valueElement);
}
}
}
save();
}
private PropertySaver propertySaver = null;
/**
* Set PropertySaver class
* @param propertySaver instance of PropertySaver
*/
public void setPropertySaver(PropertySaver propertySaver)
{
this.propertySaver = propertySaver;
}
private ServerConnection serverConnection = null;
/**
* Set setServerConnection class
* @param serverConnection instance of ServerConnection
*/
public void setServerConnection(ServerConnection serverConnection)
{
this.serverConnection = serverConnection;
}
/**
* Get plugin from index from list
*
* @param index of plugin
* @return found plugin
*/
public NormalAction getActionFromIndex(int index)
{
return normalPlugins.get(index);
}
/**
* Calls onShutDown method in every plugin
*/
public void shutDownActions()
{
if(normalPlugins != null)
{
for(NormalAction eachPlugin : normalPlugins)
{
try
{
eachPlugin.onShutDown();
}
catch (Exception e)
{
e.printStackTrace();
}
}
normalPlugins.clear();
}
}
/**
* Saves all Server Properties of each Plugin in config.xml in Plugins folder
* @throws MinorException thrown when failed to save
*/
public void save() throws MinorException
{
try
{
Transformer transformer = TransformerFactory.newInstance().newTransformer();
Result output = new StreamResult(configFile);
Source input = new DOMSource(document);
transformer.transform(input, output);
}
catch (Exception e)
{
throw new MinorException("Config", "unable to save server plugins settings");
}
}
}
package com.stream_pi.server.connection;
package com.stream_pi.server.connection;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.ActionType;
import com.stream_pi.action_api.action.ActionType;
import com.stream_pi.action_api.action.DisplayTextAlignment;
import com.stream_pi.action_api.action.DisplayTextAlignment;
import com.stream_pi.action_api.action.Location;
import com.stream_pi.action_api.action.Location;
import com.stream_pi.action_api.actionproperty.ClientProperties;
import com.stream_pi.action_api.actionproperty.ClientProperties;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.normalaction.ExternalPlugin;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.action_api.normalaction.ToggleAction;
import com.stream_pi.action_api.normalaction.ToggleAction;
import com.stream_pi.server.action.NormalActionPlugins;
import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.server.client.Client;
import com.stream_pi.server.client.Client;
import com.stream_pi.server.client.ClientProfile;
import com.stream_pi.server.client.ClientProfile;
import com.stream_pi.server.client.ClientTheme;
import com.stream_pi.server.client.ClientTheme;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.comms.Message;
import com.stream_pi.util.comms.Message;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.StreamPiException;
import com.stream_pi.util.exception.StreamPiException;
import com.stream_pi.util.platform.Platform;
import com.stream_pi.util.platform.Platform;
import com.stream_pi.util.platform.ReleaseStatus;
import com.stream_pi.util.platform.ReleaseStatus;
import com.stream_pi.util.version.Version;
import com.stream_pi.util.version.Version;
import javafx.concurrent.Task;
import javafx.concurrent.Task;
import java.io.*;
import java.io.*;
import java.lang.reflect.Array;
import java.net.Socket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.Logger;
public class ClientConnection extends Thread
public class ClientConnection extends Thread
{
{
private Socket socket;
private Socket socket;
private ServerListener serverListener;
private ServerListener serverListener;
private AtomicBoolean stop = new AtomicBoolean(false);
private AtomicBoolean stop = new AtomicBoolean(false);
private ObjectOutputStream oos;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private ObjectInputStream ois;
private Logger logger;
private Logger logger;
private Client client = null;
private Client client = null;
private ExceptionAndAlertHandler exceptionAndAlertHandler;
private ExceptionAndAlertHandler exceptionAndAlertHandler;
public ClientConnection(Socket socket, ServerListener serverListener, ExceptionAndAlertHandler exceptionAndAlertHandler)
public ClientConnection(Socket socket, ServerListener serverListener, ExceptionAndAlertHandler exceptionAndAlertHandler)
{
{
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
this.socket = socket;
this.socket = socket;
this.serverListener = serverListener;
this.serverListener = serverListener;
logger = Logger.getLogger(ClientConnection.class.getName());
logger = Logger.getLogger(ClientConnection.class.getName());
try
try
{
{
oos = new ObjectOutputStream(socket.getOutputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
ois = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
} catch (IOException e) {
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleMinorException(new MinorException("Unable to start socket streams"));
exceptionAndAlertHandler.handleMinorException(new MinorException("Unable to start socket streams"));
}
}
start();
start();
}
}
public synchronized void exit()
public synchronized void exit()
{
{
if(stop.get())
if(stop.get())
return;
return;
logger.info("Stopping ...");
logger.info("Stopping ...");
try
try
{
{
if(socket !=null)
if(socket !=null)
{
{
logger.info("Stopping connection "+socket.getRemoteSocketAddress());
logger.info("Stopping connection "+socket.getRemoteSocketAddress());
disconnect();
disconnect();
}
}
}
}
catch (SevereException e)
catch (SevereException e)
{
{
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleSevereException(e);
exceptionAndAlertHandler.handleSevereException(e);
}
}
}
}
public synchronized void exitAndRemove()
public synchronized void exitAndRemove()
{
{
exit();
exit();
removeConnection();
removeConnection();
serverListener.clearTemp();
serverListener.clearTemp();
}
}
public void removeConnection()
public void removeConnection()
{
{
ClientConnections.getInstance().removeConnection(this);
ClientConnections.getInstance().removeConnection(this);
}
}
public void sendIcon(String profileID, String actionID, String state, byte[] icon) throws SevereException
public void sendIcon(String profileID, String actionID, String state, byte[] icon) throws SevereException
{
{
try
try
{
{
Thread.sleep(50);
Thread.sleep(50);
}
}
catch (InterruptedException e)
catch (InterruptedException e)
{
{
e.printStackTrace();
e.printStackTrace();
}
}
Message message = new Message("action_icon");
Message message = new Message("action_icon");
message.setStringArrValue(profileID, actionID, state);
message.setStringArrValue(profileID, actionID, state);
message.setByteArrValue(icon);
message.setByteArrValue(icon);
sendMessage(message);
sendMessage(message);
}
}
public void initAfterConnectionQueryReceive(Message message) throws StreamPiException
public void initAfterConnectionQueryReceive(Message message) throws StreamPiException
{
{
String[] ar = message.getStringArrValue();
String[] ar = message.getStringArrValue();
logger.info("Setting up client object ...");
logger.info("Setting up client object ...");
Version clientVersion;
Version clientVersion;
Version commsStandard;
Version commsStandard;
Version themesStandard;
Version themesStandard;
ReleaseStatus releaseStatus;
ReleaseStatus releaseStatus;
try
try
{
{
clientVersion = new Version(ar[0]);
clientVersion = new Version(ar[0]);
releaseStatus = ReleaseStatus.valueOf(ar[1]);
releaseStatus = ReleaseStatus.valueOf(ar[1]);
commsStandard = new Version(ar[2]);
commsStandard = new Version(ar[2]);
themesStandard = new Version(ar[3]);
themesStandard = new Version(ar[3]);
}
}
catch (MinorException e)
catch (MinorException e)
{
{
exitAndRemove();
exitAndRemove();
throw new MinorException(e.getShortMessage()+" (client '"+socket.getRemoteSocketAddress()+"' )");
throw new MinorException(e.getShortMessage()+" (client '"+socket.getRemoteSocketAddress()+"' )");
}
}
if(!commsStandard.isEqual(ServerInfo.getInstance().getCommStandardVersion()))
if(!commsStandard.isEqual(ServerInfo.getInstance().getCommStandardVersion()))
{
{
String errTxt = "Server and client Communication standards do not match. Make sure you are on the latest version of server and client.\n" +
String errTxt = "Server and client Communication standards do not match. Make sure you are on the latest version of server and client.\n" +
"Server Comms. Standard : "+ServerInfo.getInstance().getCommStandardVersion().getText()+
"Server Comms. Standard : "+ServerInfo.getInstance().getCommStandardVersion().getText()+
"\nclient Comms. Standard : "+commsStandard.getText();
"\nclient Comms. Standard : "+commsStandard.getText();
disconnect(errTxt);
disconnect(errTxt);
throw new MinorException(errTxt);
throw new MinorException(errTxt);
}
}
client = new Client(clientVersion, releaseStatus, commsStandard, themesStandard, ar[4], Platform.valueOf(ar[7]), socket.getRemoteSocketAddress());
client = new Client(clientVersion, releaseStatus, commsStandard, themesStandard, ar[4], Platform.valueOf(ar[7]), socket.getRemoteSocketAddress());
client.setDisplayWidth(Double.parseDouble(ar[5]));
client.setDisplayWidth(Double.parseDouble(ar[5]));
client.setDisplayHeight(Double.parseDouble(ar[6]));
client.setDisplayHeight(Double.parseDouble(ar[6]));
client.setDefaultProfileID(ar[8]);
client.setDefaultProfileID(ar[8]);
client.setDefaultThemeFullName(ar[9]);
client.setDefaultThemeFullName(ar[9]);
//call get profiles command.
//call get profiles command.
serverListener.clearTemp();
serverListener.clearTemp();
}
}
public synchronized Client getClient()
public synchronized Client getClient()
{
{
return client;
return client;
}
}
@Override
@Override
public void run() {
public void run() {
try {
try {
initAfterConnectionQuerySend();
initAfterConnectionQuerySend();
} catch (SevereException e) {
} catch (SevereException e) {
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleSevereException(e);
exceptionAndAlertHandler.handleSevereException(e);
exitAndRemove();
exitAndRemove();
return;
return;
}
}
try
try
{
{
while(!stop.get())
while(!stop.get())
{
{
try
try
{
{
Message message = (Message) ois.readObject();
Message message = (Message) ois.readObject();
String header = message.getHeader();
String header = message.getHeader();
switch (header)
switch (header)
{
{
case "action_icon" : onActionIconReceived(message);
case "action_icon" : onActionIconReceived(message);
break;
break;
case "disconnect" : clientDisconnected(message);
case "disconnect" : clientDisconnected(message);
break;
break;
case "client_details" : initAfterConnectionQueryReceive(message);
case "client_details" : initAfterConnectionQueryReceive(message);
getProfilesFromClient();
getProfilesFromClient();
getThemesFromClient();
getThemesFromClient();
break;
break;
case "profiles" : registerProfilesFromClient(message);
case "profiles" : registerProfilesFromClient(message);
break;
break;
case "profile_details" : registerProfileDetailsFromClient(message);
case "profile_details" : registerProfileDetailsFromClient(message);
break;
break;
case "action_details" : registerActionToProfile(message);
case "action_details" : registerActionToProfile(message);
break;
break;
case "themes": registerThemes(message);
case "themes": registerThemes(message);
break;
break;
case "action_clicked": actionClicked(message);
case "action_clicked": actionClicked(message);
break;
break;
default: logger.warning("Command '"+header+"' does not match records. Make sure client and server versions are equal.");
default: logger.warning("Command '"+header+"' does not match records. Make sure client and server versions are equal.");
}
}
}
}
catch (IOException | ClassNotFoundException e)
catch (IOException | ClassNotFoundException e)
{
{
logger.log(Level.SEVERE, e.getMessage());
logger.log(Level.SEVERE, e.getMessage());
e.printStackTrace();
e.printStackTrace();
serverListener.clearTemp();
serverListener.clearTemp();
if(!stop.get())
if(!stop.get())
{
{
removeConnection();
removeConnection();
throw new MinorException("Accidentally disconnected from "+getClient().getNickName()+".");
throw new MinorException("Accidentally disconnected from "+getClient().getNickName()+".");
}
}
exitAndRemove();
exitAndRemove();
return;
return;
}
}
}
}
}
}
catch (StreamPiException e)
catch (StreamPiException e)
{
{
e.printStackTrace();
e.printStackTrace();
if(e instanceof MinorException)
if(e instanceof MinorException)
exceptionAndAlertHandler.handleMinorException((MinorException) e);
exceptionAndAlertHandler.handleMinorException((MinorException) e);
else if (e instanceof SevereException)
else if (e instanceof SevereException)
exceptionAndAlertHandler.handleSevereException((SevereException) e);
exceptionAndAlertHandler.handleSevereException((SevereException) e);
}
}
}
}
// commands
// commands
private void onActionIconReceived(Message message) throws MinorException
private void onActionIconReceived(Message message) throws MinorException
{
{
String[] s = message.getStringArrValue();
String[] s = message.getStringArrValue();
String profileID = s[0];
String profileID = s[0];
String actionID = s[1];
String actionID = s[1];
String iconState = s[2];
String iconState = s[2];
getClient()
getClient()
.getProfileByID(profileID)
.getProfileByID(profileID)
.getActionByID(actionID)
.getActionByID(actionID)
.addIcon(iconState,message.getByteArrValue());
.addIcon(iconState,message.getByteArrValue());
}
}
public void initAfterConnectionQuerySend() throws SevereException
public void initAfterConnectionQuerySend() throws SevereException
{
{
logger.info("Asking client details ...");
logger.info("Asking client details ...");
sendMessage(new Message("get_client_details"));
sendMessage(new Message("get_client_details"));
}
}
public void disconnect() throws SevereException {
public void disconnect() throws SevereException {
disconnect("");
disconnect("");
}
}
public void disconnect(String message) throws SevereException {
public void disconnect(String message) throws SevereException {
if(stop.get())
if(stop.get())
return;
return;
stop.set(true);
stop.set(true);
logger.info("Sending client disconnect message ...");
logger.info("Sending client disconnect message ...");
Message m = new Message("disconnect");
Message m = new Message("disconnect");
m.setStringValue(message);
m.setStringValue(message);
sendMessage(m);
sendMessage(m);
try
try
{
{
if(!socket.isClosed())
if(!socket.isClosed())
socket.close();
socket.close();
}
}
catch (IOException e)
catch (IOException e)
{
{
e.printStackTrace();
e.printStackTrace();
throw new SevereException("Unable to close socket");
throw new SevereException("Unable to close socket");
}
}
}
}
public synchronized void sendMessage(Message message) throws SevereException
public synchronized void sendMessage(Message message) throws SevereException
{
{
try
try
{
{
oos.writeObject(message);
oos.writeObject(message);
oos.flush();
oos.flush();
}
}
catch (IOException e)
catch (IOException e)
{
{
e.printStackTrace();
e.printStackTrace();
throw new SevereException("Unable to write to io Stream!");
throw new SevereException("Unable to write to io Stream!");
}
}
}
}
public void clientDisconnected(Message message)
public void clientDisconnected(Message message)
{
{
stop.set(true);
stop.set(true);
String txt = "Disconnected!";
String txt = "Disconnected!";
String msg = message.getStringValue();
String msg = message.getStringValue();
if(!msg.isBlank())
if(!msg.isBlank())
txt = "Message : "+msg;
txt = "Message : "+msg;
new StreamPiAlert("Disconnected from "+getClient().getNickName()+".", txt, StreamPiAlertType.WARNING).show();;
new StreamPiAlert("Disconnected from "+getClient().getNickName()+".", txt, StreamPiAlertType.WARNING).show();;
exitAndRemove();
exitAndRemove();
}
}
public void getProfilesFromClient() throws StreamPiException
public void getProfilesFromClient() throws StreamPiException
{
{
logger.info("Asking client to send profiles ...");
logger.info("Asking client to send profiles ...");
sendMessage(new Message("get_profiles"));
sendMessage(new Message("get_profiles"));
}
}
public void getThemesFromClient() throws StreamPiException
public void getThemesFromClient() throws StreamPiException
{
{
logger.info("Asking clients to send themes ...");
logger.info("Asking clients to send themes ...");
sendMessage(new Message("get_themes"));
sendMessage(new Message("get_themes"));
}
}
public void registerThemes(Message message)
public void registerThemes(Message message)
{
{
String[] r = message.getStringArrValue();
String[] r = message.getStringArrValue();
for(int i =0; i<(r.length);i+=4)
for(int i =0; i<(r.length);i+=4)
{
{
ClientTheme clientTheme = new ClientTheme(
ClientTheme clientTheme = new ClientTheme(
r[i],
r[i],
r[i+1],
r[i+1],
r[i+2],
r[i+2],
r[i+3]
r[i+3]
);
);
try
try
{
{
getClient().addTheme(clientTheme);
getClient().addTheme(clientTheme);
}
}
catch (CloneNotSupportedException e)
catch (CloneNotSupportedException e)
{
{
logger.log(Level.SEVERE, e.getMessage());
logger.log(Level.SEVERE, e.getMessage());
e.printStackTrace();
e.printStackTrace();
}
}
}
}
}
}
public void registerProfilesFromClient(Message message) throws StreamPiException
public void registerProfilesFromClient(Message message) throws StreamPiException
{
{
logger.info("Registering profiles ...");
logger.info("Registering profiles ...");
String[] r = message.getStringArrValue();
String[] r = message.getStringArrValue();
for (String profileID : r) {
for (String profileID : r) {
getProfileDetailsFromClient(profileID);
getProfileDetailsFromClient(profileID);
}
}
}
}
public void getProfileDetailsFromClient(String ID) throws StreamPiException
public void getProfileDetailsFromClient(String ID) throws StreamPiException
{
{
logger.info("Asking client to send details of profile : "+ID);
logger.info("Asking client to send details of profile : "+ID);
Message message = new Message("get_profile_details");
Message message = new Message("get_profile_details");
message.setStringValue(ID);
message.setStringValue(ID);
sendMessage(message);
sendMessage(message);
}
}
public void registerProfileDetailsFromClient(Message message)
public void registerProfileDetailsFromClient(Message message)
{
{
String[] r = message.getStringArrValue();
String[] r = message.getStringArrValue();
String ID = r[0];
String ID = r[0];
logger.info("Registering details for profile : "+ID);
logger.info("Registering details for profile : "+ID);
String name = r[1];
String name = r[1];
int rows = Integer.parseInt(r[2]);
int rows = Integer.parseInt(r[2]);
int cols = Integer.parseInt(r[3]);
int cols = Integer.parseInt(r[3]);
int actionSize = Integer.parseInt(r[4]);
int actionSize = Integer.parseInt(r[4]);
int actionGap = Integer.parseInt(r[5]);
int actionGap = Integer.parseInt(r[5]);
ClientProfile clientProfile = new ClientProfile(name, ID, rows, cols, actionSize, actionGap);
ClientProfile clientProfile = new ClientProfile(name, ID, rows, cols, actionSize, actionGap);
logger.info("Added client profile "+clientProfile.getName());
logger.info("Added client profile "+clientProfile.getName());
try
try
{
{
getClient().addProfile(clientProfile);
getClient().addProfile(clientProfile);
}
}
catch (CloneNotSupportedException e)
catch (CloneNotSupportedException e)
{
{
logger.severe(e.getMessage());
logger.severe(e.getMessage());
e.printStackTrace();
e.printStackTrace();
}
}
serverListener.clearTemp();
serverListener.clearTemp();
}
}
public synchronized void registerActionToProfile(Message message) throws StreamPiException
public synchronized void registerActionToProfile(Message message) throws StreamPiException
{
{
String[] r = message.getStringArrValue();
String[] r = message.getStringArrValue();
String profileID = r[0];
String profileID = r[0];
String ID = r[1];
String ID = r[1];
ActionType actionType = ActionType.valueOf(r[2]);
ActionType actionType = ActionType.valueOf(r[2]);
//3 - Version
//3 - Version
//4 - ModuleName
//4 - ModuleName
//display
//display
String bgColorHex = r[5];
String bgColorHex = r[5];
//icon
//icon
String[] allIconStateNames = r[6].split("::");
String[] allIconStateNames = r[6].split("::");
String defaultIconState = r[7];
String defaultIconState = r[7];
//text
//text
boolean isShowDisplayText = r[8].equals("true");
boolean isShowDisplayText = r[8].equals("true");
String displayFontColor = r[9];
String displayFontColor = r[9];
String displayText = r[10];
String displayText = r[10];
DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(r[11]);
DisplayTextAlignment displayTextAlignment = DisplayTextAlignment.valueOf(r[11]);
//location
//location
String row = r[12];
String row = r[12];
String col = r[13];
String col = r[13];
Location location = new Location(Integer.parseInt(row), Integer.parseInt(col));
Location location = new Location(Integer.parseInt(row), Integer.parseInt(col));
Action action = new Action(ID, actionType);
Action action = new Action(ID, actionType);
action.setBgColourHex(bgColorHex);
action.setBgColourHex(bgColorHex);
action.setCurrentIconState(defaultIconState);
action.setCurrentIconState(defaultIconState);
action.setShowDisplayText(isShowDisplayText);
action.setShowDisplayText(isShowDisplayText);
action.setDisplayTextFontColourHex(displayFontColor);
action.setDisplayTextFontColourHex(displayFontColor);
action.setDisplayText(displayText);
action.setDisplayText(displayText);
action.setDisplayTextAlignment(displayTextAlignment);
action.setDisplayTextAlignment(displayTextAlignment);
action.setLocation(location);
action.setLocation(location);
String root = r[14];
String root = r[14];
action.setParent(root);
action.setParent(root);
action.setDelayBeforeExecuting(Integer.parseInt(r[15]));
action.setDelayBeforeExecuting(Integer.parseInt(r[15]));
//client properties
//client properties
int clientPropertiesSize = Integer.parseInt(r[16]);
int clientPropertiesSize = Integer.parseInt(r[16]);
ClientProperties clientProperties = new ClientProperties();
ClientProperties clientProperties = new ClientProperties();
if(actionType == ActionType.FOLDER)
if(actionType == ActionType.FOLDER)
clientProperties.setDuplicatePropertyAllowed(true);
clientProperties.setDuplicatePropertyAllowed(true);
for(int i = 17;i<((clientPropertiesSize*2) + 17); i+=2)
for(int i = 17;i<((clientPropertiesSize*2) + 17); i+=2)
{
{
Property property = new Property(r[i], Type.STRING);
Property property = new Property(r[i], Type.STRING);
property.setRawValue(r[i+1]);
property.setRawValue(r[i+1]);
clientProperties.addProperty(property);
clientProperties.addProperty(property);
}
}
action.setClientProperties(clientProperties);
action.setClientProperties(clientProperties);
action.setModuleName(r[4]);
action.setModuleName(r[4]);
//set up action
//set up action
//action toBeAdded = null;
//action toBeAdded = null;
if(actionType == ActionType.NORMAL)
if(actionType == ActionType.NORMAL)
{
{
NormalAction actionCopy = NormalActionPlugins.getInstance().getPluginByModuleName(r[4]);
ExternalPlugin actionCopy = ExternalPlugins.getInstance().getPluginByModuleName(r[4]);
if(actionCopy == null)
if(actionCopy == null)
{
{
action.setInvalid(true);
action.setInvalid(true);
}
}
else
else
{
{
action.setVersion(new Version(r[3]));
action.setVersion(new Version(r[3]));
//action.setHelpLink(actionCopy.getHelpLink());
//action.setHelpLink(actionCopy.getHelpLink());
if(actionCopy.getVersion().getMajor() != action.getVersion().getMajor())
if(actionCopy.getVersion().getMajor() != action.getVersion().getMajor())
{
{
action.setInvalid(true);
action.setInvalid(true);
}
}
else
else
{
{
action.setName(actionCopy.getName());
action.setName(actionCopy.getName());
ClientProperties finalClientProperties = new ClientProperties();
ClientProperties finalClientProperties = new ClientProperties();
for(Property property : actionCopy.getClientProperties().get())
for(Property property : actionCopy.getClientProperties().get())
{
{
for(int i = 0;i<action.getClientProperties().getSize();i++)
for(int i = 0;i<action.getClientProperties().getSize();i++)
{
{
Property property1 = action.getClientProperties().get().get(i);
Property property1 = action.getClientProperties().get().get(i);
if (property.getName().equals(property1.getName()))
if (property.getName().equals(property1.getName()))
{
{
property.setRawValue(property1.getRawValue());
property.setRawValue(property1.getRawValue());
finalClientProperties.addProperty(property);
finalClientProperties.addProperty(property);
}
}
}
}
}
}
action.setClientProperties(finalClientProperties);
action.setClientProperties(finalClientProperties);
}
}
}
}
}
}
try
try
{
{
getClient().getProfileByID(profileID).addAction(action);
getClient().getProfileByID(profileID).addAction(action);
}
}
catch (CloneNotSupportedException e)
catch (CloneNotSupportedException e)
{
{
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleMinorException(new MinorException("action", "Unable to clone"));
exceptionAndAlertHandler.handleMinorException(new MinorException("action", "Unable to clone"));
}
}
}
}
public void saveActionDetails(String profileID, Action action) throws SevereException
public void saveActionDetails(String profileID, Action action) throws SevereException
{
{
ArrayList<String> a = new ArrayList<>();
ArrayList<String> a = new ArrayList<>();
a.add(profileID);
a.add(profileID);
a.add(action.getID());
a.add(action.getID());
a.add(action.getActionType()+"");
a.add(action.getActionType()+"");
if(action.getActionType() == ActionType.NORMAL)
if(action.getActionType() == ActionType.NORMAL)
{
{
a.add(action.getVersion().getText());
a.add(action.getVersion().getText());
System.out.println("VERSION :sdd "+action.getVersion().getText());
System.out.println("VERSION :sdd "+action.getVersion().getText());
}
}
else
else
{
{
a.add("no");
a.add("no");
}
}
if(action.getActionType() == ActionType.NORMAL)
if(action.getActionType() == ActionType.NORMAL)
{
{
a.add(action.getModuleName());
a.add(action.getModuleName());
}
}
else
else
{
{
a.add("nut");
a.add("nut");
}
}
//display
//display
a.add(action.getBgColourHex());
a.add(action.getBgColourHex());
//icon
//icon
StringBuilder allIconStatesNames = new StringBuilder();
StringBuilder allIconStatesNames = new StringBuilder();
for(String eachState : action.getIcons().keySet())
for(String eachState : action.getIcons().keySet())
{
{
allIconStatesNames.append(eachState).append("::");
allIconStatesNames.append(eachState).append("::");
}
}
a.add(allIconStatesNames.toString());
a.add(allIconStatesNames.toString());
a.add(action.getCurrentIconState());
a.add(action.getCurrentIconState());
//text
//text
a.add(action.isShowDisplayText()+"");
a.add(action.isShowDisplayText()+"");
a.add(action.getDisplayTextFontColourHex());
a.add(action.getDisplayTextFontColourHex());
a.add(action.getDisplayText());
a.add(action.getDisplayText());
a.add(action.getDisplayTextAlignment()+"");
a.add(action.getDisplayTextAlignment()+"");
//location
//location
if(action.getLocation() == null)
if(action.getLocation() == null)
{
{
a.add("-1");
a.add("-1");
a.add("-1");
a.add("-1");
}
}
else
else
{
{
a.add(action.getLocation().getRow()+"");
a.add(action.getLocation().getRow()+"");
a.add(action.getLocation().getCol()+"");
a.add(action.getLocation().getCol()+"");
}
}
a.add(action.getParent());
a.add(action.getParent());
a.add(action.getDelayBeforeExecuting()+"");
a.add(action.getDelayBeforeExecuting()+"");
//client properties
//client properties
ClientProperties clientProperties = action.getClientProperties();
ClientProperties clientProperties = action.getClientProperties();
a.add(clientProperties.getSize()+"");
a.add(clientProperties.getSize()+"");
for(Property property : clientProperties.get())
for(Property property : clientProperties.get())
{
{
a.add(property.getName());
a.add(property.getName());
a.add(property.getRawValue());
a.add(property.getRawValue());
}
}
Message message = new Message("save_action_details");
Message message = new Message("save_action_details");
String[] x = new String[a.size()];
String[] x = new String[a.size()];
x = a.toArray(x);
x = a.toArray(x);
message.setStringArrValue(x);
message.setStringArrValue(x);
sendMessage(message);
sendMessage(message);
}
}
public void deleteAction(String profileID, String actionID) throws SevereException
public void deleteAction(String profileID, String actionID) throws SevereException
{
{
Message message = new Message("delete_action");
Message message = new Message("delete_action");
message.setStringArrValue(profileID, actionID);
message.setStringArrValue(profileID, actionID);
sendMessage(message);
sendMessage(message);
}
}
public void saveClientDetails(String clientNickname, String defaultProfileID,
public void saveClientDetails(String clientNickname, String defaultProfileID,
String defaultThemeFullName) throws SevereException
String defaultThemeFullName) throws SevereException
{
{
Message message = new Message("save_client_details");
Message message = new Message("save_client_details");
message.setStringArrValue(
message.setStringArrValue(
clientNickname,
clientNickname,
defaultProfileID,
defaultProfileID,
defaultThemeFullName
defaultThemeFullName
);
);
sendMessage(message);
sendMessage(message);
client.setNickName(clientNickname);
client.setNickName(clientNickname);
client.setDefaultProfileID(defaultProfileID);
client.setDefaultProfileID(defaultProfileID);
client.setDefaultThemeFullName(defaultThemeFullName);
client.setDefaultThemeFullName(defaultThemeFullName);
}
}
public void saveProfileDetails(ClientProfile clientProfile) throws SevereException, CloneNotSupportedException {
public void saveProfileDetails(ClientProfile clientProfile) throws SevereException, CloneNotSupportedException {
if(client.getProfileByID(clientProfile.getID()) !=null)
if(client.getProfileByID(clientProfile.getID()) !=null)
{
{
client.getProfileByID(clientProfile.getID()).setName(clientProfile.getName());
client.getProfileByID(clientProfile.getID()).setName(clientProfile.getName());
client.getProfileByID(clientProfile.getID()).setRows(clientProfile.getRows());
client.getProfileByID(clientProfile.getID()).setRows(clientProfile.getRows());
client.getProfileByID(clientProfile.getID()).setCols(clientProfile.getCols());
client.getProfileByID(clientProfile.getID()).setCols(clientProfile.getCols());
client.getProfileByID(clientProfile.getID()).setActionSize(clientProfile.getActionSize());
client.getProfileByID(clientProfile.getID()).setActionSize(clientProfile.getActionSize());
client.getProfileByID(clientProfile.getID()).setActionGap(clientProfile.getActionGap());
client.getProfileByID(clientProfile.getID()).setActionGap(clientProfile.getActionGap());
}
}
else
else
client.addProfile(clientProfile);
client.addProfile(clientProfile);
Message message = new Message("save_client_profile");
Message message = new Message("save_client_profile");
message.setStringArrValue(
message.setStringArrValue(
clientProfile.getID(),
clientProfile.getID(),
clientProfile.getName(),
clientProfile.getName(),
clientProfile.getRows()+"",
clientProfile.getRows()+"",
clientProfile.getCols()+"",
clientProfile.getCols()+"",
clientProfile.getActionSize()+"",
clientProfile.getActionSize()+"",
clientProfile.getActionGap()+""
clientProfile.getActionGap()+""
);
);
sendMessage(message);
sendMessage(message);
}
}
public void deleteProfile(String ID) throws SevereException
public void deleteProfile(String ID) throws SevereException
{
{
Message message = new Message("delete_profile");
Message message = new Message("delete_profile");
message.setStringValue(ID);
message.setStringValue(ID);
sendMessage(message);
sendMessage(message);
}
}
public void actionClicked(Message message)
public void actionClicked(Message message)
{
{
try
try
{
{
String[] r = message.getStringArrValue();
String[] r = message.getStringArrValue();
String profileID = r[0];
String profileID = r[0];
String actionID = r[1];
String actionID = r[1];
boolean toggle = r[2].equals("true");
boolean toggle = r[2].equals("true");
Action action = client.getProfileByID(profileID).getActionByID(actionID);
Action action = client.getProfileByID(profileID).getActionByID(actionID);
if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
if(action.getActionType() == ActionType.NORMAL || action.getActionType() == ActionType.TOGGLE)
{
{
NormalAction original = NormalActionPlugins.getInstance().getPluginByModuleName(
ExternalPlugin original = ExternalPlugins.getInstance().getPluginByModuleName(
action.getModuleName()
action.getModuleName()
);
);
if(original == null)
if(original == null)
{
{
throw new MinorException(
throw new MinorException(
"The action isn't installed on the server."
"The action isn't installed on the server."
);
);
}
}
NormalAction normalAction = original.clone();
ExternalPlugin externalPlugin = original.clone();
normalAction.setLocation(action.getLocation());
externalPlugin.setLocation(action.getLocation());
normalAction.setDisplayText(action.getDisplayText());
externalPlugin.setDisplayText(action.getDisplayText());
normalAction.setID(actionID);
externalPlugin.setID(actionID);
normalAction.setDelayBeforeExecuting(action.getDelayBeforeExecuting());
externalPlugin.setDelayBeforeExecuting(action.getDelayBeforeExecuting());
externalPlugin.setClientProperties(action.getClientProperties());
normalAction.setClientProperties(action.getClientProperties());
new Thread(new Task<Void>() {
new Thread(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
try
try
{
{
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2 "+normalAction.getDelayBeforeExecuting());
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2 "+externalPlugin.getDelayBeforeExecuting());
Thread.sleep(normalAction.getDelayBeforeExecuting());
Thread.sleep(externalPlugin.getDelayBeforeExecuting());
if(normalAction instanceof ToggleAction)
if(externalPlugin instanceof ToggleAction)
{
{
boolean result = serverListener.onToggleActionClicked((ToggleAction) normalAction, toggle);
boolean result = serverListener.onToggleActionClicked((ToggleAction) externalPlugin, toggle);
if(!result)
if(!result)
{
{
sendActionFailed(profileID, actionID);
sendActionFailed(profileID, actionID);
}
}
}
}
else
else
{
{
boolean result = serverListener.onNormalActionClicked(normalAction);
boolean result = serverListener.onNormalActionClicked((NormalAction) externalPlugin);
if(!result)
if(!result)
{
{
sendActionFailed(profileID, actionID);
sendActionFailed(profileID, actionID);
}
}
}
}
}
}
catch (SevereException e)
catch (SevereException e)
{
{
exceptionAndAlertHandler.handleSevereException(e);
exceptionAndAlertHandler.handleSevereException(e);
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
}
}
return null;
return null;
}
}
}).start();
}).start();
}
}
} catch (Exception e) {
} catch (Exception e) {
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleMinorException(new MinorException(e.getMessage()));
exceptionAndAlertHandler.handleMinorException(new MinorException(e.getMessage()));
}
}
}
}
public void sendActionFailed(String profileID, String actionID) throws SevereException {
public void sendActionFailed(String profileID, String actionID) throws SevereException {
logger.info("Sending failed status ...");
logger.info("Sending failed status ...");
Message message = new Message("action_failed");
Message message = new Message("action_failed");
message.setStringArrValue(profileID, actionID);
message.setStringArrValue(profileID, actionID);
sendMessage(message);
sendMessage(message);
}
}
}
}
package com.stream_pi.server.controller;
package com.stream_pi.server.controller;
import com.stream_pi.action_api.action.ServerConnection;
import com.stream_pi.action_api.action.ServerConnection;
import com.stream_pi.action_api.action.PropertySaver;
import com.stream_pi.action_api.action.PropertySaver;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.action_api.normalaction.ToggleAction;
import com.stream_pi.action_api.normalaction.ToggleAction;
import com.stream_pi.server.Main;
import com.stream_pi.server.Main;
import com.stream_pi.server.action.NormalActionPlugins;
import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.server.connection.ClientConnections;
import com.stream_pi.server.connection.ClientConnections;
import com.stream_pi.server.connection.MainServer;
import com.stream_pi.server.connection.MainServer;
import com.stream_pi.server.io.Config;
import com.stream_pi.server.io.Config;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.info.ServerInfo;
import com.stream_pi.server.window.Base;
import com.stream_pi.server.window.Base;
import com.stream_pi.server.window.dashboard.DonatePopupContent;
import com.stream_pi.server.window.dashboard.DonatePopupContent;
import com.stream_pi.server.window.firsttimeuse.FirstTimeUse;
import com.stream_pi.server.window.firsttimeuse.FirstTimeUse;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlert;
import com.stream_pi.util.alert.StreamPiAlertListener;
import com.stream_pi.util.alert.StreamPiAlertListener;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.alert.StreamPiAlertType;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.exception.SevereException;
import com.stream_pi.util.iohelper.IOHelper;
import javafx.animation.Interpolator;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.concurrent.Task;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import javafx.stage.WindowEvent;
import java.awt.SystemTray;
import java.awt.SystemTray;
import javafx.util.Duration;
import javafx.util.Duration;
import java.awt.Toolkit;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.TrayIcon;
import java.awt.PopupMenu;
import java.awt.PopupMenu;
import java.awt.MenuItem;
import java.awt.MenuItem;
import java.io.File;
import java.net.Inet4Address;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Enumeration;
import java.util.Random;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Level;
public class Controller extends Base implements PropertySaver, ServerConnection
public class Controller extends Base implements PropertySaver, ServerConnection
{
{
MainServer mainServer;
MainServer mainServer;
public void setupDashWindow() throws SevereException
public void setupDashWindow() throws SevereException
{
{
try
try
{
{
StringBuilder ips = new StringBuilder();
StringBuilder ips = new StringBuilder();
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
while(e.hasMoreElements())
while(e.hasMoreElements())
{
{
NetworkInterface n = e.nextElement();
NetworkInterface n = e.nextElement();
Enumeration<InetAddress> ee = n.getInetAddresses();
Enumeration<InetAddress> ee = n.getInetAddresses();
while (ee.hasMoreElements())
while (ee.hasMoreElements())
{
{
InetAddress i = ee.nextElement();
InetAddress i = ee.nextElement();
String hostAddress = i.getHostAddress();
String hostAddress = i.getHostAddress();
if(i instanceof Inet4Address)
if(i instanceof Inet4Address)
{
{
ips.append(hostAddress);
ips.append(hostAddress);
if(e.hasMoreElements())
if(e.hasMoreElements())
ips.append(" / ");
ips.append(" / ");
}
}
}
}
}
}
getStage().setTitle("Stream-Pi Server - IP(s): "+ips.toString()+" | Port: "+ Config.getInstance().getPort()); //Sets title
getStage().setTitle("Stream-Pi Server - IP(s): "+ips.toString()+" | Port: "+ Config.getInstance().getPort()); //Sets title
getStage().setOnCloseRequest(this::onCloseRequest);
getStage().setOnCloseRequest(this::onCloseRequest);
}
}
catch (Exception e)
catch (Exception e)
{
{
e.printStackTrace();
e.printStackTrace();
throw new SevereException(e.getMessage());
throw new SevereException(e.getMessage());
}
}
}
}
@Override
@Override
public void init()
public void init()
{
{
try {
try {
initBase();
initBase();
setupDashWindow();
setupDashWindow();
setupSettingsWindowsAnimations();
setupSettingsWindowsAnimations();
NormalActionPlugins.getInstance().setPropertySaver(this);
ExternalPlugins.getInstance().setPropertySaver(this);
NormalActionPlugins.getInstance().setServerConnection(this);
ExternalPlugins.getInstance().setServerConnection(this);
getDashboardPane().getPluginsPane().getSettingsButton().setOnAction(event -> {
getDashboardPane().getPluginsPane().getSettingsButton().setOnAction(event -> {
openSettingsTimeLine.play();
openSettingsTimeLine.play();
});
});
getSettingsPane().getCloseButton().setOnAction(event -> {
getSettingsPane().getCloseButton().setOnAction(event -> {
closeSettingsTimeLine.play();
closeSettingsTimeLine.play();
});
});
getSettingsPane().getThemesSettings().setController(this);
getSettingsPane().getThemesSettings().setController(this);
mainServer = new MainServer(this, this);
mainServer = new MainServer(this, this);
if(getConfig().isFirstTimeUse())
if(getConfig().isFirstTimeUse())
{
{
Stage stage = new Stage();
Stage stage = new Stage();
Scene s = new Scene(new FirstTimeUse(this, this),
Scene s = new Scene(new FirstTimeUse(this, this),
getConfig().getStartupWindowWidth(), getConfig().getStartupWindowHeight());
getConfig().getStartupWindowWidth(), getConfig().getStartupWindowHeight());
stage.setResizable(false);
stage.setResizable(false);
stage.setScene(s);
stage.setScene(s);
stage.setTitle("Stream-Pi Server Setup");
stage.setTitle("Stream-Pi Server Setup");
stage.initModality(Modality.APPLICATION_MODAL);
stage.initModality(Modality.APPLICATION_MODAL);
stage.setOnCloseRequest(event->Platform.exit());
stage.setOnCloseRequest(event->Platform.exit());
stage.show();
stage.show();
}
}
else
else
{
{
if(getConfig().isAllowDonatePopup())
if(getConfig().isAllowDonatePopup())
{
{
if(new Random().nextInt(5) == 3)
if(new Random().nextInt(5) == 3)
new DonatePopupContent(getHostServices(), this).show();
new DonatePopupContent(getHostServices(), this).show();
}
}
othInit();
othInit();
}
}
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
}
}
@Override
@Override
public void othInit()
public void othInit()
{
{
try
try
{
{
if(ServerInfo.getInstance().isStartMinimised() && SystemTray.isSupported())
if(ServerInfo.getInstance().isStartMinimised() && SystemTray.isSupported())
minimiseApp();
minimiseApp();
else
else
getStage().show();
getStage().show();
}
}
catch(MinorException e)
catch(MinorException e)
{
{
handleMinorException(e);
handleMinorException(e);
}
}
new Thread(new Task<Void>() {
new Thread(new Task<Void>() {
@Override
@Override
protected Void call()
protected Void call()
{
{
try
try
{
{
getSettingsPane().getGeneralSettings().loadDataFromConfig();
getSettingsPane().getGeneralSettings().loadDataFromConfig();
//themes
//themes
getSettingsPane().getThemesSettings().setThemes(getThemes());
getSettingsPane().getThemesSettings().setThemes(getThemes());
getSettingsPane().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
getSettingsPane().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
getSettingsPane().getThemesSettings().loadThemes();
getSettingsPane().getThemesSettings().loadThemes();
//clients
//clients
getSettingsPane().getClientsSettings().loadData();
getSettingsPane().getClientsSettings().loadData();
try
try
{
{
//Plugins
//Plugins
Platform.runLater(()->{
Platform.runLater(()->{
getDashboardPane().getPluginsPane().clearData();
getDashboardPane().getPluginsPane().clearData();
getDashboardPane().getPluginsPane().loadOtherActions();
getDashboardPane().getPluginsPane().loadOtherActions();
});
});
NormalActionPlugins.setPluginsLocation(getConfig().getPluginsPath());
ExternalPlugins.setPluginsLocation(getConfig().getPluginsPath());
NormalActionPlugins.getInstance().init();
ExternalPlugins.getInstance().init();
Platform.runLater(()->getDashboardPane().getPluginsPane().loadData());
Platform.runLater(()->getDashboardPane().getPluginsPane().loadData());
getSettingsPane().getPluginsSettings().loadPlugins();
getSettingsPane().getPluginsSettings().loadPlugins();
}
}
catch (MinorException e)
catch (MinorException e)
{
{
getSettingsPane().getPluginsSettings().showPluginInitError();
getSettingsPane().getPluginsSettings().showPluginInitError();
handleMinorException(e);
handleMinorException(e);
}
}
//Server
//Server
mainServer.setPort(getConfig().getPort());
mainServer.setPort(getConfig().getPort());
mainServer.start();
mainServer.start();
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
return null;
return null;
}
}
}).start();
}).start();
}
}
private void setupSettingsWindowsAnimations()
private void setupSettingsWindowsAnimations()
{
{
Node settingsNode = getSettingsPane();
Node settingsNode = getSettingsPane();
Node dashboardNode = getDashboardPane();
Node dashboardNode = getDashboardPane();
openSettingsTimeLine = new Timeline();
openSettingsTimeLine = new Timeline();
openSettingsTimeLine.setCycleCount(1);
openSettingsTimeLine.setCycleCount(1);
openSettingsTimeLine.getKeyFrames().addAll(
openSettingsTimeLine.getKeyFrames().addAll(
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
0.0D, Interpolator.EASE_IN),
0.0D, Interpolator.EASE_IN),
new KeyValue(settingsNode.scaleXProperty(),
new KeyValue(settingsNode.scaleXProperty(),
1.1D, Interpolator.EASE_IN),
1.1D, Interpolator.EASE_IN),
new KeyValue(settingsNode.scaleYProperty(),
new KeyValue(settingsNode.scaleYProperty(),
1.1D, Interpolator.EASE_IN),
1.1D, Interpolator.EASE_IN),
new KeyValue(settingsNode.scaleZProperty(),
new KeyValue(settingsNode.scaleZProperty(),
1.1D, Interpolator.EASE_IN)),
1.1D, Interpolator.EASE_IN)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleXProperty(),
new KeyValue(settingsNode.scaleXProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleYProperty(),
new KeyValue(settingsNode.scaleYProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleZProperty(),
new KeyValue(settingsNode.scaleZProperty(),
1.0D, Interpolator.LINEAR)),
1.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleXProperty(),
new KeyValue(dashboardNode.scaleXProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleYProperty(),
new KeyValue(dashboardNode.scaleYProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleZProperty(),
new KeyValue(dashboardNode.scaleZProperty(),
1.0D, Interpolator.LINEAR)),
1.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
0.0D, Interpolator.LINEAR),
0.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleXProperty(),
new KeyValue(dashboardNode.scaleXProperty(),
0.9D, Interpolator.LINEAR),
0.9D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleYProperty(),
new KeyValue(dashboardNode.scaleYProperty(),
0.9D, Interpolator.LINEAR),
0.9D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleZProperty(),
new KeyValue(dashboardNode.scaleZProperty(),
0.9D, Interpolator.LINEAR))
0.9D, Interpolator.LINEAR))
);
);
openSettingsTimeLine.setOnFinished(event1 -> {
openSettingsTimeLine.setOnFinished(event1 -> {
settingsNode.toFront();
settingsNode.toFront();
});
});
closeSettingsTimeLine = new Timeline();
closeSettingsTimeLine = new Timeline();
closeSettingsTimeLine.setCycleCount(1);
closeSettingsTimeLine.setCycleCount(1);
closeSettingsTimeLine.getKeyFrames().addAll(
closeSettingsTimeLine.getKeyFrames().addAll(
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleXProperty(),
new KeyValue(settingsNode.scaleXProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleYProperty(),
new KeyValue(settingsNode.scaleYProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleZProperty(),
new KeyValue(settingsNode.scaleZProperty(),
1.0D, Interpolator.LINEAR)),
1.0D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(settingsNode.opacityProperty(),
new KeyValue(settingsNode.opacityProperty(),
0.0D, Interpolator.LINEAR),
0.0D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleXProperty(),
new KeyValue(settingsNode.scaleXProperty(),
1.1D, Interpolator.LINEAR),
1.1D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleYProperty(),
new KeyValue(settingsNode.scaleYProperty(),
1.1D, Interpolator.LINEAR),
1.1D, Interpolator.LINEAR),
new KeyValue(settingsNode.scaleZProperty(),
new KeyValue(settingsNode.scaleZProperty(),
1.1D, Interpolator.LINEAR)),
1.1D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(0.0D),
new KeyFrame(Duration.millis(0.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
0.0D, Interpolator.LINEAR),
0.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleXProperty(),
new KeyValue(dashboardNode.scaleXProperty(),
0.9D, Interpolator.LINEAR),
0.9D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleYProperty(),
new KeyValue(dashboardNode.scaleYProperty(),
0.9D, Interpolator.LINEAR),
0.9D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleZProperty(),
new KeyValue(dashboardNode.scaleZProperty(),
0.9D, Interpolator.LINEAR)),
0.9D, Interpolator.LINEAR)),
new KeyFrame(Duration.millis(90.0D),
new KeyFrame(Duration.millis(90.0D),
new KeyValue(dashboardNode.opacityProperty(),
new KeyValue(dashboardNode.opacityProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleXProperty(),
new KeyValue(dashboardNode.scaleXProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleYProperty(),
new KeyValue(dashboardNode.scaleYProperty(),
1.0D, Interpolator.LINEAR),
1.0D, Interpolator.LINEAR),
new KeyValue(dashboardNode.scaleZProperty(),
new KeyValue(dashboardNode.scaleZProperty(),
1.0D, Interpolator.LINEAR))
1.0D, Interpolator.LINEAR))
);
);
closeSettingsTimeLine.setOnFinished(event1 -> {
closeSettingsTimeLine.setOnFinished(event1 -> {
dashboardNode.toFront();
dashboardNode.toFront();
new Thread(new Task<Void>() {
new Thread(new Task<Void>() {
@Override
@Override
protected Void call() {
protected Void call() {
try {
try {
getSettingsPane().getClientsSettings().loadData();
getSettingsPane().getClientsSettings().loadData();
getSettingsPane().getGeneralSettings().loadDataFromConfig();
getSettingsPane().getGeneralSettings().loadDataFromConfig();
getSettingsPane().getPluginsSettings().loadPlugins();
getSettingsPane().getPluginsSettings().loadPlugins();
getSettingsPane().getThemesSettings().setThemes(getThemes());
getSettingsPane().getThemesSettings().setThemes(getThemes());
getSettingsPane().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
getSettingsPane().getThemesSettings().setCurrentThemeFullName(getCurrentTheme().getFullName());
getSettingsPane().getThemesSettings().loadThemes();
getSettingsPane().getThemesSettings().loadThemes();
getSettingsPane().setDefaultTabToGeneral();
getSettingsPane().setDefaultTabToGeneral();
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
catch (MinorException e)
catch (MinorException e)
{
{
handleMinorException(e);
handleMinorException(e);
}
}
return null;
return null;
}
}
}).start();
}).start();
});
});
}
}
private Timeline openSettingsTimeLine;
private Timeline openSettingsTimeLine;
private Timeline closeSettingsTimeLine;
private Timeline closeSettingsTimeLine;
public Controller(){
public Controller(){
mainServer = null;
mainServer = null;
}
}
public void onCloseRequest(WindowEvent event)
public void onCloseRequest(WindowEvent event)
{
{
try
try
{
{
if(Config.getInstance().getMinimiseToSystemTrayOnClose() &&
if(Config.getInstance().getMinimiseToSystemTrayOnClose() &&
SystemTray.isSupported())
SystemTray.isSupported())
{
{
minimiseApp();
minimiseApp();
event.consume();
event.consume();
return;
return;
}
}
getConfig().setStartupWindowSize(
getConfig().setStartupWindowSize(
getWidth(),
getWidth(),
getHeight()
getHeight()
);
);
getConfig().save();
getConfig().save();
onQuitApp();
onQuitApp();
NormalActionPlugins.getInstance().shutDownActions();
ExternalPlugins.getInstance().shutDownActions();
Platform.exit();
Platform.exit();
}
}
catch (SevereException e)
catch (SevereException e)
{
{
handleSevereException(e);
handleSevereException(e);
}
}
catch (MinorException e)
catch (MinorException e)
{
{
handleMinorException(e);
handleMinorException(e);
}
}
finally
finally
{
{
closeLogger();
closeLogger();
}
}
}
}
public void onQuitApp()
public void onQuitApp()
{
{
if(mainServer!=null)
if(mainServer!=null)
mainServer.stopListeningForConnections();
mainServer.stopListeningForConnections();
ClientConnections.getInstance().disconnectAll();
ClientConnections.getInstance().disconnectAll();
getLogger().info("Shutting down ...");
getLogger().info("Shutting down ...");
}
}
public void minimiseApp() throws MinorException
public void minimiseApp() throws MinorException
{
{
try
try
{
{
SystemTray systemTray = SystemTray.getSystemTray();
SystemTray systemTray = SystemTray.getSystemTray();
if(getTrayIcon() == null)
if(getTrayIcon() == null)
initIconTray(systemTray);
initIconTray(systemTray);
systemTray.add(getTrayIcon());
systemTray.add(getTrayIcon());
getStage().hide();
getStage().hide();
getStage().setOnShown(windowEvent -> {
getStage().setOnShown(windowEvent -> {
systemTray.remove(getTrayIcon());
systemTray.remove(getTrayIcon());
});
});
}
}
catch(Exception e)
catch(Exception e)
{
{
throw new MinorException(e.getMessage());
throw new MinorException(e.getMessage());
}
}
}
}
public void initIconTray(SystemTray systemTray)
public void initIconTray(SystemTray systemTray)
{
{
Platform.setImplicitExit(false);
Platform.setImplicitExit(false);
PopupMenu popup = new PopupMenu();
PopupMenu popup = new PopupMenu();
MenuItem exitItem = new MenuItem("Exit");
MenuItem exitItem = new MenuItem("Exit");
exitItem.addActionListener(l->{
exitItem.addActionListener(l->{
systemTray.remove(getTrayIcon());
systemTray.remove(getTrayIcon());
onQuitApp();
onQuitApp();
Platform.exit();
Platform.exit();
});
});
popup.add(exitItem);
popup.add(exitItem);
TrayIcon trayIcon = new TrayIcon(
TrayIcon trayIcon = new TrayIcon(
Toolkit.getDefaultToolkit().getImage(Main.class.getResource("app_icon.png")),
Toolkit.getDefaultToolkit().getImage(Main.class.getResource("app_icon.png")),
"Stream-Pi Server",
"Stream-Pi Server",
popup
popup
);
);
trayIcon.addActionListener(l-> Platform.runLater(()-> getStage().show()));
trayIcon.addActionListener(l-> Platform.runLater(()-> getStage().show()));
trayIcon.setImageAutoSize(true);
trayIcon.setImageAutoSize(true);
this.trayIcon = trayIcon;
this.trayIcon = trayIcon;
}
}
private TrayIcon trayIcon = null;
private TrayIcon trayIcon = null;
public TrayIcon getTrayIcon()
public TrayIcon getTrayIcon()
{
{
return trayIcon;
return trayIcon;
}
}
@Override
@Override
public void handleMinorException(MinorException e)
public void handleMinorException(MinorException e)
{
{
getLogger().log(Level.SEVERE, e.getMessage(), e);
getLogger().log(Level.SEVERE, e.getMessage(), e);
e.printStackTrace();
e.printStackTrace();
Platform.runLater(()-> new StreamPiAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.WARNING).show());
Platform.runLater(()-> new StreamPiAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.WARNING).show());
}
}
@Override
@Override
public void handleSevereException(SevereException e) {
public void handleSevereException(SevereException e) {
getLogger().log(Level.SEVERE, e.getMessage(), e);
getLogger().log(Level.SEVERE, e.getMessage(), e);
e.printStackTrace();
e.printStackTrace();
Platform.runLater(()->{
Platform.runLater(()->{
StreamPiAlert alert = new StreamPiAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.ERROR);
StreamPiAlert alert = new StreamPiAlert(e.getTitle(), e.getShortMessage(), StreamPiAlertType.ERROR);
alert.setOnClicked(new StreamPiAlertListener()
alert.setOnClicked(new StreamPiAlertListener()
{
{
@Override
@Override
public void onClick(String txt)
public void onClick(String txt)
{
{
onQuitApp();
onQuitApp();
Platform.exit();
Platform.exit();
}
}
});
});
alert.show();
alert.show();
});
});
}
}
@Override
@Override
public synchronized boolean onNormalActionClicked(NormalAction action) {
public synchronized boolean onNormalActionClicked(NormalAction action) {
try{
try{
getLogger().info("action "+action.getID()+" clicked!");
getLogger().info("action "+action.getID()+" clicked!");
action.onActionClicked();
action.onActionClicked();
return true;
return true;
}
}
catch (Exception e)
catch (Exception e)
{
{
//check if its windows UAC related
//check if its windows UAC related
if(e.getMessage().contains("operation requires elevation"))
if(e.getMessage().contains("operation requires elevation"))
{
{
handleMinorException(new MinorException(
handleMinorException(new MinorException(
"Action Execution Failed!",
"Action Execution Failed!",
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"This action requires higher UAC privileges. Re-launch Stream-Pi Server with 'Administrator Privileges' in order to run this command.")
"This action requires higher UAC privileges. Re-launch Stream-Pi Server with 'Administrator Privileges' in order to run this command.")
);
);
}
}
else
else
{
{
handleMinorException(new MinorException(
handleMinorException(new MinorException(
"Action Execution Failed!",
"Action Execution Failed!",
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Check stacktrace/log to know what exactly happened\n\nMessage : \n"+e.getMessage() )
"Check stacktrace/log to know what exactly happened\n\nMessage : \n"+e.getMessage() )
);
);
}
}
return false;
return false;
}
}
}
}
@Override
@Override
public boolean onToggleActionClicked(ToggleAction action, boolean toggle) {
public boolean onToggleActionClicked(ToggleAction action, boolean toggle) {
try{
try{
getLogger().info("action "+action.getID()+" clicked!");
getLogger().info("action "+action.getID()+" clicked!");
if(toggle)
if(toggle)
{
{
action.onToggleOn();
action.onToggleOn();
}
}
else
else
{
{
action.onToggleOff();
action.onToggleOff();
}
}
return true;
return true;
}
}
catch (Exception e)
catch (Exception e)
{
{
//check if its windows UAC related
//check if its windows UAC related
if(e.getMessage().contains("operation requires elevation"))
if(e.getMessage().contains("operation requires elevation"))
{
{
handleMinorException(new MinorException(
handleMinorException(new MinorException(
"Action Execution Failed!",
"Action Execution Failed!",
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"This action requires higher UAC privileges. Re-launch Stream-Pi Server with 'Administrator Privileges' in order to run this command.")
"This action requires higher UAC privileges. Re-launch Stream-Pi Server with 'Administrator Privileges' in order to run this command.")
);
);
}
}
else
else
{
{
handleMinorException(new MinorException(
handleMinorException(new MinorException(
"Action Execution Failed!",
"Action Execution Failed!",
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Error running action at ["+action.getLocation().getRow()+","+action.getLocation().getCol()+"] ("+action.getDisplayText()+")\n"+
"Check stacktrace/log to know what exactly happened\n\nMessage : \n"+e.getMessage() )
"Check stacktrace/log to know what exactly happened\n\nMessage : \n"+e.getMessage() )
);
);
}
}
return false;
return false;
}
}
}
}
@Override
@Override
public void clearTemp() {
public void clearTemp() {
Platform.runLater(() -> {
Platform.runLater(() -> {
getDashboardPane().getClientDetailsPane().refresh();
getDashboardPane().getClientDetailsPane().refresh();
getDashboardPane().getActionGridPane().clear();
getDashboardPane().getActionGridPane().clear();
getDashboardPane().getActionGridPane().setFreshRender(true);
getDashboardPane().getActionGridPane().setFreshRender(true);
getDashboardPane().getActionDetailsPane().clear();
getDashboardPane().getActionDetailsPane().clear();
getSettingsPane().getClientsSettings().loadData();
getSettingsPane().getClientsSettings().loadData();
});
});
}
}
@Override
@Override
public void saveServerProperties()
public void saveServerProperties()
{
{
try
try
{
{
NormalActionPlugins.getInstance().saveServerSettings();
ExternalPlugins.getInstance().saveServerSettings();
getSettingsPane().getPluginsSettings().loadPlugins();
getSettingsPane().getPluginsSettings().loadPlugins();
} catch (MinorException e) {
} catch (MinorException e) {
e.printStackTrace();
e.printStackTrace();
handleMinorException(e);
handleMinorException(e);
}
}
}
}
@Override
@Override
public void saveClientIcons() {
public void saveClientIcons() {
}
}
@Override
@Override
public com.stream_pi.util.platform.Platform getPlatform() {
public com.stream_pi.util.platform.Platform getPlatform() {
return ServerInfo.getInstance().getPlatform();
return ServerInfo.getInstance().getPlatform();
}
}
}
}
package com.stream_pi.server.window.dashboard;
package com.stream_pi.server.window.dashboard;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.Action;
import com.stream_pi.action_api.action.ActionType;
import com.stream_pi.action_api.action.ActionType;
import com.stream_pi.action_api.action.DisplayTextAlignment;
import com.stream_pi.action_api.action.DisplayTextAlignment;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.normalaction.ExternalPlugin;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.action_api.otheractions.CombineAction;
import com.stream_pi.action_api.otheractions.CombineAction;
import com.stream_pi.action_api.otheractions.FolderAction;
import com.stream_pi.action_api.otheractions.FolderAction;
import com.stream_pi.server.action.NormalActionPlugins;
import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.util.uihelper.SpaceFiller;
import com.stream_pi.util.uihelper.SpaceFiller;
import javafx.application.HostServices;
import javafx.application.HostServices;
import javafx.geometry.Insets;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Pos;
import javafx.scene.CacheHint;
import javafx.scene.CacheHint;
import javafx.scene.Node;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.image.ImageView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.*;
import javafx.scene.layout.*;
import org.kordamp.ikonli.javafx.FontIcon;
import org.kordamp.ikonli.javafx.FontIcon;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashMap;
public class PluginsPane extends VBox {
public class PluginsPane extends VBox {
private Button settingsButton;
private Button settingsButton;
public PluginsPane(HostServices hostServices)
public PluginsPane(HostServices hostServices)
{
{
setMinWidth(250);
setMinWidth(250);
setMaxWidth(350);
setMaxWidth(350);
getStyleClass().add("plugins_pane");
getStyleClass().add("plugins_pane");
setPadding(new Insets(10));
setPadding(new Insets(10));
this.hostServices = hostServices;
this.hostServices = hostServices;
initUI();
initUI();
}
}
private Accordion pluginsAccordion;
private Accordion pluginsAccordion;
public void initUI()
public void initUI()
{
{
pluginsAccordion = new Accordion();
pluginsAccordion = new Accordion();
pluginsAccordion.getStyleClass().add("plugins_pane_accordion");
pluginsAccordion.getStyleClass().add("plugins_pane_accordion");
pluginsAccordion.setCache(true);
pluginsAccordion.setCache(true);
settingsButton = new Button();
settingsButton = new Button();
settingsButton.getStyleClass().add("plugins_pane_settings_button");
settingsButton.getStyleClass().add("plugins_pane_settings_button");
FontIcon cog = new FontIcon("fas-cog");
FontIcon cog = new FontIcon("fas-cog");
settingsButton.setGraphic(cog);
settingsButton.setGraphic(cog);
HBox settingsHBox = new HBox(settingsButton);
HBox settingsHBox = new HBox(settingsButton);
settingsHBox.getStyleClass().add("plugins_pane_settings_button_parent");
settingsHBox.getStyleClass().add("plugins_pane_settings_button_parent");
settingsHBox.setAlignment(Pos.CENTER_RIGHT);
settingsHBox.setAlignment(Pos.CENTER_RIGHT);
Label pluginsLabel = new Label("Plugins");
Label pluginsLabel = new Label("Plugins");
pluginsLabel.getStyleClass().add("plugins_pane_top_label");
pluginsLabel.getStyleClass().add("plugins_pane_top_label");
getChildren().addAll(pluginsLabel, pluginsAccordion, SpaceFiller.vertical(), settingsHBox);
getChildren().addAll(pluginsLabel, pluginsAccordion, SpaceFiller.vertical(), settingsHBox);
}
}
public Button getSettingsButton()
public Button getSettingsButton()
{
{
return settingsButton;
return settingsButton;
}
}
public void clearData()
public void clearData()
{
{
pluginsAccordion.getPanes().clear();
pluginsAccordion.getPanes().clear();
}
}
public void loadData()
public void loadData()
{
{
HashMap<String, ArrayList<NormalAction>> sortedPlugins = NormalActionPlugins.getInstance().getSortedPlugins();
HashMap<String, ArrayList<ExternalPlugin>> sortedPlugins = ExternalPlugins.getInstance().getSortedPlugins();
for(String eachCategory : sortedPlugins.keySet())
for(String eachCategory : sortedPlugins.keySet())
{
{
VBox vBox = new VBox();
VBox vBox = new VBox();
vBox.getStyleClass().add("plugins_pane_each_plugin_box_parent");
vBox.getStyleClass().add("plugins_pane_each_plugin_box_parent");
TitledPane pane = new TitledPane(eachCategory, vBox);
TitledPane pane = new TitledPane(eachCategory, vBox);
pane.getStyleClass().add("plugins_pane_each_plugin_category_titled_pane");
pane.getStyleClass().add("plugins_pane_each_plugin_category_titled_pane");
for(NormalAction eachAction : sortedPlugins.get(eachCategory))
for(ExternalPlugin eachAction : sortedPlugins.get(eachCategory))
{
{
if(!eachAction.isVisibleInPluginsPane())
if(!eachAction.isVisibleInPluginsPane())
continue;
continue;
Button eachNormalActionPluginButton = new Button();
Button eachNormalActionPluginButton = new Button();
eachNormalActionPluginButton.getStyleClass().add("plugins_pane_each_plugin_button");
eachNormalActionPluginButton.getStyleClass().add("plugins_pane_each_plugin_button");
HBox.setHgrow(eachNormalActionPluginButton, Priority.ALWAYS);
HBox.setHgrow(eachNormalActionPluginButton, Priority.ALWAYS);
eachNormalActionPluginButton.setMaxWidth(Double.MAX_VALUE);
eachNormalActionPluginButton.setMaxWidth(Double.MAX_VALUE);
eachNormalActionPluginButton.setAlignment(Pos.CENTER_LEFT);
eachNormalActionPluginButton.setAlignment(Pos.CENTER_LEFT);
Node graphic = eachAction.getServerButtonGraphic();
Node graphic = eachAction.getServerButtonGraphic();
if(graphic == null)
if(graphic == null)
{
{
FontIcon cogs = new FontIcon("fas-cogs");
FontIcon cogs = new FontIcon("fas-cogs");
cogs.getStyleClass().add("plugins_pane_each_plugin_button_icon");
cogs.getStyleClass().add("plugins_pane_each_plugin_button_icon");
eachNormalActionPluginButton.setGraphic(cogs);
eachNormalActionPluginButton.setGraphic(cogs);
}
}
else
else
{
{
if(graphic instanceof FontIcon)
if(graphic instanceof FontIcon)
{
{
FontIcon fi = (FontIcon) graphic;
FontIcon fi = (FontIcon) graphic;
fi.getStyleClass().add("plugins_pane_each_plugin_button_icon");
fi.getStyleClass().add("plugins_pane_each_plugin_button_icon");
eachNormalActionPluginButton.setGraphic(fi);
eachNormalActionPluginButton.setGraphic(fi);
}
}
else if(graphic instanceof ImageView)
else if(graphic instanceof ImageView)
{
{
ImageView iv = (ImageView) graphic;
ImageView iv = (ImageView) graphic;
iv.getStyleClass().add("plugins_pane_each_plugin_button_imageview");
iv.getStyleClass().add("plugins_pane_each_plugin_button_imageview");
iv.setPreserveRatio(false);
iv.setPreserveRatio(false);
eachNormalActionPluginButton.setGraphic(iv);
eachNormalActionPluginButton.setGraphic(iv);
}
}
}
}
eachNormalActionPluginButton.setText(eachAction.getName());
eachNormalActionPluginButton.setText(eachAction.getName());
eachNormalActionPluginButton.setOnDragDetected(mouseEvent -> {
eachNormalActionPluginButton.setOnDragDetected(mouseEvent -> {
Dragboard db = eachNormalActionPluginButton.startDragAndDrop(TransferMode.ANY);
Dragboard db = eachNormalActionPluginButton.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
ClipboardContent content = new ClipboardContent();
content.put(Action.getDataFormat(), createFakeAction(eachAction, "Untitled action"));
content.put(Action.getDataFormat(), createFakeAction(eachAction, "Untitled action"));
db.setContent(content);
db.setContent(content);
mouseEvent.consume();
mouseEvent.consume();
});
});
HBox hBox = new HBox(eachNormalActionPluginButton);
HBox hBox = new HBox(eachNormalActionPluginButton);
hBox.getStyleClass().add("plugins_pane_each_plugin_box");
hBox.getStyleClass().add("plugins_pane_each_plugin_box");
hBox.setAlignment(Pos.TOP_LEFT);
hBox.setAlignment(Pos.TOP_LEFT);
HBox.setHgrow(eachNormalActionPluginButton, Priority.ALWAYS);
HBox.setHgrow(eachNormalActionPluginButton, Priority.ALWAYS);
if(eachAction.getHelpLink() != null) {
if(eachAction.getHelpLink() != null) {
Button helpButton = new Button();
Button helpButton = new Button();
helpButton.getStyleClass().add("plugins_pane_each_plugin_button_help_icon");
helpButton.getStyleClass().add("plugins_pane_each_plugin_button_help_icon");
FontIcon questionIcon = new FontIcon("fas-question");
FontIcon questionIcon = new FontIcon("fas-question");
questionIcon.getStyleClass().add("plugins_pane_each_plugin_button_help_button_icon");
questionIcon.getStyleClass().add("plugins_pane_each_plugin_button_help_button_icon");
helpButton.setGraphic(questionIcon);
helpButton.setGraphic(questionIcon);
helpButton.setOnAction(event -> hostServices.showDocument(eachAction.getHelpLink()));
helpButton.setOnAction(event -> hostServices.showDocument(eachAction.getHelpLink()));
hBox.getChildren().add(helpButton);
hBox.getChildren().add(helpButton);
}
}
vBox.getChildren().add(hBox);
vBox.getChildren().add(hBox);
}
}
if(vBox.getChildren().size() > 0)
if(vBox.getChildren().size() > 0)
pluginsAccordion.getPanes().add(pane);
pluginsAccordion.getPanes().add(pane);
}
}
}
}
private HostServices hostServices;
private HostServices hostServices;
public Action createFakeAction(Action action, String displayText)
public Action createFakeAction(Action action, String displayText)
{
{
Action newAction = new Action(action.getActionType());
Action newAction = new Action(action.getActionType());
if(action.getActionType() == ActionType.NORMAL)
if(action.getActionType() == ActionType.NORMAL)
{
{
newAction.setModuleName(action.getModuleName());
newAction.setModuleName(action.getModuleName());
newAction.setVersion(action.getVersion());
newAction.setVersion(action.getVersion());
newAction.setName(action.getName());
newAction.setName(action.getName());
}
}
newAction.setClientProperties(action.getClientProperties());
newAction.setClientProperties(action.getClientProperties());
for(Property property : newAction.getClientProperties().get())
for(Property property : newAction.getClientProperties().get())
{
{
if(property.getType() == Type.STRING || property.getType() == Type.INTEGER || property.getType() == Type.DOUBLE)
if(property.getType() == Type.STRING || property.getType() == Type.INTEGER || property.getType() == Type.DOUBLE)
property.setRawValue(property.getDefaultRawValue());
property.setRawValue(property.getDefaultRawValue());
}
}
// newAction.setLocation(location);
// newAction.setLocation(location);
newAction.setIDRandom();
newAction.setIDRandom();
newAction.setShowDisplayText(true);
newAction.setShowDisplayText(true);
newAction.setDisplayText(displayText);
newAction.setDisplayText(displayText);
newAction.setDisplayTextAlignment(DisplayTextAlignment.CENTER);
newAction.setDisplayTextAlignment(DisplayTextAlignment.CENTER);
newAction.setShowIcon(false);
newAction.setHasIcon(false);
//action.setParent(root);
//action.setParent(root);
newAction.setBgColourHex("");
newAction.setBgColourHex("");
newAction.setDisplayTextFontColourHex("");
newAction.setDisplayTextFontColourHex("");
return newAction;
return newAction;
}
}
public void loadOtherActions()
public void loadOtherActions()
{
{
VBox vBox = new VBox();
VBox vBox = new VBox();
vBox.getStyleClass().add("plugins_pane_each_plugin_box_parent");
vBox.getStyleClass().add("plugins_pane_each_plugin_box_parent");
Button folderActionButton = new Button("Folder");
Button folderActionButton = new Button("Folder");
folderActionButton.getStyleClass().add("plugins_pane_each_plugin_button");
folderActionButton.getStyleClass().add("plugins_pane_each_plugin_button");
folderActionButton.setMaxWidth(Double.MAX_VALUE);
folderActionButton.setMaxWidth(Double.MAX_VALUE);
folderActionButton.setAlignment(Pos.CENTER_LEFT);
folderActionButton.setAlignment(Pos.CENTER_LEFT);
FontIcon folder = new FontIcon("fas-folder");
FontIcon folder = new FontIcon("fas-folder");
folderActionButton.setGraphic(folder);
folderActionButton.setGraphic(folder);
folderActionButton.setOnDragDetected(mouseEvent -> {
folderActionButton.setOnDragDetected(mouseEvent -> {
Dragboard db = folderActionButton.startDragAndDrop(TransferMode.ANY);
Dragboard db = folderActionButton.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
ClipboardContent content = new ClipboardContent();
content.put(Action.getDataFormat(), createFakeAction(new FolderAction(), "Untitled Folder"));
content.put(Action.getDataFormat(), createFakeAction(new FolderAction(), "Untitled Folder"));
db.setContent(content);
db.setContent(content);
mouseEvent.consume();
mouseEvent.consume();
});
});
Button combineActionButton = new Button("Combine");
Button combineActionButton = new Button("Combine");
combineActionButton.getStyleClass().add("plugins_pane_each_plugin_button");
combineActionButton.getStyleClass().add("plugins_pane_each_plugin_button");
combineActionButton.setMaxWidth(Double.MAX_VALUE);
combineActionButton.setMaxWidth(Double.MAX_VALUE);
combineActionButton.setAlignment(Pos.CENTER_LEFT);
combineActionButton.setAlignment(Pos.CENTER_LEFT);
FontIcon list = new FontIcon("fas-list");
FontIcon list = new FontIcon("fas-list");
combineActionButton.setGraphic(list);
combineActionButton.setGraphic(list);
combineActionButton.setOnDragDetected(mouseEvent -> {
combineActionButton.setOnDragDetected(mouseEvent -> {
Dragboard db = combineActionButton.startDragAndDrop(TransferMode.ANY);
Dragboard db = combineActionButton.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
ClipboardContent content = new ClipboardContent();
content.put(Action.getDataFormat(), createFakeAction(new CombineAction(), "Untitled Combine"));
content.put(Action.getDataFormat(), createFakeAction(new CombineAction(), "Untitled Combine"));
db.setContent(content);
db.setContent(content);
mouseEvent.consume();
mouseEvent.consume();
});
});
HBox.setHgrow(folderActionButton, Priority.ALWAYS);
HBox.setHgrow(folderActionButton, Priority.ALWAYS);
HBox h1 = new HBox(folderActionButton);
HBox h1 = new HBox(folderActionButton);
h1.getStyleClass().add("plugins_pane_each_plugin_box");
h1.getStyleClass().add("plugins_pane_each_plugin_box");
HBox.setHgrow(combineActionButton, Priority.ALWAYS);
HBox.setHgrow(combineActionButton, Priority.ALWAYS);
HBox h2 = new HBox(combineActionButton);
HBox h2 = new HBox(combineActionButton);
h2.getStyleClass().add("plugins_pane_each_plugin_box");
h2.getStyleClass().add("plugins_pane_each_plugin_box");
vBox.getChildren().addAll(h1, h2);
vBox.getChildren().addAll(h1, h2);
TitledPane pane = new TitledPane("Stream-Pi", vBox);
TitledPane pane = new TitledPane("Stream-Pi", vBox);
pane.getStyleClass().add("plugins_pane_each_plugin_category_titled_pane");
pane.getStyleClass().add("plugins_pane_each_plugin_category_titled_pane");
pluginsAccordion.getPanes().add(pane);
pluginsAccordion.getPanes().add(pane);
pluginsAccordion.setCache(true);
pluginsAccordion.setCache(true);
pluginsAccordion.setCacheHint(CacheHint.SPEED);
pluginsAccordion.setCacheHint(CacheHint.SPEED);
}
}
}
}
package com.stream_pi.server.window.settings;
package com.stream_pi.server.window.settings;
import com.stream_pi.action_api.normalaction.ExternalPlugin;
import com.stream_pi.server.uipropertybox.UIPropertyBox;
import com.stream_pi.server.uipropertybox.UIPropertyBox;
import com.stream_pi.action_api.actionproperty.property.ControlType;
import com.stream_pi.action_api.actionproperty.property.ControlType;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Property;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.actionproperty.property.Type;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.action_api.normalaction.NormalAction;
import com.stream_pi.server.action.NormalActionPlugins;
import com.stream_pi.server.action.ExternalPlugins;
import com.stream_pi.server.connection.ServerListener;
import com.stream_pi.server.connection.ServerListener;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.server.window.ExceptionAndAlertHandler;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.exception.MinorException;
import com.stream_pi.util.uihelper.SpaceFiller;
import com.stream_pi.util.uihelper.SpaceFiller;
import org.kordamp.ikonli.javafx.FontIcon;
import org.kordamp.ikonli.javafx.FontIcon;
import javafx.application.HostServices;
import javafx.application.HostServices;
import javafx.application.Platform;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.layout.VBox;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.List;
import java.util.List;
import java.util.logging.Logger;
import java.util.logging.Logger;
public class PluginsSettings extends VBox {
public class PluginsSettings extends VBox {
private VBox pluginsSettingsVBox;
private VBox pluginsSettingsVBox;
private ServerListener serverListener;
private ServerListener serverListener;
private Logger logger;
private Logger logger;
private ExceptionAndAlertHandler exceptionAndAlertHandler;
private ExceptionAndAlertHandler exceptionAndAlertHandler;
private HostServices hostServices;
private HostServices hostServices;
public PluginsSettings(ExceptionAndAlertHandler exceptionAndAlertHandler, HostServices hostServices)
public PluginsSettings(ExceptionAndAlertHandler exceptionAndAlertHandler, HostServices hostServices)
{
{
getStyleClass().add("plugins_settings");
getStyleClass().add("plugins_settings");
this.hostServices = hostServices;
this.hostServices = hostServices;
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
this.exceptionAndAlertHandler = exceptionAndAlertHandler;
pluginProperties = new ArrayList<>();
pluginProperties = new ArrayList<>();
logger = Logger.getLogger(PluginsSettings.class.getName());
logger = Logger.getLogger(PluginsSettings.class.getName());
pluginsSettingsVBox = new VBox();
pluginsSettingsVBox = new VBox();
pluginsSettingsVBox.getStyleClass().add("plugins_settings_vbox");
pluginsSettingsVBox.getStyleClass().add("plugins_settings_vbox");
pluginsSettingsVBox.setAlignment(Pos.TOP_CENTER);
pluginsSettingsVBox.setAlignment(Pos.TOP_CENTER);
ScrollPane scrollPane = new ScrollPane();
ScrollPane scrollPane = new ScrollPane();
scrollPane.getStyleClass().add("plugins_settings_scroll_pane");
scrollPane.getStyleClass().add("plugins_settings_scroll_pane");
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.maxWidthProperty().bind(widthProperty().multiply(0.8));
scrollPane.maxWidthProperty().bind(widthProperty().multiply(0.8));
pluginsSettingsVBox.prefWidthProperty().bind(scrollPane.widthProperty().subtract(25));
pluginsSettingsVBox.prefWidthProperty().bind(scrollPane.widthProperty().subtract(25));
scrollPane.setContent(pluginsSettingsVBox);
scrollPane.setContent(pluginsSettingsVBox);
VBox.setVgrow(scrollPane, Priority.ALWAYS);
VBox.setVgrow(scrollPane, Priority.ALWAYS);
setAlignment(Pos.TOP_CENTER);
setAlignment(Pos.TOP_CENTER);
saveButton = new Button("Save");
saveButton = new Button("Save");
saveButton.setOnAction(event -> onSaveButtonClicked());
saveButton.setOnAction(event -> onSaveButtonClicked());
HBox hBox = new HBox(saveButton);
HBox hBox = new HBox(saveButton);
hBox.setAlignment(Pos.CENTER_RIGHT);
hBox.setAlignment(Pos.CENTER_RIGHT);
getChildren().addAll(scrollPane, hBox);
getChildren().addAll(scrollPane, hBox);
}
}
private Button saveButton;
private Button saveButton;
public void onSaveButtonClicked()
public void onSaveButtonClicked()
{
{
try {
try {
//form validation
//form validation
StringBuilder finalErrors = new StringBuilder();
StringBuilder finalErrors = new StringBuilder();
for (PluginProperties p : pluginProperties)
for (PluginProperties p : pluginProperties)
{
{
StringBuilder errors = new StringBuilder();
StringBuilder errors = new StringBuilder();
for(int j = 0; j < p.getServerPropertyUIBox().size(); j++)
for(int j = 0; j < p.getServerPropertyUIBox().size(); j++)
{
{
UIPropertyBox serverProperty = p.getServerPropertyUIBox().get(j);
UIPropertyBox serverProperty = p.getServerPropertyUIBox().get(j);
Node controlNode = serverProperty.getControlNode();
Node controlNode = serverProperty.getControlNode();
if (serverProperty.getControlType() == ControlType.TEXT_FIELD)
if (serverProperty.getControlType() == ControlType.TEXT_FIELD)
{
{
String value = ((TextField) controlNode).getText();
String value = ((TextField) controlNode).getText();
if(serverProperty.getType() == Type.INTEGER)
if(serverProperty.getType() == Type.INTEGER)
{
{
try
try
{
{
Integer.parseInt(value);
Integer.parseInt(value);
}
}
catch (NumberFormatException e)
catch (NumberFormatException e)
{
{
errors.append(" -> ").append(serverProperty.getDisplayName()).append(" must be integer.\n");
errors.append(" -> ").append(serverProperty.getDisplayName()).append(" must be integer.\n");
}
}
}
}
else
else
{
{
if(value.isBlank() && !serverProperty.isCanBeBlank())
if(value.isBlank() && !serverProperty.isCanBeBlank())
errors.append(" -> ").append(serverProperty.getDisplayName()).append(" cannot be blank.\n");
errors.append(" -> ").append(serverProperty.getDisplayName()).append(" cannot be blank.\n");
}
}
}
}
else if(serverProperty.getControlType() == ControlType.TEXT_FIELD_MASKED)
else if(serverProperty.getControlType() == ControlType.TEXT_FIELD_MASKED)
{
{
String value = ((TextField) controlNode).getText();
String value = ((TextField) controlNode).getText();
if(value.isBlank() && !serverProperty.isCanBeBlank())
if(value.isBlank() && !serverProperty.isCanBeBlank())
errors.append(" -> ").append(serverProperty.getDisplayName()).append(" cannot be blank.\n");
errors.append(" -> ").append(serverProperty.getDisplayName()).append(" cannot be blank.\n");
}
}
}
}
if(!errors.toString().isBlank())
if(!errors.toString().isBlank())
{
{
finalErrors.append(" * ").append(p.getName()).append("\n").append(errors.toString()).append("\n");
finalErrors.append(" * ").append(p.getName()).append("\n").append(errors.toString()).append("\n");
}
}
}
}
if(!finalErrors.toString().isEmpty())
if(!finalErrors.toString().isEmpty())
{
{
throw new MinorException("Form Validation Errors",
throw new MinorException("Form Validation Errors",
"Please rectify the following errors and try again \n"+finalErrors.toString());
"Please rectify the following errors and try again \n"+finalErrors.toString());
}
}
//save
//save
for (PluginProperties pp : pluginProperties) {
for (PluginProperties pp : pluginProperties) {
for (int j = 0; j < pp.getServerPropertyUIBox().size(); j++) {
for (int j = 0; j < pp.getServerPropertyUIBox().size(); j++) {
UIPropertyBox serverProperty = pp.getServerPropertyUIBox().get(j);
UIPropertyBox serverProperty = pp.getServerPropertyUIBox().get(j);
String rawValue = serverProperty.getRawValue();
String rawValue = serverProperty.getRawValue();
NormalActionPlugins.getInstance().getActionFromIndex(pp.getIndex())
ExternalPlugins.getInstance().getActionFromIndex(pp.getIndex())
.getServerProperties().get()
.getServerProperties().get()
.get(serverProperty.getIndex()).setRawValue(rawValue);
.get(serverProperty.getIndex()).setRawValue(rawValue);
}
}
}
}
NormalActionPlugins.getInstance().saveServerSettings();
ExternalPlugins.getInstance().saveServerSettings();
NormalActionPlugins.getInstance().initPlugins();
ExternalPlugins.getInstance().initPlugins();
}
}
catch (MinorException e)
catch (MinorException e)
{
{
e.printStackTrace();
e.printStackTrace();
exceptionAndAlertHandler.handleMinorException(e);
exceptionAndAlertHandler.handleMinorException(e);
}
}
}
}
private ArrayList<PluginProperties> pluginProperties;
private ArrayList<PluginProperties> pluginProperties;
public void showPluginInitError()
public void showPluginInitError()
{
{
Platform.runLater(()->{
Platform.runLater(()->{
pluginsSettingsVBox.getChildren().add(new Label("Plugin init error. Resolve issues and restart."));
pluginsSettingsVBox.getChildren().add(new Label("Plugin init error. Resolve issues and restart."));
saveButton.setVisible(false);
saveButton.setVisible(false);
});
});
}
}
public void loadPlugins() throws MinorException {
public void loadPlugins() throws MinorException {
pluginProperties.clear();
pluginProperties.clear();
List<NormalAction> actions = NormalActionPlugins.getInstance().getPlugins();
List<ExternalPlugin> actions = ExternalPlugins.getInstance().getPlugins();
Platform.runLater(()-> pluginsSettingsVBox.getChildren().clear());
Platform.runLater(()-> pluginsSettingsVBox.getChildren().clear());
if(actions.size() == 0)
if(actions.size() == 0)
{
{
Platform.runLater(()->{
Platform.runLater(()->{
Label l = new Label("No Plugins Installed.");
Label l = new Label("No Plugins Installed.");
l.getStyleClass().add("plugins_pane_no_plugins_installed_label");
l.getStyleClass().add("plugins_pane_no_plugins_installed_label");
pluginsSettingsVBox.getChildren().add(l);
pluginsSettingsVBox.getChildren().add(l);
saveButton.setVisible(false);
saveButton.setVisible(false);
});
});
return;
return;
}
}
else
else
{
{
Platform.runLater(()->saveButton.setVisible(true));
Platform.runLater(()->saveButton.setVisible(true));
}
}
for(int i = 0; i<actions.size(); i++)
for(int i = 0; i<actions.size(); i++)
{
{
NormalAction action = actions.get(i);
ExternalPlugin action = actions.get(i);
if(!action.isVisibleInServerSettingsPane())
if(!action.isVisibleInServerSettingsPane())
continue;
continue;
Label headingLabel = new Label(action.getName());
Label headingLabel = new Label(action.getName());
headingLabel.getStyleClass().add("plugins_settings_each_plugin_heading_label");
headingLabel.getStyleClass().add("plugins_settings_each_plugin_heading_label");
HBox headerHBox = new HBox(headingLabel);
HBox headerHBox = new HBox(headingLabel);
headerHBox.getStyleClass().add("plugins_settings_each_plugin_header");
headerHBox.getStyleClass().add("plugins_settings_each_plugin_header");
if (action.getHelpLink()!=null)
if (action.getHelpLink()!=null)
{
{
Button helpButton = new Button();
Button helpButton = new Button();
helpButton.getStyleClass().add("plugins_settings_each_plugin_help_button");
helpButton.getStyleClass().add("plugins_settings_each_plugin_help_button");
FontIcon questionIcon = new FontIcon("fas-question");
FontIcon questionIcon = new FontIcon("fas-question");
questionIcon.getStyleClass().add("plugins_settings_each_plugin_help_icon");
questionIcon.getStyleClass().add("plugins_settings_each_plugin_help_icon");
helpButton.setGraphic(questionIcon);
helpButton.setGraphic(questionIcon);
helpButton.setOnAction(event -> hostServices.showDocument(action.getHelpLink()));
helpButton.setOnAction(event -> hostServices.showDocument(action.getHelpLink()));
headerHBox.getChildren().addAll(SpaceFiller.horizontal() ,helpButton);
headerHBox.getChildren().addAll(SpaceFiller.horizontal() ,helpButton);
}
}
Label authorLabel = new Label(action.getAuthor());
Label authorLabel = new Label(action.getAuthor());
authorLabel.getStyleClass().add("plugins_settings_each_plugin_author_label");
authorLabel.getStyleClass().add("plugins_settings_each_plugin_author_label");
Label moduleLabel = new Label(action.getModuleName());
Label moduleLabel = new Label(action.getModuleName());
moduleLabel.getStyleClass().add("plugins_settings_each_plugin_module_label");
moduleLabel.getStyleClass().add("plugins_settings_each_plugin_module_label");
Label versionLabel = new Label("Version : "+action.getVersion().getText());
Label versionLabel = new Label("Version : "+action.getVersion().getText());
versionLabel.getStyleClass().add("plugins_settings_each_plugin_version_label");
versionLabel.getStyleClass().add("plugins_settings_each_plugin_version_label");
VBox serverPropertiesVBox = new VBox();
VBox serverPropertiesVBox = new VBox();
serverPropertiesVBox.getStyleClass().add("plugins_settings_each_plugin_server_properties_box");
serverPropertiesVBox.getStyleClass().add("plugins_settings_each_plugin_server_properties_box");
serverPropertiesVBox.setSpacing(10.0);
serverPropertiesVBox.setSpacing(10.0);
List<Property> serverProperties = action.getServerProperties().get();
List<Property> serverProperties = action.getServerProperties().get();
ArrayList<UIPropertyBox> serverPropertyArrayList = new ArrayList<>();
ArrayList<UIPropertyBox> serverPropertyArrayList = new ArrayList<>();
for(int j =0; j<serverProperties.size(); j++)
for(int j =0; j<serverProperties.size(); j++)
{
{
Property eachProperty = serverProperties.get(j);
Property eachProperty = serverProperties.get(j);
if(!eachProperty.isVisible())
if(!eachProperty.isVisible())
continue;
continue;
Label label = new Label(eachProperty.getDisplayName());
Label label = new Label(eachProperty.getDisplayName());
Region region = new Region();
Region region = new Region();
HBox.setHgrow(region, Priority.ALWAYS);
HBox.setHgrow(region, Priority.ALWAYS);
HBox hBox = new HBox(label, SpaceFiller.horizontal());
HBox hBox = new HBox(label, SpaceFiller.horizontal());
//hBox.setId(j+"");
//hBox.setId(j+"");
Node controlNode = null;
Node controlNode = null;
if(eachProperty.getControlType() == ControlType.COMBO_BOX)
if(eachProperty.getControlType() == ControlType.COMBO_BOX)
{
{
ComboBox<String> comboBox = new ComboBox<>();
ComboBox<String> comboBox = new ComboBox<>();
comboBox.getItems().addAll(eachProperty.getListValue());
comboBox.getItems().addAll(eachProperty.getListValue());
comboBox.getSelectionModel().select(eachProperty.getSelectedIndex());
comboBox.getSelectionModel().select(eachProperty.getSelectedIndex());
hBox.getChildren().add(comboBox);
hBox.getChildren().add(comboBox);
controlNode = comboBox;
controlNode = comboBox;
}
}
else if(eachProperty.getControlType() == ControlType.TEXT_FIELD)
else if(eachProperty.getControlType() == ControlType.TEXT_FIELD)
{
{
TextField textField = new TextField(eachProperty.getRawValue());
TextField textField = new TextField(eachProperty.getRawValue());
hBox.getChildren().add(textField);
hBox.getChildren().add(textField);
controlNode = textField;
controlNode = textField;
}
}
else if(eachProperty.getControlType() == ControlType.TEXT_FIELD_MASKED)
else if(eachProperty.getControlType() == ControlType.TEXT_FIELD_MASKED)
{
{
PasswordField textField = new PasswordField();
PasswordField textField = new PasswordField();
textField.setText(eachProperty.getRawValue());
textField.setText(eachProperty.getRawValue());
controlNode= textField;
controlNode= textField;
hBox.getChildren().add(controlNode);
hBox.getChildren().add(controlNode);
}
}
else if(eachProperty.getControlType() == ControlType.TOGGLE)
else if(eachProperty.getControlType() == ControlType.TOGGLE)
{
{
ToggleButton toggleButton = new ToggleButton();
ToggleButton toggleButton = new ToggleButton();
toggleButton.setSelected(eachProperty.getBoolValue());
toggleButton.setSelected(eachProperty.getBoolValue());
if(eachProperty.getBoolValue())
if(eachProperty.getBoolValue())
toggleButton.setText("ON");
toggleButton.setText("ON");
else
else
toggleButton.setText("OFF");
toggleButton.setText("OFF");
toggleButton.selectedProperty().addListener((observableValue, aBoolean, t1) -> {
toggleButton.selectedProperty().addListener((observableValue, aBoolean, t1) -> {
if(t1)
if(t1)
toggleButton.setText("ON");
toggleButton.setText("ON");
else
else
toggleButton.setText("OFF");
toggleButton.setText("OFF");
});
});
hBox.getChildren().add(toggleButton);
hBox.getChildren().add(toggleButton);
controlNode = toggleButton;
controlNode = toggleButton;
}
}
else if(eachProperty.getControlType() == ControlType.SLIDER_DOUBLE)
else if(eachProperty.getControlType() == ControlType.SLIDER_DOUBLE)
{
{
Slider slider = new Slider();
Slider slider = new Slider();
slider.setValue(eachProperty.getDoubleValue());
slider.setValue(eachProperty.getDoubleValue());
slider.setMax(eachProperty.getMaxDoubleValue());
slider.setMax(eachProperty.getMaxDoubleValue());
slider.setMin(eachProperty.getMinDoubleValue());
slider.setMin(eachProperty.getMinDoubleValue());
hBox.getChildren().add(slider);
hBox.getChildren().add(slider);
controlNode = slider;
controlNode = slider;
}
}
else if(eachProperty.getControlType() == ControlType.SLIDER_INTEGER)
else if(eachProperty.getControlType() == ControlType.SLIDER_INTEGER)
{
{
Slider slider = new Slider();
Slider slider = new Slider();
slider.setValue(eachProperty.getIntValue());
slider.setValue(eachProperty.getIntValue());
slider.setMax(eachProperty.getMaxIntValue());
slider.setMax(eachProperty.getMaxIntValue());
slider.setMin(eachProperty.getMinIntValue());
slider.setMin(eachProperty.getMinIntValue());
slider.setBlockIncrement(1.0);
slider.setBlockIncrement(1.0);
slider.setSnapToTicks(true);
slider.setSnapToTicks(true);
hBox.getChildren().add(slider);
hBox.getChildren().add(slider);
controlNode = slider;
controlNode = slider;
}
}
UIPropertyBox serverProperty = new UIPropertyBox(j, eachProperty.getDisplayName(), controlNode, eachProperty.getControlType(), eachProperty.getType(), eachProperty.isCanBeBlank());
UIPropertyBox serverProperty = new UIPropertyBox(j, eachProperty.getDisplayName(), controlNode, eachProperty.getControlType(), eachProperty.getType(), eachProperty.isCanBeBlank());
serverPropertyArrayList.add(serverProperty);
serverPropertyArrayList.add(serverProperty);
serverPropertiesVBox.getChildren().add(hBox);
serverPropertiesVBox.getChildren().add(hBox);
}
}
PluginProperties pp = new PluginProperties(i, serverPropertyArrayList, action.getName());
PluginProperties pp = new PluginProperties(i, serverPropertyArrayList, action.getName());
pluginProperties.add(pp);
pluginProperties.add(pp);
Platform.runLater(()->{
Platform.runLater(()->{
VBox vBox = new VBox();
VBox vBox = new VBox();
vBox.getStyleClass().add("plugins_settings_each_plugin_box");
vBox.getStyleClass().add("plugins_settings_each_plugin_box");
vBox.setSpacing(5.0);
vBox.setSpacing(5.0);
vBox.getChildren().addAll(headerHBox, authorLabel, moduleLabel, versionLabel, serverPropertiesVBox);
vBox.getChildren().addAll(headerHBox, authorLabel, moduleLabel, versionLabel, serverPropertiesVBox);
if(action.getButtonBar()!=null)
if(action.getButtonBar()!=null)
{
{
action.getButtonBar().getStyleClass().add("plugins_settings_each_plugin_button_bar");
action.getButtonBar().getStyleClass().add("plugins_settings_each_plugin_button_bar");
HBox buttonBarHBox = new HBox(SpaceFiller.horizontal(), action.getButtonBar());
HBox buttonBarHBox = new HBox(SpaceFiller.horizontal(), action.getButtonBar());
buttonBarHBox.getStyleClass().add("plugins_settings_each_plugin_button_bar_hbox");
buttonBarHBox.getStyleClass().add("plugins_settings_each_plugin_button_bar_hbox");
vBox.getChildren().add(buttonBarHBox);
vBox.getChildren().add(buttonBarHBox);
}
}
pluginsSettingsVBox.getChildren().add(vBox);
pluginsSettingsVBox.getChildren().add(vBox);
});
});
}
}
}
}
public class PluginProperties
public class PluginProperties
{
{
private int index;
private int index;
private ArrayList<UIPropertyBox> serverProperty;
private ArrayList<UIPropertyBox> serverProperty;
private String name;
private String name;
public PluginProperties(int index, ArrayList<UIPropertyBox> serverProperty, String name)
public PluginProperties(int index, ArrayList<UIPropertyBox> serverProperty, String name)
{
{
this.index = index;
this.index = index;
this.serverProperty = serverProperty;
this.serverProperty = serverProperty;
this.name = name;
this.name = name;
}
}
public String getName()
public String getName()
{
{
return name;
return name;
}
}
public int getIndex() {
public int getIndex() {
return index;
return index;
}
}
public ArrayList<UIPropertyBox> getServerPropertyUIBox() {
public ArrayList<UIPropertyBox> getServerPropertyUIBox() {
return serverProperty;
return serverProperty;
}
}
}
}
}
}