first impl
parent
cec70f1e1f
commit
0e2b9a4e7e
|
@ -0,0 +1,97 @@
|
||||||
|
package de.synolo.lib.fw;
|
||||||
|
|
||||||
|
import de.synolo.lib.fw.cmd.Command;
|
||||||
|
import de.synolo.lib.fw.cmd.UndoManager;
|
||||||
|
import javafx.application.Application;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.layout.BorderPane;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
public class TestMain extends Application {
|
||||||
|
|
||||||
|
static class TestCommand implements Command {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
System.out.println("Execute command!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isUndoable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCollapsable(Command other) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void collapse(Command other) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void undo() {
|
||||||
|
System.out.println("Undo command");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void redo() {
|
||||||
|
System.out.println("Redo command");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return "command.test";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
launch(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Stage primaryStage) throws Exception {
|
||||||
|
|
||||||
|
UndoManager undoManager = new UndoManager();
|
||||||
|
|
||||||
|
BorderPane bp = new BorderPane();
|
||||||
|
Scene scene = new Scene(bp);
|
||||||
|
|
||||||
|
Button btn = new Button("Execute command");
|
||||||
|
bp.setCenter(btn);
|
||||||
|
|
||||||
|
Button btnUndo = new Button("Undo");
|
||||||
|
btnUndo.disableProperty().bind(undoManager.undoAvailableProperty().not());
|
||||||
|
btnUndo.setOnAction(e -> undoManager.undo());
|
||||||
|
|
||||||
|
|
||||||
|
Button btnRedo = new Button("Redo");
|
||||||
|
btnRedo.disableProperty().bind(undoManager.redoAvailableProperty().not());
|
||||||
|
btnRedo.setOnAction(e -> undoManager.redo());
|
||||||
|
|
||||||
|
btn.setOnAction(e -> undoManager.execute(new TestCommand()));
|
||||||
|
|
||||||
|
VBox vbox = new VBox();
|
||||||
|
vbox.getChildren().addAll(btnUndo, btnRedo);
|
||||||
|
|
||||||
|
bp.setBottom(vbox);
|
||||||
|
|
||||||
|
primaryStage.setScene(scene);
|
||||||
|
primaryStage.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package de.synolo.lib.fw.app;
|
||||||
|
|
||||||
|
import de.synolo.lib.fw.utils.Logging;
|
||||||
|
import javafx.application.Application;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.stage.Modality;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.StageStyle;
|
||||||
|
|
||||||
|
public abstract class AbstractApplication<C extends ApplicationContext> extends Application {
|
||||||
|
|
||||||
|
private C context;
|
||||||
|
private Stage primaryStage;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() throws Exception {
|
||||||
|
super.init();
|
||||||
|
Logging.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Stage primaryStage) throws Exception {
|
||||||
|
this.primaryStage = primaryStage;
|
||||||
|
this.context = initContext();
|
||||||
|
|
||||||
|
buildApplication(primaryStage);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void buildApplication(Stage primaryStage) throws Exception;
|
||||||
|
|
||||||
|
public C getContext() { return this.context; }
|
||||||
|
protected abstract C initContext();
|
||||||
|
|
||||||
|
public Stage getPrimaryStage() { return this.primaryStage; }
|
||||||
|
|
||||||
|
public Stage showDialog(Modality modality, StageStyle style, Scene scene) {
|
||||||
|
Stage dialog = new Stage();
|
||||||
|
dialog.initOwner(this.primaryStage);
|
||||||
|
dialog.initModality(modality);
|
||||||
|
dialog.initStyle(style);
|
||||||
|
dialog.setScene(scene);
|
||||||
|
dialog.show();
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package de.synolo.lib.fw.app;
|
||||||
|
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
import de.synolo.lib.fw.cmd.UndoManager;
|
||||||
|
import de.synolo.lib.fw.utils.TypedProperties;
|
||||||
|
|
||||||
|
public abstract class ApplicationContext {
|
||||||
|
|
||||||
|
protected TypedProperties properties;
|
||||||
|
protected Preferences preferences;
|
||||||
|
protected UndoManager undoManager;
|
||||||
|
|
||||||
|
public ApplicationContext() {}
|
||||||
|
|
||||||
|
public TypedProperties getProperties() { return this.properties; }
|
||||||
|
public Preferences getPreferences() { return this.preferences; }
|
||||||
|
public UndoManager getUndoManager() { return this.undoManager; }
|
||||||
|
|
||||||
|
public abstract String getApplicationName();
|
||||||
|
public abstract String getApplicationVersion();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package de.synolo.lib.fw.cmd;
|
||||||
|
|
||||||
|
public interface Command {
|
||||||
|
|
||||||
|
public void execute();
|
||||||
|
|
||||||
|
public boolean isUndoable();
|
||||||
|
public boolean isCollapsable(Command other);
|
||||||
|
|
||||||
|
public void collapse(Command other);
|
||||||
|
|
||||||
|
public void undo();
|
||||||
|
public void redo();
|
||||||
|
|
||||||
|
public String getId();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package de.synolo.lib.fw.cmd;
|
||||||
|
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||||
|
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
||||||
|
|
||||||
|
public class UndoManager {
|
||||||
|
|
||||||
|
private Stack<Command> undoStack;
|
||||||
|
private Stack<Command> redoStack;
|
||||||
|
|
||||||
|
private ReadOnlyBooleanWrapper undoAvailalableProperty = new ReadOnlyBooleanWrapper(false);
|
||||||
|
private ReadOnlyBooleanWrapper redoAvailalableProperty = new ReadOnlyBooleanWrapper(false);
|
||||||
|
|
||||||
|
private int max;
|
||||||
|
|
||||||
|
public UndoManager(int maxCommands) {
|
||||||
|
this.max = maxCommands;
|
||||||
|
this.undoStack = new Stack<>();
|
||||||
|
this.redoStack = new Stack<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public UndoManager() {
|
||||||
|
this(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxCommands() { return this.max; }
|
||||||
|
public void setMaxCommands(int max) { this.max = max; }
|
||||||
|
|
||||||
|
public boolean isUndoAvailable() {
|
||||||
|
return !this.undoStack.isEmpty();
|
||||||
|
}
|
||||||
|
public ReadOnlyBooleanProperty undoAvailableProperty() { return this.undoAvailalableProperty.getReadOnlyProperty(); }
|
||||||
|
|
||||||
|
public boolean isRedoAvailable() {
|
||||||
|
return !this.redoStack.isEmpty();
|
||||||
|
}
|
||||||
|
public ReadOnlyBooleanProperty redoAvailableProperty() { return this.redoAvailalableProperty.getReadOnlyProperty(); }
|
||||||
|
|
||||||
|
public void execute(Command cmd) {
|
||||||
|
Command last = null;
|
||||||
|
|
||||||
|
if(!this.undoStack.isEmpty() && (last = this.undoStack.peek()) != null) {
|
||||||
|
if(last.isCollapsable(cmd)) {
|
||||||
|
last.collapse(cmd);
|
||||||
|
return;
|
||||||
|
}else {
|
||||||
|
this.redoStack.clear();
|
||||||
|
this.undoStack.push(cmd);
|
||||||
|
}
|
||||||
|
}else if(cmd.isUndoable()) {
|
||||||
|
this.redoStack.clear();
|
||||||
|
this.undoStack.push(cmd);
|
||||||
|
}
|
||||||
|
if(this.undoStack.size() > this.max) {
|
||||||
|
this.undoStack.remove(0);
|
||||||
|
}
|
||||||
|
cmd.execute();
|
||||||
|
update();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void undo() {
|
||||||
|
System.out.println("undo...");
|
||||||
|
if(isUndoAvailable()) {
|
||||||
|
Command cmd = this.undoStack.pop();
|
||||||
|
this.redoStack.push(cmd);
|
||||||
|
cmd.undo();
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void redo() {
|
||||||
|
if(isRedoAvailable()) {
|
||||||
|
Command cmd = this.redoStack.pop();
|
||||||
|
this.undoStack.push(cmd);
|
||||||
|
cmd.redo();
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update() {
|
||||||
|
this.undoAvailalableProperty.set(isUndoAvailable());
|
||||||
|
this.redoAvailalableProperty.set(isRedoAvailable());
|
||||||
|
System.out.println(this.undoStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package de.synolo.lib.fw.utils;
|
||||||
|
|
||||||
|
public enum LogLevel {
|
||||||
|
TRACE(16),
|
||||||
|
DEBUG(8),
|
||||||
|
INFO(4),
|
||||||
|
WARNING(2),
|
||||||
|
ERROR(0);
|
||||||
|
|
||||||
|
private int val;
|
||||||
|
|
||||||
|
private LogLevel(final int val) { this.val = val; }
|
||||||
|
|
||||||
|
public int val() { return this.val; }
|
||||||
|
|
||||||
|
public static LogLevel forVal(int val) {
|
||||||
|
LogLevel found = ERROR;
|
||||||
|
LogLevel[] levels = LogLevel.class.getEnumConstants();
|
||||||
|
for(LogLevel level : levels) {
|
||||||
|
if(val >= level.val() && found.val() < level.val()) {
|
||||||
|
found = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,187 @@
|
||||||
|
package de.synolo.lib.fw.utils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class Logging {
|
||||||
|
|
||||||
|
public static final String DEFAULT_FORMAT = "[%date][%level] %msg\n";
|
||||||
|
public static final DateFormat DEFAULT_DATEFORMAT = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss.SSS");
|
||||||
|
|
||||||
|
public static Logging out;
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
out = new Logging(null);
|
||||||
|
}
|
||||||
|
public static void init(String lvl) {
|
||||||
|
LogLevel level = lvl == null ? null : LogLevel.valueOf(lvl.toUpperCase());
|
||||||
|
out = new Logging(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String format;
|
||||||
|
protected LogLevel level;
|
||||||
|
protected PrintStream filestream, defaultstream;
|
||||||
|
protected File file = null;
|
||||||
|
protected DateFormat dateformat;
|
||||||
|
protected ArrayList<String> messages = new ArrayList<String>();
|
||||||
|
protected Thread loggingThread;
|
||||||
|
|
||||||
|
protected Logging(LogLevel level) {
|
||||||
|
this.format = DEFAULT_FORMAT;
|
||||||
|
this.dateformat = DEFAULT_DATEFORMAT;
|
||||||
|
this.level = level == null ? LogLevel.INFO : level;
|
||||||
|
this.defaultstream = System.out;
|
||||||
|
System.setErr(new PrintStream(new LoggingOutputStream(LogLevel.ERROR)));
|
||||||
|
System.setOut(new PrintStream(new LoggingOutputStream(LogLevel.INFO)));
|
||||||
|
log("Initialized Logging with LogLevel: %s", this.level.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void writeToFile(String write) {
|
||||||
|
if (filestream != null) {
|
||||||
|
filestream.println(write);
|
||||||
|
filestream.flush();
|
||||||
|
}
|
||||||
|
defaultstream.print(write);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(LogLevel level, String format, Object...args) {
|
||||||
|
if(level.val() > this.level.val()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String dateStr = this.dateformat.format(new Date());
|
||||||
|
String levelStr = String.format("%-8s", level.toString());
|
||||||
|
String msgStr = String.format(format, args);
|
||||||
|
|
||||||
|
String formatted = String.format("[%s][%s] %s \n", dateStr, levelStr, msgStr);
|
||||||
|
writeToFile(formatted);
|
||||||
|
|
||||||
|
}
|
||||||
|
public void log(String format, Object...args) {
|
||||||
|
log(LogLevel.INFO, format, args);
|
||||||
|
}
|
||||||
|
public void log(String msg) {
|
||||||
|
log(msg, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void err(String format, Object...args) {
|
||||||
|
log(LogLevel.ERROR, format, args);
|
||||||
|
}
|
||||||
|
public void err(String msg) {
|
||||||
|
err(msg, "");
|
||||||
|
}
|
||||||
|
public void err(Object obj) {
|
||||||
|
err(obj.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void warn(String format, Object...args) {
|
||||||
|
log(LogLevel.WARNING, format, args);
|
||||||
|
}
|
||||||
|
public void warn(String msg) {
|
||||||
|
warn(msg, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void debug(String format, Object...args) {
|
||||||
|
log(LogLevel.DEBUG, format, args);
|
||||||
|
}
|
||||||
|
public void debug(String msg) {
|
||||||
|
debug(msg, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void detail(String format, Object...args) {
|
||||||
|
log(LogLevel.TRACE, format, args);
|
||||||
|
}
|
||||||
|
public void detail(String msg) {
|
||||||
|
detail(msg, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormat() {
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
public void setFormat(String format) {
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogLevel getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
public void setLevel(LogLevel level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
public void setLevel(int level) {
|
||||||
|
this.level = LogLevel.forVal(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
public File getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
public void setFile(File file){
|
||||||
|
try {
|
||||||
|
if(!file.exists()) {
|
||||||
|
file.createNewFile();
|
||||||
|
}
|
||||||
|
this.filestream = new PrintStream(new FileOutputStream(file, true));
|
||||||
|
}catch(IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
this.file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateFormat getDateformat() {
|
||||||
|
return dateformat;
|
||||||
|
}
|
||||||
|
public void setDateformat(DateFormat dateformat) {
|
||||||
|
this.dateformat = dateformat;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected 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){
|
||||||
|
String str = new String(buffer,0,bufferPosition);
|
||||||
|
log(this.logLevel, str, "");
|
||||||
|
bufferPosition = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
if (b == 0x0A){
|
||||||
|
|
||||||
|
flush();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
buffer[bufferPosition++] = (byte)b;
|
||||||
|
|
||||||
|
if (bufferPosition == buffer.length){
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
package de.synolo.lib.fw.utils;
|
||||||
|
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.scene.control.MultipleSelectionModel;
|
||||||
|
|
||||||
|
public class MultipleSelectionModelWrapper<T> extends MultipleSelectionModel<T>{
|
||||||
|
|
||||||
|
private ObservableList<T> items;
|
||||||
|
private ObservableList<Integer> indices = FXCollections.observableArrayList();
|
||||||
|
private ObservableList<T> selectedItems = FXCollections.observableArrayList();
|
||||||
|
|
||||||
|
public MultipleSelectionModelWrapper(ObservableList<T> list) {
|
||||||
|
this.items = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableList<Integer> getSelectedIndices() { return this.indices; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableList<T> getSelectedItems() { return this.selectedItems; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectIndices(int index, int... indices) {
|
||||||
|
select(index);
|
||||||
|
for(int idx : indices)
|
||||||
|
select(idx);
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void selectAll() {
|
||||||
|
clearSelection();
|
||||||
|
for(int i = 0; i < this.items.size(); i++) {
|
||||||
|
this.selectedItems.add(this.items.get(i));
|
||||||
|
this.indices.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectFirst() {
|
||||||
|
clearSelection();
|
||||||
|
select(0);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void selectLast() {
|
||||||
|
clearSelection();
|
||||||
|
select(this.items.size()-1);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void clearAndSelect(int index) {
|
||||||
|
clearSelection();
|
||||||
|
select(index);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void select(int index) {
|
||||||
|
if(index < this.items.size() && index >= 0) {
|
||||||
|
T item = this.items.get(index);
|
||||||
|
if(!this.selectedItems.contains(item)) {
|
||||||
|
this.selectedItems.add(item);
|
||||||
|
this.indices.add(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void select(T obj) {
|
||||||
|
if(this.items.contains(obj) && !this.selectedItems.contains(obj)) {
|
||||||
|
int index = this.items.indexOf(obj);
|
||||||
|
this.selectedItems.add(obj);
|
||||||
|
this.indices.add(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearSelection(int index) {
|
||||||
|
if(this.indices.contains(index)) {
|
||||||
|
T item = this.items.get(index);
|
||||||
|
this.selectedItems.remove(item);
|
||||||
|
this.indices.remove(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void clearSelection() {
|
||||||
|
this.indices.clear();
|
||||||
|
this.selectedItems.clear();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean isSelected(int index) { return this.indices.contains(index); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() { return this.selectedItems.isEmpty(); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectPrevious() {
|
||||||
|
int index = this.indices.get(this.indices.size()-1);
|
||||||
|
select(index-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void selectNext() {
|
||||||
|
int index = this.indices.get(this.indices.size()-1);
|
||||||
|
select(index+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package de.synolo.lib.fw.utils;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class TypedProperties extends Properties {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
interface Converter<T> {
|
||||||
|
T convert(String input) throws Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T getObject(String key, T defaultValue, Converter<T> converter) {
|
||||||
|
T val = defaultValue;
|
||||||
|
try {
|
||||||
|
val = converter.convert(getProperty(key));
|
||||||
|
}catch(Exception e) {
|
||||||
|
val = defaultValue;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getByte(String key, byte defaultValue) { return getObject(key, defaultValue, Byte::parseByte); }
|
||||||
|
public byte getByte(String key) { return getByte(key, (byte)0); }
|
||||||
|
|
||||||
|
public short getShort(String key, short defaultValue) { return getObject(key, defaultValue, Short::parseShort); }
|
||||||
|
public short getShort(String key) { return getShort(key, (short)0); }
|
||||||
|
|
||||||
|
public int getInt(String key, int defaultValue) { return getObject(key, defaultValue, Integer::parseInt); }
|
||||||
|
public int getInt(String key) { return getInt(key, 0); }
|
||||||
|
|
||||||
|
public long getLong(String key, long defaultValue) { return getObject(key, defaultValue, Long::parseLong); }
|
||||||
|
public long getLong(String key) { return getLong(key, (byte)0); }
|
||||||
|
|
||||||
|
public float getFloat(String key, float defaultValue) { return getObject(key, defaultValue, Float::parseFloat); }
|
||||||
|
public float getFloat(String key) { return getFloat(key, (byte)0); }
|
||||||
|
|
||||||
|
public double getDouble(String key, double defaultValue) { return getObject(key, defaultValue, Double::parseDouble); }
|
||||||
|
public double getDouble(String key) { return getDouble(key, (byte)0); }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<archetype>
|
||||||
|
<id>lib-fw</id>
|
||||||
|
<sources>
|
||||||
|
<source>src/main/java/App.java</source>
|
||||||
|
</sources>
|
||||||
|
<testSources>
|
||||||
|
<source>src/test/java/AppTest.java</source>
|
||||||
|
</testSources>
|
||||||
|
</archetype>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>$de.synolo</groupId>
|
||||||
|
<artifactId>$lib-fw</artifactId>
|
||||||
|
<version>$0.0.1-SNAPSHOT</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,38 @@
|
||||||
|
package $de.synolo.lib.fw;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple App.
|
||||||
|
*/
|
||||||
|
public class AppTest
|
||||||
|
extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the test case
|
||||||
|
*
|
||||||
|
* @param testName name of the test case
|
||||||
|
*/
|
||||||
|
public AppTest( String testName )
|
||||||
|
{
|
||||||
|
super( testName );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the suite of tests being tested
|
||||||
|
*/
|
||||||
|
public static Test suite()
|
||||||
|
{
|
||||||
|
return new TestSuite( AppTest.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rigourous Test :-)
|
||||||
|
*/
|
||||||
|
public void testApp()
|
||||||
|
{
|
||||||
|
assertTrue( true );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue