Migration to wicket 1.5 - resource (path) issue - java

I got the task to migrate to wicket 1.4 to wicket 1.5. Despite lack of information in migration guide I was somehow able to refactor most issues. Unfortunetly I'm stuck with "resource" - atm I'm getting this error
java.lang.IllegalArgumentException: Argument 'resource' may not be null.
What I understand by that is that something was change and wicket can no longer "get" to my resources. So I used to have (in wicket 1.4) that piece of code that was responsible for creating image and passing it (the method is in class that extends WebPage) :
private void addImageLogo() {
Resource res = new Resource() {
#Override
public IResourceStream getResourceStream() {
String logo = ConfigurationManager.getInstance().getPathValue(ConfigurationManager.LOGO_FILE_PATH);
return new FileResourceStream(new File(logo));
};
Image logo = new Image("logo", res);
add(logo);
}
Now Resource class no longer exists or I can't find it. While searching internet I was able to change it into this
private void addImageLogo() {
String logoTxt = ConfigurationManager.getInstance().getPathValue(ConfigurationManager.LOGO_FILE_PATH);
ResourceReference res = new ResourceReference(logoTxt) {
#Override
public IResource getResource() {
return null;
}
};
Image logo = new Image("logo", res);
add(logo);
}
This is responsible for obtaining path (and its working): ConfigurationManager.getInstance().getPathValue(ConfigurationManager.LOGO_FILE_PATH)
Unfortunetly I'm still getting this error that I mentioned above. The method getResource() generated automaticly and I believe this is an issue because I'm retuning null but I have no idea what (or how) should I return.

Since it worked with a IResourceStream in 1.4.x then you can just use org.apache.wicket.request.resource.ResourceStreamResource as a IResource for the Image.
Your first code snippet is not complete so I cannot give you exact replacement code.

Related

How to access text_resources through StringResourceModel during junit

I'm building a Wicket 1.6 application.
In this I have a Parameter class and a FillParameter class to translate org.apache.wicket.PageParameters to my own Parameter class. The Parameter class has defaults (which are set during creation), the FillParameter has min/max values I check on. Both the default values as the min/max values are loaded from a text_resource.properties file using StringResourceModel.
example (line 15):
private int offset = Integer.parseInt((new StringResourceModel("bla.bla.bla.offset", null)).getString());
So far so good. This is working fine in my Wicket application.
Now I'm working on my junit tests and I want to test my FillParameters.class. This is a snippet from my current FillParametersTest.class:
private WicketTester wicketTester;
#Mock
Localizer localizer = mock(Localizer.class);
#Before
public void init() {
wicketTester = new WicketTester(MyApplication.class);
when(localizer.getString(eq("bla.bla.bla.offset"), (Component)anyObject(), anyString())).thenReturn("0");
wicketTester.getApplication().getResourceSettings().setLocalizer(localizer);
}
#Test
public void fillParametersGoodTest() {
PageParameters pageParameters = new PageParameters("pOffset=0");
Parameters parameters = FillParameters.fillParameters(pageParameters, parameters);
Assert.assertEquals(parameters.getOffset(), 0);
}
Alas, this is not working. The test seems to find the resource, but it doesn't get the value from that resource, resulting in:
java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:454)
at java.lang.Integer.parseInt(Integer.java:527)
at bla.bla.bla.Parameters.<init>(Parameters.java:15)
at bla.bla.bla.FillParametersTest.fillParametersGoodTest(FillParametersTest.java:63)
(line 15 in Parameters is the example I've mentioned above)
I've been searching for a solution to my problem, but I can only find good examples on how to read from a resource in the test class, not how to make it work in a application class called by the test class.
I hope I've made my problem clear, and that someone can help me with it. I'm quite new to wicket, but eager to learn.
Problem: how can I read text_resources during junit test with StringResourceModel?
Answer 27 feb 2015
Ok, so I've refactored my whole application and now I've got the code working, and it's actually very simple
private WicketTester wicketTester;
#Before
public void init() {
tester = new WicketTester(MyApplication.class);
}
#Test
public void fillParametersGoodTest() {
MockRequestParameters pageParameters = new MockRequestParameters();
pageParameters.addParameterValue("offset", "0");
FillParameters fp = new FillParameters();
Parameters parameters = fpo.fillParameters(pageParameters, parameters);
Assert.assertEquals(parameters.getOffset(), 0);
}
I'm pretty sure the problem is in your Mockito rule (the when):
when(localizer.getString(eq("bla.bla.bla.offset"), (Component)anyObject(), anyString())).thenReturn("0");
It doesn't match the real call and thus later the value is null.
Play in this area.

Vaadin SuperDevMode recompilation fails sometimes, Widget is not rendered as it should and Java code for the Widget is not available

I am trying to set up the SuperDevMode on a Vaadin project.
I have basically 3 problems related to this feature.
I have the following widget (created using the "New Vaadin Widget" wizard, below the code for the client-side widget, connector, state and server-side component):
// Widget:
public class CountedTextFieldWidget extends Composite {
private TextBox textBox = new TextBox();
private Label countLabel = new Label("0");
private HorizontalPanel panel = new HorizontalPanel();
public static final String CLASSNAME = "countedtextfield";
public CountedTextFieldWidget() {
initWidget(panel);
setStylePrimaryName(CLASSNAME);
textBox.setStylePrimaryName(CLASSNAME + "-field");
countLabel.setStylePrimaryName(CLASSNAME + "-label");
setStylePrimaryName(CLASSNAME);
panel.add(textBox);
panel.add(countLabel);
}
public String getText() {
return textBox.getText();
}
public void setText(String text) {
textBox.setText(text);
}
public void setCount(int count) {
countLabel.setText("" + count);
}
public int getCount() {
return Integer.parseInt(countLabel.getText());
}
// HandlerRegistration can be used to remove the key up handler (listener)
// added with this method
public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) {
return textBox.addKeyUpHandler(handler);
}
}
/********************************************************/
// Connector:
#Connect(CountedTextField.class)
public class CountedTextFieldConnector extends AbstractComponentConnector {
public CountedTextFieldConnector() {
getWidget().addKeyUpHandler(new KeyUpHandler() {
#Override
public void onKeyUp(KeyUpEvent event) {
String text = getWidget().getText();
getWidget().setCount(text.length());
}
});
}
#Override
protected Widget createWidget() {
return GWT.create(CountedTextFieldWidget.class);
}
#Override
public CountedTextFieldWidget getWidget() {
return (CountedTextFieldWidget) super.getWidget();
}
#Override
public CountedTextFieldState getState() {
return (CountedTextFieldState) super.getState();
}
#Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
final String text = getState().text;
getWidget().setText(text);
getWidget().setCount(text.length());
}
}
/********************************************************/
// State
public class CountedTextFieldState extends com.vaadin.shared.ui.textfield.AbstractTextFieldState {
{
primaryStyleName = null;
}
}
/********************************************************/
// Server-side component:
public class CountedTextField extends com.vaadin.ui.TextField {
#Override
public String getValue() {
return getState().text;
}
public void setValue(String value) {
getState().text = value;
}
#Override
public CountedTextFieldState getState() {
return (CountedTextFieldState) super.getState();
}
}
This widget is rendered as following:
Now, I have followed the following guide on the Vaadin's wiki:
https://vaadin.com/wiki/-/wiki/Main/Using%20SuperDevMode
The CodeServer starts as expected:
The code server is ready.
Next, visit: http://localhost:9876/
But when I open the project and append ?superdevmode to the URL, get the Recompilation failed... message and there's are some errors in the browser's console:
So my first problem is related to this issue:
1) Why does recompilation fail sometimes? And what are those SEVERE: JSONP compile call failed and SEVERE: Timeout Excecution?
Then if I ... click to retry sometimes the superdevmode starts, but the custom widget is not rendered as in the previous screenshot I posted.
Instead, I get a standard Vaadin's v-textfield...
2) WTF... Why? Where is my custom component?
I noticed that I get the same issue also if I open localhost:9876, drag the Dev Mode On button to the bookmarks toolbar and then click on it while on localhost:8080/project. My custom widget is disappears and instead I get the Vaadin's v-textfield widget...
And about the Enable Source Map feature. On the wiki, they say:
To be able to debug Java code in Chrome, open the Chrome Inspector
(right click -> Inspect Element), click the settings icon in the lower
corner of the window and check "Scripts -> Enable source maps".
Refresh the page with the inspector open and you will see Java code
instead of JavaScript code in the scripts tab.
In my Chrome, I don't have a settings icon on the lower corner of the window, I clicked the gear icon on the right and went to General -> Sources and checked Enable JavaScript Source Map (There's no generic Enable source maps entry on my settings tab).
I can see the Java sources, but they are all sources for GWT and Vaadin's components:
So my third issue and related question:
3) How can I see my custom widget code also?
Thanks for the attention! Hope I was clear.
I also had a similar problem trying to use SuperDev Mode with Vaadin. I'm not quite sure why recompilation fails on occasion, but I suspect it envolves the same issue I had trying to send my Java source maps. The problem I had seemed to be a caching issue due to the fact that the code server creates a persistent cache directory in my /tmp folder. So I deleted every folder it created (they usually have "gwt" in the name somewhere) and relaunched the code server. I suggest also adding the -src <complete-path-to-project> argument in the code server configurations to specify the directory containing GWT source to be prepended to the classpath for compiling and possibly changing the log level to TRACE or DEBUG. Heres an example those arguments:
com.example.AppWidgetSet -src /home/workspace/widgetset/src/main/java
-logLevel TRACE
I should mention that the log levels are quite verbose, but can be quite useful. The log should also show the location of the cache folder.

