groovy.langMissingMethodException in calling groovy function - grails

I have a Grails GSP page similar to this:
<!DOCTYPE html>
<html lang="en">
<head>
...
<script type="text/javascript">
var currency = ${Currency.getList() as JSON};
</script>
</head>
...
</html>
And a groovy file similar to this:
package enums
import java.util.List;
public final class Currency {
private static final List CURRENCIES = ['PHP','USD','HKD'];
static List getList(){
return CURRENCIES
}
}
Now it shows an error message:
groovy.lang.MissingMethodException
No signature of method: static java.util.Currency.getList() is
applicable for argument types: () values: [] Possible solutions:
getAt(java.lang.String), getClass(), split(groovy.lang.Closure),
notify(), wait()
How can I resolve this? The groovy file is placed in project/src directory, and is not allowed to move (if that helps).

According to the error message you are using a different Currency class from java.util package.
So try using your own class which is enums.Currency.getList() rather than java.util.Currencty.getList().
update:
Also import JSON class. According to your comments it seems my answer is not clear for you. So your code will be like this:
package enums
import java.util.List;
import grails.converters.JSON;
public final class Currency {
private static final List CURRENCIES = ['PHP','USD','HKD'];
static List getList(){
return CURRENCIES
}
}

Since you call the static groovy function from inside your HTML, I suspect you need to add the modifier "public" to your static method so:
public static List getList()
EDIT: Above is not the issue, but the exception complains about the class Currency from the java.util package, not from your own package "enums".

Related

New assignment to collection-type class field absent from flow program with Rascal, unlike to local variables

