Initial Commit

master
Harald Wolff 2018-05-29 11:01:49 +02:00
commit 1c2d7b5083
20 changed files with 987 additions and 0 deletions

10
.classpath 100644
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-9">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

4
.gitignore vendored 100755
View File

@ -0,0 +1,4 @@
.DS_Store
bin/*
/bin

17
.project 100644
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>bootstrap-platform</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>

View File

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=9
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=9
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=9

View File

@ -0,0 +1,5 @@
package bootstrap;
public enum ArgumentHandling {
UNHANDLED, HANDLED, CONTINUE
}

View File

@ -0,0 +1,27 @@
package bootstrap;
import java.util.Enumeration;
public class ArrayEnumerator<E> implements Enumeration<E>{
E[] values;
int cursor;
public ArrayEnumerator(E[] values) {
this.values = values;
this.cursor = 0;
}
@Override
public boolean hasMoreElements() {
return cursor < this.values.length;
}
@Override
public E nextElement() {
return this.values[ this.cursor++ ];
}
}

View File

@ -0,0 +1,46 @@
package bootstrap;
import static bootstrap.logging.Logging.*;
import bootstrap.logging.Logging;
import static bootstrap.logging.LogLevel.*;
public class Bootstrap {
static MultipleParameterOption libOption = new MultipleParameterOption('l',"library");
static SimpleOption verboseOption = new SimpleOption('v',"verbose");
static SimpleOption debugOption = new SimpleOption('d',"debug");
static SingleParameterOption logLevelOption = new SingleParameterOption("log-level",true);
static SingleParameterOption classOption = new SingleParameterOption('c',"class");
static SingleParameterOption bundleXmlOption = new SingleParameterOption('b',"bundle","bundle.xml");
static Option[] BootStrapOptions = {
verboseOption,
debugOption,
logLevelOption,
classOption,
libOption,
bundleXmlOption
};
public static void main(String[] args) {
Logging.Init(args, Bootstrap.class);
log("bootstrap-platform: Startup");
Options options = new Options(BootStrapOptions);
String[] unknown = options.parseCommandLineArguments(args);
for (String u: unknown) {
log(INFO,"Unkown Argument: %s",u);
}
for (String p: libOption.getParameters()) {
log(INFO,"Library override: %s",p);
}
}
}

View File

@ -0,0 +1,21 @@
package bootstrap;
import java.io.File;
public class Bundle {
String href;
public Bundle(String filename) {
load(new File(filename));
}
public Bundle(File file) {
load(file);
}
private void load(File file) {
}
}

View File

@ -0,0 +1,5 @@
package bootstrap;
public interface IArgumentListener {
public ArgumentHandling foundArgument(String argument,String parameter);
}

View File

@ -0,0 +1,53 @@
package bootstrap;
import java.util.LinkedList;
public class MultipleParameterOption extends Option {
boolean ignoreDoubles;
LinkedList<String> parameters = new LinkedList<>();
public MultipleParameterOption(Character shortOption, String longOption) {
super(shortOption, longOption);
}
public MultipleParameterOption(Character shortOption) {
super(shortOption);
}
public MultipleParameterOption(String longOption) {
super(longOption);
}
public MultipleParameterOption(Character shortOption, String longOption,boolean ignoreDoubles) {
super(shortOption, longOption);
this.ignoreDoubles = ignoreDoubles;
}
public MultipleParameterOption(Character shortOption,boolean ignoreDoubles) {
super(shortOption);
this.ignoreDoubles = ignoreDoubles;
}
public MultipleParameterOption(String longOption,boolean ignoreDoubles) {
super(longOption);
this.ignoreDoubles = ignoreDoubles;
}
@Override
public boolean hasParameters() {
return true;
}
@Override
public void addParameter(String parameter) throws IllegalArgumentException {
Set();
if (ignoreDoubles || !this.parameters.contains(parameter))
this.parameters.add(parameter);
}
public String[] getParameters() {
return this.parameters.toArray(new String[0]);
}
}

View File

@ -0,0 +1,107 @@
package bootstrap;
public abstract class Option {
Character shortOption;
String longOption;
boolean isset;
public Option(String longOption) {
this.longOption = longOption;
}
public Option(Character shortOption) {
this.shortOption = shortOption;
}
public Option(Character shortOption,String longOption) {
this.shortOption = shortOption;
this.longOption = longOption;
}
public Character getShortOption() {
return this.shortOption;
}
public String getLongOption() {
return this.longOption;
}
public boolean isSet() {
return this.isset;
}
public void Set() {
this.isset = true;
}
public void Unset() {
this.isset = false;
}
public boolean match(String argument) {
if (
((longOption != null) && (argument.startsWith("--")) && (longOption.equals(argument.substring(2)))) ||
((shortOption != null) && (argument.length()==2) && (argument.charAt(0)=='-') && (argument.charAt(1) == shortOption))
){
return true;
}
return false;
}
public abstract boolean hasParameters();
public void addParameter(String parameter) throws IllegalArgumentException{
throw new IllegalArgumentException(String.format("Option %s dos not accept any parameters",this));
}
@Override
public String toString() {
if (this.shortOption == null) {
return "--" + this.longOption;
} else if (this.longOption == null) {
return "-" + this.shortOption;
} else {
return String.format("[ -%c | --%s ]", shortOption,longOption);
}
}
}
/*
OptionType optionType = OptionType.BOOLEAN;
String name;
LinkedList<String> parameters = new LinkedList<>();
public Option(String name) {
this.name = name;
}
public Option(String name,OptionType OptionType) {
this.name = name;
this.optionType = OptionType;
}
public Option(String argument,String[] parameters) {
this.optionType = OptionType.MULTIPLE;
this.name = argument;
for (String p : parameters) {
this.parameters.add(p);
}
}
public Option(String name,OptionType OptionType,String[] parameters) {
this.name = name;
for (String p : parameters) {
this.parameters.add(p);
}
}
public String getName() {
return this.name;
}
public String[] getParameters() {
return this.parameters.toArray(new String[0]);
}
public String getParameter(int n) {
return this.parameters.get(n);
}
public void addParameter(String p){
this.parameters.add(p);
}
*/

View File

@ -0,0 +1,56 @@
package bootstrap;
import java.util.LinkedList;
public class Options {
LinkedList<String> unkownArguments = new LinkedList<>();
LinkedList<Option> options = new LinkedList<>();
public Options() {
}
public Options(Option[] options) {
for (Option o : options){
this.options.add(o);
}
}
public void addOption(Option option) {
this.options.add(option);
}
public void removeOption(Option option) {
this.options.remove(option);
}
public String[] parseCommandLineArguments(String[] arguments) {
ArrayEnumerator<String> en = new ArrayEnumerator<>(arguments);
while (en.hasMoreElements()) {
String arg = en.nextElement();
if (arg.startsWith("-")) {
for (Option o:this.options) {
if (o.match(arg)) {
if (o.hasParameters()) {
o.addParameter(en.nextElement());
} else {
o.Set();
}
arg = null;
break;
}
}
if (arg != null) {
unkownArguments.add(arg);
}
} else {
unkownArguments.add(arg);
}
}
return this.unkownArguments.toArray(new String[0]);
}
}

View File

@ -0,0 +1,22 @@
package bootstrap;
public class SimpleOption extends Option {
public SimpleOption(Character shortOption) {
super(shortOption);
}
public SimpleOption(Character shortOption, String longOption) {
super(shortOption, longOption);
}
public SimpleOption(String longOption) {
super(longOption);
}
@Override
public boolean hasParameters() {
return false;
}
}

View File

@ -0,0 +1,64 @@
package bootstrap;
public class SingleParameterOption extends Option {
boolean mayOverride;
String parameter;
public SingleParameterOption(Character shortOption, String longOption) {
super(shortOption, longOption);
}
public SingleParameterOption(Character shortOption) {
super(shortOption);
}
public SingleParameterOption(String longOption) {
super(longOption);
}
public SingleParameterOption(Character shortOption, String longOption,String defaultValue) {
super(shortOption, longOption);
this.parameter = defaultValue;
}
public SingleParameterOption(String longOption,String defaultValue) {
super(longOption);
this.parameter = defaultValue;
}
public SingleParameterOption(Character shortOption, String longOption,boolean mayOverride) {
super(shortOption, longOption);
this.mayOverride = mayOverride;
}
public SingleParameterOption(Character shortOption,boolean mayOverride) {
super(shortOption);
this.mayOverride = mayOverride;
}
public SingleParameterOption(String longOption,boolean mayOverride) {
super(longOption);
this.mayOverride = mayOverride;
}
@Override
public boolean hasParameters() {
return true;
}
@Override
public void addParameter(String parameter) throws IllegalArgumentException {
if (this.isSet() && !mayOverride) {
throw new IllegalArgumentException(String.format("Option %s may only be used one time. Already got '%s' and received '%s'.",this,this.parameter,parameter));
}
Set();
this.parameter = parameter;
}
public String getParameter(){
return this.parameter;
}
}

View File

@ -0,0 +1,14 @@
package bootstrap.logging;
public enum LogLevel {
FATAL(0), // Fehler welche zum Programmabbruch führen
ERROR(2), // Fehler, Ereignisse welche erwartetes Verhalten beeinflussen / verhindern
WARN(5), // Warnungen, Ereignisse welche zu weiteren Problemen ("Fehlern") führen können
INFO(10), // Allgemeine Informationen (Fortschritt, etc.)
DEBUG(25), // Ausgaben zur Fehlersuche
DEBUGDETAIL(30); // Detailausgaben zur Fehlersuche
private final int n;
LogLevel(int l){ n=l; };
public int getLevel(){ return n; }
}

View File

@ -0,0 +1,238 @@
package bootstrap.logging;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class Logging {
private static Logging _inst;
private static PrintStream liveStream;
private PrintStream logStream;
private DateFormat dateFormat;
List<LoggingListener> loggingListeners;
private int limitLogLevel;
private String logFilename;
public Logging(){
setLogFileName("application.log");
initialize();
}
public Logging(String filename){
setLogFileName(filename);
initialize();
}
private void initialize(){
loggingListeners = new LinkedList<LoggingListener>();
limitLogLevel = 10;
dateFormat = DateFormat.getDateTimeInstance();
System.setErr(new PrintStream(new LoggingOutputStream(LogLevel.ERROR)));
System.setOut(new PrintStream(new LoggingOutputStream(LogLevel.INFO)));
}
public PrintStream getLogStream(){
if (this.logStream == null){
try {
logStream = new PrintStream(logFilename);
} catch (FileNotFoundException e){
logStream = liveStream;
log(LogLevel.ERROR,"Logging: setLogFileName(%s) failed:",logFilename);
log(e);
}
}
return logStream;
}
public void setLogFileName(String filename){
this.logFilename = filename;
File f = new File(logFilename);
File fold = new File(String.format("%s.old", logFilename));
if (fold.exists()){
fold.delete();
}
if (f.exists()){
f.renameTo(fold);
}
}
public int getLimitLogLevel() {
return limitLogLevel;
}
public void setLimitLogLevel(int limitLogLevel) {
this.limitLogLevel = limitLogLevel;
}
public void addLoggingListener(LoggingListener listener){
loggingListeners.add(listener);
}
public void removeLoggingListener(LoggingListener listener){
loggingListeners.remove(listener);
}
private void _log(LogLevel logLevel,String message){
String formattedLine;
if (logLevel.getLevel() > limitLogLevel)
return;
formattedLine = String.format("%s [%-12s] %s", dateFormat.format(new Date()),logLevel.toString(),message);
getLogStream().println(formattedLine);
getLogStream().flush();
if (liveStream != null){
liveStream.println(formattedLine);
liveStream.flush();
}
for (LoggingListener l: loggingListeners){
l.logMessageArrived(formattedLine);
}
}
static public void log(LogLevel logLevel,String message){
if (_inst == null){
_inst = new Logging("application.log");
}
_inst._log(logLevel, message);
}
static public void log(String message){
log(LogLevel.INFO,message);
}
static public void log(LogLevel logLevel,String message,Object... args){
log(logLevel,String.format(message, args));
}
static public void log(String message,Object... args){
log(LogLevel.INFO,message,args);
}
static public void log(Exception e){
log(LogLevel.ERROR,"Exception: %s [%s]",e.getClass().getName(), e.getMessage());
/* if (ExtendedExceptionBase.class.isInstance(e)){
ExtendedExceptionBase ee = (ExtendedExceptionBase)e;
if (ee.getDebugMessage()!=null)
log(LogLevel.DEBUG,String.format("%s: %s", e.getClass().getName(),ee.getDebugMessage()));
if (ee.getDebugDetails()!=null)
log(LogLevel.DEBUGDETAIL,String.format("%s: %s",e.getClass().getName(),ee.getDebugDetails()));
}
*/
log(LogLevel.DEBUG,formatStackTrace(e.getStackTrace()));
}
static String formatStackTrace(StackTraceElement[] stackTrace){
StringBuilder sb = new StringBuilder();
for (StackTraceElement ste: stackTrace){
sb.append(String.format("-> %s.%s() = %s:%s\n", ste.getClassName(),ste.getMethodName(),ste.getFileName(),ste.getLineNumber()));
}
return sb.toString();
}
static public Logging getInstance() {
return _inst;
}
static public String[] Init(String[] arguments,Class<?> mainClass){
return Init(arguments, mainClass.getCanonicalName() + ".log");
}
static public String[] Init(String[] arguments,String defaultFileName){
LinkedList<String> args = new LinkedList<>();
Iterator<String> i = Arrays.asList(arguments).iterator();
Logging._inst = new Logging();
Logging._inst.setLogFileName(defaultFileName);
while (i.hasNext()){
String option = i.next();
switch (option){
case "--log-filename":
Logging._inst.setLogFileName(i.next());
break;
case "--log-level":
Logging._inst.setLimitLogLevel(Integer.parseInt(i.next()));
break;
default:
args.add(option);
break;
}
}
return args.toArray(new String[0]);
}
static {
liveStream = System.out;
}
public class LoggingOutputStream extends OutputStream {
byte[] buffer;
int bufferPosition;
LogLevel
logLevel;
public LoggingOutputStream() {
buffer = new byte[4096];
bufferPosition = 0;
this.logLevel = LogLevel.INFO;
}
public LoggingOutputStream(LogLevel logLevel) {
buffer = new byte[4096];
bufferPosition = 0;
this.logLevel = logLevel;
}
@Override
public void flush(){
if (bufferPosition > 0){
_log(this.logLevel,new String(buffer,0,bufferPosition));
bufferPosition = 0;
};
}
@Override
public void write(int b) throws IOException {
if (b == 0x0A){
flush();
} else {
buffer[bufferPosition++] = new Integer(b).byteValue();
if (bufferPosition == buffer.length){
flush();
}
};
}
}
}

