import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.math.*;
import java.text.SimpleDateFormat;
import java.nio.charset.Charset;
import java.text.NumberFormat;
import java.nio.file.Path;
import javax.swing.undo.UndoManager;
import java.awt.datatransfer.*;
import javax.swing.event.AncestorListener;
import javax.swing.event.AncestorEvent;
import javax.swing.Timer;
import java.awt.datatransfer.StringSelection;
import java.text.*;
import javax.imageio.metadata.*;
import javax.imageio.stream.*;
import java.util.TimeZone;
import java.awt.geom.*;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
class main {
abstract static class DynCRUD_v2 extends DynModule {
static boolean _switchableField_caseID = true; String caseID;
transient Concepts cc = db_mainConcepts();
transient Class conceptClass;
transient SimpleCRUD_v2 crud;
transient boolean addCountToName = true, addCountToName_installed;
void start_DynCRUD() {
// set flag to save space
if (cc == db_mainConcepts())
dbWithCase(caseID); // So we can do stuff in overridden start methods
crud = makeCRUD(); // so we can customize early
if (addCountToName) addCountToName();
}
JComponent visualizeWithCountInTab() {
JComponent c = visualize();
bindToComponent(table(), new Runnable() { public void run() { try { updateTabTitle();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "updateTabTitle();"; }});
onConceptChange(cc, new Runnable() { public void run() { try { updateTabTitle();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "updateTabTitle();"; }});
return c;
}
void updateTabTitle() {
updateEnclosingTabTitleWithCount(table(), conceptCount());
}
public JComponent visualize() {
if (crud == null) start_DynCRUD();
crud.idWidth = 0;
crud.afterUpdate = new Runnable() { public void run() { try {
int n = tableColumnCount(table());
for (int i = 0; i < n; i++)
setColumnName(table(), i, i == 0 ? "" : humanizeFormLabel(getColumnName(table(), i)));
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "int n = tableColumnCount(table());\r\n for (int i = 0; i < n; i++)\r\n se..."; }};
return withMargin(crud.make_dontStartBots());
}
SimpleCRUD_v2 makeCRUD() {
return new SimpleCRUD_v2(cc, conceptClass);
}
JTable table() { return crud == null ? null : crud.table; }
A selected() { return crud == null ? null : crud.selectedConcept(); }
void addButton(JComponent button) {
if (crud != null) addComponent(crud.buttons, button);
}
void addButton(String name, Object action) { addButton(jbutton(name, action)); }
void addSelectionDependentButton(String name, Object action) {
addButton(tableDependentButton(table(), name, action));
}
void makeSortable() { // broken?
addRowSorter(table());
rowSorter_setComparatorForAllColumns(table(), alphaNumComparator());
}
String searchTerm() {
return crud == null || crud.tableSearcher == null ? null : gtt(crud.tableSearcher.tfInput);
}
void addCountToName() {
if (addCountToName_installed) return;
addCountToName_installed = true;
onConceptChangeAndNow(cc, new Runnable() { public void run() { try { AutoCloseable __1 = enter(); try { setModuleName(dm_originalModuleName() + " (" + conceptCount() + ")") ;
} finally { _close(__1); }} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "temp enter(); setModuleName(dm_originalModuleName() + \" (\" + conceptCount() ..."; }});
}
Concepts conceptsObject() {
return crud.concepts;
}
// overwrite for compact modules to work
List list(Class c) {
return conceptsObject().list(c);
}
// API
List concepts() { AutoCloseable __2 = enter(); try { return list(conceptClass); } finally { _close(__2); }}
List data() { return concepts(); }
List list() { return concepts(); }
List conceptsOfType(String type) { AutoCloseable __3 = enter(); try { return conceptsObject().list(type); } finally { _close(__3); }}
// TODO: use index
List conceptsOfTypeWhere(String type, Object[] params) { AutoCloseable __4 = enter(); try {
return filterConcepts(conceptsOfType(type), params);
} finally { _close(__4); }}
int conceptCount() { AutoCloseable __5 = enter(); try { return countConcepts(cc, conceptClass); } finally { _close(__5); }}
void deleteAll() { AutoCloseable __6 = enter(); try {
deleteConcepts(cc, conceptClass);
} finally { _close(__6); }}
void addDialog() { AutoCloseable __7 = enter(); try { crud.newConcept(); } finally { _close(__7); }}
A uniqConcept(Object... params) {
return uniq_sync(cc, conceptClass, params);
}
Pair uniqConcept2(Object... params) {
return uniq2_sync(cc, conceptClass, params);
}
int cset(Concept c, Object... values) {
return _cset(c, values);
}
DynCRUD_v2() {}
DynCRUD_v2(Class conceptClass) {
this.conceptClass = conceptClass;}
void start() { try { super.start();
start_DynCRUD();
} catch (Exception __e) { throw rethrow(__e); } }
}
static volatile Concepts mainConcepts; // Where we create new concepts
static Concepts db_mainConcepts() {
if (mainConcepts == null)
mainConcepts = newConceptsWithClassFinder(getDBProgramID());
return mainConcepts;
}
static void cleanMeUp_concepts() {
if (db_mainConcepts() != null) db_mainConcepts().cleanMeUp();
// mainConcepts = null; // TODO
}
static void dbWithCase(String caseID) {
caseID(caseID);
db();
}
static A bindToComponent(final A component, final Runnable onShow, final Runnable onUnShow) {
{ swing(new Runnable() { public void run() { try {
final Var < Boolean > flag = new Var<>(false);
component.addAncestorListener(new AncestorListener() {
public void ancestorAdded(AncestorEvent event) {
if (flag.get()) print("Warning: bindToComponent logic failure");
flag.set(true);
pcallF(onShow);
}
public void ancestorRemoved(AncestorEvent event) {
if (!flag.get()) print("Warning: bindToComponent logic failure");
flag.set(false);
pcallF(onUnShow);
}
public void ancestorMoved(AncestorEvent event) {
}
});
if (component.isShowing()) { // Hopefully this matches the AncestorListener logic
flag.set(true);
pcallF(onShow);
}
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "final Var flag = new(false);\r\n component.addAncestorListener(new ..."; }}); }
return component;
}
static A bindToComponent(A component, Runnable onShow) {
return bindToComponent(component, onShow, null);
}
static RuntimeException rethrow(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static RuntimeException rethrow(String msg, Throwable t) {
throw new RuntimeException(msg, t);
}
static void onConceptChange(Object r) {
onConceptChange(db_mainConcepts(), r);
}
static void onConceptChange(Concepts cc, Object r) {
onConceptsChange(cc, toRunnable(r));
}
static void updateEnclosingTabTitleWithCount(JComponent c, int n) {
Pair p = enclosingTab(c);
if (p == null) return;
setTabTitle(p.a, p.b, appendBracketedCount(dropTrailingBracketedCount(getTabTitle(p.a, p.b)), n));
}
static int tableColumnCount(JTable table) {
return tableNumColumns(table);
}
static void setColumnName(final JTable table, final int idx, final String name) {
if (table != null) { swing(new Runnable() { public void run() { try {
if (table.getColumnCount() > idx)
table.getColumnModel().getColumn(idx).setHeaderValue(name);
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "if (table.getColumnCount() > idx)\r\n table.getColumnModel().getColumn(idx..."; }}); }
}
static Map humanizeFormLabel_replacements = litmap("id" , "ID", "md5" , "MD5");
static String humanizeFormLabel(String s) {
if (containsSpace(s)) return s;
return firstToUpper(
joinWithSpace(replaceElementsUsingMap(splitCamelCase(s), humanizeFormLabel_replacements)).replace("I D", "ID")
);
}
static String getColumnName(final JTable table, final int idx) {
return table == null ? null : swing(new F0() { public String get() { try {
return table.getColumnCount() <= idx ? null
: str(table.getColumnModel().getColumn(idx).getHeaderValue());
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "ret table.getColumnCount() <= idx ? null\r\n : str(table.getColumnModel()...."; }});
}
static int withMargin_defaultWidth = 6;
static JPanel withMargin(Component c) {
return withMargin(withMargin_defaultWidth, c);
}
static JPanel withMargin(int w, Component c) {
return withMargin(w, w, c);
}
static JPanel withMargin(int w, int h, Component c) {
return withMargin(w, h, w, h, c);
}
static JPanel withMargin(final int top, final int left, final int bottom, final int right, final Component c) {
return swing(new F0() { public JPanel get() { try {
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createEmptyBorder(top, left, bottom, right));
p.add(c);
return p;
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "JPanel p = new JPanel(new BorderLayout);\r\n p.setBorder(BorderFactory.creat..."; }});
}
static A addComponent(final A c, final Component component) {
if (component != null) { swing(new Runnable() { public void run() { try {
c.add(component);
revalidate(c);
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "c.add(component);\r\n revalidate(c);"; }}); }
return c;
}
static JButton jbutton(String text, Object action) {
return newButton(text, action);
}
// button without action
static JButton jbutton(String text) {
return newButton(text, null);
}
/*static JButton jbutton(BufferedImage img, O action) {
ret setButtonImage(img, jbutton("", action));
}*/
static JButton jbutton(Action action) {
return swingNu(JButton.class, action);
}
static JButton tableDependentButton(JTable tbl, String text, Object action) {
return tableDependButton(tbl, jbutton(text, action));
}
static JTable addRowSorter(final JTable table) {
if (table != null) { swing(new Runnable() { public void run() { try {
table.setRowSorter(new TableRowSorter(table.getModel()));
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "table.setRowSorter(new TableRowSorter(table.getModel()));"; }}); }
return table;
}
// params: column index, Comparator, column index, Comparator, ...
static void rowSorter_setComparatorForAllColumns(JTable table, final Comparator comparator) {
if (table == null) return;
setTableModel_fixSorter.put(table, new VF2() { public void get(JTable table, RowSorter sorter) { try {
if (sorter instanceof TableRowSorter) {
int n = tableColumnCount(table);
for (int i = 0; i < n; i++)
((TableRowSorter) sorter).setComparator(i, comparator);
}
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "if (sorter cast TableRowSorter) {\r\n int n = tableColumnCount(table);\r\n ..."; }});
}
static AlphanumComparator alphaNumComparator_instance;
static Comparator alphaNumComparator() {
if (alphaNumComparator_instance == null)
alphaNumComparator_instance = new AlphanumComparator();
return alphaNumComparator_instance;
}
static String gtt(JTextComponent c) {
return getTextTrim(c);
}
static String gtt(JComboBox cb) {
return getTextTrim(cb);
}
static void onConceptChangeAndNow(Runnable r) {
onConceptsChangeAndNow(r);
}
static void onConceptChangeAndNow(Concepts cc, Runnable r) {
onConceptsChangeAndNow(cc, r);
}
static String dm_originalModuleName() {
return dm_originalModuleName(assertNotNull(dm_current()));
}
static String dm_originalModuleName(Object module) {
return (String) callOpt(dm_getStem(module), "originalModuleName");
}
static void _close(AutoCloseable c) {
if (c != null) try {
c.close();
} catch (Throwable e) {
// Some classes stupidly throw an exception on double-closing
if (c instanceof javax.imageio.stream.ImageOutputStream)
return;
else throw rethrow(e);
}
}
static List list(Class type) {
return db_mainConcepts().list(type);
}
static List list(Concepts concepts, Class type) {
return concepts.list(type);
}
static List list(String type) {
return db_mainConcepts().list(type);
}
static List list(Concepts concepts, String type) {
return concepts.list(type);
}
static List conceptsOfType(String type) {
return db_mainConcepts().conceptsOfType(type);
}
static List filterConcepts(List list, Object... params) {
if (empty(params)) return list;
List l = new ArrayList();
for (A x : list)
if (checkConceptFields(x, params))
l.add(x);
return l;
}
static int countConcepts(Concepts concepts, Class c, Object... params) {
return concepts.countConcepts(c, params);
}
static int countConcepts(Class c, Object... params) {
return db_mainConcepts().countConcepts(c, params);
}
static int countConcepts() {
return db_mainConcepts().countConcepts();
}
static int countConcepts(String className) {
return db_mainConcepts().countConcepts(className);
}
static int countConcepts(Concepts concepts, String className) {
return concepts.countConcepts(className);
}
static int countConcepts(Concepts concepts) {
return concepts.countConcepts();
}
static void deleteConcepts(Collection conceptsOrIDs) {
db_mainConcepts().deleteConcepts(asList(conceptsOrIDs));
}
static List deleteConcepts(Class c, Object... params) {
return deleteConcepts(db_mainConcepts(), c, params);
}
static List deleteConcepts(Concepts cc, Class c, Object... params) {
List l = asList(findConceptsWhere(cc, c, params));
deleteConcepts(l);
return l;
}
static A uniq_sync(final Class c, final Object... params) {
return uniq(c, params);
}
static A uniq_sync(Concepts concepts, Class c, final Object... params) {
return uniq(concepts, c, params);
}
static Pair uniq2_sync(Class c, final Object... params) {
return uniq2(c, params);
}
static Pair uniq2_sync(Concepts cc, Class c, final Object... params) {
return uniq2(cc, c, params);
}
// returns number of changes
static int _cset(Concept c, Object... values) {
return cset(c, values);
}
static Map> setTableModel_after = weakHashMap();
static Map> setTableModel_fixSorter = weakHashMap();
static void setTableModel(final JTable table, final TableModel model) {
{ swing(new Runnable() { public void run() { try {
Map widths = tableColumnWidthsByName(table);
int[] i = table.getSelectedRows();
TableRowSorter sorter = model.getColumnCount() == tableColumnCount(table) ? (TableRowSorter) table.getRowSorter() : null;
List extends RowSorter.SortKey> sortKeys = sorter == null ? null : sorter.getSortKeys();
table.setModel(model);
int n = model.getRowCount();
ListSelectionModel sel = table.getSelectionModel();
for (int j = 0; j < i.length; j++)
if (i[j] < n)
sel.addSelectionInterval(i[j], i[j]);
tableSetColumnPreferredWidths(table, widths);
if (sorter != null) {
sorter.setModel(model);
callF(setTableModel_fixSorter.get(table), table, sorter);
//print("Keeping sorter: " + sorter + " Sort keys: " + sortKeys);
if (sortKeys != null) sorter.setSortKeys(sortKeys);
}
table.setRowSorter(sorter);
callF(setTableModel_after.get(table), table);
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Map widths = tableColumnWidthsByName(table);\r\n int[] i = ..."; }}); }
}
static Concepts newConceptsWithClassFinder(String progID) {
Concepts cc = new Concepts(progID);
cc.classFinder = _defaultClassFinder();
return cc;
}
static String getDBProgramID_id;
static String getDBProgramID() {
return nempty(getDBProgramID_id) ? getDBProgramID_id : programIDWithCase();
}
static volatile String caseID_caseID;
static String caseID() { return caseID_caseID; }
static void caseID(String id) {
caseID_caseID = id;
}
static void db() {
conceptsAndBot();
}
// use -10000 for 10 seconds plus slowdown logic
static void db(Integer autoSaveInterval) {
conceptsAndBot(autoSaveInterval);
}
static Object swing(Object f) {
return swingAndWait(f);
}
static A swing(F0 f) {
return (A) swingAndWait(f);
}
static A swing(IF0 f) {
return (A) swingAndWait(f);
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
static boolean print_silent = false; // total mute if set
static Object print_byThread_lock = new Object();
static volatile ThreadLocal