Consider the following Java code:
import java.util.LinkedList;
import java.util.List;
class Library {
List<String> loans = new LinkedList<>();
public List<String> searchUser(String name) {
List<String> usersFound = new LinkedList<>();
return loans;
}
}
and the following Rascal module:
module Mwe
import lang::java::flow::JavaToObjectFlow;
import lang::java::jdt::m3::AST;
import IO;
void m() {
ast = createAstFromEclipseFile(|project://test/src/test.java|, true);
fp = createOFG({ast});
print(fp);
}
The resulting flow program will be:
flowProgram({
attribute(|java+field:///Library/loans|),
method(|java+method:///Library/searchUser(java.lang.String)|,[|java+parameter:///Library/searchUser(java.lang.String)/scope(name)/scope(0)/name|]),
constructor(|java+constructor:///Library/Library()|,[])
},{
assign(|java+method:///Library/searchUser(java.lang.String)/return|,|id:///|,|java+field:///Library/loans|),
newAssign(|java+variable:///Library/searchUser(java.lang.String)/usersFound|,|java+class:///java/util/LinkedList|,|java+constructor:///java/util/LinkedList/LinkedList()|,[])
})
So, there is a new assignment of LinkedList to usersFound, but nothing comparable for loans. Why would that happen? Is that the intended behaviour?
Just checked the implementation, the field initializers are not included in the getStatements function (see lang::java::flow::JavaToObjectFlow on line 169). Similarly the static initializers of a class are ignored.
The best way forward would be to either report it as a bug, or fix it and turn it into a pull-request. (pull request is the quickest way to getting it fixed on unstable)
As a possible, yet work intensive workaround you rewrite the AST to put the field initializers inside all existing constructors (or add a constructor if there is none).

Setting the response status code in Sightly

I have a Sightly template which I want to use as an Apache Sling error handler.
How do I set the status code?
response is a global object for Use-API objects. In Java you can access these objects from the bindings map, whereas in the JavaScript implementation of the Use-API these global objects are in the global namespace.
Java Use-API example:
public class ErrorHandlerUseObject implements Use {
#Override
public void init(Bindings bindings) {
SlingHttpServletResponse response = (SlingHttpServletResponse) bindings.get(SlingBindings.RESPONSE);
response.setStatus(403);
}
}
JavaScript Use-API example (let's assume the script's name is errorhandler.js):
use(function () {
response.setStatus(403);
});
In your Sightly template instantiating any of the defined Use objects should do the trick of setting your response code:
<html data-sly-use.errorHandler="ErrorHandlerUseObject">
...
</html>
<html data-sly-use.errorHandler="errorhandler.js">
...
</html>

PolymerDart: Data binding templates with complex models

So I have a shared library with some models I intend to use on the server as well as the client:
library models;
class Model {
String id;
}
class Theatre extends Model {
String name;
// implements List<E>
CustomCollection<Movie> movies = new CustomCollection();
Theatre(this.name);
}
class Movie extends Model {
String name;
Movie(this.name);
}
I have a Polymer element like this:
<polymer-element name="my-app">
<template>
<movie-list movies="{{theatre.movies}}"></movie-list>
<button on-click="{{moreMovies}}">More movies!</button>
</template>
<script type="application/dart" src="my_app.dart"></script>
</polymer-element>
With the following code behind:
import 'package:polymer/polymer.dart';
import 'package:my_app/models.dart';
#CustomTag('my-app')
class MyApp extends PolymerElement {
#observable theatre = new Theatre('Lucky Seven Cinema');
void moreMovies(event, detail, sender) {
theatre.movies.add(new Movie('The Goonies'));
}
}
PolymerDart doesn't seem to observe my property changes: after the initial page load, changing theatre.name or adding or removing an item from theatre.movies does not result in the bindings updating. Polymer's documentation says that expressions are re-evaluated when the value of one or more paths in an expression changes.
If I go into models library and add #observable to all of my model properties, PolymerDart seems to pick up the changes, but now I've added a new dependency to my models library -- and I want this library to work both on the client and the server so I don't have to duplicate my logic.
Also, adding #observable to every possible property I might want to data bind is super overkill and pretty messy to look at.
I assume I'm doing something wrong here: what is it?
The model classes need to extend Observable and the properties need an #observable annotation. See Observe package from polymer dart for more details.
class model extends Observable {
...
}
class Theatre extends Model {
#observable
String name;
}
I can't tell how the implementation of your CustomCollection looks like but if it contains an embedded List or Map you should initialize it like List backingList = toObservable([]); so Polymer gets notified when elements are added/removed.

How to internationalize a converter or renderer in Wicket?

I'm translating a web application and things are generally going smoothly with wicket:message and properties files. But Wicket always wants to have a component for looking up strings.
How can I translate converters and renderers (i.e. implementations of IConverter and IChoiceRenderer) which don't have access to any Wicket component in their methods?
So far I found one way - Application.get().getResourceSettings().getLocalizer().getString(key, null) - but I have to make the strings "global", i.e. associated with the application class. That's not nice for separation and reuse. How can I do it better?
I think you should invent you own way how to achieve this. Here in my current project we registered our own IStringResourceLoader like this:
IStringResourceLoader stringResourceLoader = new OurOwnResourceLoaderImpl();
Application.get().getResourceSettings().getStringResourceLoaders().add(stringResourceLoader);
Then for example in IChoiceRenderer we just call Application.get().getLocalizer().getString("key", null).
Inside our IStringResourceLoader we are looking for bundles (property files) with some string pattern according our own conventions.
Or you can just register localization bundle (ie. properties file) distributed inside your library's jar in Application#init through org.apache.wicket.resource.loader.BundleStringResourceLoader.
Afaik there is no standard way to do that so it's up to you what path you choose.
Updated:
I found another solution how your library/extension can register it's own localization by itself so you needn't to touch Application#init or create your own IStringResourceLoaders.
There is preregistered string resource loader org.apache.wicket.resource.loader.InitializerStringResourceLoader (see wickets default IResourceSetting implementation ie. ResourceSetting and it's constructor) which uses wicket's Initializer mechanism - see IInitializer javadoc - basically you add wicket.properties file in your jar class root (ie. it is in default/none package) and inside file there is:
initializer=i.am.robot.MyInitilizer
then i.am.robot.MyInitilizer:
public class MyInitializer implements IInitializer {
/**
* #param application
* The application loading the component
*/
void init(Application application) {
// do whatever want
}
/**
* #param application
* The application loading the component
*/
void destroy(Application application) {
}
}
and now you create your localization bundles in same package and same name as IInitializer implementation (in our example MyInitializer)
I think I found another way...
I noticed that IStringResourceLoader also has a method String loadStringResource(Class<?> clazz, String key, Locale locale, String style); (and one more parameter for variation in newer Wicket versions) which does not require a component. clazz is supposed to be a component class, but... it doesn't actually have to be :)
I was able to implement my own class MyLocalizer extends Localizer with a new method
getString(String key, Class<?> cl, IModel<?> model, Locale locale, String defaultValue)
which works in a similar way to
getString(String key, Component component, IModel<?> model, String defaultValue)
but uses the class directly instead of a component. It still uses the same properties cache and resource loaders.
Then I wrote an abstract class MyConverter implements IConverter which has a MyLocalizer getLocalizer() and a few getString methods like the Component class. Basically it does getLocalizer().getString(key, getClass(), model, locale, defaultValue), so the properties can now be attached to the converter class.
Seems to work :)
If I understand your question...
You can use package based properties that means if you put your keys/values into a property file 'package.properties' in a package. Each localized resource of any subpackage under that package returns the value associated to the requested key until you override it in another property file.
The file name is 'package.properties' in Wicket prior to 1.6.x and 'wicket-package.properties' in Wicket 1.6+
See
https://cwiki.apache.org/confluence/display/WICKET/Migration+to+Wicket+6.0#MigrationtoWicket6.0-package.propertiesrenamedtowicket-package.properties
However it works just for componet, outside the componet (when component argument is null), it is possible to use:
WicketApplication.properties (the WebApplication class is WicketApplication.class, this property file is in the same package).
applicationGlobalProperty=My Global Localized Property
wicket-package.properties (package based, place it in the same package as the page)
localText=Localized text: A local component text based on wicket-package.properties
LocalizedPage.html (markup template)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Localized Page</title>
</head>
<body xmlns:wicket="http://wicket.apache.org">
<div>
<div>
<h2>Texts</h2>
<div>
<wicket:message key="localText"/> <br/>
<span wicket:id="localizedLabel"></span>
</div>
</div>
</div>
</body>
</html>
LocalizePage.java (code)
public class LocalizedPage extends WebPage {
private static final long serialVersionUID = 1L;
public LocalizedPage() {
super();
}
#Override
protected void onInitialize() {
super.onInitialize();
add(new Label("localizedLabel", new AbstractReadOnlyModel<String>() {
private static final long serialVersionUID = 1L;
#Override
public String getObject() {
return WicketApplication.get().getResourceSettings().getLocalizer().getString("applicationGlobalProperty", null);
}
}));
}
}
See the full example on https://repo.twinstone.org/projects/WISTF/repos/wicket-examples-6.x/browse

flash cs5 packages can't be nested issue

So I am working on an app and I am getting a "packages cannot be nested" error when I try to run. There are no errors in the syntax that flash told me.
Code -
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class main extends MovieClip {
public function main() {
init()
}
private function init():void
{
home_button.addEventListener(MouseEvent.CLICK, handleButtonClicks);
}
private function handleButtonClicks():void
{
stop();
gotoAndStop("home_page");
}
}
}
Thanks
Old thread (month ago), i know.
I guess your code is in de fla (not an external as file).
Simply remove the word Package and it parenthesis (package {}) and run again.
This will work, guaranteed.
And also it is possible that flash gives an error about scope declarations like 'public', 'private' etc, remove also these.

Resources