comparison src/nabble/view/web/template/NabbleNamespace.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children 18cf4872fd7f
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1 package nabble.view.web.template;
2
3 import fschmidt.db.DbDatabase;
4 import fschmidt.html.Html;
5 import fschmidt.util.java.HtmlUtils;
6 import fschmidt.util.mail.AlternativeMultipartContent;
7 import fschmidt.util.mail.Content;
8 import fschmidt.util.mail.HtmlTextContent;
9 import fschmidt.util.mail.Mail;
10 import fschmidt.util.mail.MailAddress;
11 import fschmidt.util.mail.MailHome;
12 import fschmidt.util.mail.PlainTextContent;
13 import nabble.model.Executors;
14 import nabble.model.Init;
15 import nabble.model.Lucene;
16 import nabble.model.Message;
17 import nabble.model.ModelException;
18 import nabble.model.ModelHome;
19 import nabble.model.Node;
20 import nabble.model.Person;
21 import nabble.model.Site;
22 import nabble.model.SystemProperties;
23 import nabble.model.User;
24 import nabble.modules.ModuleManager;
25 import nabble.naml.compiler.Command;
26 import nabble.naml.compiler.CommandSpec;
27 import nabble.naml.compiler.CompileException;
28 import nabble.naml.compiler.Encoder;
29 import nabble.naml.compiler.IPrintWriter;
30 import nabble.naml.compiler.Interpreter;
31 import nabble.naml.compiler.Macro;
32 import nabble.naml.compiler.Meaning;
33 import nabble.naml.compiler.Namespace;
34 import nabble.naml.compiler.Program;
35 import nabble.naml.compiler.ScopedInterpreter;
36 import nabble.naml.compiler.Source;
37 import nabble.naml.compiler.Template;
38 import nabble.naml.compiler.TemplatePrintWriter;
39 import nabble.naml.compiler.Usage;
40 import nabble.naml.namespaces.BasicNamespace;
41 import nabble.naml.namespaces.StringList;
42 import nabble.naml.namespaces.TemplateException;
43 import nabble.view.lib.Jtp;
44 import nabble.view.lib.Permissions;
45 import nabble.view.lib.Shared;
46 import nabble.view.lib.help.Help;
47 import nabble.view.web.Javascript;
48 import nabble.view.web.user.OnlineStatus;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 import javax.servlet.ServletException;
53 import java.io.File;
54 import java.io.IOException;
55 import java.io.PrintWriter;
56 import java.io.StringWriter;
57 import java.net.MalformedURLException;
58 import java.net.URL;
59 import java.util.ArrayList;
60 import java.util.Collection;
61 import java.util.Collections;
62 import java.util.HashMap;
63 import java.util.HashSet;
64 import java.util.LinkedHashMap;
65 import java.util.LinkedHashSet;
66 import java.util.List;
67 import java.util.Map;
68 import java.util.Set;
69 import java.util.TreeMap;
70 import java.util.regex.Pattern;
71
72
73 @Namespace (
74 name = "nabble",
75 global = true
76 )
77 public final class NabbleNamespace {
78 private static final Logger logger = LoggerFactory.getLogger(NabbleNamespace.class);
79
80 public static final String newsflash = (String)Init.get("newsflash");
81
82 private static ThreadLocal<NabbleNamespace> tl = new ThreadLocal<NabbleNamespace>();
83
84 public static NabbleNamespace current() {
85 return tl.get();
86 }
87
88 private Site site;
89
90 public NabbleNamespace(Site site) {
91 if( site == null )
92 throw new NullPointerException("site is null");
93 this.site = site;
94 tl.set(this);
95 }
96
97 public Site site() {
98 return site;
99 }
100
101 public DbDatabase db() {
102 return site.getDb();
103 }
104
105 public static final CommandSpec root_node = CommandSpec.DO;
106
107 @Command public void root_node(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) {
108 NodeNamespace ns = new NodeNamespace(site().getRootNode());
109 out.print( interp.getArg(ns,"do") );
110 }
111
112 @Command public void site_id(IPrintWriter out,Interpreter interp) {
113 out.print( site.getId() );
114 }
115
116 @Command public void base_url(IPrintWriter out,Interpreter interp) {
117 out.print( interp.encode( site.getBaseUrl() ) );
118 }
119
120 public static final CommandSpec terms_of_use_url = CommandSpec.DO()
121 .optionalParameters("is_registration_form")
122 .build()
123 ;
124
125 @Command public static void terms_of_use_url(IPrintWriter out,Interpreter interp) {
126 boolean isRegistrationForm = interp.getArgAsBoolean("is_registration_form", false);
127 out.print( interp.encode(Jtp.termsUrl(isRegistrationForm)));
128 }
129
130
131 public static final CommandSpec javascript_string_encode = CommandSpec.TEXT;
132
133 @Command public void javascript_string_encode(IPrintWriter out,Interpreter interp) {
134 out.print( HtmlUtils.javascriptStringEncode(interp.getArgString("text")) );
135 }
136
137 public static final CommandSpec break_up = CommandSpec.TEXT;
138
139 @Command public void break_up(IPrintWriter out,Interpreter interp) {
140 out.print( Jtp.breakUp(interp.getArgString("text")) );
141 }
142
143 public static final CommandSpec hide_emails = CommandSpec.TEXT;
144
145 @Command public void hide_emails(IPrintWriter out,Interpreter interp) {
146 Encoder encoder = interp.getEncoder();
147 interp.setEncoder(Encoder.TEXT);
148 String text = interp.getArgString("text");
149 interp.setEncoder(encoder);
150 out.print( interp.encode( ModelHome.hideAllEmails(text) ) );
151 }
152
153
154
155 @Namespace (
156 name = "help_instance",
157 global = false
158 )
159 public static class HelpNs {
160 private final Help help;
161
162 private HelpNs(Help help) {
163 this.help = help;
164 }
165
166 @Command public void url(IPrintWriter out,Interpreter interp) {
167 out.print( help.url() );
168 }
169
170 @Command public void link(IPrintWriter out,Interpreter interp) {
171 out.print( help.link() );
172 }
173 }
174
175 @Namespace (
176 name = "help",
177 global = false
178 )
179 public static class HelpsNs {
180
181 private static void print(IPrintWriter out,ScopedInterpreter<HelpNs> interp,Help help) {
182 out.print( interp.getArg(new HelpNs(help),"do") );
183 }
184
185 @Command public void index_path(IPrintWriter out,Interpreter interp) {
186 out.print( interp.encode( "/help/Index.jtp" ) );
187 }
188
189 public static final CommandSpec mailing_list_intro = CommandSpec.DO;
190
191 @Command public void mailing_list_intro(IPrintWriter out,ScopedInterpreter<HelpNs> interp) {
192 print(out,interp,Help.mailingListIntro);
193 }
194
195 public static final CommandSpec search = CommandSpec.DO;
196
197 @Command public void search(IPrintWriter out,ScopedInterpreter<HelpNs> interp) {
198 print(out,interp,Help.search);
199 }
200
201 public static final CommandSpec cataloging = CommandSpec.DO;
202
203 @Command public void cataloging(IPrintWriter out,ScopedInterpreter<HelpNs> interp) {
204 print(out,interp,Help.cataloging);
205 }
206
207 public static final CommandSpec embed_what_how = CommandSpec.DO;
208
209 @Command public void embed_what_how(IPrintWriter out,ScopedInterpreter<HelpNs> interp) {
210 print(out,interp,Help.embed_what_how);
211 }
212
213 public static final CommandSpec mixed_lengths = CommandSpec.DO;
214
215 @Command public void mixed_lengths(IPrintWriter out,ScopedInterpreter<HelpNs> interp) {
216 print(out,interp,Help.mixed_lengths);
217 }
218
219 public static final CommandSpec password = CommandSpec.DO;
220
221 @Command public void password(IPrintWriter out,ScopedInterpreter<HelpNs> interp) {
222 print(out,interp,Help.password);
223 }
224
225 public static final CommandSpec userid = CommandSpec.DO;
226
227 @Command public void userid(IPrintWriter out,ScopedInterpreter<HelpNs> interp) {
228 print(out,interp,Help.userid);
229 }
230 }
231 private static final HelpsNs helpsNs = new HelpsNs();
232
233 public static final CommandSpec help = CommandSpec.DO;
234
235 @Command public void help(IPrintWriter out,ScopedInterpreter<HelpsNs> interp) {
236 out.print( interp.getArg(helpsNs,"do") );
237 }
238
239
240
241
242
243 public static final CommandSpec truncate = new CommandSpec.Builder()
244 .dotParameter("text")
245 .parameters("size")
246 .optionalParameters("if_truncated")
247 .build()
248 ;
249
250 @Command public void truncate(IPrintWriter out,Interpreter interp) {
251 String text = interp.getArgString("text");
252 String size = interp.getArgString("size");
253 int n;
254 try {
255 n = Integer.valueOf(size);
256 } catch (NumberFormatException e) {
257 throw new RuntimeException("Invalid \"size\" attribute: " + size);
258 }
259 if (text.length() > n) {
260 text = text.substring(0, n-4) + "...";
261 out.print(text);
262 Object ifTruncated = interp.getArg("if_truncated");
263 if (ifTruncated != null) {
264 out.print(ifTruncated);
265 }
266 } else
267 out.print(text);
268 }
269
270
271
272 private static final BasicNamespace.ExceptionNamespaceFactory<ErrorNamespace> myExceptionNamespaceFactory =
273 new BasicNamespace.ExceptionNamespaceFactory<ErrorNamespace>() {
274 public ErrorNamespace newExceptionNamespace(TemplateException ex) {
275 return new ErrorNamespace(ex);
276 }
277 }
278 ;
279
280 public static final CommandSpec handle_exception = BasicNamespace.handle_exception;
281
282 @Command public void handle_exception(IPrintWriter out,ScopedInterpreter<ErrorNamespace> interp) {
283 interp.getFromStack(BasicNamespace.class).handleException(out,interp,myExceptionNamespaceFactory);
284 }
285
286
287 @Command public static void tabs_library_path(IPrintWriter out,Interpreter interp) {
288 out.print( interp.encode( Shared.getTabsPath() ) );
289 }
290
291 @Command public static void nabble_global_apps_url(IPrintWriter out,Interpreter interp) {
292 out.print( interp.encode( Jtp.homeContextUrl() + "/UserSites.jtp" ) );
293 }
294
295 @Command public void get_newsflash(IPrintWriter out,Interpreter interp) {
296 out.print( newsflash );
297 }
298
299
300 /** Number of pages to be displayed before/after the current page*/
301 private static final int NEIGHBOR_PAGES = 3;
302
303 public static final CommandSpec paging = new CommandSpec.Builder()
304 .parameters("total_rows","current_row","rows_per_page")
305 .scopedParameters("do")
306 .dotParameter("do")
307 .build()
308 ;
309
310 @Command public void paging(IPrintWriter out,ScopedInterpreter<PagingNamespace> interp) {
311 int totalRows = interp.getArgAsInt("total_rows");
312 int currentRow = interp.getArgAsInt("current_row",0);
313 int rowsPerPage = interp.getArgAsInt("rows_per_page");
314 out.print( interp.getArg( new PagingNamespace(totalRows,currentRow,rowsPerPage,NEIGHBOR_PAGES), "do" ) );
315 }
316
317
318
319 // Basic Nabble Urls
320
321 @Command public void nabble_homepage(IPrintWriter out,Interpreter interp) {
322 out.print(Jtp.homePage());
323 }
324
325 public static final CommandSpec get_int = new CommandSpec.Builder()
326 .parameters("exception")
327 .optionalParameters("default")
328 .dotParameter("int")
329 .build()
330 ;
331
332 @Command public void get_int(IPrintWriter out,Interpreter interp)
333 throws TemplateException
334 {
335 String ex = interp.getArgString("exception");
336 String s = interp.getArgString("int");
337 if( s != null ) {
338 s = s.trim();
339 if( s.length() > 0 ) {
340 try {
341 out.print( Integer.parseInt(s) );
342 return;
343 } catch(NumberFormatException e) {
344 throw TemplateException.newInstance( ex );
345 }
346 }
347 }
348 String def = interp.getArgString("default");
349 if( def == null )
350 throw TemplateException.newInstance( ex );
351 out.print( Integer.parseInt(def) );
352 }
353
354 @Command public void site_activity(IPrintWriter out,Interpreter interp) {
355 out.print( site().getActivity() );
356 }
357
358 @Command public void site_has_delete_date(IPrintWriter out,Interpreter interp) {
359 out.print( site().getDeleteDate() != null );
360 }
361
362 public static final CommandSpec site_delete_date = CommandSpec.DO;
363
364 @Command public void site_delete_date(IPrintWriter out,ScopedInterpreter<DateNamespace> interp) {
365 out.print( interp.getArg( new DateNamespace(site().getDeleteDate()), "do" ) );
366 }
367
368 public static final CommandSpec new_email = CommandSpec.DO;
369
370 @Command public void new_email(IPrintWriter out,ScopedInterpreter<EmailNamespace> interp) {
371 out.print( interp.getArg( new EmailNamespace(), "do" ) );
372 }
373
374 public static final CommandSpec parse_email = new CommandSpec.Builder()
375 .dotParameter("text")
376 .build()
377 ;
378
379 @Command public void parse_email(IPrintWriter out,Interpreter interp)
380 throws ModelException.EmailFormat
381 {
382 String email = null;
383 String text = interp.getArgString("text");
384 if( text != null ) {
385 text = text.trim();
386 if( text.length() > 0 ) {
387 int posOpen = text.indexOf('<');
388 int posClose = text.indexOf('>');
389 if (posOpen >= 0 && posClose > posOpen)
390 text = text.substring(posOpen+1, posClose).trim();
391 if (!new MailAddress(text).isValid())
392 throw new ModelException.EmailFormat(text);
393 email = text;
394 }
395 }
396 out.print(email);
397 }
398
399 public static final CommandSpec is_valid_node= CommandSpec.DO()
400 .parameters("node_id")
401 .build()
402 ;
403
404 @Command public void is_valid_node(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) {
405 long nodeId = interp.getArgAsLong("node_id");
406 Node node = site.getNode(nodeId);
407 out.print(node != null);
408 }
409
410 public static final CommandSpec get_node_from_id = CommandSpec.DO()
411 .parameters("node_id")
412 .build()
413 ;
414
415 @Command public void get_node_from_id(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) {
416 long nodeId = interp.getArgAsLong("node_id");
417 Node node = site.getNode(nodeId);
418 out.print( interp.getArg(new NodeNamespace(node),"do") );
419 }
420
421 public static final CommandSpec get_user_from_id = CommandSpec.DO()
422 .parameters("user_id")
423 .build();
424
425 @Command public void get_user_from_id(IPrintWriter out,ScopedInterpreter<UserNamespace> interp)
426 throws IOException, ServletException
427 {
428 String userId = interp.getArgString("user_id");
429 Person person = site().getPerson(userId);
430 out.print( interp.getArg(new UserNamespace(person),"do") );
431 }
432
433 public static final CommandSpec user_groups = CommandSpec.DO;
434
435 @Command public void user_groups(IPrintWriter out,ScopedInterpreter<GroupList> interp) {
436 List<String> groups = Permissions.getGroups(site());
437 Object block = interp.getArg(new GroupList(groups),"do");
438 out.print(block);
439 }
440
441 @Namespace (
442 name = "group_list",
443 global = true
444 )
445 public static final class GroupList extends StringList {
446
447 GroupList(List<String> groups) {
448 super(groups);
449 }
450
451 @Command public void current_group(IPrintWriter out,Interpreter interp) {
452 out.print(get());
453 }
454 }
455
456 public static final CommandSpec permissions = CommandSpec.DO()
457 .optionalParameters("values")
458 .build()
459 ;
460
461 @Command public void permissions(IPrintWriter out,ScopedInterpreter<PermissionList> interp)
462 throws IOException, ServletException
463 {
464 List<String> list = new ArrayList<String>();
465 String values = interp.getArgString("values");
466 for( String s : values.split(",") ) {
467 list.add( s.trim() );
468 }
469 Object block = interp.getArg(new PermissionList(list),"do");
470 out.print(block);
471 }
472
473 @Namespace (
474 name = "permission_list",
475 global = true
476 )
477 public static final class PermissionList extends StringList {
478
479 PermissionList(List<String> list) {
480 super(list);
481 }
482
483 @Command public void current_permission(IPrintWriter out,Interpreter interp) {
484 out.print(get());
485 }
486 }
487
488
489 public static final CommandSpec get_node = CommandSpec.DO()
490 .parameters("node")
491 .build()
492 ;
493
494 @Command public void get_node(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) {
495 NodeNamespace nodeNs = interp.getArgAsNamespace(NodeNamespace.class,"node");
496 if( nodeNs == null )
497 throw new RuntimeException("node is null");
498 out.print( interp.getArg(nodeNs,"do") );
499 }
500
501 public static final CommandSpec get_user = CommandSpec.DO()
502 .parameters("user")
503 .build()
504 ;
505
506 @Command public void get_user(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) {
507 UserNamespace userNs = interp.getArgAsNamespace(UserNamespace.class,"user");
508 if( userNs == null ) {
509 out.print( (String)null );
510 return;
511 }
512 out.print( interp.getArg(userNs,"do") );
513 }
514
515 public static final CommandSpec get_subscription = CommandSpec.DO()
516 .parameters("subscription")
517 .build()
518 ;
519
520 @Command public void get_subscription(IPrintWriter out,ScopedInterpreter<SubscriptionNamespace> interp) {
521 SubscriptionNamespace subscriptionNs = interp.getArgAsNamespace(SubscriptionNamespace.class,"subscription");
522 out.print( interp.getArg(subscriptionNs,"do") );
523 }
524 /*
525 not needed yet
526 public static final CommandSpec get_mailing_list = CommandSpec.DO()
527 .parameters("mailing_list")
528 .build()
529 ;
530
531 @Command public void get_mailing_list(IPrintWriter out,ScopedInterpreter<MailingListNamespace> interp) {
532 MailingListNamespace ns = interp.getArgAsNamespace(MailingListNamespace.class,"mailing_list");
533 out.print( interp.getArg(ns,"do") );
534 }
535 */
536
537
538 @Command public void anyone_group(IPrintWriter out,Interpreter interp) {
539 out.print( Permissions.ANYONE_GROUP );
540 }
541
542 @Command public void registered_group(IPrintWriter out,Interpreter interp) {
543 out.print( Permissions.REGISTERED_GROUP );
544 }
545
546 @Command public void authors_group(IPrintWriter out,Interpreter interp) {
547 out.print( Permissions.AUTHOR_GROUP );
548 }
549
550 @Command public void administrators_group(IPrintWriter out,Interpreter interp) {
551 out.print( Permissions.ADMINISTRATORS_GROUP );
552 }
553
554 @Command public void view_permission(IPrintWriter out,Interpreter interp) {
555 out.print( Permissions.VIEW_PERMISSION );
556 }
557
558 public static final CommandSpec set_default_permissions = CommandSpec.NO_OUTPUT()
559 .scopedParameters("do")
560 .dotParameter("do")
561 .parameters("version")
562 .build()
563 ;
564
565 @Command public void set_default_permissions(IPrintWriter out,ScopedInterpreter<DefaultPermissionEditorNamespace> interp) {
566 String version = interp.getArgString("version");
567 synchronized( ("permission-lock-"+site().getId()).intern() ) {
568 site = site.getGoodCopy();
569 if( !Permissions.isPermissionVersion(site,interp.getArgString("version")) ) {
570 DefaultPermissionEditorNamespace ns;
571 while(true) {
572 db().beginTransaction();
573 try {
574 Site site = this.site.getGoodCopy();
575 Permissions.setPermissionVersion(site,version);
576 ns = new DefaultPermissionEditorNamespace(site);
577 interp.getArgString(ns,"do");
578 db().commitTransaction();
579 } finally {
580 db().endTransaction();
581 }
582 site = site.getGoodCopy();
583 if( ns.ok(site) )
584 break;
585 logger.error("set_default_permissions failed for "+site+", trying again");
586 }
587 }
588 }
589 }
590
591 @Namespace (
592 name = "default_permission_editor",
593 global = true
594 )
595 public static final class DefaultPermissionEditorNamespace {
596 private static class PermGroup {
597 final String perm;
598 final String group;
599
600 PermGroup(String perm,String group) {
601 this.perm = perm;
602 this.group = group;
603 }
604 }
605
606 private final Site site;
607 private final List<PermGroup> permissions = new ArrayList<PermGroup>();
608 private final List<PermGroup> sitePermissions = new ArrayList<PermGroup>();
609
610 DefaultPermissionEditorNamespace(Site site) {
611 this.site = site;
612 }
613
614 public static final CommandSpec add_permission = CommandSpec.NO_OUTPUT()
615 .parameters("group","permission")
616 .build()
617 ;
618
619 @Command public void add_permission(IPrintWriter out,Interpreter interp) {
620 String perm = interp.getArgString("permission");
621 String group = interp.getArgString("group");
622 Permissions.addPermission(site,perm,group);
623 permissions.add(new PermGroup(perm,group));
624 }
625
626 public static final CommandSpec add_site_permission = add_permission;
627
628 @Command public void add_site_permission(IPrintWriter out,Interpreter interp) {
629 String perm = interp.getArgString("permission");
630 String group = interp.getArgString("group");
631 Permissions.addSiteDefaultPermission(site,perm,group);
632 sitePermissions.add(new PermGroup(perm,group));
633 }
634
635 boolean ok(Site site) {
636 for( PermGroup pg : permissions ) {
637 if( !Permissions.hasPermission(site,pg.group,pg.perm) ) {
638 logger.error("add_permission failed for "+site+" permission="+pg.perm+" group="+pg.group);
639 return false;
640 }
641 }
642 for( PermGroup pg : sitePermissions ) {
643 if( !Permissions.hasSiteDefaultPermission(site,pg.group,pg.perm) ) {
644 logger.error("add_site_permission failed for "+site+" permission="+pg.perm+" group="+pg.group);
645 return false;
646 }
647 }
648 return true;
649 }
650 }
651
652 public static final CommandSpec save_site_permissions = CommandSpec.DO;
653
654 @Command public void save_site_permissions(IPrintWriter out,ScopedInterpreter<SitePermissionEditorNamespace> interp) {
655 db().beginTransaction();
656 try {
657 interp.getArgString(new SitePermissionEditorNamespace(site()),"do");
658 db().commitTransaction();
659 } finally {
660 db().endTransaction();
661 }
662 }
663
664 @Namespace (
665 name = "site_permission_editor",
666 global = true
667 )
668 public static final class SitePermissionEditorNamespace {
669 private final Site site;
670
671 SitePermissionEditorNamespace(Site site) {
672 this.site = site;
673 }
674
675 public static final CommandSpec remove_site_permissions = CommandSpec.NO_OUTPUT;
676
677 @Command public void remove_site_permissions(IPrintWriter out,Interpreter interp) {
678 Permissions.removeSitePermissions(site);
679 }
680
681 public static final CommandSpec add_site_permission = CommandSpec.NO_OUTPUT()
682 .parameters("permission")
683 .optionalParameters("group")
684 .build()
685 ;
686
687 @Command public void add_site_permission(IPrintWriter out,Interpreter interp) {
688 String perm = interp.getArgString("permission");
689 String group = interp.getArgString("group");
690 if( group == null )
691 Permissions.addSitePermission(site,perm);
692 else
693 Permissions.addSitePermission(site,perm,group);
694 }
695
696 public static final CommandSpec remove_site_permission = CommandSpec.NO_OUTPUT()
697 .parameters("permission")
698 .optionalParameters("group")
699 .build()
700 ;
701
702 @Command public void remove_site_permission(IPrintWriter out,Interpreter interp) {
703 String group = interp.getArgString("group");
704 String perm = interp.getArgString("permission");
705 if (group == null)
706 Permissions.removeSitePermission(site,perm);
707 else
708 Permissions.removeSitePermission(site,perm,group);
709 }
710
711 }
712
713 public static final CommandSpec has_default_permission = new CommandSpec.Builder()
714 .parameters("group","permission")
715 .build()
716 ;
717
718 @Command public void has_default_permission(IPrintWriter out,Interpreter interp) {
719 String group = interp.getArgString("group");
720 String perm = interp.getArgString("permission");
721 out.print( Permissions.hasPermission(site(),group,perm) );
722 }
723
724 public static final CommandSpec has_site_default_permission = has_default_permission;
725
726 @Command public void has_site_default_permission(IPrintWriter out,Interpreter interp) {
727 String group = interp.getArgString("group");
728 String perm = interp.getArgString("permission");
729 out.print( Permissions.hasSiteDefaultPermission(site(),group,perm) );
730 }
731
732 public static final CommandSpec group_has_site_permission = has_default_permission;
733
734 @Command public void group_has_site_permission(IPrintWriter out,Interpreter interp) {
735 String group = interp.getArgString("group");
736 String perm = interp.getArgString("permission");
737 out.print( Permissions.hasSitePermission(site(),group,perm) );
738 }
739
740 public static final CommandSpec site_has_site_permission = new CommandSpec.Builder()
741 .dotParameter("permission")
742 .build()
743 ;
744
745 @Command public void site_has_site_permission(IPrintWriter out,Interpreter interp) {
746 String perm = interp.getArgString("permission");
747 out.print( Permissions.siteHasSitePermission(site(),perm) );
748 }
749
750 public static final CommandSpec remove_group = CommandSpec.NO_OUTPUT()
751 .parameters("group")
752 .build()
753 ;
754
755 @Command public void remove_group(IPrintWriter out,Interpreter interp) {
756 String group = interp.getArgString("group");
757 Permissions.removeGroup(site(),group);
758 }
759
760 public static final CommandSpec users_in_group = CommandSpec.DO()
761 .parameters("group")
762 .build()
763 ;
764
765 @Command public void users_in_group(IPrintWriter out,ScopedInterpreter<UserNamespace.UserList> interp) {
766 String group = interp.getArgString("group");
767 List<User> users = Permissions.getUsersInGroup(site,group);
768 UserNamespace.UserList usersNs = new UserNamespace.UserList(users);
769 out.print( interp.getArg(usersNs,"do") );
770 }
771
772 public static final CommandSpec site_users = new CommandSpec.Builder()
773 .parameters("length")
774 .optionalParameters("start", "filter")
775 .scopedParameters("do")
776 .dotParameter("do")
777 .outputtedParameters("do")
778 .build()
779 ;
780
781 @Command public void site_users(IPrintWriter out,ScopedInterpreter<UserNamespace.UserList> interp) {
782 int start = interp.getArgAsInt("start",0);
783 int length = interp.getArgAsInt("length");
784 String cnd = interp.getArgString("filter");
785 List<User> users = site.getUsersByNodeCount(start,length,cnd);
786 UserNamespace.UserList usersNs = new UserNamespace.UserList(users);
787 out.print( interp.getArg(usersNs,"do") );
788 }
789
790 public static final CommandSpec site_user_count = CommandSpec.DO()
791 .optionalParameters("filter")
792 .build();
793
794 @Command public void site_user_count(IPrintWriter out,Interpreter interp) {
795 String cnd = interp.getArgString("filter");
796 out.print( site.getUserCount(cnd) );
797 }
798
799 @Command public void registered_filter(IPrintWriter out,Interpreter interp) {
800 out.print( "registered is not null" );
801 }
802
803 public static final CommandSpec online_users = CommandSpec.DO()
804 .optionalParameters("include_invisible_users")
805 .build();
806
807 @Command public void online_users(IPrintWriter out,ScopedInterpreter<UserNamespace.UserList> interp) {
808 boolean includeInvisibleUsers = interp.getArgAsBoolean("include_invisible_users", false);
809 List<User> users = OnlineStatus.getOnlineUsers(site, includeInvisibleUsers);
810 UserNamespace.UserList usersNs = new UserNamespace.UserList(users);
811 out.print( interp.getArg(usersNs,"do") );
812 }
813
814 @Command public void online_anonymous_users_count(IPrintWriter out,Interpreter interp) {
815 out.print( OnlineStatus.getOnlineAnonymousUsersCount(site) );
816 }
817
818 @Command public void online_invisible_users_count(IPrintWriter out,Interpreter interp) {
819 out.print( OnlineStatus.getOnlineInvisibleUsersCount(site) );
820 }
821
822 public static final CommandSpec url_belongs_to_site = new CommandSpec.Builder()
823 .parameters("url")
824 .build()
825 ;
826
827 @Command public void url_belongs_to_site(IPrintWriter out,Interpreter interp)
828 throws TemplateException
829 {
830 try {
831 String url = interp.getArgString("url");
832 String domain = new URL(url).getHost();
833 Long siteId = Jtp.getSiteIdFromDomain(domain);
834 out.print( siteId != null && siteId.longValue() == site().getId() );
835 } catch(MalformedURLException e) {
836 throw new ModelException.InvalidPermalink();
837 }
838 }
839
840 public static final CommandSpec check_registered_user = new CommandSpec.Builder()
841 .parameters("email","password_hash")
842 .build()
843 ;
844
845 @Command public void check_registered_user(IPrintWriter out,Interpreter interp) {
846 String email = interp.getArgString("email");
847 String pwd = interp.getArgString("password_hash");
848 User user = site.getUserFromEmail(email);
849 out.print( user != null && user.isRegistered() && user.checkPasscookie(pwd) );
850 }
851
852 public static final CommandSpec get_or_create_user = CommandSpec.DO()
853 .parameters("email")
854 .build()
855 ;
856
857 @Command public void get_or_create_user(IPrintWriter out,ScopedInterpreter<UserNamespace> interp)
858 throws ModelException.EmailFormat
859 {
860 String email = interp.getArgString("email");
861 if (!new MailAddress(email).isValid())
862 throw new ModelException.EmailFormat(email);
863 User user = site.getOrCreateUser(email);
864 out.print( interp.getArg(new UserNamespace(user),"do") );
865 }
866
867 public static final CommandSpec exists_user_for_email = new CommandSpec.Builder()
868 .dotParameter("email")
869 .build()
870 ;
871
872 @Command public void exists_user_for_email(IPrintWriter out,Interpreter interp)
873 throws ModelException.EmailFormat
874 {
875 String email = interp.getArgString("email");
876 User user = site.getUserFromEmail(email);
877 out.print( user != null );
878 }
879
880 public static final CommandSpec get_user_from_email = CommandSpec.DO()
881 .parameters("email")
882 .build()
883 ;
884
885 @Command public void get_user_from_email(IPrintWriter out,ScopedInterpreter<UserNamespace> interp)
886 throws ModelException.EmailFormat
887 {
888 String email = interp.getArgString("email");
889 User user = site.getUserFromEmail(email);
890 if( user==null ) {
891 out.print( (String)null );
892 return;
893 }
894 out.print( interp.getArg(new UserNamespace(user),"do") );
895 }
896
897 public static final CommandSpec has_authenticated_user_with_name = new CommandSpec.Builder()
898 .parameters("name")
899 .build()
900 ;
901
902 @Command public void has_authenticated_user_with_name(IPrintWriter out,Interpreter interp) {
903 String name = interp.getArgString("name");
904 out.print( site.getUserFromName(name) != null );
905 }
906
907 public static final CommandSpec get_authenticated_user_with_name = CommandSpec.DO()
908 .parameters("name")
909 .build()
910 ;
911
912 @Command public void get_authenticated_user_with_name(IPrintWriter out,ScopedInterpreter<UserNamespace> interp)
913 throws ModelException.EmailFormat
914 {
915 String name = interp.getArgString("name");
916 User user = site.getUserFromName(name);
917 out.print( interp.getArg(new UserNamespace(user),"do") );
918 }
919
920 public static final CommandSpec banned_users = CommandSpec.DO;
921
922 @Command public void banned_users(IPrintWriter out,ScopedInterpreter<UserNamespace.UserList> interp) {
923 List<User> banned = Permissions.getBannedUsers(site());
924 Object block = interp.getArg(new UserNamespace.UserList(banned),"do");
925 out.print(block);
926 }
927
928 @Command public void administrator_notice(IPrintWriter out,Interpreter interp) {
929 out.print( SystemProperties.get("administrator.notice") );
930 }
931
932 @Command public void administrator_notice_version(IPrintWriter out,Interpreter interp) {
933 String version = SystemProperties.get("administrator.notice.version");
934 out.print( version == null? "0" : version );
935 }
936
937
938 /*
939 public static final CommandSpec macro_text = new CommandSpec.Builder()
940 .parameters("macro")
941 .optionalParameters("namespace")
942 .build()
943 ;
944
945 @Command public void macro_text(IPrintWriter out,Interpreter interp) {
946 String macro = interp.getArgString("macro");
947 String namespace = interp.getArgString("namespace");
948 out.print( site.getTemplates().source().getMacro(macro,namespace) );
949 }
950 */
951
952
953 public static final CommandSpec log = new CommandSpec.Builder()
954 .dotParameter("text")
955 .outputtedParameters()
956 .build()
957 ;
958
959 @Command public void log(IPrintWriter out,Interpreter interp) {
960 interp.setEncoder(Encoder.TEXT);
961 String text = interp.getArgString("text");
962 NamlLogger.getLogger(site).log(text);
963 }
964
965 @Command public void get_log(IPrintWriter out,Interpreter interp) {
966 out.print( interp.encode( NamlLogger.getLogger(site).getLog() ) );
967 }
968
969 public static final CommandSpec clear_log = CommandSpec.NO_OUTPUT;
970
971 @Command public void clear_log(IPrintWriter out,Interpreter interp) {
972 NamlLogger.removeLogger(site);
973 }
974
975
976 @Command public void lucene_is_ready(IPrintWriter out,Interpreter interp) {
977 out.print( Lucene.isReady(site) );
978 }
979
980 @Command public void support_url(IPrintWriter out,Interpreter interp) {
981 out.print( Jtp.supportUrl() );
982 }
983
984 @Command public void dot_pack(IPrintWriter out,Interpreter interp) {
985 }
986
987
988
989
990
991 public static final CommandSpec call_later = new CommandSpec.Builder()
992 .dotParameter("param")
993 .optionalParameters("value")
994 .build()
995 ;
996
997 private Map<String,Set<String>> callLaterMap = new LinkedHashMap<String,Set<String>>();
998
999 @Command public void call_later(IPrintWriter out,Interpreter interp) {
1000 String param = interp.getArgString("param");
1001 Set<String> values = callLaterMap.get(param);
1002 if( values == null ) {
1003 values = new LinkedHashSet<String>();
1004 callLaterMap.put(param,values);
1005 }
1006 String value = interp.getArgString("value");
1007 if( value == null )
1008 value = "";
1009 values.add(value);
1010 }
1011
1012 private static final int JS_PATH_LIM = 1200;
1013
1014 @Command public void load_call_later_script(IPrintWriter out,Interpreter interp)
1015 throws IOException, ServletException
1016 {
1017 if( !callLaterMap.isEmpty() ) {
1018 String jsPath = "/template/NamlServlet.jtp?macro=js_page";
1019 StringBuilder path = new StringBuilder();
1020 path.append(jsPath);
1021 for (Map.Entry<String, Set<String>> entry : callLaterMap.entrySet()) {
1022 String param = entry.getKey();
1023 Set<String> values = entry.getValue();
1024 boolean isFirst = true;
1025 for (String value : values) {
1026 if (path.length() > JS_PATH_LIM) {
1027 loadScript(out,path);
1028 path.setLength(0);
1029 path.append(jsPath);
1030 isFirst = true;
1031 }
1032 if( isFirst ) {
1033 path.append('&').append(param).append('=');
1034 isFirst = false;
1035 } else {
1036 path.append('|');
1037 }
1038 path.append(HtmlUtils.urlEncode(HtmlUtils.urlEncode(value)));
1039 }
1040 }
1041 loadScript(out,path);
1042 }
1043 callLaterMap = null;
1044 }
1045
1046 private static void loadScript(IPrintWriter out,Object path) {
1047 out.print( "<script type='text/javascript'>\n" );
1048 out.print( "var scriptUrl = '" + path + "';\n" );
1049 out.print( "scriptUrl += '&_=' + Math.floor(Math.random()*9999);\n" );
1050 out.print( "$.getScript(scriptUrl, function() { Nabble.resizeFrames(); });\n" );
1051 out.print( "</script>\n" );
1052 }
1053
1054 public static final CommandSpec get_parameters_from_run_later = CommandSpec.DO()
1055 .parameters("name")
1056 .build()
1057 ;
1058
1059 @Command public void get_parameters_from_run_later(IPrintWriter out,ScopedInterpreter<RequestNamespace.ParameterValueList> interp) {
1060 String name = interp.getArgString("name");
1061 Set<String> values = callLaterMap.get(name);
1062 List<String> list = values == null ? Collections.<String>emptyList() : new ArrayList<String>(values);
1063 Object block = interp.getArg(new RequestNamespace.ParameterValueList(list),"do");
1064 out.print(block);
1065 }
1066
1067 // Tweaks & NAML code
1068
1069 public static final CommandSpec macro_source = new CommandSpec.Builder()
1070 .parameters("id")
1071 .optionalParameters("base", "breadcrumbs")
1072 .scopedParameters("do")
1073 .dotParameter("do")
1074 .build()
1075 ;
1076
1077 @Command public void macro_source(IPrintWriter out,ScopedInterpreter<MacroSourceNamespace> interp) {
1078 MacroSourceNamespace ns = new MacroSourceNamespace(site(),interp.getArgString("id"), interp.getArgString("base"), interp.getArgString("breadcrumbs"));
1079 out.print( interp.getArg( ns, "do" ) );
1080 }
1081
1082 public static final CommandSpec macro_editor = CommandSpec.DO()
1083 .optionalParameters("id", "base", "breadcrumbs")
1084 .build()
1085 ;
1086
1087 @Command public void macro_editor(IPrintWriter out,ScopedInterpreter<MacroEditorNamespace> interp) {
1088 MacroEditorNamespace ns = new MacroEditorNamespace(site(),interp.getArgString("id"),interp.getArgString("base"), interp.getArgString("breadcrumbs"));
1089 out.print( interp.getArg( ns, "do" ) );
1090 }
1091
1092 public static final CommandSpec macro_search = CommandSpec.DO()
1093 .parameters("query", "search_by")
1094 .build();
1095
1096 @Command public void macro_search(IPrintWriter out,ScopedInterpreter<MacroSourceNamespace.Commands> interp)
1097 throws IOException, ServletException, CompileException {
1098 String query = interp.getArgString("query");
1099 String searchBy = interp.getArgString("search_by");
1100 boolean byName = "name".equals(searchBy);
1101 Map<String,MacroSourceNamespace.CommandInfo> map = new TreeMap<String, MacroSourceNamespace.CommandInfo>();
1102 if (query != null) {
1103 query = query.toLowerCase();
1104 Pattern ptn = compileWildcardPattern(query);
1105 Program program = site().getProgram();
1106 List<Source> sources = program.getSources();
1107 for (Source s : sources) {
1108 for (Macro m : s.getMacros()) {
1109 if (byName) {
1110 boolean isOverridden = program.getMacroWhichOverrides(m) != null;
1111 if (isOverridden)
1112 continue;
1113 }
1114 boolean matches = byName? ptn.matcher(m.getName().toLowerCase()).matches() : ptn.matcher(m.element.toString().toLowerCase()).find();
1115 if (matches) {
1116 // Now we look for the first usage of this meaning
1117 MacroSourceNamespace.CommandInfo info = getCommandInfo(m);
1118 String key = m.getName() + '-' + MacroSourceNamespace.csv(m.getRequiredNamespaces());
1119 map.put(key, info);
1120 }
1121 }
1122 }
1123 }
1124 List<MacroSourceNamespace.CommandInfo> list = new ArrayList<MacroSourceNamespace.CommandInfo>(map.values());
1125 Object block = interp.getArg(new MacroSourceNamespace.Commands(list),"do");
1126 out.print(block);
1127 }
1128
1129 private MacroSourceNamespace.CommandInfo getCommandInfo(Macro m) {
1130 MacroSourceNamespace.CommandInfo info;
1131 Set<Usage> usages = site.getProgram().getUsages(m);
1132 if (usages == null || usages.size() == 0) {
1133 info = new MacroSourceNamespace.CommandInfo(m, null, null);
1134 } else {
1135 Usage u = usages.iterator().next();
1136 String usageBase = MacroSourceNamespace.asBaseParam(u.baseIds());
1137 String breadcrumbs = MacroSourceNamespace.asBreadcrumbsParam(u.macroPath());
1138 info = new MacroSourceNamespace.CommandInfo(m, usageBase, breadcrumbs);
1139 }
1140 return info;
1141 }
1142
1143 private static Pattern compileWildcardPattern(String query) {
1144 String[] a = query.split("\\*",-1);
1145 StringBuilder regex = new StringBuilder();
1146 boolean isFirst = true;
1147 for( String s : a ) {
1148 if( isFirst )
1149 isFirst = false;
1150 else
1151 regex.append( ".*" );
1152 if( s.length() > 0 )
1153 regex.append( Pattern.quote(s) );
1154 }
1155 return Pattern.compile(regex.toString());
1156 }
1157
1158 @Command public void has_custom_macros(IPrintWriter out,Interpreter interp)
1159 throws CompileException
1160 {
1161 out.print(ModuleManager.getCustomMacros(site.getProgram()).size() > 0);
1162 }
1163
1164 public static final CommandSpec custom_macros = CommandSpec.DO;
1165
1166 @Command public void custom_macros(IPrintWriter out,ScopedInterpreter<MacroSourceNamespace.Commands> interp)
1167 throws IOException, ServletException, CompileException
1168 {
1169 Collection<Macro> macros = ModuleManager.getCustomMacros(site.getProgram());
1170 printMacros(macros, out, interp);
1171 }
1172
1173 private void printMacros(Collection<Macro> macros, IPrintWriter out, ScopedInterpreter<MacroSourceNamespace.Commands> interp) {
1174 List<MacroSourceNamespace.CommandInfo> list = new ArrayList<MacroSourceNamespace.CommandInfo>();
1175 Set<String> names = new HashSet<String>();
1176 for (Macro m : macros) {
1177 String key = m.getName() + '-' + MacroSourceNamespace.csv(m.getRequiredNamespaces());
1178 if (names.contains(key))
1179 continue;
1180 names.add(key);
1181 MacroSourceNamespace.CommandInfo info = getCommandInfo(m);
1182 list.add(info);
1183 }
1184 Collections.sort(list, MacroSourceNamespace.CommandInfo.MACRO_NAME_COMPARATOR);
1185 Object block = interp.getArg(new MacroSourceNamespace.Commands(list),"do");
1186 out.print(block);
1187 }
1188
1189 @Command public void has_configuration_macros(IPrintWriter out,Interpreter interp)
1190 throws CompileException
1191 {
1192 out.print(ModuleManager.getConfigurationMacros(site.getProgram()).size() > 0);
1193 }
1194
1195 public static final CommandSpec configuration_macros = CommandSpec.DO;
1196
1197 @Command public void configuration_macros(IPrintWriter out,ScopedInterpreter<MacroSourceNamespace.Commands> interp)
1198 throws IOException, ServletException, CompileException
1199 {
1200 Collection<Macro> macros = ModuleManager.getConfigurationMacros(site.getProgram());
1201 printMacros(macros, out, interp);
1202 }
1203
1204 @Command public void has_tweak_exception(IPrintWriter out,Interpreter interp)
1205 throws CompileException
1206 {
1207 out.print(site.getTweakException() != null);
1208 }
1209
1210 @Command public void tweak_exception_message(IPrintWriter out,Interpreter interp)
1211 throws CompileException
1212 {
1213 Exception e = site.getTweakException();
1214 out.print(e == null? null : e.getMessage());
1215 }
1216
1217 public static final CommandSpec advanced_editor_path = new CommandSpec.Builder()
1218 .parameters("prev_url")
1219 .build();
1220
1221 @Command public void advanced_editor_path(IPrintWriter out,Interpreter interp) {
1222 String prev = interp.getArgString("prev_url");
1223 out.print("/template/NamlEditor.jtp?prev=" + HtmlUtils.urlEncode(prev));
1224 }
1225
1226 static boolean isCompiledAll(Program program) {
1227 Meaning meaning = program.getMeaning(COMPILED_ALL_CHECK_ID);
1228 return meaning != null && program.isCompiled(meaning);
1229 }
1230
1231 private static final String COMPILED_ALL_CHECK_ID = "compiled_all_check!nabble:compile_all.naml";
1232
1233 @Command public void is_compiled_all(IPrintWriter out, Interpreter interp) {
1234 Program program = interp.template().program();
1235 out.print(isCompiledAll(program));
1236 }
1237
1238 @Command public void run_compile_all(IPrintWriter out,Interpreter interp) throws CompileException {
1239 CompileTest.compileAll(site.getProgram());
1240 }
1241
1242 public static final CommandSpec naml_configuration = CommandSpec.DO;
1243
1244 @Command public void naml_configuration(IPrintWriter out,ScopedInterpreter<NamlConfigurationNamespace> interp)
1245 throws IOException, ServletException, CompileException
1246 {
1247 out.print(interp.getArg(new NamlConfigurationNamespace(),"do"));
1248 }
1249
1250 @Command public void js_basic_nabble_functions(IPrintWriter out,Interpreter interp)
1251 throws CompileException
1252 {
1253 StringWriter sw = new StringWriter();
1254 PrintWriter jsOut = new PrintWriter(sw);
1255 Javascript.basicNabbleFunctions(jsOut);
1256 jsOut.close();
1257 out.print(sw.toString());
1258 }
1259
1260 public static final CommandSpec NAME = new CommandSpec.Builder()
1261 .dotParameter("name")
1262 .build()
1263 ;
1264
1265 public static final CommandSpec has_site_property = NAME;
1266
1267 @Command public void has_site_property(IPrintWriter out,Interpreter interp) {
1268 String name = interp.getArgString("name");
1269 out.print(site.getProperty(name) != null);
1270 }
1271
1272 public static final CommandSpec get_site_property = NAME;
1273
1274 @Command public void get_site_property(IPrintWriter out,Interpreter interp) {
1275 String name = interp.getArgString("name");
1276 out.print(site.getProperty(name));
1277 }
1278
1279 public static final CommandSpec delete_site_property = CommandSpec.NO_OUTPUT()
1280 .parameters("name")
1281 .build()
1282 ;
1283
1284 @Command public void delete_site_property(IPrintWriter out,Interpreter interp) {
1285 String name = interp.getArgString("name");
1286 site.setProperty(name, null);
1287 site.update();
1288 }
1289
1290 public static final CommandSpec set_site_property = CommandSpec.NO_OUTPUT()
1291 .parameters("name", "value")
1292 .build()
1293 ;
1294
1295 @Command public void set_site_property(IPrintWriter out,Interpreter interp) {
1296 String name = interp.getArgString("name");
1297 String value = interp.getArgString("value");
1298 site.setProperty(name, value);
1299 site.update();
1300 }
1301
1302
1303 public static final CommandSpec to_html_list = CommandSpec.DO()
1304 .parameters("text")
1305 .build()
1306 ;
1307
1308 @Command public void to_html_list(IPrintWriter out,ScopedInterpreter<HtmlListNamespace> interp) {
1309 String text = interp.getArgString("text");
1310 HtmlListNamespace html = new HtmlListNamespace(new Html(text), null, Message.Format.HTML);
1311 interp.getArgString(html,"do"); // processing, no output
1312 out.print(html);
1313 }
1314
1315
1316 @Command public void is_embarrassing(IPrintWriter out,Interpreter interp) {
1317 out.print(site.isEmbarrassing());
1318 }
1319
1320 public static final Set<Long> sitesRunningBackup = Collections.synchronizedSet(new HashSet<Long>());
1321
1322 @Command public void is_running_backup(IPrintWriter out,Interpreter interp) {
1323 out.print(sitesRunningBackup.contains(site.getId()));
1324 }
1325
1326 public static final CommandSpec make_backup = CommandSpec.NO_OUTPUT()
1327 .parameters("email")
1328 .build()
1329 ;
1330
1331 @Command public void make_backup(IPrintWriter out,Interpreter interp) {
1332 synchronized (sitesRunningBackup) {
1333 if (sitesRunningBackup.contains(site.getId()))
1334 return;
1335 sitesRunningBackup.add(site.getId());
1336 final String email = interp.getArgString("email");
1337 Executors.executeSometime(new Runnable(){
1338 public void run() {
1339 File file = site.backup();
1340 Template template = site.getTemplate( "backup email",
1341 BasicNamespace.class, NabbleNamespace.class
1342 );
1343 Map<String,Object> params = new HashMap<String,Object>();
1344 params.put("email", email);
1345 params.put("file", file.getName());
1346 template.run( TemplatePrintWriter.NULL, params,
1347 new BasicNamespace(template),
1348 new NabbleNamespace(site)
1349 );
1350 sitesRunningBackup.remove(site.getId());
1351 }
1352 });
1353 }
1354 }
1355
1356 @Command public void server_url(IPrintWriter out,Interpreter interp) {
1357 out.print( interp.encode( Jtp.defaultContextUrl() ) );
1358 }
1359
1360 @Command public void javascript_version(IPrintWriter out,Interpreter interp) {
1361 out.print(Shared.javascriptVersion);
1362 }
1363
1364 @Command public void css_version(IPrintWriter out,Interpreter interp) {
1365 out.print(Shared.cssVersion);
1366 }
1367
1368 }