
de.tsl2.nano.incubation.terminal.ItemAdministrator Maven / Gradle / Ivy
/*
* File: $HeadURL$
* Id : $Id$
*
* created by: Tom, Thomas Schneider
* created on: 13.06.2015
*
* Copyright: (c) Thomas Schneider 2015, all rights reserved
*/
package de.tsl2.nano.incubation.terminal;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import de.tsl2.nano.action.IConstraint;
import de.tsl2.nano.bean.def.Constraint;
import de.tsl2.nano.core.cls.BeanClass;
import de.tsl2.nano.core.cls.PrivateAccessor;
import de.tsl2.nano.core.execution.SystemUtil;
import de.tsl2.nano.core.util.FileUtil;
import de.tsl2.nano.core.util.StringUtil;
import de.tsl2.nano.core.util.Util;
import de.tsl2.nano.execution.AntRunner;
import de.tsl2.nano.format.RegExpFormat;
import de.tsl2.nano.incubation.terminal.item.AItem;
import de.tsl2.nano.incubation.terminal.item.Action;
import de.tsl2.nano.incubation.terminal.item.Command;
import de.tsl2.nano.incubation.terminal.item.Container;
import de.tsl2.nano.incubation.terminal.item.Input;
import de.tsl2.nano.incubation.terminal.item.MainAction;
import de.tsl2.nano.incubation.terminal.item.Option;
import de.tsl2.nano.incubation.terminal.item.selector.ActionSelector;
import de.tsl2.nano.incubation.terminal.item.selector.CSVSelector;
import de.tsl2.nano.incubation.terminal.item.selector.DirSelector;
import de.tsl2.nano.incubation.terminal.item.selector.FieldSelector;
import de.tsl2.nano.incubation.terminal.item.selector.FileSelector;
import de.tsl2.nano.incubation.terminal.item.selector.PropertySelector;
import de.tsl2.nano.incubation.terminal.item.selector.SQLSelector;
import de.tsl2.nano.incubation.terminal.item.selector.Sequence;
import de.tsl2.nano.incubation.terminal.item.selector.XPathSelector;
import de.tsl2.nano.incubation.vnet.workflow.Condition;
/**
* item administration shell
*
* @author Tom, Thomas Schneider
* @version $Revision$
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public class ItemAdministrator extends Container {
private static final String NEWINDEX = "newindex";
/** the items position in a container/tree */
private static final String INDEX = "index";
/** mostly needed to define an action */
private static final String ARGS = "args[]";
/** the items type (full class name) */
private static final String TYPE = "type";
private static final long serialVersionUID = 5127419882040627794L;
transient IItem parent;
transient SIShell terminal;
/** item as descriptor for new items */
transient Properties item;
private Action addingAction;
private Action removingAction;
private Action changingAction;
private Action constraintsAction;
private Action terminalAction;
private static int count = 0;
static Map itemTypes;
static {
String file = "admin.properties";
Properties adminProperties =
FileUtil.hasResource(file) ? FileUtil.loadProperties(file, null) : new Properties();
itemTypes = new HashMap();
if (adminProperties.isEmpty()) {
//add special parameter to available items
itemTypes.put("container", new String[] { Container.class.getName(), "multiple", "sequential" });
itemTypes.put("option", new String[] { Option.class.getName() });
itemTypes.put("input", new String[] { Input.class.getName() });
itemTypes.put("action", new String[] { Action.class.getName(), "mainClass", "method", ARGS });
itemTypes.put("mainaction", new String[] { MainAction.class.getName(), "mainClass", ARGS });
itemTypes.put("command", new String[] { Command.class.getName(), "cmd", ARGS });
itemTypes.put("shell", new String[] { Action.class.getName(), "mainClass=" + SystemUtil.class.getName(),
"method=execute", ARGS });
itemTypes.put("ant", new String[] { Action.class.getName(), "mainClass=" + AntRunner.class.getName(),
"method=runTask", ARGS /*"task", "properties", "fileset"*/});
itemTypes.put("selector", new String[] { ActionSelector.class.getName(), "mainClass=", "method", ARGS });
itemTypes.put("file", new String[] { FileSelector.class.getName(), "roots", "include" });
itemTypes.put("dir", new String[] { DirSelector.class.getName(), "roots", "include" });
itemTypes.put("csv", new String[] { CSVSelector.class.getName(), "csv", "pattern" });
itemTypes.put("properties", new String[] { PropertySelector.class.getName() });
itemTypes.put("field", new String[] { FieldSelector.class.getName(), "cls", "field"/*field-type*/});
itemTypes.put("xpath", new String[] { XPathSelector.class.getName(), "xml", "xpath"});
itemTypes.put("sql", new String[] { SQLSelector.class.getName(), "driver", "url", "user", "password", "sql"});
itemTypes.put("sequence", new String[] { Sequence.class.getName(), "action", "selector"});
Properties p = new Properties();
for (String k : itemTypes.keySet()) {
p.put(k, StringUtil.concat(", ".toCharArray(), (Object[]) itemTypes.get(k)));
}
FileUtil.saveProperties(file, p);
} else {
String k, v;
for (Object key : adminProperties.keySet()) {
k = (String) key;
v = adminProperties.getProperty(k);
itemTypes.put(k, v.split("\\,\\s*"));
}
}
}
/**
* constructor
*/
public ItemAdministrator(SIShell terminal, Container toAdmin) {
init(terminal, toAdmin);
}
protected void init(final SIShell terminal, Container toAdmin) {
this.terminal = terminal;
this.parent = toAdmin;
this.nodes = (List>) new PrivateAccessor(toAdmin).member("nodes");
item = new Properties();
name = "Admin: " + toAdmin.getName();
setDescription("Provides administration of item " + toAdmin.getName());
//action to add items
addingAction = new Action(this, "addItem") {
@Override
public IItem react(IItem caller, String input, InputStream in, PrintStream out, Properties env) {
askItem(in, out, env, this, item, TYPE, INDEX, "name", "value", "description", "condition", "style");
return super.react(caller, input, in, out, env);
}
};
addingAction.setParent(this);
nodes.add(addingAction);
//action to change items
changingAction = new Action(this, "changeItem") {
@Override
public IItem react(IItem caller, String input, InputStream in, PrintStream out, Properties env) {
//which item - show some infos
out.print("select item to change: ");
item.put(INDEX, nextLine(in, out));
out.println(StringUtil.toFormattedString(new PrivateAccessor(nodes.get(getSelectedIndex())).members(),
-1));
askItem(in, out, env, this, item, NEWINDEX, "name", "value", "description", "condition", "style");
return super.react(caller, input, in, out, env);
}
};
changingAction.setParent(this);
nodes.add(changingAction);
//action to change items constraints
constraintsAction = new Action(this, "changeConstraints") {
@Override
public IItem react(IItem caller, String input, InputStream in, PrintStream out, Properties env) {
//which item - show some infos
out.print("select item to change constraints: ");
item.put(INDEX, nextLine(in, out));
IConstraint> c = nodes.get(getSelectedIndex()).getConstraints();
if (c != null)
out.println(StringUtil.toFormattedString(new PrivateAccessor(c).members(), -1));
askItem(in, out, env, this, item, "type", "format", "nullable", "length", "scale", "precision", "min",
"max", "defaultValue");
return super.react(caller, input, in, out, env);
}
};
constraintsAction.setParent(this);
nodes.add(constraintsAction);
//action to remove items
removingAction = new Action(this, "removeItem") {
@Override
public IItem react(IItem caller, String input, InputStream in, PrintStream out, Properties env) {
out.print("select item to remove: ");
item.put(INDEX, nextLine(in, out));
env.put("instance", this);
return super.react(caller, input, in, out, env);
}
};
removingAction.setParent(this);
nodes.add(removingAction);
//action to change the terminal
terminalAction = new Action(this, "changeTerminal") {
@Override
public IItem react(IItem caller, String input, InputStream in, PrintStream out, Properties env) {
out.println("\nchanging terminal:\n" + terminal);
askItem(in, out, env, this, item, SIShell.presentalMembers());
return super.react(caller, input, in, out, env);
}
};
terminalAction.setParent(this);
nodes.add(terminalAction);
setDescription("the type should be one of: [container, input, option] or:\n"
+ StringUtil.toFormattedString(itemTypes, -1, true));
}
/**
* asks for the given item attributes like name, value, description etc.
*
* @param in user input stream
* @param out user information print stream
* @param env action context to add this instance to.
*/
public static void askItem(InputStream in,
PrintStream out,
Properties env,
Object instance,
Properties item,
String... itemAttributes) {
//first, the standard attributes
for (int i = 0; i < itemAttributes.length; i++) {
out.print(itemAttributes[i] + ": ");
item.put(itemAttributes[i], SIShell.nextLine(in, out));
}
//some defaults and instances
boolean hasType = item.containsKey(TYPE);
if (!Util.isEmpty(item.get("condition")))
item.put("condition", new Condition(item.getProperty("condition")));
if (!Util.isEmpty(item.get("condition")))
item.put("condition", new Condition(item.getProperty("condition")));
//now, the type specific attributes
if (hasType) {
String type = item.getProperty(TYPE);
if (Util.isEmpty(type))
type = "input";
if (Util.isEmpty(item.get("name")))
item.put("name", type + "-" + ++count);
String description[] = itemTypes.get(type.toLowerCase());
if (description != null) {
item.put(TYPE, description[0]);
for (int i = 1; i < description.length; i++) {
if (!description[i].equals(ARGS)) {
if (!description[i].contains("=")) {
out.print(description[i] + ": ");
item.put(description[i], SIShell.nextLine(in, out));
} else {
String kv[] = description[i].split("=");
item.put(kv[0], kv[1]);
}
} else {
//method arguments
List argNames = new LinkedList();
String arg;
while (true) {
out.print("argument name " + argNames.size() + ": ");
if (Util.isEmpty(arg = SIShell.nextLine(in, out)))
break;
argNames.add(arg);
}
item.put("argNames", argNames.toArray(new String[0]));
}
}
} else if (hasType) {
out.println("The type should be one of:\n" + StringUtil.toString(itemTypes.keySet(), -1));
type = StringUtil.toFirstUpper(type);
String cls = type.contains(".") ? type : AItem.class.getPackage().getName() + "." + type;
out.println("\nTrying type: " + cls);
out.println("<<>>");
SIShell.nextLine(in, out);
item.put(TYPE, cls);
}
}
env.put("instance", instance);
}
/**
* clean, to be called, if administration will be left.
*/
public void clean() {
nodes.remove(addingAction);
nodes.remove(removingAction);
nodes.remove(changingAction);
nodes.remove(constraintsAction);
nodes.remove(terminalAction);
}
/**
* adds a new item
*/
public void addItem() {
item.put("parent", parent);
add(nodes, item);
}
int getSelectedIndex() {
return Integer.valueOf(item.getProperty(INDEX)) - 1;
}
/**
* add a new item
*
* @param nodes node list to add the new item to
* @param item to be added
*/
public static void add(List> nodes, Properties item) {
try {
AItem instance = BeanClass.createInstance(item.getProperty(TYPE));
int index = !Util.isEmpty(item.get(INDEX)) ? Integer.valueOf((String) item.get(INDEX)) : nodes.size();
item.remove(TYPE);
item.remove(INDEX);
nodes.add(index, PrivateAccessor.assign(instance, item, false));
} finally {
item.clear();
}
}
public void removeItem() {
try {
nodes.remove(getSelectedIndex());
} finally {
item.clear();
}
}
public void changeItem() {
try {
AItem selectedItem = nodes.get(getSelectedIndex());
int index = !Util.isEmpty(item.get(NEWINDEX)) ? Integer.valueOf((String) item.get(NEWINDEX)) : -1;
item.remove(TYPE);
item.remove(INDEX);
item.remove(NEWINDEX);
PrivateAccessor.assign(selectedItem, item, false);
if (index != -1) {
nodes.remove(selectedItem);
nodes.add(index - 1, selectedItem);
}
} finally {
item.clear();
}
}
public void changeConstraints() {
try {
IItem selectedItem = nodes.get(getSelectedIndex());
String pattern = item.getProperty("format");
if (!Util.isEmpty(pattern)) {
String slen = item.getProperty("length");
if (!Util.isEmpty(slen))
item.put("format", new RegExpFormat(pattern, Integer.valueOf(slen)));
else
item.put("format", new RegExpFormat(pattern, null));
}
item.remove("name");
item.remove(INDEX);
IConstraint c = selectedItem.getConstraints() != null ? selectedItem.getConstraints() : new Constraint();
PrivateAccessor.assign(c, item, false);
} finally {
item.clear();
}
}
public void changeTerminal() {
try {
PrivateAccessor.assign(terminal, item, false);
} finally {
item.clear();
}
}
@Override
public String getDescription(Properties env, boolean full) {
if (full)
return "Provides administration of item " + parent.getName() + "\n"
+ StringUtil.toFormattedString(itemTypes, -1, true);
return super.getDescription(env, full);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy