calling a java method in velocity template - templates

I have a class CurrencyUtil in which I have written a method convertCurrency(String symbol, long value) I want to call this method from velocity template. I am putting object of this class map.put("formatter", currencyUtil); and in template I am using the tag as $formatter.convertCurrency($currency, $total) but when the template is rendered it is not printing the result.
here my question is that, should the parameter names in the java method and in template be same? or is there any other problem?

Parameter names in java method and template can be different. You may try to locate your problem using the following example.
Example.java
package com.example.currency;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.Template;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import java.io.*;
public class Example
{
public Example(String templateFile)
{
try
{
Velocity.init("velocity.properties");
VelocityContext context = new VelocityContext();
CurrencyUtil cu = new CurrencyUtil();
cu.setCurrencyRate("EUR", 1.25);
context.put("formatter", cu);
Template template = null;
try
{
template = Velocity.getTemplate(templateFile);
}
catch( ResourceNotFoundException rnfe )
{
System.out.println("Example : error : cannot find template " + templateFile );
}
catch( ParseErrorException pee )
{
System.out.println("Example : Syntax error in template " + templateFile + ":" + pee );
}
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(System.out));
if ( template != null)
template.merge(context, writer);
writer.flush();
writer.close();
}
catch( Exception e )
{
System.out.println(e);
}
}
public static void main(String[] args)
{
Example t = new Example("example.vm");
}
}
CurrencyUtil.java
package com.example.currency;
import java.util.Map;
import java.util.HashMap;
public class CurrencyUtil {
private static Map<String, Double> rates = new HashMap<String, Double>();
public double getCurrencyRate(String symbol){
return rates.get(symbol);
}
public void setCurrencyRate(String symbol, double currencyRate){
rates.put(symbol, currencyRate);
}
public double convertCurrency(String symbol, long value){
return value * getCurrencyRate(symbol);
}
}
example.vm
#set( $total = 10000000000)
#set( $currency = "EUR")
$formatter.convertCurrency($currency, $total)

Velocity receives all parameters as Strings. In your function you receive a String and apply a cast.

Related

Adding a custom type to a RedBlackTree

I want to keep an ordered set of records and the standard provides me with RedBlackTree. The record is of type Tuple!(string, uint). Here's what it looks like:
import std.json : parseJSON;
uint[string] wordTable;
import std.datetime.stopwatch : StopWatch, AutoStart;
auto sw = StopWatch(AutoStart.yes);
const auto j = parseJSON(get(link));
const long downloadTime = sw.peek.total!"msecs";
import std.typecons : Tuple, tuple;
import std.container.rbtree : RedBlackTree;
import std.functional : binaryFun;
RedBlackTree!(Tuple!(string, uint), binaryFun!("a[1] > b[1]")) records;
foreach (node; j["posts"].array()) {
import std.stdio : writeln;
import std.utf : decode;
if ("com" in node) {
import std.algorithm : splitter;
foreach (word; getStr(node["com"].str()).splitter(' ')) {
import std.string : strip;
if (word.strip().length > 0)
wordTable.require(word, 0)++;
records ~= (tuple(word, wordTable[word])); // error
}
}
}
Now primarily I had used insert() method to add a record to the records but it causes segfault in runtime. So I decided to use ~= in hopes for better error messages. And here's what the compiler says:
Error: cannot append type Tuple!(string, uint) to type std.container.rbtree.RedBlackTree!(Tuple!(string, uint), binaryFun, false)
According to https://dlang.org/phobos/std_container_rbtree.html#.RedBlackTree I have to provide a type such that calling less(a, b) on it returns a boolean. So I went ahead and created a type for it:
struct Record {
string key;
uint value;
int opCmp(ref const Record other) const {
return value - other.value;
}
}
// bool less(Record a, Record b) {
// return a < b;
// }
void main(string[] args) {
import std.stdio : writeln, writefln;
if (args.length < 3) {
writeln("Must have 2 arguments " ~ "first argument is the link, "
~ "the second one is for minimum repeatation threshold. Exiting.");
import core.stdc.stdlib : exit;
exit(-1);
}
const auto link = parseLink(args[1]);
const auto threshold = atoui(args[2]);
import std.json : parseJSON;
uint[string] wordTable;
import std.datetime.stopwatch : StopWatch, AutoStart;
auto sw = StopWatch(AutoStart.yes);
const auto j = parseJSON(get(link));
const long downloadTime = sw.peek.total!"msecs";
import std.container.rbtree : RedBlackTree;
import std.functional : binaryFun;
RedBlackTree!Record records;
foreach (node; j["posts"].array()) {
import std.utf : decode;
if ("com" in node) {
import std.algorithm : splitter;
foreach (word; getStr(node["com"].str()).splitter(' ')) {
import std.string : strip;
if (word.strip().length > 0)
wordTable.require(word, 0)++;
records ~= (Record(word, wordTable[word]));
}
}
}
This time the compiler complains:
Error: cannot append type Record to type std.container.rbtree.RedBlackTree!(Record, "a < b", false)
So the gist of the question is, if I have an RedBlackTree with a custom binaryFun, how can I add an instance of a tuple or a custom type to it?

Unloading Java classes using CustomClassLoader

I have been through many posts and questions but none of them had a absolute Java program to implement this.
Requirement : For some reasons my application loads the Common-codec 1.3.jar,
and later on ,within same jvm the process needs to use Common-code 1.10.jar which is of different version.
But since the previous classes are loaded and they have same package name ,reloading them with a Java program is not replacing the existing classes.
Here is the code (sample) i used to reload(replace) the existing keys,but found no luck as expected. Please let me know hoe this could be done by a Java example.
String pathToJar=/root/Desktop/commons-codec-1.10.jar";
JarFile jarFile = null;
try {
jarFile = new JarFile(pathToJar);
} catch (IOException e) {
e.printStackTrace();
}
Enumeration<JarEntry> e = jarFile.entries();
URL[] urls = new URL[0];
try {
urls = new URL[]{ new URL("jar:file:" + pathToJar+"!/") };
} catch (MalformedURLException e1) {
e1.printStackTrace();
}
URLClassLoader cl = URLClassLoader.newInstance(urls);
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
if(je.isDirectory() || !je.getName().endsWith(".class")){
continue;
}
// -6 because of .class
String className = je.getName().substring(0,je.getName().length()-6);
className = className.replace(File.separatorChar, '.');
String check="org.apache.commons.codec.binary.Base32";
try {
Class c = cl.loadClass(className); // Excepting it to replace old files,but thats not happening
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
I was advised to write Custom class loader and unloading is possible via it.
Could some show some relevant code or process of doing it.
Class "unloading" may only occur when both the Class and the ClassLoader that defined it are eligible for garbage collection. Furthermore, any given loader can only define a class of a specific name once. Therefore (save for exotic workarounds such as instrumentation or JDK implementation internals), there is no such thing as a "reloading-capable class loader" -- at least not in the true sense of the term; in order to obtain n distinct "versions" of a class, C, defineClass(C) must be invoked on n distinct ClassLoader objects.
Let's examine the following trivial use case: We have an app.jar, (unsurprisingly) containing a class declaring a main method; and two copies of a lib.jar, each having a single class, LibApiImpl, encapsulating a single method that just prints a version-dependent string to stdout. Our goal is to merely reference two copies of the "library" class from our main and see two different strings being output. The remainder of this post demonstrates just two of all the possible approaches to satisfy this requirement.
Approach #1 - Manually instantiating ClassLoaders
The straightforward solution is to simply create a new URLClassLoader every time a different LibApiImpl needs to be loaded. No custom class loader implementation is required, and the default parent-first delegation model serves both the application and the library well. A couple of things to note:
The library JARs must not sit on the classpath, in order to not be discoverable by the default application class loader. Otherwise the application class loader will "favor" one over the other, and, due to the default delegation model, standard URLClassLoader children of the application loader will not be able to override their parent's opinion on the matter.
To access the library class, the 3-argument Class::forName must be employed, specifying the manually-instantiated class loader. The single-arg version will delegate to the application class loader, which (as per the former point) is of course unaware of the existence of the corresponding .class file.
If the reflectively-obtained class is to be cast to an interface, as will be the case herein, the interface must, as opposed to the implementation, reside on the classpath.
Demo code
package com.example.app;
import java.net.URL;
import java.net.URLClassLoader;
import com.example.lib.api.LibApi;
public class App {
public static void main(String... args) throws Exception {
try (URLClassLoader loader = new URLClassLoader(new URL[] { new URL("file:/path/to/lib1.jar") })) {
((LibApi) Class.forName("com.example.lib.impl.LibApiImpl", true, loader).newInstance()).printVersionInfo();
}
try (URLClassLoader loader = new URLClassLoader(new URL[] { new URL("file:/path/to/lib2.jar") })) {
((LibApi) Class.forName("com.example.lib.impl.LibApiImpl", true, loader).newInstance()).printVersionInfo();
}
}
}
package com.example.lib.api;
public interface LibApi {
void printVersionInfo();
}
package com.example.lib.impl;
import com.example.lib.api.LibApi;
public class LibApiImpl implements LibApi {
#Override
public void printVersionInfo() {
System.out.println("\n** lib " + getClass() + " / loaded by " + getClass().getClassLoader() + " **\n");
}
}
Packaging
Correct the paths in com.example.app.App; then produce the following 4 JARs:
An app.jar containing the com.example.app package.
A lib-api.jar containing the com.example.lib.api package.
Two "versions" (just export twice), lib1.jar and lib2.jar, each containing the com.example.lib.impl package.
Testing
Run as follows:
java -cp '/path/to/app.jar:/path/to/lib-api.jar' com.example.app.App
Sample output:
** lib class com.example.lib.impl.LibApiImpl / loaded by java.net.URLClassLoader#55f96302 **
** lib class com.example.lib.impl.LibApiImpl / loaded by java.net.URLClassLoader#135fbaa4 **
Approach #2 - Creating a "Master-Slave" loader
Sometimes the "parent-first" model is insufficient. As a contrived example, suppose that we wanted to obtain the "copy" of LibApiImpl that was last loaded by some child of the application class loader, without having to care about which child it actually was that defined the copy. In other words, we want the call Class.forName("com.example.lib.impl.LibApiImpl") to return the "most fresh" LibApiImpl version. But, unless we override the application class loader, or, more generally, the class loader of the App class, with a custom implementation, that call will always fail, because, under the default delegation model, delegation flows unidirectionally from lower-level loaders to their ancestors and not vice versa.
The application class loader implementation, given below, behaves as follows (refer to the Javadoc overview of the Loaders class for a concrete explanation): There is a "master" loader, serving as the application class loader, that may have a child, referred to as its "slave". The master is responsible for loading non-reloadable application classes from the classpath (app.jar and lib-api.jar, in this case), while the slave gets to load reloadable, non-classpath-residing ones (lib1.jar and lib2.jar). The communication between the two is bidirectional, and the loader that will ultimately define any given class, "fixed" or "reloadable", is always respectively the master and the slave, regardless the "initiating" loader, i.e., the loader on which the application called loadClass, or passed to Class::forName. Of course this is nothing but a toy implementation meant to (hopefully) illustrate how a different delegation scheme might look like, and is probably flawed in ways I have not even begun to imagine. A real-world implementation would, e.g., have to provide proper concurrency; provide compliant implementations of getResource et al.; address concerns of code accessibility, verification, and possibly code base privilege assignment; and allow extensibility by, and configuration of, multiple slaves, or even attachment of other children, potentially of arbitrary implementation, to the master, while preserving well-defined delegation semantics. The point of course being that it is generally too much effort to write a proper implementation, when there is OSGi and the like doing just that (among many others).
Demo code
package com.example.app;
import java.net.URL;
import com.example.app.Loaders.MasterLoader;
import com.example.lib.api.LibApi;
public class App2 {
public static void main(String... args) throws Exception {
MasterLoader loader = (MasterLoader) ClassLoader.getSystemClassLoader();
loader.setDebug(true);
loader.refresh(new URL[] { new URL("file:/path/to/lib1.jar") });
newLibApi().printVersionInfo();
loader.refresh(new URL[] { new URL("file:/path/to/lib2.jar") });
newLibApi().printVersionInfo();
}
static LibApi newLibApi() throws Exception {
return (LibApi) Class.forName("com.example.lib.impl.LibApiImpl").newInstance();
}
}
package com.example.app;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
/**
* Contains a "Master (parent)/Slave (child)" <code>ClassLoader</code> "duo".<br/>
* <br/>
* The class loading "protocol" adhered by the respective {#code loadClass(String, boolean)}
* implementations of the two is as follows:
* <ol>
* <li>If the name argument matches the name of the loader's class itself, return that class.
* Otherwise proceed.</li>
* <li>If a call to {#code findLoadedClass(name)} yields a non-null class, return that class.
* Otherwise proceed.</li>
* <li>Let <em>C</em> be either this loader's parent, if this is a "slave", or its child, if this is
* a "master". If <em>C</em> is non-null, have it execute steps (1), (2) itself. If a class gets
* produced, return that class. Otherwise (i.e., if there either is no result, or <em>C</em> is
* null) proceed.</li>
* <li>If the name argument refers to a potential bootstrap classpath class name, call
* {#code loadClass(name)} on the default system classloader (the "master's" parent). If the call
* succeeds, return that class. Otherwise proceed.</li>
* <li>If the name argument refers to a .class file under this loader's search path, read it, define
* and link a new class off of its contents, and return that "freshly-fefined" class. Otherwise
* proceed.</li>
* <li>Once again, let <em>C</em> be the loader specified in step (3). If non-null, have it execute
* step (5) on itself. If a class gets produced, return that class. Otherwise fail.</li>
* </ol>
*/
public class Loaders {
private static class SlaveLoader extends URLClassLoader {
static final Pattern BOOT_CLASS_PATH_RES_NAMES = Pattern.compile("((com\\.)?sun|java(x)?)\\..*");
static final URL[] EMPTY_SEARCH_PATH = new URL[0];
static final URL[] createSearchPath(String pathNames) {
if (pathNames != null) {
List<URL> searchPath = new ArrayList<>();
for (String pathName : pathNames.split(File.pathSeparator)) {
try {
searchPath.add(Paths.get(pathName).toUri().toURL());
}
catch (MalformedURLException e) {
e.printStackTrace();
}
}
return searchPath.toArray(new URL[0]);
}
return EMPTY_SEARCH_PATH;
}
static final byte[] readClassData(URL classResource) throws IOException {
try (InputStream in = classResource.openStream(); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
while (in.available() > 0) {
out.write(in.read());
}
return out.toByteArray();
}
}
final String loadClassOutcomeMsgFmt = "loadClass return '{'\n\tloader = {0}\n\ttarget = {1}\n\tresult : {2}\n'}'";
volatile boolean debug;
SlaveLoader(URL[] searchPath, ClassLoader parent) {
super(searchPath, parent);
}
#Override
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
validateName(name);
Class<?> ret = loadFromCache(name);
if (ret != null) {
return ret;
}
MasterLoader parent = (MasterLoader) getParent();
if ((ret = parent.loadFromCache(name)) != null) {
log(loadClassOutcomeMsgFmt, this, name, "3 - early return - pre-loaded/cached - via " + parent);
return ret;
}
if ((ret = loadFromBootClasspath(name)) != null) {
return ret;
}
if ((ret = loadFromSearchPath(name, resolve)) != null) {
return ret;
}
if ((ret = parent.loadFromSearchPath(name, resolve)) != null) {
log(loadClassOutcomeMsgFmt, this, name,
"6 - common/non-reloadable classpath delegation - via " + parent);
return ret;
}
if ((ret = parent.loadFromSearchPath(name, resolve)) != null) {
return ret;
}
throw createCnfe(name, null);
}
void validateName(String name) throws ClassNotFoundException {
log("loadClass entry '{'\n\tloader = {0}\n\ttarget = {1}\n'}'", this, name);
if ((name == null) || name.trim().isEmpty()) {
throw createCnfe(name, null);
}
}
Class<?> loadFromCache(String name) {
Class<?> ret = getClass();
if (ret.getName().equals(name)) {
log(loadClassOutcomeMsgFmt, this, name, "1 - early return - own class");
return ret;
}
if ((ret = findLoadedClass(name)) != null) {
log(loadClassOutcomeMsgFmt, this, name, "2 - early return - pre-loaded/cached");
return ret;
}
return null;
}
Class<?> loadFromBootClasspath(String name) {
if (BOOT_CLASS_PATH_RES_NAMES.matcher(name).matches()) {
ClassLoader defSysCl = ClassLoader.getSystemClassLoader().getParent();
try {
Class<?> ret = ClassLoader.getSystemClassLoader().getParent().loadClass(name);
log(loadClassOutcomeMsgFmt, this, name, "4 - bootstrap classpath delegation - via " + defSysCl);
return ret;
}
catch (ClassNotFoundException cnfe) {
}
}
return null;
}
Class<?> loadFromSearchPath(String name, boolean resolve) throws ClassNotFoundException {
Class<?> ret = null;
URL res = findResource(name.replace(".", "/") + ".class");
if (res != null) {
byte[] b;
try {
b = readClassData(res);
}
catch (IOException ioe) {
throw createCnfe(name, ioe);
}
ret = defineClass(name, b, 0, b.length);
if (resolve) {
resolveClass(ret);
}
log(loadClassOutcomeMsgFmt, this, name, "5 - freshly-defined from local search path");
return ret;
}
return null;
}
ClassNotFoundException createCnfe(String name, Throwable cause) throws ClassNotFoundException {
return new ClassNotFoundException(MessageFormat.format("Class loading : {0} : {1} : FAILED", this,
(name == null) ? "null" : name, cause));
}
void log(String msg, Object... args) {
if (debug) {
System.out.println(MessageFormat.format("\n" + msg + "\n", args));
}
}
public void setDebug(boolean debug) {
this.debug = debug;
}
#Override
protected void finalize() throws Throwable {
try {
close();
}
finally {
super.finalize();
}
log("ClassLoader finalization : {0}", this);
}
}
public static class MasterLoader extends SlaveLoader {
static final URL[] DEFAULT_CLASS_PATH = createSearchPath(System.getProperty("java.class.path"));
private URL[] reloadableSearchPath = EMPTY_SEARCH_PATH;
private volatile SlaveLoader slave;
public MasterLoader(ClassLoader parent) {
super(DEFAULT_CLASS_PATH, parent);
}
public synchronized void refresh(URL[] reloadableSearchPath) {
int len;
if ((reloadableSearchPath != null) && ((len = reloadableSearchPath.length) > 0)) {
List<URL> path = new ArrayList<>(len + 1);
for (int i = 0; i < len; i++) {
URL entry = reloadableSearchPath[i];
if (entry != null) {
path.add(entry);
}
}
this.reloadableSearchPath = (!path.isEmpty()) ? path.toArray(EMPTY_SEARCH_PATH) : EMPTY_SEARCH_PATH;
}
else {
this.reloadableSearchPath = EMPTY_SEARCH_PATH;
}
if (slave != null) {
try {
slave.close();
}
catch (IOException ioe) {
}
slave = null;
/*
* At least two calls to System::gc appear to be required in order for Class::forName to cease
* returning cached classes previously defined by slave and for which the master served as an
* intermediary, i.e., an "initiating loader".
*
* See also http://blog.hargrave.io/2007/09/classforname-caches-defined-class-in.html
*/
for (int i = 0; i < 2; i++) {
System.gc();
try {
Thread.sleep(100);
}
catch (InterruptedException ie) {
}
}
}
if (this.reloadableSearchPath != EMPTY_SEARCH_PATH) {
log("Class loader search path refresh : {0}\n\tSearch path = {1}", this,
Arrays.toString(this.reloadableSearchPath));
slave = new SlaveLoader(this.reloadableSearchPath, this);
slave.setDebug(debug);
}
}
#Override
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
validateName(name);
Class<?> ret = loadFromCache(name);
if (ret != null) {
return ret;
}
if ((slave != null) && ((ret = slave.loadFromCache(name)) != null)) {
log(loadClassOutcomeMsgFmt, this, name, "3 - early return - pre-loaded/cached - via " + slave);
return ret;
}
if ((ret = loadFromBootClasspath(name)) != null) {
return ret;
}
if ((ret = loadFromSearchPath(name, resolve)) != null) {
return ret;
}
if ((slave != null) && ((ret = slave.loadFromSearchPath(name, resolve)) != null)) {
log(loadClassOutcomeMsgFmt, this, name,
"6 - reloadable classpath delegation - via " + ret.getClassLoader());
return ret;
}
throw createCnfe(name, null);
}
}
}
Packaging
Once again correct the paths in com.example.app.App2; add App2 and com.example.app.Loaders to app.jar; and re-export. The other JARs should remain as in the former example.
Testing
Run as follows:
java -cp '/path/to/app.jar:/path/to/lib-api.jar' \
'-Djava.system.class.loader=com.example.app.Loaders$MasterLoader' \
com.example.app.App2
Sample output (loadClass debug omitted):
** lib class com.example.lib.impl.LibApiImpl / loaded by com.example.app.Loaders$SlaveLoader#7f31245a **
...
ClassLoader finalization : com.example.app.Loaders$SlaveLoader#7f31245a
...
** lib class com.example.lib.impl.LibApiImpl / loaded by com.example.app.Loaders$SlaveLoader#12a3a380 **

Mocking void methods using Mockito

I cannot seem to mock void methods on Mockito. It gives a unfinished stubbing detected here error. Here is my classfile.
package com.twu.biblioteca;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.InputMismatchException;
import java.util.Scanner;
public class BibliotecaApp {
public static class IntegerAsker {
private final Scanner scanner;
private final PrintStream out;
public IntegerAsker(InputStream in, PrintStream out) {
scanner = new Scanner(in);
this.out = out;
}
public int ask(String message) {
out.print(message);
return scanner.nextInt();
}
}
public static int numberOfBooks = 0;
public static class book{
int serialNo;
String name;
String author;
int publication;
int checkoutstatus;
book(){
serialNo = -1;
name = null;
author = null;
publication = -1;
checkoutstatus = -1;
}
book(int serialNo,String name, String author, int publication){
this.serialNo = serialNo;
this.name = name;
this.author = author;
this.publication = publication;
this.checkoutstatus=checkoutstatus = 1;
}
}
public static int getBoundIntegerFromUser(IntegerAsker asker,String message,int lowerBound,int upperBound) {
int input;
try
{
input = asker.ask(message);
while(input>upperBound || input<lowerBound)
input = asker.ask("Select a valid option! ");
return input;
}
catch(InputMismatchException exception)
{
System.out.print("You have selected an invalid option! ");
}
return -1;
}
public static book[] booksList = new book[20];
public static String welcome(){
IntegerAsker asker = new IntegerAsker(System.in,System.out);
return "**** Welcome Customer! We are glad to have you at Biblioteca! ****";
}
public static void addBooks(){
book newBook1 = new book(1,"Head First Java","Bert Bates",2014);
booksList[1] = newBook1;
numberOfBooks += 1;
book newBook2 = new book(2,"1000 IT Quizzes","Dheeraj Malhotra",2009);
booksList[2] = newBook2;
numberOfBooks += 1;
book newBook3 = new book(3,"100 Shell Programs in Unix","Shivani Jain",2009);
booksList[3] = newBook3;
numberOfBooks += 1;
}
public static void mainMenu(IntegerAsker asker){
System.out.println("1 " + "List Books");
System.out.println("2" + " Checkout a Book");
System.out.println("3 " + "Quit");
int n = getBoundIntegerFromUser(asker,"Enter your choice. ",1,3);
mainMenuaction(n,asker);
}
public static void mainMenuaction(int n,IntegerAsker asker){
if(n==1){
showBooks();
mainMenu(asker);
}
else if(n==2){
checkout(asker);
}
else if(n==3){
return;
}
}
public static void showBooks(){
for(int i=1;i<=numberOfBooks;i++){
if(booksList[i].checkoutstatus!=0)
System.out.println(booksList[i].serialNo + ".\t" + booksList[i].name + "\t" + booksList[i].author + "\t" + booksList[i].publication);
}
}
public static void checkout(IntegerAsker asker){
int Input = asker.ask("Enter the serial numebr of the book that you want to checkout");
if(booksList[Input]!=null){
if(booksList[Input].checkoutstatus!=0){
booksList[Input].checkoutstatus=0;
System.out.println("Thank you! Enjoy the book");
}
else{
System.out.println("That book is not available.");
}
}
else{
System.out.println("That book is not available.");
}
mainMenu(asker);
}
public static void main(String[] args) {
System.out.println(welcome());
addBooks();
IntegerAsker asker = new IntegerAsker(System.in,System.out);
mainMenu(asker);
}
}
And here goes my test file -
package com.twu.biblioteca;
import org.mockito.Mockito;
import org.mockito.Mockito.*;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
public class ExampleTest {
BibliotecaApp test = Mockito.mock(BibliotecaApp.class);
#Test
public void welcometest() {
assertEquals("**** Welcome Customer! We are glad to have you at Biblioteca! ****",test.welcome());
}
#Test
public void addBooksTest(){
test.addBooks();
assertEquals("Head First Java",test.booksList[1].name);
assertEquals("Dheeraj Malhotra",test.booksList[2].author);
assertEquals(2009,test.booksList[3].publication);
}
#Test
public void getBoundIntegerFromUserTest(){
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
when(asker.ask("Enter your choice. ")).thenReturn(99);
when(asker.ask("Select a valid option! ")).thenReturn(1);
BibliotecaApp.getBoundIntegerFromUser(asker,"Enter your choice. ",1,2);
verify(asker).ask("Select a valid option! ");
}
#Test
public void mainMenuTest(){
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
when(asker.ask("Enter your choice. ")).thenReturn(3);
test.mainMenu(asker);
verify(test).mainMenuaction(1,asker);
}
#Test
public void checkoutTest(){
BibliotecaApp.IntegerAsker asker = mock(BibliotecaApp.IntegerAsker.class);
BibliotecaApp test = new BibliotecaApp();
BibliotecaApp mock = spy(test);
when(asker.ask("Enter the serial numebr of the book that you want to checkout")).thenReturn(2);
Mockito.doNothing().when(mock).mainMenu(asker);
test.addBooks();
test.checkout(asker);
assertEquals(0,test.booksList[2].checkoutstatus);
}
}
Can someone point out what I am doing wrong please ?
/* system */ public static void mainMenu(IntegerAsker asker){ ... }
/* test */ Mockito.doNothing().when(mock).mainMenu(asker);
Your problem isn't about mocking void methods, it's about mocking static methods, which Mockito can't do. Behind the scenes, Mockito is creating an override of your mocked/spied class (BibliotecaApp) to override each of the methods, but because static methods can't be overridden the same way, Mockito can't change mainMenu's behavior—even just to detect that you called it in the stubbing, which is why this shows up as "unfinished stubbing".
Remove the static modifier from mainMenu and you'll be over that hurdle.
Side note: You also spy on a class but keep the original around. This isn't a good idea in Mockito: A spy actually creates a copy of the object, so if you're relying on behavior that applies to the spy, you'll have to call the test methods on the spy. (This is part of the reason to avoid spies in your tests: using spies can blur the line between testing your system's behavior and testing Mockito's behavior.)
BibliotecaApp test = new BibliotecaApp();
BibliotecaApp mock = spy(test);
when(asker.ask("...")).thenReturn(2);
Mockito.doNothing().when(mock).mainMenu(asker);
test.addBooks(); // should be: mock.addBooks()
test.checkout(asker); // should be: mock.checkout(asker)

