!7
sinterface IBEAReactor {
A uniqResult(Class c, O... params);
}
extend BEAObject {
bool canReactWith(BEAObject o) {
ret isInstanceOfAny(o, (Cl) reactableWithClasses());
}
Cl> reactableWithClasses() {
ret (Cl) collectFirstMethodArguments(findMethodsNamed_nonSynthetic(this, "reactWith"));
}
}
beaConcept BReactor {}
beaConcept BInput {
S text;
toString { ret "[\*id*/] Input " + quote(text); }
}
beaConcept BOutput {
S text;
toString { ret "[\*id*/] Output " + quote(text); }
}
beaConcept BPattern {
S text;
toString { ret "[\*id*/] " + shortDynName(this) + " " + quote(text); }
void reactWith(BInput input, IBEAReactor reactor) {}
@Override Map _fieldMigrations() {
ret litmap(pattern := new FieldMigration("text"));
}
}
beaConcept BStarPattern > BPattern {
void reactWith(BInput input, IBEAReactor reactor) {
LS mapping = matchesToStringList(flexMatchIC_first(text, input.text));
if (mapping == null) ret;
reactor.uniqResult(BEAObject,
type := "match",
+input,
pattern := this,
+mapping);
}
}
beaConcept BAngleVarPattern > BPattern {
void reactWith(BInput input, IBEAReactor reactor) {
SS mapping = flexMatchAngleBracketVarsIC_first(text, input.text);
if (mapping == null) ret;
uniqPeer BEAObject(this,
type := "match",
+input,
pattern := this,
+mapping);
}
}
beaConcept BMatch {
new Ref pattern;
SS mapping;
}
beaConcept BMatchToScenario {
void reactWith(BMatch match, IBEAReactor reactor) {
reactor.uniqResult(BEAObject,
type := "scenario",
text := mapToLines(match.mapping,
(a, b) -> b + " is a " + a));
}
}
beaConcept BScenarioToOutput {
bool canReactWith(BEAObject o) {
ret o.typeIs("scenario");
}
void reactWith(BEAObject scenario, IBEAReactor reactor) {
reactor.uniqResult(BOutput,
type := "Output",
text := getString text(scenario));
}
}
cmodule2 > DynCRUD_v2 {
S input, output;
transient new BEAUtils beaUtils;
{ tableFontSize = 15; }
start {
crud.humanizeFieldNames = false;
crud.showBackRefs = true;
crud.specialFieldsForItem = a -> {
MapSO map = litorderedmap(crud.hID, str(a.id));
S j = crud.javaClassDescForItem(a);
mapPut(map, "Class/Type", joinUniqueNemptiesCI("/", j, a.type()));
ret map;
};
crud.itemToMap_inner = a -> {
MapSO map = crud.itemToMap_inner_base(a);
map.remove("type");
ret map;
};
thread {
uniq BMatchToScenario();
uniq BScenarioToOutput();
uniq BInput(text := "UBports community delivers 'second-largest release of Ubuntu Touch ever'");
//uniq BPattern(text := "* delivers *");
uniq BAngleVarPattern(text := " delivers ");
}
}
visualize {
JComponent c = jvsplit(jhsplit(dm_wordWrapTextAreaAsSection input(),
dm_wordWrapTextAreaAsSection output()),
super.visualize());
tablePopupMenuFirst(table(), (menu, row) -> {
BEAObject o = getItem(row);
print("Item: " + o);
if (o == null) ret;
Class extends BEAObject> targetClass = beaUtils.defaultCustomClass(o);
print(+targetClass);
if (targetClass != null && targetClass != _getClass(o)) pcall-short {
beaUtils.migrateConceptToClass(targetClass, o);
addMenuItem(menu, "Convert to " + shortName(targetClass), r {
replaceConceptAndUpdateRefs(o, beaUtils.migrateConceptToClass(targetClass, o));
});
}
pcall {
L partners = filter(list(BEAObject),
partner -> o.canReactWith(partner));
if (nempty(partners))
addScrollingSubMenu(menu, "React with", menu2 -> {
for (BEAObject p : partners)
addMenuItem(menu2, str(p), rThread {
new BEAReactor("User reacts " + o + " with " + p).react(o, p);
});
});
}
});
ret c;
}
class BEAReactor {
BReactor reactorConcept;
*(S purpose) {
reactorConcept = cnew BReactor(+purpose);
}
void react(BEAObject a, BEAObject b) {
call(a, 'reactWith, b, new IBEAReactor {
public A uniqResult(Class c, O... params) {
A product = uniq(c, paramsPlus(params,
_reactor := reactorConcept,
_fromReaction := ll(a, b)));
onReactionProduct(product);
ret product;
}
});
}
}
void onReactionProduct(BEAObject a) pcall {
if (a.typeIs("output"))
setField(output := getStringOpt text(a));
}
}