Eclipse tracing.What is best practice?How to get instance of DebugTrace?

I'm working on RCP aplicattion, that works on Eclipse 4 platform(Luna). I neeed to find out how to get instance that implement tracing inside my Application. I found out the following ways
-
Using ILog interface, that can be get via Platform.getLog call. ILog has good point. It prints to .log file that located in .metadata, but
it get IStatus object as parameter. So for logging each line to log I have to created new instance of Status object. And it cannot put automatically information about caller like class name etc.(like Log4j, LogBack)
I found interface DebugTrace that provide good functionality for traicing. It can be obtained via DebugOptions inerface(DebugOptions.newDebugTrace()). To my regret I could not find appropriated way for getting instance of DebugOptions
To use DebugTrace, add this to the plugin Activator:
private DebugTrace tracer = null;
public static DebugTrace getTrace()
{
return plugin.tracer;
}
public void start(final BundleContext context) throws Exception
{
...
final Hashtable<String, String> properties = new Hashtable<String, String>(4);
properties.put(DebugOptions.LISTENER_SYMBOLICNAME, "org.eclipse.ui.trace"); //$NON-NLS-1$
context.registerService(
DebugOptionsListener.class.getName(),
new DebugOptionsListener()
{
#Override
public void optionsChanged(DebugOptions options)
{
tracer = options.newDebugTrace(context.getBundle().getSymbolicName());
}
}, properties);
You will need to add a .options file to the plugin project which will contain your logging options:
# Editor-related tracing
com.acme.atf.app/trace/editor=false
#Start-up tracing
com.acme.atf.app/trace/startup=true
org.eclipse.core.jobs/jobs=true
org.eclipse.core.jobs/jobs/beginend=true
org.eclipse.core.jobs/jobs/errorondeadlock=true
Hope this helps...

Path requests must specify a user by using UserEnvironment

I am getting "Path requests must specify a user by using UserEnvironment" error by using
Environment.getExternalStorageDirectory().getPath()
I traced my code and I found that in java.io.Environment there is a function to produce this error :
private static void throwIfUserRequired() {
if (sUserRequired) {
Log.wtf(TAG, "Path requests must specify a user by using UserEnvironment",
new Throwable());
}
}
I searched in the web and found this solution from here
Environment.setUserRequired(false);
But this solution is not working for me because I cannot access to the "setUserRequired" method of Environment. I get compilation error. I searched this function in the Environment class and I found this :
/** {#hide} */
public static void setUserRequired(boolean userRequired) {
sUserRequired = userRequired;
}
Can anyone help me how can I access to my external storage of my phone? any solution ? it is emergency. Thanks a lot
You need to use UserEnvironment and get the path for this user.
int userId = UserHandle.myUserId();
sCurrentUser = new UserEnvironment(userId);
This code stolen from Environment.java and the code they use to initialize their internal user.
I could solve my problem by removing
Environment.getExternalStorageDirectory().getPath()
inside try-catch block and writing outside of the try-catch block,and it is working now.
Through the reflection to solve this problem
fun setUserRequired() {
var state = Environment.getExternalStorageDirectory()
if ("mounted".equals(state)) {
try {
var environmentcls = Class.forName("android.os.Environment");
var setUserRequiredM = environmentcls.getMethod("setUserRequired", Boolean::class.java);
setUserRequiredM.invoke(null, false);
} catch (e: Exception) {
e.printStackTrace()
}
}
}

How to check if a Java ResourceBundle is loadable, without loading it?

I would like to check the existence of a ResourceBundle without actually loading it.
Typically, I'm using Guice, and at initialization time, I want to check the existence, while at execution time, I want to load it. If the bundle doesn't exist, I want an early report of the inexistence of the RB.
If it was possible to get the ResourceBundle.Control instance used for a specific ResourceBundle, I would have no problem getting the basic information to build the actual resource name (using toBundleName() and toResourceName()), but it is not the case at that level.
Edit:
Ok, I found the way to do it. I'll create a ResourceBundle.Control that is extensible (using a custome addFormat(String, Class)) to store all the bundle formats, then use another method of my own to check all possible file names for a specific locale (using Class.getResource as indicated here below).
Coding speaking:
class MyControl extends ResourceBundle.Control {
private Map<String,Class<? extends ResourceBundle>> formats = new LinkedHashMap();
public void addFormat(String format,Class<? extends ResourceBundle> rbType) {
formats.put(format, rbType);
}
public boolean resourceBundleExists(ClassLoader loader, String baseName, Locale locale) {
for (String format: formats.keySet()) {
// for (loop on locale hierarchy) {
if (loader.getResource(toResourceName(toBundleName(baseName, locale), format)) != null) {
return true;
}
// }
}
return false;
}
}
If the default bundle must exists you can do:
Class.getResource("/my/path/to/bundle.properties")
and it will return an URL to the file or null if it doesn't exists.
Of course use the correct class or classloader if you have many.
EDIT: if you have resources as classes you have to check also
Class.getResource("/my/path/to/bundle.class")
In Java 6 you can store resource bundles in XML. I don't know how ResourceBundle class lookups this resource, but I bet it's in the same way.
You can load the bundles, thus making your checks, and then call ResourceBundle.clearCache() so that they are loaded again next time.
This happens once (at initialization time), and it isn't such a heavy operation, so it won't be a problem.
Or you can simply try to find whether a resource is present on the classpath. For example the fallback .properties file, or the properties file for your default locale.
Finally, after having a look at the code for ResourceBundle.Control, you have the option to do what they do in the newBundle() method.
Something like this, maybe
ResourceBundle bundle;
public PropertiesExist() {
String propsFile = "log4j";
String propsPath = this.getClass().getClassLoader().getResource(".").getPath();
File f = new File(propsPath, propsFile + ".properties");
if(!f.exists()){
System.out.println("File not found!!!!");
System.exit(-1);
}
bundle = ResourceBundle.getBundle(propsFile);
System.out.println(bundle.getString("log4j.rootLogger"));
}
public static void main(String[] args) {
new PropertiesExist();
}
This will look for the logging file, log4.properties, if not found program will exit

Categories