Initial commit
This commit is contained in:
commit
a1ee3cf1b5
11
ShoppingList/.classpath
Normal file
11
ShoppingList/.classpath
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="lib" path="lib/commons-lang3-3.9.jar"/>
|
||||
<classpathentry kind="lib" path="lib/mariadb-java-client-2.4.4.jar"/>
|
||||
<classpathentry kind="lib" path="C:/Users/Jens/Documents/Entwicklung/Eclipse workspace/libs/mailapi-1.5.0.jar"/>
|
||||
<classpathentry kind="lib" path="C:/Users/Jens/Documents/Entwicklung/Eclipse workspace/libs/smtp-1.5.0.jar"/>
|
||||
<classpathentry kind="lib" path="C:/Users/Jens/Documents/Entwicklung/Eclipse workspace/libs/activation-1.1.1.wso2v2.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
74
ShoppingList/.gitignore
vendored
Normal file
74
ShoppingList/.gitignore
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/eclipse
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=eclipse
|
||||
|
||||
### Eclipse ###
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
.recommenders
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# PyDev specific (Python IDE for Eclipse)
|
||||
*.pydevproject
|
||||
|
||||
# CDT-specific (C/C++ Development Tooling)
|
||||
.cproject
|
||||
|
||||
# CDT- autotools
|
||||
.autotools
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific (PHP Development Tools)
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# Tern plugin
|
||||
.tern-project
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
|
||||
# Code Recommenders
|
||||
.recommenders/
|
||||
|
||||
# Annotation Processing
|
||||
.apt_generated/
|
||||
.apt_generated_test/
|
||||
|
||||
# Scala IDE specific (Scala & Java development for Eclipse)
|
||||
.cache-main
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
|
||||
# Uncomment this line if you wish to ignore the project description file.
|
||||
# Typically, this file would be tracked if it contains build/dependency configurations:
|
||||
#.project
|
||||
|
||||
### Eclipse Patch ###
|
||||
# Spring Boot Tooling
|
||||
.sts4-cache/
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/eclipse
|
||||
|
||||
ShoppingListLogFile.txt
|
||||
ShoppingList-settings.ini
|
17
ShoppingList/.project
Normal file
17
ShoppingList/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ShoppingList</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
BIN
ShoppingList/lib/commons-lang3-3.9.jar
Normal file
BIN
ShoppingList/lib/commons-lang3-3.9.jar
Normal file
Binary file not shown.
BIN
ShoppingList/lib/javax.xml.bind.jar
Normal file
BIN
ShoppingList/lib/javax.xml.bind.jar
Normal file
Binary file not shown.
BIN
ShoppingList/lib/mariadb-java-client-2.4.4.jar
Normal file
BIN
ShoppingList/lib/mariadb-java-client-2.4.4.jar
Normal file
Binary file not shown.
@ -0,0 +1,134 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class DatabaseHandler implements Runnable
|
||||
{
|
||||
private static DatabaseHandler instance = null;
|
||||
static final String databaseConnectionEncoding = "utf8";
|
||||
|
||||
Connection conn = null;
|
||||
|
||||
private DatabaseHandler()
|
||||
{
|
||||
}
|
||||
|
||||
public static DatabaseHandler getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
instance = new DatabaseHandler();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Connection getConnection()
|
||||
{
|
||||
// if(isConnectedToDatabase())
|
||||
// {
|
||||
// // It has occured that the connection was there, but dead due to timeout or whatever
|
||||
// try
|
||||
// {
|
||||
// conn.getSchema();
|
||||
// }
|
||||
// catch (SQLException e)
|
||||
//// if(conn.isValid(5000))
|
||||
// {
|
||||
// Miscellaneous.logEvent("DB connection probably dropped. Reestablishing...");
|
||||
// conn = null;
|
||||
// establishConnection();
|
||||
// }
|
||||
// }
|
||||
|
||||
if(!isConnectedToDatabase())
|
||||
establishConnection(true);
|
||||
|
||||
return this.conn;
|
||||
}
|
||||
|
||||
/** force means that connection is definitely reestablished, even if there seems to be an existing one **/
|
||||
private synchronized void establishConnection(boolean force)
|
||||
{
|
||||
if(conn == null | force)
|
||||
{
|
||||
for(String dbServer : Settings.databaseServerNames)
|
||||
{
|
||||
Miscellaneous.logEvent("Trying to connect to database " + Settings.databaseName + "@" + dbServer + " as " + Settings.databaseUsername + "...", 3);
|
||||
|
||||
// String url = "jdbc:mysql://" + dbServer + ":" + Settings.databasePort + "/";
|
||||
// String driver = "com.mysql.jdbc.Driver";
|
||||
String url = "jdbc:mariadb://" + dbServer + ":" + Settings.databasePort + "/";
|
||||
String driver = "org.mariadb.jdbc.Driver";
|
||||
try
|
||||
{
|
||||
Class.forName(driver).newInstance();
|
||||
conn = DriverManager.getConnection(url + Settings.databaseName + "?characterEncoding=" + databaseConnectionEncoding, Settings.databaseUsername, Settings.databasePassword);
|
||||
Miscellaneous.logEvent("Connected to database.", 3);
|
||||
|
||||
break;
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
Miscellaneous.logEvent(Settings.languageBlock.get("dbDriverNotFound"), 1);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent(Settings.languageBlock.get("dbCouldNotConnect"), 1);
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 2);
|
||||
this.conn = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect()
|
||||
{
|
||||
// TODO: Timeout after which the DB connection is terminated automatically.
|
||||
|
||||
if(conn != null)
|
||||
{
|
||||
Miscellaneous.logEvent("Disconnecting from database.", 3);
|
||||
try
|
||||
{
|
||||
this.conn.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("Not disconnecting from database because not connected.", 4);
|
||||
|
||||
conn=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
getConnection();
|
||||
}
|
||||
|
||||
public boolean isConnectedToDatabase()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(conn != null && conn.isValid(5000))
|
||||
return true;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
611
ShoppingList/src/com/jens/rhasspy/shoppinglist/Diverse.java
Normal file
611
ShoppingList/src/com/jens/rhasspy/shoppinglist/Diverse.java
Normal file
@ -0,0 +1,611 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.security.SecureRandom;
|
||||
import java.sql.Time;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpression;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
public class Diverse
|
||||
{
|
||||
public final static String networkSeparatorCommunication = ";commSep";
|
||||
public final static String networkSeparatorSettings = ";commSett";
|
||||
|
||||
public static enum cacheObjectsEnum { all, devices, commands, rooms, rules, users, houses, nodes, sensors, userDevices };
|
||||
|
||||
public enum SolarEvent {sunrise, sunset};
|
||||
|
||||
public static final String lineSeparator = System.getProperty("line.separator");
|
||||
|
||||
public static String intToOpenClosed(int value)
|
||||
{
|
||||
if(value == 1)
|
||||
return "closed";
|
||||
else if(value == 0)
|
||||
return "open";
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static String intToWaterYesNo(int value)
|
||||
{
|
||||
if(value == 1)
|
||||
return "water";
|
||||
else if(value == 0)
|
||||
return "dry";
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static String intToSmokeYesNo(int value)
|
||||
{
|
||||
if(value == 1)
|
||||
return "smoke";
|
||||
else if(value == 0)
|
||||
return "no smoke";
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static String getEnabledDisabledString(boolean value)
|
||||
{
|
||||
if(value)
|
||||
return "enabled";
|
||||
else
|
||||
return "disabled";
|
||||
}
|
||||
|
||||
public static Calendar calendarFromLong(long source)
|
||||
{
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(source);
|
||||
return cal;
|
||||
}
|
||||
|
||||
public static String getOnOffString(boolean value)
|
||||
{
|
||||
if(value)
|
||||
return "on";
|
||||
else
|
||||
return "off";
|
||||
}
|
||||
|
||||
public static String getIniLikeValue(String fullText, String searchObject, String separator)
|
||||
{
|
||||
fullText = fullText.trim();
|
||||
|
||||
if (fullText.toLowerCase().contains(searchObject.toLowerCase()))
|
||||
{
|
||||
if (fullText.toLowerCase().contains(separator.toLowerCase())) // multiple values
|
||||
{
|
||||
int start = fullText.toLowerCase().indexOf(searchObject.toLowerCase() + "=") + searchObject.length() + 1;
|
||||
int end = fullText.toLowerCase().indexOf(separator.toLowerCase(), start);
|
||||
|
||||
if (end == -1) // if the last index in fullText
|
||||
return fullText.substring(start);
|
||||
else
|
||||
return fullText.substring(start, end);
|
||||
}
|
||||
else // only one value
|
||||
{
|
||||
return fullText.substring(fullText.indexOf("=") + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("Index " + searchObject + " cannot be found in full text.", 5);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String addOrReplaceIniLikeValue(String fullText, String key, String value, String separator)
|
||||
{
|
||||
fullText = fullText.trim();
|
||||
|
||||
if (fullText.startsWith(key + "=") | fullText.contains(separator + key + "="))
|
||||
{
|
||||
if (fullText.contains(separator)) // multiple values
|
||||
{
|
||||
int start = fullText.indexOf(key + "=") + key.length() + 1;
|
||||
int end = fullText.indexOf(separator, start);
|
||||
|
||||
String oldValue;
|
||||
if (end == -1) // if the last index in fullText
|
||||
oldValue = fullText.substring(start);
|
||||
else
|
||||
oldValue = fullText.substring(start, end);
|
||||
|
||||
return fullText.replace(key + "=" + oldValue, key + "=" + value);
|
||||
}
|
||||
else // only one value
|
||||
{
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fullText.length() > 0)
|
||||
return fullText + separator + key + "=" + value;
|
||||
else
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
public static String removeIniLikeValue(String fullText, String key, String separator)
|
||||
{
|
||||
fullText = fullText.trim();
|
||||
String toBeRemoved = getIniLikeValue(fullText, key, separator);
|
||||
|
||||
if(toBeRemoved != null && fullText.contains(toBeRemoved))
|
||||
{
|
||||
if(fullText.contains(";"))
|
||||
{
|
||||
if(fullText.contains(";" + toBeRemoved))
|
||||
return fullText.replace(";" + toBeRemoved, "");
|
||||
else
|
||||
return fullText.replace(toBeRemoved + ";", "");
|
||||
}
|
||||
else
|
||||
return "";
|
||||
}
|
||||
else
|
||||
return fullText;
|
||||
}
|
||||
|
||||
public static String updateIniLikeValue(String fullText, String key, String value, String separator)
|
||||
{
|
||||
if (fullText.contains(key))
|
||||
{
|
||||
if (fullText.contains(separator)) // multiple values
|
||||
{
|
||||
String[] lines = fullText.split(separator);
|
||||
for(int i=0; i < lines.length; i++)
|
||||
{
|
||||
if(lines[i].startsWith(key))
|
||||
{
|
||||
int equalsPosition = lines[i].indexOf(key + "=") + key.length() + 1;
|
||||
lines[i] = lines[i].substring(0, equalsPosition) + value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Diverse.arrayImplode(separator, lines);
|
||||
}
|
||||
else // only one value
|
||||
{
|
||||
return fullText + separator + key + "=" + value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return fullText + separator + key + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
public static int boolToInt(boolean in)
|
||||
{
|
||||
if (in)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static boolean intToBool(int in)
|
||||
{
|
||||
if (in > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
// ClientServerSplit.logEvent("Error transforming int to bool.", 3);
|
||||
// return false;
|
||||
}
|
||||
|
||||
public static boolean isNumeric(String stringToCheck)
|
||||
{
|
||||
String character;
|
||||
|
||||
for(int i = 0; i < stringToCheck.length(); i++)
|
||||
{
|
||||
character = stringToCheck.substring(i, i + 1);
|
||||
|
||||
if(!character.matches("[1234567890]") && !character.equals(".") && !character.equals(","))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean arraySearch(String[] haystack, String needle, boolean caseSensitive, boolean matchFullLine)
|
||||
{
|
||||
if(matchFullLine)
|
||||
{
|
||||
if(caseSensitive)
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.equals(needle))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.toLowerCase().equals(needle.toLowerCase()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(caseSensitive)
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.contains(needle))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.toLowerCase().contains(needle.toLowerCase()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean arraySearch(ArrayList<String> requestList, String needle, boolean caseSensitive, boolean matchFullLine)
|
||||
{
|
||||
return arraySearch(requestList.toArray(new String[requestList.size()]), needle, caseSensitive, matchFullLine);
|
||||
}
|
||||
|
||||
public static boolean arraySearch(cacheObjectsEnum[] haystack, cacheObjectsEnum needle)
|
||||
{
|
||||
if (needle != null)
|
||||
{
|
||||
for (cacheObjectsEnum c : haystack)
|
||||
{
|
||||
if (c.equals(needle))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("Needle should not be null in function arraySearch()", 5);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String arrayImplode(String glue, String... values)
|
||||
{
|
||||
String returnString = "";
|
||||
|
||||
for (String s : values)
|
||||
returnString += s + glue;
|
||||
|
||||
if (returnString.length() > 0)
|
||||
returnString = returnString.substring(0, returnString.length() - glue.length());
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
public static String arrayImplode(String glue, ArrayList<String> arrayList)
|
||||
{
|
||||
String returnString = "";
|
||||
|
||||
for (Object s : arrayList)
|
||||
returnString += s + glue;
|
||||
|
||||
if (returnString.length() > 0)
|
||||
returnString = returnString.substring(0, returnString.length() - glue.length());
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
public static String arrayImplode(String glue, Object[] array)
|
||||
{
|
||||
String returnString = "";
|
||||
|
||||
for (Object s : array)
|
||||
returnString += s.toString() + glue;
|
||||
|
||||
if (returnString.length() > 0)
|
||||
returnString = returnString.substring(0, returnString.length() - glue.length());
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
public static String arrayImplode(String glue, HashMap<String, String> map)
|
||||
{
|
||||
String returnString = "";
|
||||
|
||||
for (String key : map.keySet())
|
||||
returnString += map.get(key) + glue;
|
||||
|
||||
if (returnString.length() > 0)
|
||||
returnString = returnString.substring(0, returnString.length() - glue.length());
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
public static String getSystemTimezone()
|
||||
{
|
||||
// https://coderanch.com/t/386398/java/System-Timezone
|
||||
TimeZone tz = Calendar.getInstance().getTimeZone();
|
||||
// System.out.println(tz.getDisplayName());// (i.e. Moscow Standard Time)
|
||||
return tz.getID();
|
||||
|
||||
// Should return something like this: Asia/Calcutta
|
||||
}
|
||||
|
||||
public static String createPassword(int length)
|
||||
{
|
||||
final String allowedChars = "0123456789abcdefghijklmnopqrstuvwABCDEFGHIJKLMNOP!§$%&?*+#";
|
||||
SecureRandom random = new SecureRandom();
|
||||
StringBuilder pass = new StringBuilder(length);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
pass.append(allowedChars.charAt(random.nextInt(allowedChars.length())));
|
||||
}
|
||||
return pass.toString();
|
||||
}
|
||||
|
||||
public static Element getXmlTree(String inputString) throws SAXException, IOException, ParserConfigurationException
|
||||
{
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
|
||||
// Create a Document from a file or stream
|
||||
/*
|
||||
StringBuilder xmlStringBuilder = new StringBuilder();
|
||||
xmlStringBuilder.append("<?xml version="1.0"?> <class> </class>");
|
||||
ByteArrayInputStream input = new ByteArrayInputStream(xmlStringBuilder.toString().getBytes("UTF-8"));
|
||||
*/
|
||||
// Document doc = builder.parse(input);
|
||||
Document doc = builder.parse(new InputSource(new StringReader(inputString)));
|
||||
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
|
||||
return rootElement;
|
||||
/*
|
||||
// Examine attributes
|
||||
|
||||
//returns specific attribute
|
||||
root.getAttribute("attributeName");
|
||||
|
||||
//returns a Map (table) of names/values
|
||||
root.getAttributes();
|
||||
|
||||
// Examine sub-elements
|
||||
|
||||
//returns a list of subelements of specified name
|
||||
root.getElementsByTagName("subelementName");
|
||||
|
||||
//returns a list of all child nodes
|
||||
root.getChildNodes();
|
||||
*/
|
||||
}
|
||||
|
||||
public static String xmlToString(Node node, boolean omitXmlDeclaration, boolean prettyPrint)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
throw new IllegalArgumentException("node is null.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Remove unwanted whitespaces
|
||||
node.normalize();
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
XPathExpression expr = xpath.compile("//text()[normalize-space()='']");
|
||||
NodeList nodeList = (NodeList) expr.evaluate(node, XPathConstants.NODESET);
|
||||
|
||||
for (int i = 0; i < nodeList.getLength(); ++i)
|
||||
{
|
||||
Node nd = nodeList.item(i);
|
||||
nd.getParentNode().removeChild(nd);
|
||||
}
|
||||
|
||||
// Create and setup transformer
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
|
||||
|
||||
if (omitXmlDeclaration == true)
|
||||
{
|
||||
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
}
|
||||
|
||||
if (prettyPrint == true)
|
||||
{
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
|
||||
}
|
||||
|
||||
// Turn the node into a string
|
||||
StringWriter writer = new StringWriter();
|
||||
transformer.transform(new DOMSource(node), new StreamResult(writer));
|
||||
return writer.toString();
|
||||
}
|
||||
catch (TransformerConfigurationException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (TransformerException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (XPathExpressionException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String getStackTrace()
|
||||
{
|
||||
StringBuilder trace = new StringBuilder();
|
||||
for (StackTraceElement ste : Thread.currentThread().getStackTrace())
|
||||
trace.append(ste + Diverse.lineSeparator);
|
||||
|
||||
trace.delete(trace.length(), trace.length());
|
||||
|
||||
return trace.toString();
|
||||
}
|
||||
|
||||
public static String getStackTraceAsString(Throwable aThrowable)
|
||||
{
|
||||
Writer result = new StringWriter();
|
||||
PrintWriter printWriter = new PrintWriter(result);
|
||||
aThrowable.printStackTrace(printWriter);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a custom format for the stack trace as String.
|
||||
*/
|
||||
public static String getCustomStackTrace(Throwable aThrowable)
|
||||
{
|
||||
//add the class name and any message passed to constructor
|
||||
StringBuilder result = new StringBuilder( "Stacktrace: " );
|
||||
result.append(aThrowable.toString());
|
||||
String NEW_LINE = System.getProperty("line.separator");
|
||||
result.append(NEW_LINE);
|
||||
|
||||
//add each element of the stack trace
|
||||
for (StackTraceElement element : aThrowable.getStackTrace())
|
||||
{
|
||||
result.append(element);
|
||||
result.append(NEW_LINE);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static ArrayList<Element> getSubElements(Node node, String parentName, String childName)
|
||||
{
|
||||
ArrayList<Element> returnList = new ArrayList<Element>();
|
||||
NodeList nodeElements = ((Element)node).getElementsByTagName("houses");
|
||||
for(int i = 0; i < nodeElements.getLength(); i++)
|
||||
{
|
||||
if (nodeElements.item(i).getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
NodeList childElements = nodeElements.item(i).getChildNodes();
|
||||
for (int j = 0; j < childElements.getLength(); j++)
|
||||
{
|
||||
Element element = (Element) childElements.item(j);
|
||||
// HouseTemplate house = HouseTemplate.fromXmlStringStatic(Diverse.getXmlFull(element));
|
||||
returnList.add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*ArrayList<Element> returnList = new ArrayList<>();
|
||||
|
||||
NodeList children = ((Element)node).getElementsByTagName(parentName);
|
||||
|
||||
for(int i=0; i < children.getLength(); i++)
|
||||
{
|
||||
returnList.add((Element)children.item(i));
|
||||
}*/
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public static double round(double value, int places)
|
||||
{
|
||||
if (places < 0) throw new IllegalArgumentException();
|
||||
|
||||
BigDecimal bd = new BigDecimal(Double.toString(value));
|
||||
bd = bd.setScale(places, RoundingMode.HALF_UP);
|
||||
return bd.doubleValue();
|
||||
}
|
||||
|
||||
public static Class getCallerClass()
|
||||
{
|
||||
StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
|
||||
for (int i=1; i<stElements.length; i++)
|
||||
{
|
||||
StackTraceElement ste = stElements[i];
|
||||
if (!ste.getClassName().equals(Diverse.class.getName()) && ste.getClassName().indexOf("java.lang.Thread")!=0)
|
||||
{
|
||||
return ste.getClass().getDeclaringClass();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Class getCallerCallerClassName()
|
||||
{
|
||||
StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
|
||||
String callerClassName = null;
|
||||
for (int i=1; i<stElements.length; i++)
|
||||
{
|
||||
StackTraceElement ste = stElements[i];
|
||||
if (!ste.getClassName().equals(Diverse.class.getName())&& ste.getClassName().indexOf("java.lang.Thread")!=0)
|
||||
{
|
||||
if (callerClassName==null)
|
||||
{
|
||||
callerClassName = ste.getClassName();
|
||||
}
|
||||
else if (!callerClassName.equals(ste.getClassName()))
|
||||
{
|
||||
try
|
||||
{
|
||||
Class returnClass = Class.forName(ste.getClassName());
|
||||
return returnClass;
|
||||
}
|
||||
catch(Exception e)
|
||||
{}
|
||||
// return ste.getClassName();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int countOccurences(String input, String needle)
|
||||
{
|
||||
String out = input.replace (needle, "");
|
||||
int lenDiff = input.length () - out.length ();
|
||||
return lenDiff / needle.length();
|
||||
}
|
||||
}
|
@ -0,0 +1,562 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.mail.Authenticator;
|
||||
import javax.mail.Message;
|
||||
import javax.mail.PasswordAuthentication;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.Transport;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
public class Miscellaneous
|
||||
{
|
||||
protected static Calendar logDate;
|
||||
static Logger logger = Logger.getLogger(Miscellaneous.class.getName());
|
||||
static FileHandler fileHandler = null;
|
||||
|
||||
|
||||
public static final String genericErrorMessage = "sldaskdm32oierror";
|
||||
|
||||
protected static boolean logCleanerRunning = false;
|
||||
|
||||
static File getLogFileFullPath()
|
||||
{
|
||||
File logFile;
|
||||
File folder = new File(Settings.logFolderPath);
|
||||
|
||||
if((folder.exists() && folder.canWrite()) | folder.mkdir())
|
||||
logFile = new File(folder.getAbsolutePath() + "/" + Settings.logFileName);
|
||||
else
|
||||
logFile = new File(Settings.logFileName);
|
||||
|
||||
// System.out.println("Using " + logFile.getAbsolutePath().toString() + " as log file path.");
|
||||
|
||||
return logFile;
|
||||
}
|
||||
|
||||
public static String formatDate(Date input)
|
||||
{
|
||||
DateFormat sdf = null;
|
||||
SimpleDateFormat fallBackFormatter = new SimpleDateFormat(Settings.dateFormat);
|
||||
|
||||
if(sdf == null && Settings.dateFormat != null)
|
||||
sdf = new SimpleDateFormat(Settings.dateFormat);
|
||||
|
||||
String formattedDate;
|
||||
if(sdf != null)
|
||||
formattedDate = sdf.format(input);
|
||||
else
|
||||
formattedDate = fallBackFormatter.format(input);
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
public static synchronized void logEvent(String eventDescription, int logLevel)
|
||||
{
|
||||
if(logLevel <= Settings.logLevel)
|
||||
{
|
||||
logDate = Calendar.getInstance();
|
||||
|
||||
String formattedDate = Miscellaneous.formatDate(logDate.getTime());
|
||||
|
||||
String callingClass = Thread.currentThread().getStackTrace()[2].getClassName();
|
||||
|
||||
String textToLog = Diverse.lineSeparator + formattedDate + ": " + callingClass + ": " + eventDescription;
|
||||
|
||||
File logFile = getLogFileFullPath();
|
||||
|
||||
if(!logFile.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
logFile.createNewFile();
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Files.write(Paths.get(logFile.toString()), textToLog.getBytes(), StandardOpenOption.APPEND);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
//exception handling left as an exercise for the reader
|
||||
// System.out.println("Error appending to file " + logFile + ": " + Diverse.getStackTraceAsString(e));
|
||||
}
|
||||
|
||||
if(Miscellaneous.isDevelopment())
|
||||
System.out.println(textToLog);
|
||||
|
||||
if(!logCleanerRunning && Math.random() < 0.01) // tidy up with 0,1% probability
|
||||
{
|
||||
logCleanerRunning = true;
|
||||
|
||||
Miscellaneous.logEvent("Cleaning up log file.", 3);
|
||||
|
||||
long maxSizeInBytes = (long)Settings.logMaxSize * 1024 * 1024;
|
||||
|
||||
if(logFile.exists() && logFile.length() > (maxSizeInBytes))
|
||||
{
|
||||
File archivedLogFile = new File(logFile.getAbsolutePath() + "-old");
|
||||
logFile.renameTo(archivedLogFile);
|
||||
Miscellaneous.logEvent("Log renamed to " + archivedLogFile.getAbsolutePath(), 3);
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("Cleaning up log file finished.", 3);
|
||||
|
||||
logCleanerRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getGCStats()
|
||||
{
|
||||
StringBuilder returnString = new StringBuilder();
|
||||
|
||||
long totalGarbageCollections = 0;
|
||||
long garbageCollectionTime = 0;
|
||||
|
||||
for(GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans())
|
||||
{
|
||||
|
||||
long count = gc.getCollectionCount();
|
||||
|
||||
if(count >= 0) {
|
||||
totalGarbageCollections += count;
|
||||
}
|
||||
|
||||
long time = gc.getCollectionTime();
|
||||
|
||||
if(time >= 0)
|
||||
garbageCollectionTime += time;
|
||||
}
|
||||
|
||||
returnString.append("Total Garbage Collections: " + totalGarbageCollections + Diverse.lineSeparator);
|
||||
returnString.append("Total Garbage Collection Time (ms): " + garbageCollectionTime);
|
||||
|
||||
return returnString.toString();
|
||||
}
|
||||
|
||||
public static class SmtpSimple
|
||||
{
|
||||
/**
|
||||
* Send a single email.
|
||||
*/
|
||||
public boolean sendEmail(String mailServer, int mailServerPor, String encryptionType, boolean useAuthentication, final String username, final String password, String aFromEmailAddr, String aToEmailAddr, String aSubject, String aBody)
|
||||
{
|
||||
// Properties über die Systemeigenschaften anlegen
|
||||
Properties properties = System.getProperties();
|
||||
|
||||
properties.setProperty("mail.smtp.host", mailServer);
|
||||
properties.setProperty("mail.smtp.port", String.valueOf(mailServerPor));
|
||||
|
||||
properties.setProperty("mail.smtp.auth", String.valueOf(useAuthentication));
|
||||
|
||||
/*
|
||||
* final Properties props = new Properties();
|
||||
* props.put("mail.smtp.host", "SMTPHOST");
|
||||
* props.put("mail.smtp.port", "PORTNUMBER");
|
||||
* props.put("mail.transport.protocol","smtp");
|
||||
* props.put("mail.smtp.auth", "true");
|
||||
* props.put("mail.smtp.starttls.enable", "true");
|
||||
* props.put("mail.smtp.tls", "true");
|
||||
* props.put("mail.smtp.ssl.checkserveridentity", "true");
|
||||
*/
|
||||
|
||||
if(encryptionType.equalsIgnoreCase("STARTTLS"))
|
||||
properties.setProperty("mail.smtp.starttls.enable", "true");
|
||||
else if(encryptionType.equalsIgnoreCase("TLS"))
|
||||
properties.put("mail.smtp.tls", "true");
|
||||
else if(encryptionType.equalsIgnoreCase("SSL"))
|
||||
properties.setProperty("mail.smtp.ssl.enable", "true");
|
||||
|
||||
// properties.put("mail.smtp.ssl.checkserveridentity", "false");
|
||||
|
||||
Session session;
|
||||
|
||||
Authenticator auth = new Authenticator()
|
||||
{
|
||||
protected PasswordAuthentication getPasswordAuthentication()
|
||||
{
|
||||
return new PasswordAuthentication(username, password);
|
||||
}
|
||||
};
|
||||
|
||||
if(useAuthentication)
|
||||
session = Session.getDefaultInstance(properties, auth);
|
||||
else
|
||||
session= Session.getDefaultInstance(properties, null);
|
||||
|
||||
// session.setDebug(true);
|
||||
|
||||
MimeMessage message = new MimeMessage(session);
|
||||
try
|
||||
{
|
||||
//the "from" address may be set in code, or set in the
|
||||
//config file under "mail.from" ; here, the latter style is used
|
||||
message.setFrom(new InternetAddress(aFromEmailAddr));
|
||||
message.addRecipient(Message.RecipientType.TO, new InternetAddress(aToEmailAddr));
|
||||
message.setSubject(aSubject);
|
||||
message.setText(aBody);
|
||||
Transport.send(message);
|
||||
return true;
|
||||
}
|
||||
catch (AddressException e)
|
||||
{
|
||||
System.err.println("Cannot send email. " + Diverse.getStackTraceAsString(e));
|
||||
}
|
||||
catch (javax.mail.MessagingException e)
|
||||
{
|
||||
System.err.println("Cannot send email. " + Diverse.getStackTraceAsString(e));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String readFile(File file)
|
||||
{
|
||||
String content = null;
|
||||
try
|
||||
{
|
||||
FileReader reader = new FileReader(file);
|
||||
char[] chars = new char[(int) file.length()];
|
||||
reader.read(chars);
|
||||
content = new String(chars);
|
||||
reader.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
public static double convertCelsiusToFahrenheit(double celsius)
|
||||
{
|
||||
return (celsius * 1.8 + 32);
|
||||
}
|
||||
|
||||
public static double convertFahrenheitToCelsius(double fahrenheit)
|
||||
{
|
||||
return ((fahrenheit - 32)/1.8);
|
||||
}
|
||||
|
||||
public static String downloadWebpage(String urlAddress)
|
||||
{
|
||||
URL url;
|
||||
InputStream is = null;
|
||||
BufferedReader br = null;
|
||||
String line;
|
||||
|
||||
try
|
||||
{
|
||||
url = new URL(urlAddress);
|
||||
is = url.openStream(); // throws an IOException
|
||||
br = new BufferedReader(new InputStreamReader(is));
|
||||
|
||||
StringBuilder returnString = new StringBuilder();
|
||||
|
||||
while ((line = br.readLine()) != null)
|
||||
{
|
||||
// System.out.println(line);
|
||||
returnString.append(line);
|
||||
}
|
||||
|
||||
if(br != null)
|
||||
br.close();
|
||||
|
||||
if (is != null)
|
||||
is.close();
|
||||
|
||||
Miscellaneous.logEvent("Webpage downloaded: " + returnString.toString(), 5);
|
||||
|
||||
return returnString.toString();
|
||||
}
|
||||
catch (MalformedURLException mue)
|
||||
{
|
||||
mue.printStackTrace();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if(br != null)
|
||||
br.close();
|
||||
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
// nothing to see here
|
||||
}
|
||||
}
|
||||
|
||||
return genericErrorMessage;
|
||||
}
|
||||
|
||||
public static boolean isDevelopment()
|
||||
{
|
||||
Boolean desenv = null;
|
||||
|
||||
// if (desenv != null)
|
||||
// return desenv;
|
||||
|
||||
try
|
||||
{
|
||||
desenv = new File(".").getCanonicalPath().contains("workspace");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return desenv;
|
||||
}
|
||||
|
||||
public static String getOnOffStringForBoolean(boolean state)
|
||||
{
|
||||
if(state)
|
||||
return "on";
|
||||
else
|
||||
return "off";
|
||||
}
|
||||
|
||||
// public enum SolarEvent { dawn, sunrise, solarNoon, sunset, dusk };
|
||||
|
||||
/**
|
||||
*
|
||||
* @param commandToExecute
|
||||
* @param timeout
|
||||
* @return Returns an array: 0=exit code, 1=cmdline output
|
||||
*/
|
||||
public static Object[] runExternalApplication(String commandToExecute, long timeout)
|
||||
{
|
||||
/*
|
||||
* Classes stolen from https://github.com/stleary/JSON-java
|
||||
*/
|
||||
|
||||
Miscellaneous.logEvent("Running external application " + commandToExecute + "...", 4);
|
||||
|
||||
Object[] returnObject = new Object[2];
|
||||
|
||||
StringBuilder output = new StringBuilder();
|
||||
String line = null;
|
||||
OutputStream stdin = null;
|
||||
InputStream stderr = null;
|
||||
InputStream stdout = null;
|
||||
|
||||
try
|
||||
{
|
||||
Process process = null;
|
||||
|
||||
process = Runtime.getRuntime().exec(commandToExecute);
|
||||
stdin = process.getOutputStream ();
|
||||
stderr = process.getErrorStream ();
|
||||
stdout = process.getInputStream ();
|
||||
|
||||
// "write" the parms into stdin
|
||||
/*line = "param1" + "\n";
|
||||
stdin.write(line.getBytes() );
|
||||
stdin.flush();
|
||||
|
||||
line = "param2" + "\n";
|
||||
stdin.write(line.getBytes() );
|
||||
stdin.flush();
|
||||
|
||||
line = "param3" + "\n";
|
||||
stdin.write(line.getBytes() );
|
||||
stdin.flush();
|
||||
|
||||
stdin.close(); */
|
||||
|
||||
// clean up if any output in stdout
|
||||
BufferedReader brCleanUp = new BufferedReader (new InputStreamReader (stdout));
|
||||
while ((line = brCleanUp.readLine ()) != null)
|
||||
{
|
||||
Miscellaneous.logEvent ("[Stdout] " + line, 4);
|
||||
output.append(line);
|
||||
}
|
||||
brCleanUp.close();
|
||||
|
||||
// clean up if any output in stderr
|
||||
brCleanUp = new BufferedReader (new InputStreamReader (stderr));
|
||||
while ((line = brCleanUp.readLine ()) != null)
|
||||
{
|
||||
Miscellaneous.logEvent ("[Stderr] " + line, 4);
|
||||
output.append(line);
|
||||
}
|
||||
brCleanUp.close();
|
||||
|
||||
try
|
||||
{
|
||||
// Wait for the process to exit, we want the return code
|
||||
if(timeout > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!process.waitFor(timeout, TimeUnit.MILLISECONDS))
|
||||
{
|
||||
Miscellaneous.logEvent("Timeout of " + String.valueOf(timeout) + " ms reached. Killing check attempt.", 3);
|
||||
process.destroyForcibly();
|
||||
}
|
||||
}
|
||||
catch(NoSuchMethodError e)
|
||||
{
|
||||
process.waitFor();
|
||||
}
|
||||
}
|
||||
else
|
||||
process.waitFor();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
Miscellaneous.logEvent("Waiting for process failed: " + Diverse.getStackTraceAsString(e), 4);
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("ReturnCode: " + String.valueOf(process.exitValue()), 4);
|
||||
|
||||
returnObject[0] = process.exitValue();
|
||||
returnObject[1] = output.toString();
|
||||
|
||||
return returnObject;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("Error running external application.", 1);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean restartNode()
|
||||
{
|
||||
// return true;
|
||||
return (boolean) runExternalApplication("sudo shutdown -r", 60000)[0];
|
||||
}
|
||||
|
||||
public static boolean isLeapYear(int year)
|
||||
{
|
||||
boolean leap = false;
|
||||
|
||||
if(year % 4 == 0)
|
||||
{
|
||||
if( year % 100 == 0)
|
||||
{
|
||||
// year is divisible by 400, hence the year is a leap year
|
||||
if ( year % 400 == 0)
|
||||
leap = true;
|
||||
else
|
||||
leap = false;
|
||||
}
|
||||
else
|
||||
leap = true;
|
||||
}
|
||||
else
|
||||
leap = false;
|
||||
|
||||
return leap;
|
||||
|
||||
/*if(leap)
|
||||
System.out.println(year + " is a leap year.");
|
||||
else
|
||||
System.out.println(year + " is not a leap year.");*/
|
||||
}
|
||||
|
||||
public static double getStarDate(Calendar when)
|
||||
{
|
||||
int y = when.get(Calendar.YEAR);
|
||||
|
||||
int n = 0;
|
||||
if(Miscellaneous.isLeapYear(y))
|
||||
n = 366;
|
||||
else
|
||||
n = 365;
|
||||
|
||||
int b = 2005;
|
||||
|
||||
long c = 58000;
|
||||
|
||||
int d = when.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
int m = 0;
|
||||
switch(when.get(Calendar.MONTH))
|
||||
{
|
||||
case Calendar.JANUARY:
|
||||
m = 0;
|
||||
break;
|
||||
case Calendar.FEBRUARY:
|
||||
m = 31;
|
||||
break;
|
||||
case Calendar.MARCH:
|
||||
m = 59;
|
||||
break;
|
||||
case Calendar.APRIL:
|
||||
m = 90;
|
||||
break;
|
||||
case Calendar.MAY:
|
||||
m = 120;
|
||||
break;
|
||||
case Calendar.JUNE:
|
||||
m = 151;
|
||||
break;
|
||||
case Calendar.JULY:
|
||||
m = 181;
|
||||
break;
|
||||
case Calendar.AUGUST:
|
||||
m = 212;
|
||||
break;
|
||||
case Calendar.SEPTEMBER:
|
||||
m = 243;
|
||||
break;
|
||||
case Calendar.OCTOBER:
|
||||
m = 273;
|
||||
break;
|
||||
case Calendar.NOVEMBER:
|
||||
m = 304;
|
||||
break;
|
||||
case Calendar.DECEMBER:
|
||||
m = 334;
|
||||
break;
|
||||
}
|
||||
|
||||
double stardate = c + (1000 * (y-b)) + (1000/n * (m+d-1));
|
||||
|
||||
return stardate;
|
||||
}
|
||||
}
|
194
ShoppingList/src/com/jens/rhasspy/shoppinglist/Product.java
Normal file
194
ShoppingList/src/com/jens/rhasspy/shoppinglist/Product.java
Normal file
@ -0,0 +1,194 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
import< |