You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by hfriederichs <h....@ohra.nl> on 2011/08/17 09:43:31 UTC

How to Handle ResourceStreamNotFoundException

Hello to you all,

First of all, I apologise for submitting this post for the second time, but
the first didn't use the correct user group. 

I'm adding a new feature to a Wicket application that manages
JEE-applications (I'm using 1.4.18). For example, it's possible to install
and configure a JEE-appliation on an Application server. If a user chooses
to do so, he enters a unique application code and submits: a zipfile
containing the application, it's documentation and configuration is
downloaded via http from a Nexus repository, and installed with
soap/jmx/mbeans on the application server.

What I have added, is a button that - once clicked - opens an installation
manual in msword that is part of the aforementioned zipfile. The general
idea is: take a zipinputstream, read it until the installation manual is
found, then hand the inputstream over to a wicket IResourceStream that
provides the getInputStream for a Wicket WebResource. I think it's a quite
elegant solution; it's all streaming, no temporary files etcetera.
And it works marvelously, that is, if the zipfile actually containes a
installation manual. My problem is twofold:
When pressing the button without entering an application code (so there is
no inputstream and no installation manual) wicket produces:
org.apache.wicket.WicketRuntimeException: Could not get resource stream
        at org.apache.wicket.Resource.init(Resource.java:217)
        at org.apache.wicket.Resource.onResourceRequested(Resource.java:117)
        at
org.apache.wicket.markup.html.link.ResourceLink.onResourceRequested(ResourceLink.java:108)
        ... 36 more
That's to be expected, but the user is confronted with a white screen, and I
can't catch this Exception.
Secondly, if there is a zipinputstream, but no installation manual found in
it, all I can do is throw a ResourceStreamNotFoundException (see my code
below), but then again,  I can't catch it, and again there is a white screen
for the user.

What is need, I think, is to override onResourceRequested() in Resource, but
that is a final method... And the onclick happens after
onResourceRequested()...

So what I want, is to handle the ResourceStreamNotFoundException in a
user-friendly way, by showing an info or error message in the wicket
feedbackpanel.

The code:
(So the user enters an application code an presses the new button:)

<td><input type="button" wicket:id="downloadinstallationmanual"
value="Download Installatiehandleiding" /></td>

The button is counterparted by a ResourceLink in a Wicket-Form:

private Link<String> downloadInstallationmanualButton = null;

...

final InstallationManualWebResource installationManualWebResource = new
InstallationManualWebResource(this);
installationManualWebResource.setCacheable(false);
downloadInstallationmanualButton = new
ResourceLink<String>("downloadinstallationmanual",
installationManualWebResource);
downloadInstallationmanualButton.setOutputMarkupId(true);
add(downloadInstallationmanualButton);

The above mentioned
InstallationManualWebResource is a subclass of WebResource, and overrides
the usual methods:

    @Override
    public IResourceStream getResourceStream() {
       installationManualResourceStream = new
InstallationManualResourceStream(getZipInputStream());
       return installationManualResourceStream;
    }

    @Override
    protected void setHeaders(WebResponse response) {
        super.setHeaders(response);
        if (installationManualResourceStream.getInstallatieHandleidingName()
!= null)           
response.setAttachmentHeader(installationManualResourceStream.getInstallatieHandleidingName());
    }

At it's turn InstallationManualResourceStream implements IResourceStream:

In it's constructor, the zipinputstream is read until an installation manual
is found. If so, a boolean installationManualFound is set to true, and
file-attributes are set (name, size, time). The implementation is
straightforward:

@Override
    public void close() throws IOException {
       
        zipFile.close();
       
    }

    @Override
    public String getContentType() {
        return "application/msword";
    }

    @Override
    public InputStream getInputStream() throws
ResourceStreamNotFoundException {
        if (!installationManualFound) throw new
ResourceStreamNotFoundException("No installation manual in zipfile");
        return zipFile;
    }

    @Override
    public Locale getLocale() {
        return new Locale("nl", "NL");
    }

    @Override
    public long length() {
        return size;
    }

    @Override
    public void setLocale(Locale locale) {

    }

    @Override
    public Time lastModifiedTime() {
        return Time.milliseconds(time);
    }





--
View this message in context: http://apache-wicket.1842946.n4.nabble.com/How-to-Handle-ResourceStreamNotFoundException-tp3749331p3749331.html
Sent from the Users forum mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: How to Handle ResourceStreamNotFoundException

Posted by Dan Retzlaff <dr...@gmail.com>.
Hans,

Something like the following will probably work better for you. The key
concept is changing the request target. Sorry if my previous suggestion put
you down a dead end.

add(new Link<DeployVersion>("manualLink", deployVersionModel) {
@Override
public void onClick() {
IResourceStream manualStream = getManualStream(getModelObject());
if (manualStream == null) {
error("no manual, sorry!");
}
else {
RequestCycle.get().setRequestTarget(new
ResourceStreamRequestTarget(manualStream));
}
}
});

Regards,
Dan

On Thu, Aug 18, 2011 at 8:06 AM, hfriederichs <h....@ohra.nl> wrote:

> Firstly, thank you very much for your advice, it helps to a certain extend,
> but it also raises new questions.
>
> Unfortunately, there's only one way to determine whether a zip-file
> contains
> an installation manual. Since the zip-file is on another server (where the
> nexus repository resides), I have to read it from an InputStream. If there
> isn't an installation manual, this reading can take up to 10 seconds.
> Initially - when there's not a user entry yet, I can disable the
> download-button. But once an application code is entered, I only render
> meta
> information from all the zip-file versions, so the user can pick a desired
> version (usually the most recent build). Only when the form is submitted,
> or
> the new download button pressed, the corresponding zip-file is read, and
> only then I can determine whether it contains an installation manual. But I
> have to enable the button if there is a user entry. That can be a very
> disapointing user experience. He/she starts the appication, the button is
> disabled. He/she then enters an application code, en presses the now
> enabled
> button, only to find out that there isn't an installation manual...
>
> One question that comes to mind is: is my use case so exceptional? A button
> for a resource is pressed, all I want is a nice feedback in case a resource
> isn't available...
> Personally, I'm not a great fan of disabling or 'invisibling' buttons. I
> adhere to the five-year-old-boy-philosophy concerning buttons: you should
> /allways/ be able to press them, that's what buttons are for.
>
> Your alternative (using the RestartResponseException) solves the 'white
> screen-problem', but there are a few drawbacks:
> - The URL of my application after pressing the button changes from
> http://localhost:9081/deploy/ to
>
> http://localhost:9081/deploy/?wicket:interface=:3:deploytabs:panel:deployForm:downloadinstallationmanual::IResourceListener:
> :.
> I really like Wicket, but this is so annoying. Who wants this? I just want
> my original url back - and yes, I read all the posts on mount strategies.
> - What's worse, the user has entered an application code that generates
> other field values (like a dropdownlists for the versions). When the page
> is
> reloaded after a RestartResponseException, I want to initialize it with the
> afore entered data. I managed to do that using PageParameters (or the
> Session), but in that case the refresh button will always generate a
> 'prefilled' page, with the values of the lat entered application code.
>
> Regards, Hans Friederichs
>
> --
> View this message in context:
> http://apache-wicket.1842946.n4.nabble.com/How-to-Handle-ResourceStreamNotFoundException-tp3749331p3752826.html
> Sent from the Users forum mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

Re: How to Handle ResourceStreamNotFoundException

Posted by hfriederichs <h....@ohra.nl>.
Firstly, thank you very much for your advice, it helps to a certain extend,
but it also raises new questions.

Unfortunately, there's only one way to determine whether a zip-file contains
an installation manual. Since the zip-file is on another server (where the
nexus repository resides), I have to read it from an InputStream. If there
isn't an installation manual, this reading can take up to 10 seconds.
Initially - when there's not a user entry yet, I can disable the
download-button. But once an application code is entered, I only render meta
information from all the zip-file versions, so the user can pick a desired
version (usually the most recent build). Only when the form is submitted, or
the new download button pressed, the corresponding zip-file is read, and
only then I can determine whether it contains an installation manual. But I
have to enable the button if there is a user entry. That can be a very
disapointing user experience. He/she starts the appication, the button is
disabled. He/she then enters an application code, en presses the now enabled
button, only to find out that there isn't an installation manual...

One question that comes to mind is: is my use case so exceptional? A button
for a resource is pressed, all I want is a nice feedback in case a resource
isn't available...
Personally, I'm not a great fan of disabling or 'invisibling' buttons. I
adhere to the five-year-old-boy-philosophy concerning buttons: you should
/allways/ be able to press them, that's what buttons are for.

Your alternative (using the RestartResponseException) solves the 'white
screen-problem', but there are a few drawbacks:
- The URL of my application after pressing the button changes from
http://localhost:9081/deploy/ to
http://localhost:9081/deploy/?wicket:interface=:3:deploytabs:panel:deployForm:downloadinstallationmanual::IResourceListener::.
I really like Wicket, but this is so annoying. Who wants this? I just want
my original url back - and yes, I read all the posts on mount strategies.
- What's worse, the user has entered an application code that generates
other field values (like a dropdownlists for the versions). When the page is
reloaded after a RestartResponseException, I want to initialize it with the
afore entered data. I managed to do that using PageParameters (or the
Session), but in that case the refresh button will always generate a
'prefilled' page, with the values of the lat entered application code.

Regards, Hans Friederichs

--
View this message in context: http://apache-wicket.1842946.n4.nabble.com/How-to-Handle-ResourceStreamNotFoundException-tp3749331p3752826.html
Sent from the Users forum mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: How to Handle ResourceStreamNotFoundException

Posted by Dan Retzlaff <dr...@gmail.com>.
Can you determine whether the zipfile contains an installation manual before
you show the user a link for it? If there is no manual, don't show the link
(or show something else). That seems like a better user experience and
simplifies the resource implementation.

Alternatively, in your resource request handling try using
RestartResponseException (instead of ResourceStreamNotFoundException) to
redirect them back to the original page, after using
Session.get().error("...") to generate a feedback message.

On Wed, Aug 17, 2011 at 12:43 AM, hfriederichs <h....@ohra.nl>wrote:

> Hello to you all,
>
> First of all, I apologise for submitting this post for the second time, but
> the first didn't use the correct user group.
>
> I'm adding a new feature to a Wicket application that manages
> JEE-applications (I'm using 1.4.18). For example, it's possible to install
> and configure a JEE-appliation on an Application server. If a user chooses
> to do so, he enters a unique application code and submits: a zipfile
> containing the application, it's documentation and configuration is
> downloaded via http from a Nexus repository, and installed with
> soap/jmx/mbeans on the application server.
>
> What I have added, is a button that - once clicked - opens an installation
> manual in msword that is part of the aforementioned zipfile. The general
> idea is: take a zipinputstream, read it until the installation manual is
> found, then hand the inputstream over to a wicket IResourceStream that
> provides the getInputStream for a Wicket WebResource. I think it's a quite
> elegant solution; it's all streaming, no temporary files etcetera.
> And it works marvelously, that is, if the zipfile actually containes a
> installation manual. My problem is twofold:
> When pressing the button without entering an application code (so there is
> no inputstream and no installation manual) wicket produces:
> org.apache.wicket.WicketRuntimeException: Could not get resource stream
>        at org.apache.wicket.Resource.init(Resource.java:217)
>        at org.apache.wicket.Resource.onResourceRequested(Resource.java:117)
>        at
>
> org.apache.wicket.markup.html.link.ResourceLink.onResourceRequested(ResourceLink.java:108)
>        ... 36 more
> That's to be expected, but the user is confronted with a white screen, and
> I
> can't catch this Exception.
> Secondly, if there is a zipinputstream, but no installation manual found in
> it, all I can do is throw a ResourceStreamNotFoundException (see my code
> below), but then again,  I can't catch it, and again there is a white
> screen
> for the user.
>
> What is need, I think, is to override onResourceRequested() in Resource,
> but
> that is a final method... And the onclick happens after
> onResourceRequested()...
>
> So what I want, is to handle the ResourceStreamNotFoundException in a
> user-friendly way, by showing an info or error message in the wicket
> feedbackpanel.
>
> The code:
> (So the user enters an application code an presses the new button:)
>
> <td><input type="button" wicket:id="downloadinstallationmanual"
> value="Download Installatiehandleiding" /></td>
>
> The button is counterparted by a ResourceLink in a Wicket-Form:
>
> private Link<String> downloadInstallationmanualButton = null;
>
> ...
>
> final InstallationManualWebResource installationManualWebResource = new
> InstallationManualWebResource(this);
> installationManualWebResource.setCacheable(false);
> downloadInstallationmanualButton = new
> ResourceLink<String>("downloadinstallationmanual",
> installationManualWebResource);
> downloadInstallationmanualButton.setOutputMarkupId(true);
> add(downloadInstallationmanualButton);
>
> The above mentioned
> InstallationManualWebResource is a subclass of WebResource, and overrides
> the usual methods:
>
>    @Override
>    public IResourceStream getResourceStream() {
>       installationManualResourceStream = new
> InstallationManualResourceStream(getZipInputStream());
>       return installationManualResourceStream;
>    }
>
>    @Override
>    protected void setHeaders(WebResponse response) {
>        super.setHeaders(response);
>        if (installationManualResourceStream.getInstallatieHandleidingName()
> != null)
>
> response.setAttachmentHeader(installationManualResourceStream.getInstallatieHandleidingName());
>    }
>
> At it's turn InstallationManualResourceStream implements IResourceStream:
>
> In it's constructor, the zipinputstream is read until an installation
> manual
> is found. If so, a boolean installationManualFound is set to true, and
> file-attributes are set (name, size, time). The implementation is
> straightforward:
>
> @Override
>    public void close() throws IOException {
>
>        zipFile.close();
>
>    }
>
>    @Override
>    public String getContentType() {
>        return "application/msword";
>    }
>
>    @Override
>    public InputStream getInputStream() throws
> ResourceStreamNotFoundException {
>        if (!installationManualFound) throw new
> ResourceStreamNotFoundException("No installation manual in zipfile");
>        return zipFile;
>    }
>
>    @Override
>    public Locale getLocale() {
>        return new Locale("nl", "NL");
>    }
>
>    @Override
>    public long length() {
>        return size;
>    }
>
>    @Override
>    public void setLocale(Locale locale) {
>
>    }
>
>    @Override
>    public Time lastModifiedTime() {
>        return Time.milliseconds(time);
>    }
>
>
>
>
>
> --
> View this message in context:
> http://apache-wicket.1842946.n4.nabble.com/How-to-Handle-ResourceStreamNotFoundException-tp3749331p3749331.html
> Sent from the Users forum mailing list archive at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

Re: How to Handle ResourceStreamNotFoundException

Posted by hfriederichs <h....@ohra.nl>.
Hi Dan,

This is /exactly/ what I was looking for! A simple solution for a simple
problem. I used a (subclass) of a WebResource before for another use case,
and that worked fine, so I got blinded by wanting to reuse the same
solution, at least that is what I think has happened. Whatever.

Thank you very much for your interest and help.

Regards, Hans

--
View this message in context: http://apache-wicket.1842946.n4.nabble.com/How-to-Handle-ResourceStreamNotFoundException-tp3749331p3754846.html
Sent from the Users forum mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org