Anyone knows how to define an interface in Jpad? Code like this will result in an "interface not allowed here" error.
interface Try{
boolean validate(String s);
}
class ValidateString implements Try{
boolean validate(String s) {return true; }
}
ValidateString val = new ValidateString();
Dump(val.validate("hi"));
JPad automatically wraps your code in a RunnContainer class as well as any 'loose' code in a static main method if you don't specify one. So the code provided was trying to stick a Class and Interface into the main method. Specifying the main resolves the issue. After running a jpad script you can view the "File" tab to show the results of how JPad wrapped it.
public static void main(String args[]) {
ValidateString val = new ValidateString();
Dump(val.validate("hi"));
}
public static class ValidateString implements Try{
public boolean validate(String s) {return true; }
}
interface Try{
boolean validate(String s);
}
Related
I've found several examples on how to pipe and redirect messages from System.out and System.err.
Having decided to develop an application using the JavaFX Webview and Dukescript, I've found useful having one place where to display all messages, i.e. the Firebug Lite console.
See below.
PS This is the exact opposite as this
First define an abstract class
public abstract class FirebugConsole extends OutputStream {
abstract void log( String msg );
StringBuilder sb = new StringBuilder();
#Override
public void write(int i) {
sb.append((char)i);
}
#Override
public void flush() {
if( sb.length() >0 && !sb.toString().equals("\r\n"))
log(sb.toString());
sb = new StringBuilder();
}
}
Then extend it with methods that implement native calls into JavaScript. Here's for example how to write log messages
public class FirebugConsoleInfo extends FirebugConsole{
#net.java.html.js.JavaScriptBody(args = { "msg" }, body = ""
+ "Firebug.Console.log(msg);")
public native void log( String msg );
}
Finally, pipe System.out and System.err to those objects
public static void onPageLoad() throws Exception {
...
System.setOut(new PrintStream(new FirebugConsoleInfo(), true));
System.setErr(new PrintStream(new FirebugConsoleError(), true));
...
}
Note: for some reasons the usual console.log() doesn't work for me, I know Firebug doesn't bind a console if a console object is already present, so I suspect the WebFX webview must itself pipe console.log messages to System.out in the first place.
Update
The solution above doesn't work when the messages are generated by a thread other than the browser's. Here's an updated solution based on BrwsrCtx.execute()
public abstract static class FirebugConsole extends OutputStream {
protected final BrwsrCtx ctx;
public FirebugConsole( BrwsrCtx ctx ){
this.ctx = ctx;
}
abstract void logNative( String msg );
void log(String msg) {
ctx.execute(new Runnable(){
#Override
public void run() {
logNative(msg);
}
});
}
StringBuilder sb = new StringBuilder();
#Override
public void write(int i) {
sb.append((char)i);
}
#Override
public void flush() {
if( sb.length() >0 && !sb.toString().equals("\r\n"))
log(sb.toString());
sb = new StringBuilder();
}
}
public static class FirebugConsoleInfo extends FirebugConsole{
public FirebugConsoleInfo(BrwsrCtx ctx) {
super(ctx);
}
#net.java.html.js.JavaScriptBody(args = { "msg" }, body = ""
+ "Firebug.Console.log(msg);")
public native void logNative( String msg );
}
public static class FirebugConsoleError extends FirebugConsole{
public FirebugConsoleError(BrwsrCtx ctx) {
super(ctx);
}
#net.java.html.js.JavaScriptBody(args = { "msg" }, body = ""
+ "Firebug.Console.error(msg);")
public native void logNative( String msg );
}
}
and
public static void onPageLoad() throws Exception {
BrwsrCtx ctx = BrwsrCtx.findDefault(GoGPS_Fx.class);
System.setOut(new PrintStream(new FirebugConsoleInfo(ctx), true));
System.setErr(new PrintStream(new FirebugConsoleError(ctx), true));
}
Note: it's quite slow for large logs, there might be faster alternatives (StringWriter is one). But I suspect the bottleneck is the passing of messages back and forth from Java to JavaScript.
I was using org.apache.commons.collections.CollectionUtils and for this version using find method was like this:
BeanPropertyValueEqualsPredicate objIdEqualsPredicate = new BeanPropertyValueEqualsPredicate("objId", objId);
myObj = (MyClass) CollectionUtils.find(myObjSet, objIdEqualsPredicate);
But with org.apache.commons.collections4.CollectionUtils, I don't know how to make it work.
Here what I do now but if there is a clear way of it, I will be glad to learn:
Predicate<MyClass> objIdEqualsPredicate = new Predicate<MyClass>() {
#Override
public boolean evaluate(MyClass obj) {
return obj.getObjId().equals(objId);
}
};
myObj = CollectionUtils.find(myObjSet, objIdEqualsPredicate);
Is there a way to filter some objects according to the their fields' values. If possible I don't want to use anonymous class for this.
Thanks.
As the common-beanutils still have commons-collections as dependency, you must implement the Predicate interface.
For example you can take the source code of BeanPropertyValueEqualsPredicate and refactor it, so your version implements the org.apache.commons.collections4.Predicate interface.
Or you write your own version. I would prefer not to use anonymous inner classes, because of the possibility to write unit tests for the predicate and reuse it.
Quick Example (not nullsafe,..)
#Test
public class CollectionsTest {
#Test
void test() {
Collection<Bean> col = new ArrayList<>();
col.add(new Bean("Foo"));
col.add(new Bean("Bar"));
Predicate<Bean> p = new FooPredicate("Bar");
Bean find = CollectionUtils.find(col, p);
Assert.assertNotNull(find);
Assert.assertEquals(find.getFoo(), "Bar");
}
private static final class FooPredicate implements Predicate<CollectionsTest.Bean> {
private String fieldValue;
public FooPredicate(final String fieldValue) {
super();
this.fieldValue = fieldValue;
}
#Override
public boolean evaluate(final Bean object) {
// return true for a match - false otherwise
return object.getFoo().equals(fieldValue);
}
}
public static class Bean {
private final String foo;
Bean(final String foo) {
super();
this.foo = foo;
}
public String getFoo() {
return foo;
}
}
}
I'm using Reflection to work out my project classes with the Generics from a third party, however, I keep getting the error "Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true." when I try to Invoke an static method from an static generic class which contains generics invocation.
Third Party code looks like this
public interface INestedGeneric<TResult>
{
INestedGeneric<TResult> DoSomethingElse();
}
public static class GenericClass<TResult> where TResult : new()
{
public static INestedGeneric<TResult> DoSomething()
{ return new NestedClass<TResult>(); }
}
public class NestedClass<TResult> : INestedGeneric<TResult>
{
public INestedGeneric<TResult> DoSomethingElse()
{ return new NestedClass<TResult>(); }
}
My code looks like:
public class Someone
{
private int _integerProperty;
private string _stringProperty;
public int IntegerProperty
{
get { return _integerProperty; }
set { _integerProperty = value; }
}
public string StringProperty
{
get { return _stringProperty; }
set { _stringProperty = value; }
}
}
static void Main(string[] args)
{
Type classType = typeof(Someone);
Type theclass = typeof(GenericClass<>); theclass.MakeGenericType(classType);
Type theinterface = typeof(INestedGeneric<>); theinterface.MakeGenericType(classType);
MethodInfo dosomething = theclass.GetMethod("DoSomething", BindingFlags.Public | BindingFlags.Static);
dosomething.Invoke(null, null);
dosomething = null;
}
Any idea how to invoke the method strictly in this scenario? I have read and try the help from other posts, but didn't work.
Thank you so much...
I already figure it out. The solution was to use the type provided by the MakeGenericType method.
Like this:
...
Type theclass = typeof(GenericClass<>).MakeGenericType(classType);
Type theinterface = typeof(INestedGeneric<>).MakeGenericType(classType);
MethodInfo dosomething = theclass.GetMethod("DoSomething", BindingFlags.Public | BindingFlags.Static);
dosomething.Invoke(null, null);
...
I would like to write something like :
#Autowired
private SpringTemplateEngine engine;
....
// Thymeleaf Context
WebContext thymeleafContext = new WebContext(request, response, request.getServletContext(), locale);
// cached html of a thymeleaf template file
String cachedHtml=....
// process the cached html
String html=engine.process(cachedHtml, thymeleafContext);
By default, the [process] method can't do that. I can understand from the docs that I need a special Template Resolver :
In order to execute templates, the process(String, IContext) method will be used:
final String result = templateEngine.process("mytemplate", ctx);
The "mytemplate" String argument is the template name, and it will relate to the physical/logical location of the template itself in a way configured at the template resolver/s.
Does anyone know how to solve my problem ?
The goal is to cache the Thymeleaf templates (files) in strings and then process theses strings rather than the files.
The solution we ended up using consisted of a new IResourceResolver with a custom Context rather than a custom TemplateResolver. We chose this because we still wanted to use classpath scanning in most cases, but occasionally had dynamic content.
The following shows how we did it:
public class StringAndClassLoaderResourceResolver implements IResourceResolver {
public StringAndClassLoaderResourceResolver() {
super();
}
public String getName() {
return getClass().getName().toUpperCase();
}
public InputStream getResourceAsStream(final TemplateProcessingParameters params, final String resourceName) {
Validate.notNull(resourceName, "Resource name cannot be null");
if( StringContext.class.isAssignableFrom( params.getContext().getClass() ) ){
String content = ((StringContext)params.getContext()).getContent();
return IOUtils.toInputStream(content);
}
return ClassLoaderUtils.getClassLoader(ClassLoaderResourceResolver.class).getResourceAsStream(resourceName);
}
public static class StringContext extends Context{
private final String content;
public StringContext(String content) {
this.content = content;
}
public StringContext(String content, Locale locale) {
super(locale);
this.content = content;
}
public StringContext(String content, Locale locale, Map<String, ?> variables) {
super(locale, variables);
this.content = content;
}
public String getContent() {
return content;
}
}
Test Case
public class StringAndClassLoaderResourceResolverTest {
private static SpringTemplateEngine templateEngine;
#BeforeClass
public static void setup(){
TemplateResolver resolver = new TemplateResolver();
resolver.setResourceResolver(new StringAndClassLoaderResourceResolver());
resolver.setPrefix("mail/"); // src/test/resources/mail
resolver.setSuffix(".html");
resolver.setTemplateMode("LEGACYHTML5");
resolver.setCharacterEncoding(CharEncoding.UTF_8);
resolver.setOrder(1);
templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(resolver);
}
#Test
public void testStringResolution() {
String expected = "<div>dave</div>";
String input = "<div th:text=\"${userName}\">Some Username Here!</div>";
IContext context = new StringAndClassLoaderResourceResolver.StringContext(input);
context.getVariables().put("userName", "dave");
String actual = templateEngine.process("redundant", context);
assertEquals(expected, actual);
}
#Test
public void testClasspathResolution(){
IContext context = new Context();
context.getVariables().put("message", "Hello Thymeleaf!");
String actual = templateEngine.process("dummy", context);
String expected = "<h1>Hello Thymeleaf!</h1>";
assertEquals(expected, actual);
}
}
Dummy template file at src/main/resources/mail/dummy.html
<h1 th:text="${message}">A message will go here!</h1>
Note: We used Apache CommonsIO's IOUtils for converting the String to an InputStream
You can implement your own TemplateResolver and IResourceResolver to work with String.
for simple unit tests:
static class TestResourceResolver implements IResourceResolver {
public String content = "";
#Override
public String getName() {
return "TestTemplateResolver";
}
#Override
public InputStream getResourceAsStream(TemplateProcessingParameters templateProcessingParameters,
String resourceName) {
return new ByteArrayInputStream(content.getBytes());
}
}
or just use org.thymeleaf.templateresolver.StringTemplateResolver in Thymeleaf 3
Yep StringTemplateResolver is the way to go.
public class ReportTemplateEngine {
private static TemplateEngine instance;
private ReportTemplateEngine() {}
public static TemplateEngine getInstance() {
if(instance == null){
synchronized (ReportTemplateEngine.class) {
if(instance == null) {
instance = new TemplateEngine();
StringTemplateResolver templateResolver = new StringTemplateResolver();
templateResolver.setTemplateMode(TemplateMode.HTML);
instance.setTemplateResolver(templateResolver);
}
}
}
return instance;
}
}
Currently we have a very strange issue on our production server. For a specific param in query string, we get the data for query string in other request. I'm trying to figure out if this behavior can be caused, by the way I use ConcurrentDictionary in IHttpHandler:
Below is pseudo code example:
public class MyHandler : IHttpHandler
{
private static ConcurrentDictionary<string, DataObject> _dataCache = new ConcurrentDictionary<string, DataObject>();
public virtual bool IsReusable
{
get { return true; }
}
public virtual void ProcessRequest(HttpContext context)
{
Func<DataObject> getDataMethod = () =>
{
return DataFactory.GetData(context.Request.QueryString["dataid"].ToLower());
}
string cacheKey = HttpUtility.UrlDecode(context.Request.QueryString["dataid"].ToLower());
DataObject infoItem = _dataCache .GetOrAdd(cacheKey, (key) => { return getDataMethod(); })
//Other processing code
}
}
So it happens that for "dataid=1" i get the data for "dataid=2"...
When getDataMethod is executed, can I be sure that it will access the relevant context?