View File

@ -0,0 +1,7 @@
package bootstrap.logging;
public interface LoggingListener {
public void logMessageArrived(String message);
}

View File

@ -0,0 +1,119 @@
package bootstrap.platform;
import java.io.File;
import java.io.IOException;
import bootstrap.platform.Platform;
import bootstrap.platform.Ressource;
public class NativeLoader {
private static boolean patchedLinux = false;
public static String nativeLibraryName(String libName){
switch (Platform.getOperatingSystem())
{
case LINUX:
return String.format("lib%s.so",libName);
case OSX:
return String.format("lib%s.dylib",libName);
case WINDOWS:
return String.format("%s.dll",libName);
default:
throw new RuntimeException("Betriebssystem nicht unterstützt!");
}
}
public static String nativeResourceName(String libName){
return String.format("/native/%s/%s", Platform.PlatformName(), nativeLibraryName(libName));
}
public static String nativeLocalResourceName(String libName){
return String.format("native%s%s%s%s", File.separator, Platform.PlatformName(), File.separator, nativeLibraryName(libName));
}
/*
* loadLibrary()
*
* Versuche native Bibliothek zu laden
*
* 1. System.loadLibrary(...)
* 2. System.load(...)
* 3. /native/...
* 4. CLASSPATH:/native/...
*
*/
public static void loadLibrary(String libName)
{
try
{
System.loadLibrary(libName);
System.out.println(String.format("NativeLoader.loadLibrary(): System.loadLibrary('%s') erfolgreich",libName));
return;
} catch (UnsatisfiedLinkError e)
{
System.err.println(String.format("NativeLoader.loadLibrary(): System.loadLibrary('%s') erfolglos",libName));
};
String libFileName = new File("").getAbsolutePath() + File.separator + nativeLibraryName(libName);
try
{
System.load(libFileName);
System.out.println(String.format("NativeLoader.loadLibrary(): System.load('%s') erfolgreich",libFileName));
return;
} catch (UnsatisfiedLinkError e)
{
System.err.println(String.format("NativeLoader.loadLibrary(): System.load('%s') erfolglos",libFileName));
};
String nativeLocalResourceName = new File("").getAbsolutePath() + File.separator + nativeLocalResourceName(libName);
try
{
System.load(nativeLocalResourceName);
System.out.println(String.format("NativeLoader.loadLibrary(): System.load('%s') erfolgreich",nativeLocalResourceName));
return;
} catch (UnsatisfiedLinkError e)
{
System.err.println(String.format("NativeLoader.loadLibrary(): System.load('%s') erfolglos",nativeLocalResourceName));
};
String nativeResourceName = nativeResourceName(libName);
try
{
System.load(nativeResourceName);
System.out.println(String.format("NativeLoader.loadLibrary(): System.load('%s') erfolgreich",nativeResourceName));
return;
} catch (UnsatisfiedLinkError e)
{
System.err.println(String.format("NativeLoader.loadLibrary(): System.load('%s') erfolglos",nativeResourceName));
};
File tempLibFile;
try {
tempLibFile = File.createTempFile("extract-", nativeLibraryName(libName));
} catch (IOException ioe){
System.err.println(String.format("NativeLoader.loadLibrary(): File.createTempFile('extract-','%s') erfolglos",nativeLibraryName(libName)));
throw new RuntimeException(ioe);
}
try {
Ressource.extract(nativeResourceName, tempLibFile.getAbsolutePath());
System.load(tempLibFile.getAbsolutePath());
System.out.println(String.format("NativeLoader.loadLibrary(): System.load('%s') erfolgreich",tempLibFile.getAbsolutePath()));
return;
} catch (UnsatisfiedLinkError e)
{
System.err.println(String.format("NativeLoader.loadLibrary(): System.load('%s') erfolglos",tempLibFile.getAbsolutePath()));
} catch (Exception e){
System.err.println(String.format("NativeLoader.loadLibrary(): Resource.extract('%s','%s') erfolglos",nativeResourceName,tempLibFile.getAbsolutePath()));
throw new RuntimeException(e);
}
}
static {
/* Suchpfad um aktuelles Arbeitsberzeichnis erweitern */
System.setProperty("java.library.path",String.format(".:%s",System.getProperty("java.library.path")));
}
}

