LazyList is not defined in ZUL Page - java

I'm trying to pass data from DAO with flexbile search query trough to the zul page using de the widgetModel. But when I print the widgetModel.orders it says...
(index):93 Uncaught ReferenceError: LazyList is not defined
at window.onload ((index):93)
zul page
window.onload = function () {
const myChart = new Chart(
document.getElementById('myChart'),
config
);
const test = [[${widgetModel.orders}]];
console.log(test);
};
controller class
public class customGraphController extends DefaultWidgetController {
private static final long serialVersionUID = 7954736389190109887L;
#WireVariable
private transient customGraphService customGraphService;
#Override
public void preInitialize(Component comp) {
super.preInitialize(comp);
WidgetModel model = getWidgetInstanceManager().getModel();
model.put("orders", customGraphService.getAllOrders());
}
}
service class
public class customGraphService {
#Autowired
private OrdersDataDao ordersDataDao;
public List<OrderModel> getAllOrders() {
return ordersDataDao.getAllOrders();
}
}
dao class
public class OrdersDataDao {
#Resource
private FlexibleSearchService flexibleSearchService;
public List<OrderModel> getAllOrders() {
final String stringQuery = "select {o.pk} from {order as o}";
final FlexibleSearchQuery query = new FlexibleSearchQuery(stringQuery);
final SearchResult<OrderModel> result = flexibleSearchService.search(query);
if (null != result.getResult()) {
return result.getResult();
} else {
return null;
}
}
}
Does someone knows a solution?

window.onLoad is always too early to manipulate ZK widgets. The onLoad callback will trigger once the initial document has been loaded, but that document itself will load ZK libaries, initialize the client engine, etc.
If you need to do something "after libraries have been loaded", you can use zk.afterload. This hook is good if you need to modify a framework function before the widgets actually use it.
However, this is still before widget instantiation by the client engine, so if your goal is to access a widget, it is still too early.
If you want to do something to a widget after that widget has been added to the page an initialized, what you actually need is a client-side onBind listener.
You can set that listener in zul or in java, but the simplest way to do that is like this: https://zkfiddle.org/sample/1v9phuk/1-Another-new-ZK-fiddle
Lastly, if you are going to use ZK's client-side API to access / modify content at client-side, I'd recommend looking into the ZK client-side selectors. Way easier than trying to manually lookup elements by ID, and way more robust in the long run.
document.getElementById('myChart') will only work if you have a dom element with the actual ID "myChart", which is not how ZK works (not with default UUID generator anyway).
Instead, you can select a widget by it's ZK ID.
Assuming you have <charts id="myChart" /> in your zul, you can get the ZK widget directly as argument to the onBind listener, or you can get it with the ZK selector:
zk.$("$myChart"), and from there you can get the DOM node: zk.$("$myChart").$n()
Make sure you know what is client-side (JavaScript), and what is Server side.
(Lastly)^2, keep in mind that in a ZK architecture, the server is the source of the state, and the client only update the state by sending client commands back to the server.
If you use JS to modify the client-side state, you can create desynchronization between the server-side state and the client-side state, so proceed with caution.

I found a solution, I used GSON to stringify the list and than pass it to the zul page :-)
private Object convertAllOrderModelsToJSON() {
//get all the models
List list = customGraphService.getAllOrdersModels();
//convert models to JSON
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(list);
return json;
}

Related

CORDA: Invoke custom query on all parties involved in transaction

I have multiple questions on Corda:
Can we predefine the h2 configuration to pick in build.gradle file?
I have a transaction in my corda network where i want to validate something based on custom fields the validation has to happen based on query that needs to be fired on all 3 parties sender, receiver, notary how can i fetch the session of all 3 nodes? i am able to pull the session of sender using getServiceHub().jdbcSession()
What will be the most suggested way to query a notary for custom fields? Can it be done using creating a sub-flow if yes then how?
we have validating and non validating notaries, where do we actually validate using notary? Where do we write the validation code?
how can we enable autosuggest in intellij for java api of corda?
You can set the h2Port option in deployNodes:
node {
name "O=PartyA,L=London,C=GB"
advertisedServices = []
p2pPort 10005
rpcPort 10006
webPort 10007
h2Port 10008
cordapps = ["net.corda:corda-finance:$corda_release_version"]
rpcUsers = [[ user: "user1", "password": "test", "permissions": []]]
}
Is that the kind of configuration you needed?
Each node's database is private by design, and cannot be queried from another node. Instead, you need to communicate with the other nodes as part of your flow in a way that causes them to initiate a response flow on their end where they query their own databases and send the results back. Something like:
public class CollectDBDataFlow {
#InitiatingFlow
#StartableByRPC
public static class Initiator extends FlowLogic<List<Object>> {
Party counterparty;
public Initiator(Party counterparty) {
this.counterparty = counterparty;
}
#Suspendable
#Override public List<Object> call() {
// TODO: Implement queryMyDatabase to perform querying.
Object myDBData = queryMyDatabase();
FlowSession counterpartySession = initiateFlow(counterparty);
Object theirDBData = counterpartySession.receive(Object.class);
return ImmutableList.of(myDBData, theirDBData);
}
}
#InitiatedBy(Initiator.class)
public static class Responder extends FlowLogic<Void> {
private FlowSession counterpartySession;
public Responder(FlowSession counterpartySession) {
this.counterpartySession = counterpartySession;
}
#Suspendable
#Override
public Void call() {
// TODO: Implement queryMyDatabase to perform querying.
Object myDBData = queryMyDatabase();
counterpartySession.send(myDBData);
return null;
}
}
}
The role of the notary isn't to be queried for data, but to prevent double-spends. You could technically do it using the method described in (2) above, but it wouldn't be advised. What are you trying to achieve?
The validation logic is written into the platform. See https://github.com/corda/corda/blob/release-V1/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt.
The auto-complete should appear automatically, just like any other library.

Consuming Spring Hateoas Restservice with RestTemplate

I have two applications, one is called bar, what provides me resources in HAL format. The other is bcm to consume that service.
Example of response bar looks like this:
[
{
"name":"Brenner/in",
"_links":{
"self":{
"href":"..host/bbsng-app-rest/betrieb/15"
}
}
},
{
"name":"Dienstleistungshelfer/in HW",
"_links":{
"self":{
"href":"..host/bbsng-app-rest/betrieb/4"
}
}
},
{
...
Now I try to consume that from bcm using Spring RestTemplate. My Solution works, but I am not happy with that solution somehow and I guess there is a more clean way.
My Client-Code consuming RestService looks like:
#Autowired private RestTemplate template;
#Override
#SuppressWarnings("unchecked")
public BerufListe findeAlleBerufe() {
final BerufListe berufListe = new BerufListe();
final ResponseEntity<List> entity = template.getForEntity(LinkUtils.findBeruf(), List.class);
if (OK.equals(entity.getStatusCode())) {
final List<LinkedHashMap> body = entity.getBody();
for (final LinkedHashMap map : body) {
final LinkedHashMap idMap = (LinkedHashMap) map.get("_links");
String id = remove(String.valueOf(idMap.get("self")), "href=");
id = remove(id, "{");
id = remove(id, "}");
final String name = String.valueOf(map.get("name"));
final Beruf beruf = new Beruf(id, name);
berufListe.add(beruf);
}
}
return berufListe;
}
There are few ugly code as you see. One of them is, that I don't have any generics for my collections. The other point, I get the Resource_ID very complicated, and I use StringUtils.remove many times to extract the self url.
I am sure there must be a more convenient way to consume HAL-Response by Spring.
Thanks you.
Take a look the the Resource class from spring-hateaos.
It provides methods to extract the links from the response.
However, as RestTemplate requires you to provide the class as variable, I have not found a different way other than creating a subclass of the desired entity and use it for RestTemplate.
You code could then look like this:
public class BerufResource extends Resource<Beruf> { }
BerufResource resource = template.getForEntity("http://example.at/berufe/1", BerufResource.class);
Beruf beruf = resource.getContent();
// do something with the entity
If you want to request a complete list, you would need to pass the array version of your entity to RestTemplate:
BerufResource[] resources = template.getForEntity("http://example.at/berufe", BerufResource[].class);
List<BerufResource> berufResources = Arrays.asList(resources);
for(BerufResource resource : berufResources) {
Beruf beruf = resource.getContent();
}
Unfortunately, we cannot write Resource<Beruf>.class which defeats the whole purpose of the generic class, as we need to again create a subclass for every entity. The reason behind that is called type erasure. I've read somewhere that they are planning to introduce generic support for RestTemplate but I am not aware of any details.
Addressing the extraction of the id from the url:
I would recommend to use a different model on the client side and replace the type of the id field with string and store the whole url in it. This way, you can easily refetch the whole entity whenever you like and do not need to construct the URL yourself. You will need the URL later anyway, if you plan on submitting POST-requests to your API, as spring-hateaos requires you to send the link instead of the id.
A typical POST-request could look like this:
{
"firstname": "Thomas",
"nachname": "Maier",
"profession": "http://example.at/professions/1"
}

Reusing the Result of a Controller in another Controller in the Play framework

Apologies if this has been answered already - I've had a look and can't find anything.
Using the Play framework, I have defined two controllers - one is a public API that returns JSON, and one is a consumer of this API which presents the JSON as HTML. E.g. my routes file look as follows:
GET /foos controllers.App.foos() #produces HTML
GET /api/foos controllers.API.foos() #produces JSON
A requirement of the project is that our data should only be accessed via our public API. Therefore, the way that I'd like to implement this is to have App.foos() invoke API.foos(), parse the JSON result, and pass it to a template to be rendered. For example:
public App extends Controller {
public static Result foos() {
Result result = API.foos();
// TODO: get the JSON out of the result object
}
}
Can anyone tell me how I can extract the JSON from the result object? I can get the body of the object as an Enumerator using ((SimpleResult)result.getWrappedResult()).body(), but I am still unclear how I can get out the JSON.
Because I am new to the Play framework, perhaps I am going about this wrong and there is an easier/better way to do this?
Many thanks in advance,
James
The easiest way would be to expose the underlying method.
public Api extends Controller {
public static Result foos() {
Ok(foosJson());
}
public static JsValue foosJson() {
// ...
}
}
public App extends Controller {
public static Result foos() {
JsValue json = API.foosJson();
}
}

Java Annotations removing string literals from them?

Not sure if this is a decent question or not but here it goes. We are trying to implement a UI testing framework (selenium web-driver) and want to use a Page driven design for example
class HomePage {
#FindBy(how = How.Id, id="myPageHeaderID")
private String pageHeader
In the simple example above I need to hard-code the "myPageHeaderID" string literal. One of the requirements proposed is that we be able to pull in the "myPageHeaderID" from a property for both maintenance reasons (no code deploy if something changes) and for internationalization reasons. I have been searching around and probably not doing a proper search but is there any way of doing what I am asking above?
I briefly went down this route, but due to our application it wasn't quite achievable (pages aren't always displayed in the same order once you've visited a page).
public class PageElement implements WebElementAdapter, Locatable {
private How how;
private String using;
private boolean required;
#FindBy(how = How.ID_OR_NAME, using = DEFAULT_LOCATION_STRATEGY)
private WebElement backingElement;
public PageElement(How how, String using using) {
this.how = how;
this.using = using;
this.required = true;
}
/**
* This is how the overriding of the element location is done. I then injected
* these values in a spring configured bean file.
*
* This is needed on your config file:
* default-lazy-init="true" default-init-method="initialize">
*/
public final void initElement() {
if (backingElement == null || isStale() {
backingElement = getDriver().findElement(getLocationStrategy());
}
}
public By getLocationStrategy() {
By by = new ByIdOrName(using.replace(DEFAULT_LOCATION_STRATEGY, using));
switch(how) {
case CLASS_NAME:
by = By.className(using.replace(DEFAULT_LOCATION_STRATEGY, using));
break;
//Do for others
}
return by;
}
public WebElement getBackingElement() {
return backingElement;
}
}
public interface WebElementAdapter {
WebElement getBackingElement();
}
public interface Locatable {
By getLocationStrategy();
}
I then created common widgets in POJOs, and injected these into page objects which were a collection of these widgets.
From there I had a simple test harness which was responsible for taking in strings (which were then executed. Basically it allowed for test cases to be written in SpEL and act on the beans which were injected.
It was what I thought a pretty neat project, but I had to shelf it to get some other things done.
Annotations are essentially metadata. Taking database metadata for example, it would be weird if Oracle database would turn into MySQL, right? Here is the article about Annotation Transformers in TestNG. Didn't try it myself, but I think it could be implemented in some way or another.
AFAIK, you can call a method from the Annotation.
#FindBy(how = How.Id, id=getProp())
private String pageHeader;
private String getProp()
{
String prop = //whatever way you want to get the value
return prop;
}
Doesn't that work?

Is reflection my best option here?

We allow users to set some preferences in our web application. When they login to certain sites, they are allowed to do/see different screens vs. when they are in another site. One of our requirements is that we hide preferences on the page which they can't access in the currently logged in site. Currently we are using Spring MVC to handle these requests.
Here is a simplified example of our POJO:
public class Preferences {
boolean prefA; //Valid when can do A
String prefB; //Valid when can do B
Integer prefC; //Valid when can do C
....
Long prefZ; //Valid when can do Z
}
Here is the controller code:
#RequestMapping(method = RequestMethod.POST, value = "preferences.xhtml")
public ModelAndView updateRequestPreferences(#ModelAttribute(USER_PREFERENCES) final Preference preferences, final BindingResult results)
{
return updatePreferences(preferences, results);
}
Currently updatePreferences does reflection, and ensures that the value is not null before it persists the input preferences -- This is due to Spring MVC creating a new instance of Preferences and then populating the values with what was on the UI.
We could do the following in the setter of the preferences:
public void setPreferences(Preferences preferences) {
if (preferences.getPrefA() != null) {
this.preferences.setPrefA(preferences.getPrefA());
}
if (preferences.getPrefB() != null) {
this.preferences.setPrefB(preferences.getPrefB());
}
...
if (preferences.getPrefZ() != null) {
this.preferences.setPrefZ(preferences.getPrefZ());
}
}
It would get unwieldy even with a helper function for all the checks in the setter method (and seems like an easy step to forget when a new preference is created); at the same time reflection seems like a cop out. Is there a better way to refactor this?
You can configure Spring MVC to populate fields of a preexisting object rather than to create a new one.
For example, you can use #SessionAttributes(USER_PREFERENCES) in order to store an instance of Preferences in a session between rendering a form and processing its submit.
Another approach is to load new instance of Preferences from the database as an implicit model attribute:
#ModelAttribute(USER_PREFERENCES)
public Preferences loadPreferences(#RequestParam("key") String key) {
return loadPreferencesByKey(key);
}
Note that in all cases (and your original approach needs it as well) you need to specify a set of allowed fields in #InitBinder method, to prevent malicious user from modifying fields that was not rendered in a form:
#InitBinder(USER_PREFERENCES)
public void initBinder(WebDataBinder b) {
b.setAllowedFields("prefA", "prefB");
}

Categories