Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

912
LINES

< > BotCompany Repo | #1030954 // Gazelle BEA [new compact include test]

JavaX source code (Dynamic Module) [tags: use-pretranspiled] - run with: Stefan's OS

Uses 1951K of libraries. Click here for Pure Java version (4314L/36K).

1  
!7
2  
3  
!include early #1030953 // specialized Compact Module Include
4  
import loadableUtils.utils.User;
5  
import loadableUtils.utils.UserPost;
6  
import static loadableUtils.utils.botMod;
7  
8  
!include once #1030833 // BEACalculations
9  
10  
set flag NoNanoHTTPD.
11  
12  
module GazelleBEA > DynGazelleRocks {
13  
  switchable bool mirrorBEAObjects; // don't do it for now
14  
  switchable bool enableAutoRuns = true;
15  
  switchable bool enableNewBEAObjectNotis = true;
16  
  
17  
  transient ReliableSingleThread_Multi<BEAObject> rstAutoRuns = new(1000, lambda1 performAutoRuns);
18  
  transient Q notificationQ;
19  
  transient ReliableSingleThread_Multi<BEAObject> rstDistributeNewObject = new(1000, lambda1 distributeNewObject_impl);
20  
  transient Set<BEAObject> newObjectsDistributed = weakSet();
21  
22  
  transient BEACalculations calculations = new(this);
23  
  transient int newFieldsToShow = 3;
24  
  transient bool allowAnonymousInputUpload = true; // TODO
25  
  switchable int maxInputLength = 50000;
26  
27  
  // add more fields here
28  
  
29  
  //!include #1030883 // DB quickImport mix-in
30  
  
31  
  void init {
32  
    super.init();
33  
    botName = heading = adminName = "Gazelle BEA";
34  
    set enableVars;
35  
    set showTalkToBotLink;
36  
    unset phoneNumberSpecialInputField;
37  
  }
38  
  
39  
  void startDB { db(); }
40  
41  
  void start {
42  
    assertEquals(BEAObject, callF(defaultDefaultClassFinder(), "main$BEAObject"));
43  
    assertEquals(ConceptWithGlobalID, callF(defaultDefaultClassFinder(), "main$ConceptWithGlobalID"));
44  
    seedDBFrom(#1030602);
45  
    set storeBaseClassesInStructure;
46  
    super.start();
47  
    print("main concepts: " + db_mainConcepts() + ", count: " + db_mainConcepts().countConcepts());
48  
    print(renderConceptClassesWithCount(db_mainConcepts()));
49  
    print("Inputs: " + n2(beaCount("Input")));
50  
    set showCRUDToEveryone;
51  
    //set showOnlySelectedObject;
52  
53  
    if (!enabled) ret;
54  
55  
    // mirror all objects to be sure
56  
    rstUpdateBEAMirrors.addAll(list(BEAObject));
57  
    
58  
    newObjectsDistributed.addAll(list(BEAObject));
59  
    
60  
    /*onIndividualConceptChange_notOnAllChanged(BEAObject,
61  
      p -> { calculations.makeSyntacticPattern(p); });*/
62  
      
63  
    onIndividualConceptChange_notOnAllChanged(BEAObject,
64  
      o -> {
65  
        if (enableAutoRuns) rstAutoRuns.add(o);
66  
        if (enableNewBEAObjectNotis && newObjectsDistributed.add(o))
67  
          rstDistributeNewObject.add(o);
68  
      });
69  
      
70  
    notificationQ = dm_startQ();
71  
    
72  
    // Until the ref leak bug is fixed, fix things every 30...
73  
    
74  
    dm_doEvery(30.0, r {
75  
      print(ConceptsRefChecker(db_mainConcepts()).runAndFixAll());
76  
    });
77  
  }
78  
79  
  void makeIndices :: after {    
80  
    indexConceptFieldDesc(BEAObject, "_modified");
81  
    indexConceptFieldIC(BEAObject, "type");
82  
    
83  
    // TODO: don't index nulls, also maybe just use backRefs
84  
    indexConceptField(BEAObject, "input"); // e.g. for counting how many matches we have for a given input
85  
  }
86  
  
87  
  L<Class> crudClasses(Req req) {
88  
    ret listPlus(super.crudClasses(req), BEAObject);
89  
  }
90  
  
91  
  S authFormHeading() {
92  
    ret h3("Gazelle BEA");
93  
  }
94  
  
95  
  void makeFramer(Req req) {
96  
    super.makeFramer(req);
97  
    
98  
    req.framer.renderTitle = () -> h1(ahref(baseLink + "/", "Gazelle BEA")
99  
      + " " + htmlEncode2(req.framer.title));
100  
      
101  
    req.framer.addInHead(hjs_autoExpandingTextAreas());
102  
  }
103  
104  
  <A extends Concept> HCRUD_Concepts<A> crudData(Class<A> c, Req req) {
105  
    HCRUD_Concepts<A> cc = super.crudData(c, req);
106  
    
107  
    if (c == BEAObject) {
108  
      cc.humanizeFieldNames = false;
109  
      cc.convertConceptValuesToRefs = true;
110  
      cc.itemName = () -> "BEA Object";
111  
      
112  
      cc.onCreate.add(o ->
113  
        cset(o, createdBy := currentUser()));
114  
      
115  
      cc.getObjectForDuplication = id -> {
116  
        MapSO item = cc.getObjectForDuplication_base(id);
117  
        item.put(creator := req.auth.user!); // set default creator to current user
118  
        item.put(createdFrom := getConcept(toLong(id)));
119  
        ret item;
120  
      };
121  
      
122  
      cc.emptyObject = () -> {
123  
        MapSO item = cc.emptyObject_base();
124  
        item.put(type := "");
125  
        ret item;
126  
      };
127  
      
128  
      Set<S> deletableRefs = litciset("Match");
129  
      
130  
      cc.objectCanBeDeleted = id ->
131  
        all(findBackRefs(BEAObject, cc.conceptForID(id)),
132  
          o -> contains(deletableRefs, o.type()));
133  
134  
      cc.actuallyDeleteConcept = o -> {
135  
        deleteConcepts(filter(findBackRefs(BEAObject, o),
136  
          o2 -> contains(deletableRefs, o2.type())));
137  
        cdelete(o);
138  
      };
139  
    }
140  
141  
    ret cc;
142  
  }
143  
144  
  <A extends Concept> HCRUD makeCRUD(Class<A> c, Req req, HTMLFramer1 framer) {
145  
    HCRUD crud = super.makeCRUD(c, req, framer);
146  
    HCRUD_Concepts data = cast crud.data;
147  
    crud.showOnlySelected = true;
148  
    crud.showSearchField = true;
149  
    if (data.customFilter == null)
150  
      crud.descending = true; // show latest objects first by default except when searching
151  
    crud.cleanItemIDs = true;
152  
153  
    if (c == BEAObject) {
154  
      crud.cellColumnToolTips = true;
155  
      crud.unshownFields = litset("mirrorPost", "globalID");
156  
      crud.showTextFieldsAsAutoExpandingTextAreas = true;
157  
      HCRUD_Concepts cc = cast crud.data;
158  
      
159  
      S typeFilter = req.get("type");
160  
      if (nempty(typeFilter))
161  
        cc.addCIFilter(type := typeFilter);
162  
      
163  
      crud.renderCmds = map -> {
164  
        BEAObject o = getConcept BEAObject(crud.itemIDAsLong(map));
165  
        
166  
        new LS cmds;
167  
        
168  
        // special commands for BEA types or objects with certain fields
169  
        
170  
        if (nempty(o.text()))
171  
          cmds.add(
172  
            targetBlank(addParamsToURL(baseLink + "/query",
173  
              q := o.text(), algorithm := "process input"),
174  
              "Use text as query"));
175  
176  
        if (o.typeIs("Input")) {
177  
          cmds.add(ahref(addParamsToURL(crudLink(BEAObject),
178  
            cmd := "new",
179  
            title := "Add Pattern For Input",
180  
            f_type := "Pattern",
181  
            f_text := getStringOpt text(o),
182  
            f_shouldMatch := o.id, metaInfo_shouldMatch := "concept",
183  
          ), "Add pattern"));
184  
185  
          cmds.add(ahref(appendParamsToURL(baseLink + "/query", q := o.text(), algorithm := "Apply all text functions"),
186  
           "Apply all text functions"));
187  
        }
188  
189  
        if (o.typeIs("Pattern"))
190  
          cmds.add(ahref(appendParamsToURL(baseLink + "/query", q := o.id, algorithm := "Run pattern"),
191  
           "Run pattern against all inputs"));
192  
           
193  
        if (o.typeIs("Match"))
194  
          cmds.add(ahref(appendParamsToURL(baseLink + "/query", q := o.id, algorithm := "Find rewrites for match"),
195  
           "Find rewrites"));
196  
197  
        cmds.add(
198  
          ahref(addParamsToURL(baseLink + "/markUseful",
199  
            redirect := beaShortURL(o),
200  
            objectID := o.id),
201  
            "Mark useful"));
202  
        
203  
        cmds.add(ahref(addParamsToURL(crudLink(BEAObject),
204  
          cmd := "new",
205  
          title := "Add Comment",
206  
          f_type := "Comment",
207  
          f_on := o.id,
208  
          f_text := "",
209  
          metaInfo_on := "concept"), "Add comment"));
210  
          
211  
        if (o.typeIsOneOf("Script", "Step in script") || eqic(beforeVerticalBar(o.type()), "Instruction"))
212  
          cmds.add(
213  
            ahref(addParamsToURL(baseLink + "/runInstruction",
214  
              instruction := o.id),
215  
              "Run"));
216  
              
217  
        if (o.typeIs("Function Result") && eqic(cget resultType(o), "string"))
218  
          cmds.add(
219  
            ahref(addParamsToURL(baseLink + "/convertResultToInput",
220  
              result := o.id),
221  
              "Convert to input"));
222  
        
223  
        framer.addInHead(hjs_copyToClipboard());
224  
        
225  
        cmds.add(ahref_onClick(formatFunctionCall copyToClipboard(jsQuote(o.globalIDStr())), "Copy global ID [" + o.globalIDStr() + "]"));
226  
        
227  
        ret joinNemptiesWithVBar(
228  
          crud.renderCmds_base(map),
229  
          !o.typeIsOneOf("Input", "Pattern", "Syntactic Pattern")
230  
            ? null : addRewriteHTML(o),
231  
          hPopDownButton(cmds));
232  
      };
233  
      
234  
      cc.massageItemMapForList = (item, map) -> {
235  
        BEAObject o = cast item;
236  
        if (o.typeIs("Input")) {
237  
          Cl<BEAObject> matches = objectsWhereCI(findBackRefs(o, BEAObject), type := "match");
238  
          map/Map.put("Best Matches", HTML(hparagraphs(
239  
            lmap matchDescHTML(takeFirst(3, matches)))));
240  
        }
241  
        S idField = crud.idField();
242  
        O id = map/Map.get(idField);
243  
        if (id instanceof S)
244  
          map/Map.put(idField, HTML(ahref(beaShortURL(o), id)));
245  
        if (o.typeIs("Function Result")) {
246  
          O value = o~.result;
247  
          map/Map.put("result", HTML(javaValueToHTML(value)));
248  
        }
249  
      };
250  
      
251  
      crud.massageFormMatrix = (map, matrix) -> {
252  
        for (int i = 1; i <= newFieldsToShow; i++) {
253  
          S nf = "newField" + i;
254  
          
255  
          S refSelector =
256  
            crud.renderInput("\*nf*/_conceptValue",
257  
              cc.makeConceptsComboBox("\*nf*/_conceptValue", BEAObject), null)
258  
            + hjs([[$("[name=]] + nf + [[_conceptValue]").hide()]]);
259  
              
260  
          LS types = ll("String", "BEAObject", "Bool");
261  
              
262  
          S typeSelector = hselect_list(types, name := "\*nf*/_type",
263  
              onchange := [[
264  
                var value = this.value;
265  
                $("[name=]] + nf + [[_value]").toggle(value != "BEAObject");
266  
                $("#]] + nf + [[_refBox").toggle(value == "BEAObject");
267  
              ]]);
268  
          
269  
          matrix.add(ll("Add field:<br>" + htextfield("\*nf*/_name", title := "New field name"),
270  
            htmlTable2_noHtmlEncode(ll(ll(
271  
              // string input
272  
              htextfield("\*nf*/_value"),
273  
              span(refSelector, id := "\*nf*/_refBox", style := "display: none"),
274  
            "Type", typeSelector
275  
            )),
276  
            noHeader := true,
277  
            tableParams := litobjectarray(style := "width: 100%"))));
278  
          }
279  
        };
280  
      
281  
      crud.preprocessUpdateParams = params -> {
282  
        params = cloneMap(params);
283  
284  
        // drop empty strings
285  
        //removeFromMapWhereValue(params, v -> eq(v, ""));
286  
        params = mapValues(params, v -> eq(v, "") ? null : v);
287  
        
288  
        for (int i = 1; i <= max(newFieldsToShow, 10); i++) {
289  
          S nf = "newField" + i;
290  
          S name = params.get("\*nf*/_name"),
291  
            type = params.get("\*nf*/_type"),
292  
            refValue = params.get("\*nf*/_conceptValue"),
293  
            value = params.get("\*nf*/_value");
294  
  
295  
          if (eqic(type, "BEAObject")) {
296  
            value = refValue;
297  
            params.put("metaInfo_" + name, "concept");
298  
          } else if (eqic(type, "Bool"))
299  
            params.put("metaInfo_" + name, "bool");
300  
          
301  
          if (eq(value, "")) value = null;
302  
            
303  
          if (nempty(name) /*&& neqOneOf(value, null, "")*/)
304  
            params.put(crud.fieldPrefix + name, value);
305  
        }
306  
        
307  
        ret params;
308  
      };
309  
    }
310  
    
311  
    ret crud;
312  
  }
313  
  
314  
  O serveBotFunction(Req req, S function, Map data, User user) {
315  
    if (eq(function, "beaList")) {
316  
      long changedAfter = toLong(data.get("changedAfter"));
317  
      double pollFor = min(bot_maxPollSeconds, toLong(data.get("pollFor"))); // how long to poll (seconds)
318  
      long startTime = sysNow();
319  
320  
      // We're super-anal about catching all changes. This will probably never trigger
321  
      if (changedAfter > 0 && changedAfter == now()) sleep(1);
322  
      
323  
      Cl<BEAObject> objects;
324  
      while true {
325  
        objects = changedAfter == 0 ? list(BEAObject)
326  
          : conceptsWithFieldGreaterThan_sorted(BEAObject, _modified := changedAfter);
327  
328  
        // return when there are results, no polling or poll expired
329  
        if (nempty(objects) || pollFor == 0 || elapsedSeconds_sysNow(startTime) >= pollFor)
330  
          ret serveJSON_breakAtLevels(2, result := map(objects, obj ->
331  
            litorderedmap(gid := str(obj.globalID()), struct := obj.structureString())
332  
          ));
333  
334  
        // sleep and try again
335  
        sleep(bot_pollInterval);
336  
      }
337  
    }
338  
    
339  
    ret super.serveBotFunction(req, function, data, user);
340  
  }
341  
342  
  transient ReliableSingleThread_Multi<BEAObject> rstUpdateBEAMirrors = new(100, c -> c.updateMirrorPost());
343  
  
344  
  O serveOtherPage2(Req req) null {
345  
    printVars_str serveOtherPage2(uri := req.uri);
346  
    try object super.serveOtherPage2(req);
347  
    
348  
    S uri = dropTrailingSlashIfNemptyAfterwards(req.uri);
349  
    new Matches m;
350  
    
351  
    if (swic_notSame(uri, "/beaCRUD/", m))
352  
      ret renderBEAObjectTable(req, urldecode(m.rest()));
353  
    
354  
    if (eq(uri, "/inputs"))
355  
      ret renderBEAObjectTable(req, "input");
356  
    
357  
    if (eq(uri, "/syntacticPatternsWithoutRewrites")) {
358  
      HCRUD crud = makeBEAObjectCRUD(req, "Syntactic Pattern");
359  
      HCRUD_Concepts<BEAObject> data = cast crud.data;
360  
      
361  
      IF1 prev = data.customFilter;
362  
      data.customFilter = list -> {
363  
        list = filter(list, c -> empty(beaBackRefs(c, "Rewrite")));
364  
        ret postProcess(prev, list);
365  
      };
366  
      crud.customTitle = "Syntactic patterns without rewrites";
367  
      ret serveCRUD(req, BEAObject, crud);
368  
    }
369  
      
370  
    if (eq(uri, "/inputsWithoutRewrites")) {
371  
      HCRUD crud = makeBEAObjectCRUD(req, "input");
372  
      HCRUD_Concepts<BEAObject> data = cast crud.data;
373  
      
374  
      IF1 prev = data.customFilter;
375  
      data.customFilter = list -> {
376  
        list = filter(list, c -> empty(beaBackRefs(c, "Rewrite")));
377  
        ret postProcess(prev, list);
378  
      };
379  
      crud.customTitle = "Inputs without rewrites";
380  
      ret serveCRUD(req, BEAObject, crud);
381  
    }
382  
      
383  
    if (eq(uri, "/inputsWithoutMatches")) {
384  
      HCRUD crud = makeBEAObjectCRUD(req, "input");
385  
      HCRUD_Concepts<BEAObject> data = cast crud.data;
386  
      
387  
      IF1 prev = data.customFilter;
388  
      data.customFilter = list -> {
389  
        list = filter(list, c -> empty(beaBackRefs(c, "Match")));
390  
        ret postProcess(prev, list);
391  
      };
392  
      crud.customTitle = "Inputs without matches";
393  
      ret serveCRUD(req, BEAObject, crud);
394  
    }
395  
      
396  
    if (eq(uri, "/patterns"))
397  
      ret renderBEAObjectTable(req, "pattern");
398  
399  
    if (eq(uri, "/syntacticPatterns"))
400  
      ret renderBEAObjectTable(req, "Syntactic Pattern");
401  
402  
    if (eq(uri, "/matches"))
403  
      ret renderBEAObjectTable(req, "match");
404  
405  
    if (eq(uri, "/rewrites"))
406  
      ret renderBEAObjectTable(req, "rewrite");
407  
408  
    if (eq(uri, "/aiTasks"))
409  
      ret renderBEAObjectTable(req, "AI Task");
410  
411  
    if (eq(uri, "/query"))
412  
      ret calculations.serveQueryPage(req);
413  
      
414  
    if (eq(uri, "/saveInput")) {
415  
      S text = trim(req.get("text"));
416  
      S info = trim(req.get("info"));
417  
      if (empty(text)) ret subBot_serve500("Input empty");
418  
      if (l(text) > maxInputLength) ret subBot_serve500("Input too long");
419  
      BEAObject input = uniqCI BEAObject(type := "Input", +text, createdBy := user(req));
420  
      if (nempty(info))
421  
        uniqCI BEAObject(type := "Input Source", +input, source := info);
422  
      ret hrefresh(or2(req.get("redirect"), baseLink + "/"));
423  
    }
424  
      
425  
    if (eq(uri, "/markUseful")) {
426  
      BEAObject o = beaGet(req.get("objectID"));
427  
      if (o == null) ret subBot_serve500("Object not found");
428  
      uniqCI BEAObject(type := "Useful", object := o, createdBy := user(req));
429  
      ret hrefresh(or2(req.get("redirect"), baseLink + "/"));
430  
    }
431  
      
432  
    if (eq(uri, "/saveAnswer")) {
433  
      S text = trim(req.get("text"));
434  
      S rewriteType = or2(trim(req.get("rewriteType")), "Suggested Answer";
435  
      long inputID = toLong(req.get("inputID"));
436  
      BEAObject input = beaGet(inputID);
437  
      if (input == null) ret subBot_serve500("Input not found");
438  
      if (empty(text)) ret subBot_serve500("Text empty");
439  
      if (l(text) > maxInputLength) ret subBot_serve500("Text too long");
440  
      uniqCI BEAObject(type := "Rewrite", +text, isRewriteOf := input, +rewriteType, createdBy := user(req));
441  
      ret hrefresh(or2(req.get("redirect"), baseLink + "/"));
442  
    }
443  
      
444  
    // add more public URLs here
445  
      
446  
    if (!inMasterMode(req)) null;
447  
    
448  
    if (eq(uri, "/uploadInputs"))
449  
      ret serveUploadTexts(req, "Input");
450  
    
451  
    if (eq(uri, "/uploadPatterns"))
452  
      ret serveUploadTexts(req, "Pattern");
453  
      
454  
    if (eq(uri, "/analyzeInput"))
455  
      ret calculations.serveAnalyzeInput(req);
456  
      
457  
    if (eq(uri, "/allBEATypes")) {
458  
      MultiSet<S> ms = asCIMultiSet(collect type(list(BEAObject)));
459  
      ret h2_title("All BEA object types")
460  
        //+ hpre(renderMultiSetAsLines_byPopularity(ms));
461  
        + ul(mapPairs(multiSetToPairsByPopularity(ms),
462  
          (type, count) -> {
463  
            S _type = or2(type, "(no type)");
464  
            ret count + " " + ahref(baseLink + "/beaCRUD/" + urlencode(_type), htmlEncode2(_type));
465  
          }));
466  
    }
467  
    
468  
    if (eq(uri, "/storeMatch")) {
469  
      BEAObject pattern = beaGet(req.get("pattern"));
470  
      BEAObject input = beaGet(req.get("input"));
471  
      S label = req.get("label");
472  
      BEAObject match = calculations.reactInputWithPattern(input, pattern);
473  
      if (match == null) ret "Couldn't match";
474  
      cset(match, +label);
475  
      ret hrefresh(or2(req.get("redirect"), beaObjectURL(match)));
476  
    }
477  
    
478  
    if (eq(uri, "/saveSyntacticPattern")) {
479  
      S text = req.get("text");
480  
      BEAObject fromInput = beaGet(req.get("fromInput"));
481  
      BEAObject pat = uniqCI BEAObject(type := "Syntactic Pattern", +text, createdBy := user(req));
482  
      csetIfUnset(pat, +fromInput);
483  
      if (fromInput != null)
484  
        calculations.reactInputWithPattern(fromInput, pat);
485  
      ret hrefresh(or2(req.get("redirect"), baseLink + "/"));
486  
    }
487  
    
488  
    if (eq(uri, "/runInstruction")) {
489  
      BEAObject o = beaGet(req.get("instruction"));
490  
      runInstruction(o);
491  
      ret hrefresh(beaObjectURL(o));
492  
    }
493  
    
494  
    if (eq(uri, "/convertResultToInput")) {
495  
      BEAObject result = beaGet(req.get("result"));
496  
      if (result == null) ret subBot_serve500("Object not found");
497  
      S text = unquote(getString result(result));
498  
      if (l(text) > maxInputLength) ret subBot_serve500("Input too long");
499  
      BEAObject input = uniqCI BEAObject(type := "Input", +text);
500  
      uniqCI BEAObject(type := "Input Source", +input, source := result);
501  
      ret hrefresh(beaShortURL(input));
502  
    }
503  
      
504  
    // add more master-mode URLs here
505  
  }
506  
  
507  
  HCRUD makeBEAObjectCRUD(Req req, S type) {
508  
    HCRUD crud = makeCRUD(BEAObject, req);
509  
    crud.baseLink = req.uri();
510  
    HCRUD_Concepts data = cast crud.data;
511  
    data.itemName = () -> firstToUpper(type);
512  
    data.addCIFilter(type := eqic(type, "(no type)") ? null : type);
513  
    
514  
    if (eqicOneOf(type, "Input", "Pattern", "AI Task")) {
515  
      IF0<MapSO> prev = data.emptyObject;
516  
      data.emptyObject = () -> {
517  
        MapSO item = data.emptyObject_fallback(prev);
518  
        item.put(text := ""); // show text field when creating new objects
519  
        ret item;
520  
      };
521  
    }
522  
    ret crud;
523  
  }
524  
  
525  
  O renderBEAObjectTable(Req req, S type) {
526  
    HCRUD crud = makeBEAObjectCRUD(req, type);
527  
    ret serveCRUD(req, BEAObject, crud);
528  
  }
529  
  
530  
  O serveUploadTexts(Req req, S type) {
531  
    S inputs = req.get("text");
532  
    
533  
    new LS output;
534  
    
535  
    if (nempty(inputs)) {
536  
      for (S text : tlft(inputs)) {
537  
        Pair<BEAObject, Bool> p = uniqCI2_sync BEAObject(+type, +text);
538  
        if (cget uploadedBy(p.a) == null)
539  
          cset(p.a, uploadedBy := req.auth.user);
540  
        output.add(type + " " + (p.b ? "added" : "exists")
541  
          + " (ID " + p.a.id + "): " + text);
542  
      }
543  
    }
544  
    
545  
    ret h2("Upload " + plural(type))
546  
      + hpostform(
547  
          p(plural(type) + " (one per line):")
548  
        + p(htextarea(inputs, name := "text"))
549  
        + pIfNempty(htmlEncode_nlToBR(lines(output)))
550  
        + hsubmit("Upload " + plural(type)));
551  
  }
552  
  
553  
  Cl<BEAObject> beaObjectsOfType(S type) {
554  
    ret conceptsWhereCI BEAObject(+type);
555  
  }
556  
  
557  
  void reactAllInputsWithSomePatterns {
558  
    calculations.reactAllInputsWithSomePatterns();
559  
  }
560  
  
561  
  S navDiv() {
562  
    HCRUD crud = makeCRUD(BEAObject, currentReq!);
563  
564  
    int inputsWithoutRewrites = countPred(beaList("Input"), c -> empty(beaBackRefs(c, "Rewrite")));
565  
    int inputsWithoutMatches = countPred(beaList("Input"), c -> empty(beaBackRefs(c, "Match")));
566  
    int syntacticPatternsWithoutRewrites = countPred(beaList("Syntactic Pattern"), c -> empty(beaBackRefs(c, "Rewrite")));
567  
    
568  
    ret joinNemptiesWithVBar(
569  
      beaNavLink("Input", crud),
570  
      beaNavLink("Pattern", crud),
571  
      beaNavLink("Syntactic Pattern", crud),
572  
      ahref(baseLink + "/syntacticPatternsWithoutRewrites", n2(syntacticPatternsWithoutRewrites) + " Syntactic patterns w/o rewrites"),
573  
      beaNavLink("Match", crud),
574  
      beaNavLink("Rewrite", crud),
575  
      beaNavLink("AI Task", crud),
576  
      ahref(baseLink + "/query", "Query"),
577  
      ahref(baseLink + "/inputsWithoutMatches", n2(inputsWithoutMatches) + " Inputs w/o matches"),
578  
      ahref(baseLink + "/inputsWithoutRewrites", n2(inputsWithoutRewrites) + " Inputs w/o rewrites"),
579  
      hPopDownButtonWithText("Bot Forum", navLinks(flat := true, withStats := false)),
580  
      hPopDownButton(
581  
        ahref(baseLink + "/allBEATypes", "All object types"),
582  
        ahref(baseLink + "/stats", "Stats"),
583  
        !inMasterMode(currentReq!) ? null : ahref(baseLink + "/refchecker", "Reference checker"),
584  
      ));
585  
  }
586  
  
587  
  // crud is just the cached BEAObject crud to check for creation rights
588  
  S beaNavLink(S type, HCRUD crud, int count default beaCount(type)) {
589  
    S plural = firstToLower(plural(type));
590  
    S link = baseLink + "/" + camelCase(plural);
591  
    
592  
    ret ahref(link, count + " " + firstToUpper(plural)) + (!crud.actuallyAllowCreate() ? "" : " " + ahref(addParamToURL(link, cmd := "new"), "+"));
593  
  }
594  
  
595  
  S beaObjectURL(BEAObject o) {
596  
    ret conceptLink(o, currentReq!);
597  
    /*ret o == null ?:
598  
      addParamsToURL(baseLink + "/crud/BEAObject",
599  
        selectObj := o.id) + "#" + o.id;*/
600  
  }
601  
  
602  
  S matchDescHTML(BEAObject m) {
603  
    pcall {
604  
      BEAObject pat = cget pattern(m);
605  
      SS mapping = cast cget mapping(m);
606  
      ret ahref_undecorated(crudLink(m), htmlEncode2(quote(getString text(pat)))
607  
        + "<br>&nbsp; with " + renderEqualsCommaProperties(mapping));
608  
    }
609  
    ret htmlEncode2(str(m));
610  
  }
611  
  
612  
  int beaCount(S type) {
613  
    ret countConceptsWhereCI BEAObject(+type);
614  
  }
615  
  
616  
  Cl<BEAObject> beaList(S type) {
617  
    ret conceptsWhereCI BEAObject(+type);
618  
  }
619  
  
620  
  Cl<BEAObject> beaListAny(S... types) {
621  
    ret concatLists(lmap beaList(litciset(types)));
622  
  }
623  
  
624  
  BEAObject beaGet(long id) {
625  
    ret getConceptOpt BEAObject(id);
626  
  }
627  
  
628  
  BEAObject beaGet(S id) {
629  
    ret beaGet(parseFirstLong(id));
630  
  }
631  
632  
  BEAObject mapMethodLike cgetBEA(S field, BEAObject o) {
633  
    ret (BEAObject) cget(field, o);
634  
  }
635  
  
636  
  S beaLinkHTML(BEAObject o) {  
637  
    ret o == null ?: ahref(conceptLink(o), htmlEncode2_nlToBr(str(o));
638  
  }
639  
  
640  
  S beaToHTML(BEAObject o) { ret beaLinkHTML(o); }
641  
  S beaHTML(BEAObject o) { ret beaLinkHTML(o); }
642  
  
643  
  S beaShortURL(BEAObject o) {
644  
    ret o == null ?: baseLink + "/" + o.id;
645  
  }
646  
  
647  
  Cl<BEAObject> beaBackRefs(BEAObject o, S type) {
648  
    ret objectsWhereCI(findBackRefs BEAObject(o), +type);
649  
  }
650  
  
651  
  O serveDefaultPage(Req req) {
652  
    HTMLFramer1 framer = req.framer;
653  
    framer.add(hcenter3(hsnippetimg_scaleToWidth(200, #1102967, 200, 110, title := "Gazelle"), style := "margin-top: 100px"));
654  
    ret completeFrame(req);
655  
  }
656  
  
657  
  S html_loggedIn() {
658  
    User user = user(currentReq!);
659  
    ret user == null
660  
      ? /*"Not logged in"*/ ahref(baseLink + "/", "Log in")
661  
      : "Logged in as " + htmlEncode2(user.name);
662  
  }
663  
  
664  
  void distributeNewObject_impl(BEAObject o) {
665  
    if (o.typeIs("Match")) ret;
666  
    distributeNotification("New object: " + o);
667  
  }
668  
  
669  
  void performAutoRuns(BEAObject o) {
670  
    print("performAutoRuns", o);
671  
    
672  
    for (BEAObject autoRun : beaList("Auto Run")) {
673  
      if (!isTrue(getOpt enabled(autoRun)))
674  
        continue with print("Not enabled: " + autoRun);
675  
      
676  
      S type = getString onChangedObjectOfType(autoRun);
677  
      if (!o.typeIs(type)) continue with print("Wrong type: " + type;
678  
      
679  
      print("Running " + autoRun);
680  
      BEAObject procedure = cast cget procedure(autoRun);
681  
      
682  
      S internalCode = getString internalCode(procedure);
683  
      print(+internalCode);
684  
      
685  
      if (eqic(internalCode, "convertInputToPattern")) {
686  
        S text = o.text();
687  
        if (!containsAngleBracketVars(text)) continue with print("No angle bracket vars");
688  
        BEAObject p = uniqCI_returnIfNew BEAObject(type := "Pattern", +text);
689  
        cset(p, fromInput := o, byProcedure := procedure, byAutoRun := autoRun);
690  
        print(+p);
691  
      } else if (eqic(internalCode, "makeSyntacticPattern")) {
692  
        print(sp := calculations.makeSyntacticPattern(o));
693  
      } else
694  
        print("Unknown internal code");
695  
    }
696  
  }
697  
698  
  BEAObject findInput(S text) {
699  
    ret conceptWhereIC(BEAObject, type := "Input", +text);
700  
  }
701  
  
702  
  S addRewriteHTML(BEAObject o) {
703  
    ret ahref(addParamsToURL(crudLink(BEAObject),
704  
      cmd := "new",
705  
      title := "Add Rewrite",
706  
      f_type := "Rewrite",
707  
      f_text := getStringOpt text(o),
708  
      f_isRewriteOf := o.id, metaInfo_isRewriteOf := "concept",
709  
    ), "Add Rewrite");
710  
  }
711  
  
712  
  O serveIntegerLink(Req req, long id) {
713  
    BEAObject o = getConceptOpt BEAObject(id);
714  
    if (o != null)
715  
      ret htitle(str(o)) + hrefresh(conceptLink(o));
716  
    ret super.serveIntegerLink(req, id);
717  
  }
718  
  
719  
  void distributeTestNotification() {
720  
    distributeNotification("It is " + localTimeWithSeconds());
721  
  }
722  
  
723  
  void distributeNotification(S text) {
724  
    notificationQ.add(r {
725  
      /*for (User user)
726  
        if (nemptyAfterTrim(user.notificationSetting))
727  
          sendNotification(text);*/
728  
          
729  
      for (Pair<virtual WebSocket, WebSocketInfo> p : syncMapToPairs(webSockets)) {
730  
        // TODO: check user
731  
        S jsCode =
732  
          "window.createNotification({ theme: 'success', showDuration: 3000 })("
733  
          + jsonEncodeMap(message := text) + ");";
734  
        call(p.a, "send", jsonEncodeMap(eval := jsCode));
735  
      }
736  
    });
737  
  }
738  
  
739  
  void runInstruction(BEAObject o) {
740  
    if (o == null) ret;
741  
    try {
742  
      BEAObject instruction = o;
743  
      if (o.typeIs("Step in script"))
744  
        instruction = (BEAObject) cget(o, "instruction");
745  
      
746  
      if (instruction.typeIs("Instruction | List objects by type")) {
747  
        saveInstructionResult(o, beaList(getString typeToList(instruction)));
748  
        ret;
749  
      }
750  
      
751  
      if (instruction.typeIs("Instruction | List object types"))
752  
        ret with saveInstructionResult(o, distinctCIFieldValuesOfConcepts(BEAObject, "type"));
753  
754  
      if (instruction.typeIs("Instruction | Filter list by text starting with")) {
755  
        // find list made before
756  
        BEAObject scriptRun = cgetBEA scriptRun(o);
757  
        if (scriptRun == null) fail("Need to be run as part of script");
758  
        L<BEAObject> steps = scriptRunSteps(scriptRun);
759  
        int idx = indexOf(steps, o);
760  
        if (idx < 0) fail("Step not found in script run");
761  
        
762  
        L<BEAObject> list = firstNotNull(map(reversed(takeFirst(steps, idx)),
763  
          step -> optCast L(cget data(cgetBEA result(step)))));
764  
         
765  
        S prefix = getString prefix(instruction);
766  
        L<BEAObject> filtered = filter(list, obj -> swic(obj.text(), prefix);
767  
        saveInstructionResult(o, filtered);
768  
        ret;
769  
      }
770  
      
771  
      if (instruction.typeIs("Script")) {
772  
        BEAObject script = instruction;
773  
        BEAObject scriptRun = cnew BEAObject(type := "Script Run", +script);
774  
        
775  
        // Make an instance of all the instructions
776  
        
777  
        int i = 0;
778  
        new L<BEAObject> steps;
779  
        while not null (instruction = (BEAObject) cget(instruction, "step" + (++i))) {
780  
          BEAObject step = cnew(BEAObject, type := "Step in script", step := i, +scriptRun, +instruction);
781  
          steps.add(step);
782  
        }
783  
        
784  
        cset(scriptRun, +steps);
785  
        
786  
        // TODO: run steps?
787  
788  
        ret;
789  
      }
790  
      
791  
      cnew BEAObject(type := "Instruction Error", instruction := o, error := "Unknown instruction type");
792  
    } catch e {
793  
      cnew BEAObject(type := "Instruction Error", instruction := o, error := getStackTrace(e));
794  
    }
795  
  }
796  
797  
  BEAObject saveInstructionResult(BEAObject instruction, O data) {
798  
    BEAObject result = cnew BEAObject(type := "Instruction Result",
799  
      +instruction, +data);
800  
    cset(instruction, +result);
801  
    ret result;
802  
  }
803  
  
804  
  L<BEAObject> scriptRunSteps(BEAObject scriptRun) {
805  
    ret (L) cget steps(scriptRun);
806  
  }
807  
} // end of module
808  
809  
extend User {
810  
  S notificationSetting;
811  
}
812  
813  
concept BEAObject > ConceptWithGlobalID {
814  
  new Ref<UserPost> mirrorPost;
815  
816  
  void change :: after {
817  
    ((GazelleBEA) botMod()).rstUpdateBEAMirrors.add(this);
818  
  }
819  
820  
  void delete :: before {
821  
    cdelete(mirrorPost!);
822  
  }
823  
  
824  
  void updateMirrorPost {
825  
    GazelleBEA mod = cast botMod();
826  
    if (isDeleted() || !mod.mirrorBEAObjects) ret;
827  
828  
    if (!mirrorPost.has())
829  
      cset(this, mirrorPost := cnew UserPost(
830  
        type := "BEA Object",
831  
        creator := mod.internalUser(),
832  
        botInfo := "BEA Mirror Bot"));
833  
834  
    S text = structureString();
835  
836  
    cset(mirrorPost!, 
837  
      title := str(this),
838  
      +text);
839  
  }
840  
841  
  S structureString() {
842  
    S text = "Error";
843  
    pcall {
844  
      structure_Data data = new {
845  
        structure_ClassInfo newClass(Class c) {
846  
          structure_ClassInfo info = super.newClass(c);
847  
          if (c == Concept.Ref.class) {
848  
            info.special = true;
849  
            info.serializeObject = o -> {
850  
              Concept cc = cast deref((Concept.Ref) o);
851  
              //append("cu CRef " + (cc != null ? str(cc.id) : "null"), 3);
852  
              if (cc cast BEAObject)
853  
                append("CRef(gid=" + quote(cc.globalID()) + ")", 6);
854  
              else if (cc != null)
855  
                append("CRef(id=" + cc.id + ")", 6);
856  
              else
857  
                append("CRef", 1);
858  
            };
859  
          }
860  
          ret info;
861  
        }
862  
863  
        void setFields(structure_ClassInfo info, L<Field> fields) {
864  
          if (isSubclassOf(info.c, BEAObject)) {
865  
            // Don't serialize "refs" and "backRefs" fields
866  
            removeAll(fields,
867  
              getField(BEAObject, "refs"),
868  
              getField(BEAObject, "backRefs"));
869  
          }
870  
          super.setFields(info, fields);
871  
        }
872  
      };
873  
      
874  
      S struct = structure(this, data);
875  
      struct = dropLoadableUtilsPackageFromStruct(struct);
876  
      text = indentStructureString_firstLevels(1, struct);
877  
    }
878  
879  
    ret text;
880  
  }
881  
      
882  
  toString {
883  
    S type = strOrNull(cget type(this));
884  
    S s = super.toString();
885  
    
886  
    if (nempty(type)) {
887  
      s = type + " " + id;
888  
      if (eqic(type, "Match"))
889  
        s += appendBracketed(strOrNull(this~.label))
890  
          + " " + this.~mapping
891  
          + appendBracketed(this.~input + " + " + this~.pattern);
892  
    }
893  
    
894  
    bool enabled = eq(true, getOpt enabled(this));
895  
    if (enabled) s += " [enabled]";
896  
    
897  
    S text = or2(text(), getStringOpt name(this));
898  
    if (text != null)
899  
      s += " " + quote(text);
900  
      
901  
    O fc = this~.functionCalled;
902  
    if (fc != null) s += " " + fc;
903  
      
904  
    ret s;
905  
  }
906  
  
907  
  S type() { ret getStringOpt type(this); }
908  
  bool typeIs(S type) { ret eqic(type(), type); }
909  
  bool typeIsOneOf(S... types) { ret eqicOneOf(type(), types); }
910  
  
911  
  S text() { ret getStringOpt text(this); }
912  
} // end of BEAObject

Author comment

Began life as a copy of #1030602

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1030954
Snippet name: Gazelle BEA [new compact include test]
Eternal ID of this version: #1030954/18
Text MD5: 4d26184a9a4aed3c15e9b1bdcaddc39b
Transpilation MD5: d4449ae854231ea254976411247ed8c3
Author: stefan
Category: javax
Type: JavaX source code (Dynamic Module)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-04-14 22:42:45
Source code size: 32005 bytes / 912 lines
Pitched / IR pitched: No / No
Views / Downloads: 230 / 459
Version history: 17 change(s)
Referenced in: [show references]