View File

@ -0,0 +1,105 @@
package bootstrap.platform;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Platform {
public enum OsType { UNKNOWN, LINUX, OSX, WINDOWS};
public enum Bitness { B32, B64 };
public static OsType getOperatingSystem()
{
if (System.getProperty("os.name").equals("Mac OS X"))
return OsType.OSX;
if (System.getProperty("os.name").equals("Linux"))
return OsType.LINUX;
if (System.getProperty("os.name").startsWith("Windows"))
return OsType.WINDOWS;
return OsType.UNKNOWN;
}
public static Bitness getBitness(){
String arch = System.getProperty("os.arch");
if (arch == null) {
return null;
}
if (arch.equals("x86")){
return Bitness.B32;
} else if (arch.equals("i386")){
return Bitness.B32;
} else if (arch.equals("xmd64")){
return Bitness.B64;
} else if (arch.equals("amd64")){
return Bitness.B64;
} else if (arch.equals("x86_64")){
return Bitness.B64;
}
return null;
}
public static String PlatformName(){
OsType ost = getOperatingSystem();
Bitness bit = getBitness();
return String.format("%s%s",
(ost == OsType.LINUX) ? "linux" :
(ost == OsType.OSX) ? "osx" :
(ost == OsType.WINDOWS) ? "mswin" :
"unknown",
(bit == Bitness.B32) ? "32" :
(bit == Bitness.B64) ? "64" :
"XX"
);
}
static private String getHostNameFromFile(){
String hostname = System.getenv("HOSTNAME");
if (hostname == null){
try {
FileReader fr = new FileReader("/etc/hostname");
char[] b = new char[2048];
fr.read(b, 0, 2048);
fr.close();
hostname = new String(b).trim();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return hostname;
}
public static String getHostName(){
switch (getOperatingSystem()){
case WINDOWS:
return System.getenv("COMPUTERNAME");
case LINUX:
case OSX:
ProcessBuilder pb = new ProcessBuilder();
pb.command("/bin/hostname");
try {
Process p = pb.start();
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String hostname = reader.readLine().trim();
return hostname;
} catch (IOException e1) {
} catch (InterruptedException e) {
}
default:
return getHostNameFromFile();
}
}
}

View File

@ -0,0 +1,56 @@
package bootstrap.platform;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import bootstrap.platform.NativeLoader;
public class Ressource {
public static boolean extract(Class<?> clazz,String resource,String filename){
return extract(
clazz.getResourceAsStream(resource),
filename
);
}
public static boolean extract(String resource,String filename){
return extract(
NativeLoader.class.getResourceAsStream(resource),
filename
);
}
public static byte[] load(String resource){
try {
return load(NativeLoader.class.getResourceAsStream(resource));
} catch (IOException ioe){
return null;
}
}
public static byte[] load(InputStream in) throws IOException{
if (in == null){
return new byte[0];
}
byte[] buffer = new byte[in.available()];
in.read(buffer);
return buffer;
}
private static boolean extract(InputStream in,String filename){
try {
FileOutputStream fos = new FileOutputStream(filename);
fos.write(load(in));
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}