Spring Data Neo4j 4 : Failed to convert from type java.util.LinkedHashSet<?> to type org.springframework.data.domain.Page<?>

Having this Repository method
#Query("MATCH (i:`Interest`) WHERE not(i-[:PARENT]->()) return i")
public Page<Interest> findAllByParentIsNull(Pageable pageRequest);
It cause (it didn't respect the specification):
org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.util.LinkedHashSet<?> to type org.springframework.data.domain.Page<?> for value '[com.nearofme.model.Interest#12a4479, com.nearofme.model.Interest#15bdfb3, com.nearofme.model.Interest#1af6067, com.nearofme.model.Interest#1c17d4d, com.nearofme.model.Interest#df65f4, com.nearofme.model.Interest#3b140d, com.nearofme.model.Interest#1e24566, com.nearofme.model.Interest#da49c9]'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.util.LinkedHashSet<?> to type org.springframework.data.domain.Page<?>
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:176)
at org.springframework.data.repository.core.support.QueryExecutionResultHandler.postProcessInvocationResult(QueryExecutionResultHandler.java:75)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:439)
Debugging the code shows that a conversion is needed at the GraphRepositoryQuery level :
#Override
public final Object execute(Object[] parameters) {
Class<?> returnType = graphQueryMethod.getMethod().getReturnType();
Class<?> concreteType = graphQueryMethod.resolveConcreteReturnType();
Map<String, Object> params = resolveParams(parameters);
// could be converted here
return execute(returnType, concreteType, getQueryString(), params);
}
The current code convert the result at GraphRepositoryImpl with the private method updatePage that should be used in the GraphRepositoryQuery
#Override
public Page<T> findAll(Pageable pageable, int depth) {
Collection<T> data = session.loadAll(clazz, convert(pageable.getSort()), new Pagination(pageable.getPageNumber(), pageable.getPageSize()), depth);
return updatePage(pageable, new ArrayList<T>(data));
}
So my current temporary solution is to update GraphRepositoryQuery with :
#Override
public final Object execute(Object[] parameters) {
Class<?> returnType = graphQueryMethod.getMethod().getReturnType();
Class<?> concreteType = graphQueryMethod.resolveConcreteReturnType();
Map<String, Object> params = resolveParams(parameters);
Object result = execute(returnType, concreteType, getQueryString(), params);
if (params.size()>0){
Object param = params.values().toArray()[0];
if (param instanceof Pageable){
Pageable pageable = (Pageable) param;
result = updatePage(pageable, new ArrayList((Collection) result));
}
}
return result;
}
private Page updatePage(Pageable pageable, List results) {
int pageSize = pageable.getPageSize();
int pageOffset = pageable.getOffset();
int total = pageOffset + results.size() + (results.size() == pageSize ? pageSize : 0);
return new PageImpl(results, pageable, total);
}
No more need to convert inside the GraphRepositoryImpl but it still working

JavaFX - bind property to properties of every element in observable Collection

Does exist any method which bind BooleanProperty to conjunction of every element in ObservableList?
ObservableList<BooleanProperty> list;
list = FXCollections.observableList(new ArrayList<BooleanProperty>));
BooleanProperty emptyProperty = new SimpleBooleanProperty();
emptyProperty.bind(Bindings.conunction(list));`
Is there such a method as:
static BooleanBinding conjunction(ObservableList<BooleanProperty> op)
There is no conjunction api defined in the JavaFX 2.2 platform.
You could create a ConjunctionBooleanBinding (aka AllTrueBinding) by subclassing BooleanBinding.
Accept the ObservableList in the constructor of your new class, and use the low level binding api in an overridden computeValue method to set the binding value based upon logically anding together all of the boolean values in the list.
Here is a sample implementation. The sample could be further performance optimized and make use of WeakReferences, so it does not require manual disposition.
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.collections.*;
public class AllTrueBinding extends BooleanBinding {
private final ObservableList<BooleanProperty> boundList;
private final ListChangeListener<BooleanProperty> BOUND_LIST_CHANGE_LISTENER =
new ListChangeListener<BooleanProperty>() {
#Override public void onChanged(
ListChangeListener.Change<? extends BooleanProperty> change
) {
refreshBinding();
}
};
private BooleanProperty[] observedProperties = {};
AllTrueBinding(ObservableList<BooleanProperty> booleanList) {
booleanList.addListener(BOUND_LIST_CHANGE_LISTENER);
boundList = booleanList;
refreshBinding();
}
#Override protected boolean computeValue() {
for (BooleanProperty bp: observedProperties) {
if (!bp.get()) {
return false;
}
}
return true;
}
#Override public void dispose() {
boundList.removeListener(BOUND_LIST_CHANGE_LISTENER);
super.dispose();
}
private void refreshBinding() {
super.unbind(observedProperties);
observedProperties = boundList.toArray(new BooleanProperty[0]);
super.bind(observedProperties);
this.invalidate();
}
}
And here is a test harness to demonstrate how it works:
import java.util.*;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class ListBindingTest {
final BooleanProperty a = new SimpleBooleanProperty(true);
final BooleanProperty b = new SimpleBooleanProperty(true);
final BooleanProperty c = new SimpleBooleanProperty(true);
final BooleanProperty d = new SimpleBooleanProperty(true);
final ObservableList<BooleanProperty> booleanList =
FXCollections.observableArrayList(a, b, c, d);
public static void main(String[] args) {
new ListBindingTest().test();
}
private void test() {
AllTrueBinding at = new AllTrueBinding(booleanList);
System.out.println(at.get() + forArrayString(booleanList));
b.set(false);
System.out.println(at.get() + forArrayString(booleanList));
b.set(true);
System.out.println(at.get() + forArrayString(booleanList));
booleanList.add(new SimpleBooleanProperty(false));
System.out.println(at.get() + forArrayString(booleanList));
booleanList.remove(3, 5);
System.out.println(at.get() + forArrayString(booleanList));
at.dispose();
}
private String forArrayString(List list) {
return " for " + Arrays.toString(list.toArray());
}
}
You can easily implement the method as follows:
public static BooleanBinding conjunction(ObservableList<BooleanProperty> list){
BooleanBinding and = new SimpleBooleanProperty(true).and(list.get(0));
for(int i = 1; i < list.size(); i++){
and = and.and(list.get(i));
}
return and;
}