Is Representation in acceptRepresentation == Request.getEntity() ?

2009-08-04 Thread Paul J. Lucas
If I am implementing:

public void acceptRepresentation( Representation rep ) {
// ...
}

Is using that "rep" exactly the same as if I had instead done:

Representation rep1 = getRequest().getEntity();

?  Is the "rep" being passed to acceptRepresentation() just a  
convenience?

- Paul

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2380079


Form parsing doesn't work

2009-02-18 Thread Paul J. Lucas
I have a bit of code that processes a multipart/form-data form.  I'm  
sending a test request using curl, e.g.:

curl -v -F "from=paul%40lucasmail.org" "http://localhost:8182/foo";

I have code that parses the form that starts off with:

final MediaType mediaType = request.getEntity().getMediaType();
final Form form =
MediaType.APPLICATION_WWW_FORM.equals( mediaType, true ) ||
MediaType.MULTIPART_FORM_DATA.equals( mediaType, true ) ?
request.getEntityAsForm() :
request.getResourceRef().getQueryAsForm();

The form data isn't parsed correctly: the one and only name is the  
boundary string.  The FormReader class doesn't seem to handle  
multipart/form-data.

I'm using an older Restlet version (1.0.9), but I tried upgrading to  
1.1.2 and it makes no difference.

How to I parse multipart/form-data forms correctly?  (Preferably using  
1.0.9.)

- Paul

--
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=1188665


ERROR: 'Broken pipe'

2008-11-17 Thread Paul J. Lucas

I've been seeing a lot of:

ERROR:  'Broken pipe'
Exception intercepted @ HttpServerConverter.commit

lately.  What exactly does it mean?  How can I print out the  
exception?  And possible how to debug this?


I'm using Restlet 1.0.9.

- Paul


Re: Knowing if a client disconnected?

2008-08-13 Thread Paul J. Lucas

On Aug 13, 2008, at 10:26 AM, Jerome Louvel wrote:


The closest you'll find in the Restlet API is the
org.restlet.service.ConnectorService class that has two callback  
methods:

- beforeSend(Representation entity)
- afterSend(Representation entity)

Maybe we could introduce a new call-back method "onSendError(...)"  
that

would inform you about the failed response and the reason for failure.


So you're saying there's no way to know *now* with the API as it  
currently is?  It would be nice to know *now*.


- Paul


Re: Knowing if a client disconnected?

2008-08-13 Thread Paul J. Lucas

On Aug 13, 2008, at 9:53 AM, Jerome Louvel wrote:

If the socket is broken or was closed by the client while the  
response is
written, you won't be able to "restore" it. However, you can log the  
fact
the you got this request from this client and wait for the client to  
retry

its request.


OK, but my question was: how do I *know* it actually happened?

- Paul


Knowing if a client disconnected?

2008-08-12 Thread Paul J. Lucas
Suppose I have  a service that takes some time to compute the response  
to.  Further suppose that a client connects but then disconnects  
prematurely for whatever reason either before I start or while I am  
returning a response.  Is there any way to know if the client is  
really still there and connected?


- Paul


Any interest in a DTO class?

2008-08-07 Thread Paul J. Lucas
I wanted a simple way to get the values of request parameters into an  
Object.  I've implemented a DTO (Data Transfer Object) class that can  
be used for this.


Suppose you want to implement a query request.  You could do something  
like:


public class QueryDTO extends DTO {
@Required public String q;
public SortOrder order; // SortOrder is enum { NAME, DATE, SIZE }
public Boolean desc;

QueryDTO( Request request ) throws DTOException {
super( request );
if ( order == null ) order == SortOrder.NAME;
if ( desc == null ) desc = Boolean.FALSE;
}
}

What this says is that a request has 3 query parameters.  Of those,  
"q" is a required String.  The DTO constructor takes care of all the  
parsing of form data (for both APPLICATION_WWW_FORM and  
MULTIPART_FORM_DATA cases), enforces @Require constraints, and handles  
enum values.  You can then use it like:


public void handleGet() {
try {
QueryDTO dto = new QueryDTO( getRequest() );
// ... use dto.{members} as you please ...
}
catch ( DTOException e ) {
e.setStatusOf( getResponse() );
}
}

DTO also correctly handles array values.  For example, specifying:

public String[] field;

allows "field" to be specified more than once:

http://server/foo?field=val1&field=val2&;...

There are also @Permitted and @Forbidden annotations.  For example:

@Permitted( onlyIf={"y"} )
public Integer x;

@Permitted( onlyIf={"x"} )
public Integer y;

This will cause DTO to throw an exception if either "x" or "y" is  
given without the other.  (@Forbidden works similarly, but in reverse.)


If there's interest, I'd be willing to donate this code to Restlet.

- Paul



Re: Hanging on ServerSocket.accept()

2008-07-07 Thread Paul J. Lucas

On Jul 4, 2008, at 3:57 AM, Jerome Louvel wrote:


What do you mean by launching 1/10 times?


I mean that the problem only manifests immediately after launch (if it  
manifests at all).  The problem never manifests if the software has  
been running OK for a while (meaning it has been servicing requests).



Do you stop and restart the application?


Yes.


Do you do this using Component#start() and stop() methods ...


Yes.


and differently?


I don't know what you mean by that.

It is important to cleanly shutdown your server connector in order  
to quickly release the open sockets.


It's not that the server can not *bind* to the socket -- it does.   
(The problem I assume you are referring to is the SO_LINGER option on  
the socket.)


It binds, listens, and does an accept -- and it hangs on the accept.

Did you looked at the list of open TCP/IP sockets under Windows? You  
can try

'netstat -n' for example.


I know the socket is open and accepting because I can telnet to the  
port.  Both the telnet client and server hang.


- Paul


Hanging on ServerSocket.accept()

2008-07-03 Thread Paul J. Lucas
When launching my application, perhaps 1/10 times, the underlying web  
server gets stuck in ServerSocket.accept().  This happens only when  
run under Windows and only for one of our users.  (The user had turned  
off all firewall and virus software.)  The thing that concerns me is  
how wide-spread the problem is.  (Our product is not yet released.)   
The problem has never been observed to happen under Mac OS X.


We have been using the Simple web server.  I tried replacing it with  
Jetty, but the same thing happens.


Has anybody else experienced something like this or have any  
suggestions?


- Paul


Re: Series.getValues()

2008-03-24 Thread Paul J. Lucas

On Mar 23, 2008, at 10:50 AM, Jerome Louvel wrote:

Paul, the Series class address the lack of a structure maintaining a  
list of
named entries. There is no reusable Parameter class (name, value  
pair) in
the JDK. Only the Map.Entry interface comes close to it. Having  
just a
List (via ArrayList or similar) is good but doesn't  
provide any

facility to lookup the structure by parameter name (like the
getValuesArray(name) method you were looking for). This is what the  
Series
class adds in addition of being a List. I hope that makes  
sense.



You can use List if you write more generic utility classes:

public interface CollectionFilter {
boolean accept( T obj );
}

public final class CollectionUtil {

public static  Collection filter( Collection in,
Collection out,
 
CollectionFilter filter ) {

for ( T x : in )
if ( filter.accept( x ) )
out.add( x );
return out;
}
}

Then you just implement CollectionFilter:

public ParameterNameFilter implements CollectionFilter {
public ParameterNameFilter( String name ) {
m_name = name;
}
public boolean accept( Parameter p ) {
return p.getName().equals( m_name );
}
private final String m_name;
}

Finally:

List fooParams = CollectionUtil.filter(
in, new LinkedList, new ParameterNameFilter( "foo" )
);

The bonuses are:

1. The "Series" class doesn't "leak" into places that shouldn't have a  
dependency on it since you're using an ordinary List.


2. The solution above is completely generic and can be used for lots  
of other stuff.


If you want, you can add other "Util" methods that are convenience  
methods to lessen typing.


- Paul


Re: Series.getValues()

2008-03-22 Thread Paul J. Lucas

On Mar 22, 2008, at 11:16 AM, Stephan Koops wrote:

Since we have java.util.List. Ok, sometime it is useful to ue  
arrays, but IMO in the most cases the list is the better solution.  
Typically you collect the result in a List, because you don't know  
the result size. Than you perhaps convert it to an array. So it is  
not faster to return arrays. The only argument for arrays are for  
me, that they are faster.



I don't have that strong opinions on List vs. arrays.  My only point  
was saying that Java arrays are not "legacy".



Series is also a List. you can handle it as List.


Yes, I know.  I simply don't see that Series solves any particular  
problem and hence why it's necessary.  IMHO, it would have been  
simpler and cleaner just to use List directly which every Java  
programmers knows how to use already.


- Paul


Re: Series.getValues()

2008-03-22 Thread Paul J. Lucas

On Mar 22, 2008, at 4:21 AM, Stephan Koops wrote:


is it necessary to use the legacy datatype array?


Since when is an array a "legacy datatype"?  (If this were C++ instead  
of Java, that question would have more merit.)


I think never the Series deals with arrays. What about returning  
Series?


I prefer simpler APIs.  Your suggestion means I have to understand  
what a Series is, why it's supposedly better than either an array or a  
Collection, and how I have to use it.


In Restlet, I don't even really understand what problem all the  
Wrapper classes solve, never mind Series.  To me, it's a lot of code  
one either has to maintain or learn about for very little (if any)  
benefit.  IMHO, Restlet should be a reference implementation of REST,  
not an exercise in how to tweak the Java collections API.


- Paul


Series.getValues()

2008-03-20 Thread Paul J. Lucas
Sorry if this is a duplicate, but I never say my original message echo  
to the list.


Begin forwarded message:
Date: March 19, 2008 4:19:32 PM PDT
To: discuss@restlet.tigris.org
Subject: Series.getValues()

This method, as written in Restlet 1.0.8, specifically this variant:

getValues(String name, String separator, boolean ignoreCase)

has room for improvement.  Aside from the fact that the ignoreCase  
parameter is not used, globbing the values together with a separator  
is not that useful.  I really want:


String[] getValues(String name)

with an implementation like:

   public String[] getFormValues( String paramName ) {
   final List temp = new LinkedList();
   for ( Parameter param : this )
   if ( param.getName().equalsIgnoreCase( paramName ) )
   temp.add( param.getValue() );
   return temp.toArray( new String[ temp.size() ] );
   }

- Paul



Re: Root URIs under Windows

2008-03-11 Thread Paul J. Lucas

On Mar 11, 2008, at 9:46 AM, Jerome Louvel wrote:

Actually, there is already a paragraph on this in the Javadocs (1.1  
M2) at
the class level, but not for each getter. I have just added a note  
to each

getter returning encoded strings.


Thanks.

I meant that it might 'clutter' the class to add "getDecoded***()"  
methods.


Yes, but I prefer to err on the side of points of use rather than  
class definition.  By that I mean that if getDecoded*() methods are  
not defined, then every use of get*() methods where one wants decoding  
requires something like:


path = Reference.decode( ref.getPath() );

which is more verbose than:

path = ref.getDecodedPath();

The "clutter", instead of being hidden away in the source file of  
Reference.java, is now dispersed to every use of the functions.


- Paul


Re: Root URIs under Windows

2008-03-10 Thread Paul J. Lucas

On Mar 10, 2008, at 10:22 AM, Jerome Louvel wrote:


We made the choice to keep the URI reference unchanged and to provide
Reference.decode()/encode() static methods instead.


Well, at least update the Javadoc so it specifically says that the  
strings returned are not decoded.


Now, maybe we could add getDecodedPath() and similar methods, but it  
might

crop the class. Any thought?


I think there's a language barrier here.  I don't know what "crop"  
means in this context.


- Paul


Re: Root URIs under Windows

2008-03-10 Thread Paul J. Lucas

On Mar 10, 2008, at 1:45 AM, Thierry Boileau wrote:


I've tested this code below with both Restlet 1.1 (snapshot) and
Restlet 1.0.8 and it works.
Could you tell us more about your code?


I have my own classes derived from Directory and DirectoryResource.  I  
override DirectoryResource.handleGet().  In handleGet(), I need to  
know what the Directory's "root directory" is so I call  
Directory.getRootRef().getPath().  The path it returns is URL-encoded,  
e.g., spaces are encoded as %20.  This is why my code fails (because  
it needs to be decoded first).


So the question is: should Reference.getPath() (and other get*()  
methods) return their component strings already decoded?  This would  
parallel URI.getPath().  If you really want the original form, there's  
URI.getRawPath() and there could correspondingly be  
Reference.getRaw*() methods.


- Paul


Re: Root URIs under Windows

2008-03-07 Thread Paul J. Lucas

On Mar 7, 2008, at 5:12 PM, cleverpig wrote:


   public Restlet createRoot(){
   final String
DIR_ROOT_URI="file:///E:/eclipse3.1RC3/workspace/RestletPractice/static_files/ 
";


Yes, I already know how to do the code.  That's not my question.  The  
differences between your example and mine are:


+ Yours has "file:///" whereas mine has "file:/"
+ Yours has no spaces encoded as %20.

I hacked my code and made it use "file:///" and it made no  
difference.  After some more experimentation, it seems the problem is  
the %20 characters.  To make a simpler test-case, I used a path like:


C:\tmp\sub_directory

When converted via File.toURI().toString(), I get:

file:/C:/tmp/sub_directory

and that works.  When I rename sub_directory so it has a space instead:

C:\tmp\sub directory

I get:

file:/C:/tmp/sub%20directory

And this causes Restlet not to work.  It seems like a bug to me.

- Paul


Root URIs under Windows

2008-03-07 Thread Paul J. Lucas
Does anybody use Restlet under Windows?  I want my server's root URI  
to be a directory like:


C:\Documents and Settings\pjl\My Documents\My Pictures\

That's held in a File variable.  I convert that to a URI then to a  
String like:


String rootURI = rootDir.toURI().toString();

That gives me a URI like:

file:/C:/Documents%20and%20Settings/pjl/My%20Documents/My%20Pictures/

but that doesn't work.  I get FileNotFound for all files.

What's the right way to use Windows' directories with Restlet?

- Paul


Restlet vs. Resource

2008-02-08 Thread Paul J. Lucas
Is there a guideline when one should extend Restlet vs. extens  
Resource?  My rationalization is that: if X represents some kind of  
"physical" resource, the one should extend Resource; if X represents  
some kind of service, e.g., a "search service," then one should  
extend Restlet.


Opinions?

- Paul


Re: Status class should have a Throwable field

2008-01-26 Thread Paul J. Lucas
OK, fine: then simply add a constructor that takes a Throwable as  
well as a getThrown() method.  Status can stay immutable.


- Paul


On Jan 26, 2008, at 1:06 PM, Stephan Koops wrote:


Hello Paul,

if I understood you right, than you want to add method to the class  
Status to save the exception in the status object. But the Status  
objects are immutable as all metadata. So this won't work.


best regards
  Stephan


Status class should have a Throwable field

2008-01-26 Thread Paul J. Lucas

I would like to be able to have code like:

try {
// ...
}
catch ( SomeException e ) {
response.setStatus( CLIENT_ERROR_BAD_REQUEST, e );
}

That is that you can pass a Throwable to setStatus() and that the  
Status class have the additional methods of:


void setThrown( Throwable t );
Throwable getThrown();

The default implementation of the response that gets returned to the  
client will simply do an:


t.getMessage()

and include that as the textual error message.  However, if I  
implement my own StatusService, I have full access to the exception.   
In my case, I'd like to return an XML entity containing an XML-ized  
version of the exception's stack trace.


- Paul


Re: Directory redirection issues

2008-01-21 Thread Paul J. Lucas

On Jan 21, 2008, at 1:32 PM, Jerome Louvel wrote:

1. How do I turn directory redirection off?  Specifically, if the  
request refers to a directory and the URI doesn't end in '/', it's  
OK for the server to add the '/' internally for processing, but I  
don't want it to issue a 303 response.


The problem that arise if you don't force a redirect is that all  
relative URIs served become harder to construct and read.


For example with the "/foo/bar" base URI, the "joe.html" relative  
URI resolves to "/foo/joe.html" instead of the expected "/foo/bar/ 
joe.html" because the browser has no way to know that "/foo/bar" is  
corresponding to a directory.


I understand the problem.  I'm not saying "don't add the '/' at the  
end"; I'm saying have a flag that silently adds it internally without  
doing an explicit redirect.  In the cases where you set  
directoryRedirection to true, mutate the Request instead to append  
the '/' as if you did the redirection and the client sent you back a  
new request with the trailing '/'.


- Paul


Changing the root URI

2008-01-17 Thread Paul J. Lucas
So I create a Router, create some Directory instances with a given  
rootURI, and attach them to the router.


At some later time, I want to change what the rootURI is globally  
while the server is running.  In Directory, rootRef is private and  
there's no setRootRef() method.  Why not? Similarly, Application  
doesn't have a setRoot() method.  Why not?


How can I do what I want?  Right now it seems the only way would be  
to do something like call Router.getRoutes() and replace the list  
with new Directory instances.


- Paul


Directory redirection issues

2008-01-17 Thread Paul J. Lucas
In DirectoryResource, there's code that sets directorRedirection if  
the directory's URI doesn't end in '/' so that, when a request comes  
in for a directory and it doesn't end in '/', the server will issue a  
303 response.


1. How do I turn directory redirection off?  Specifically, if the  
request refers to a directory and the URI doesn't end in '/', it's OK  
for the server to add the '/' internally for processing, but I don't  
want it to issue a 303 response.


2. Even if I wanted to keep the redirection the way it is, the  
Location header is wrong. For a URL like:


/foo/bar

I get back:

Location: file:///disk/user/foo/bar/

The Location should be:

Location: http://foo/bar/

i.e., it should never return file URLs.  Why is it doing that and how  
can I get it to return what I would want?


- Paul

P.S.: This is using restlet 1.0.7.


Re: Bad implementation of Status error checking

2008-01-16 Thread Paul J. Lucas

On Jan 16, 2008, at 12:43 PM, Rob Heittman wrote:

The behavior of intermediaries, such as forward and reverse  
proxies, would be undefined in relation to a custom status code,  
which could lead to some really difficult-to-find problems.


Perhaps, but that shouldn't be for you to decree.  If a programmer  
wants to have his own status codes, let him; and let him accept the  
consequences as well.  Restlet is neither a server or a client: it's  
a framework for letting others write their own and as such, it should  
be as extensible as possible.


In my case, we're dealing with a custom server and a custom client  
that talk only to each other.  That, plus what Joshua Tuberville  
quoted from RFC 2616:


... applications MUST understand the class of any status code, as  
indicated by the first digit, and treat any unrecognized response  
as being equivalent to the x00 status code of that class



Note the use of the word "MUST".  Hence, Restlet is NOT in compliance  
with the RFC.  I would consider this a bug.


- Paul


Re: Bad implementation of Status error checking

2008-01-16 Thread Paul J. Lucas
Also, it seems that isSuccess() is wrong.  In reading RFC 2616, 1xx  
and 3xx codes are not errors, so they should be considered success  
codes, no?


- Paul


On Jan 16, 2008, at 10:09 AM, Paul J. Lucas wrote:

What if I want to make up my own Status codes?  The isSuccess() and  
is*Error() methods do explicit code checks.  Why?  Why isn't the  
implementation for, say, isSuccess() this:


return code >= 200 && code < 300;

?


Bad implementation of Status error checking

2008-01-16 Thread Paul J. Lucas
What if I want to make up my own Status codes?  The isSuccess() and  
is*Error() methods do explicit code checks.  Why?  Why isn't the  
implementation for, say, isSuccess() this:


return code >= 200 && code < 300;

?

- Paul

P.S.: And the boolean 'result' variable is so unnecessary.


Re: Directory

2008-01-14 Thread Paul J. Lucas

On Jan 14, 2008, at 10:49 AM, Valdis Rigdon wrote:

Why does it have to be a text representation?  What if I wanted to  
return a generated PNG image of the file names instead as the  
index?  I realize that building a zip of the contents isn't exactly  
an "index", but requiring a text representation just seems limiting.


It is.  I wanted to return an XML representation.  The representations  
should be pluggable and none of them should be hard-coded into  
Directory or DirectoryResource.


- Paul


Re: Aborting request in Filter

2008-01-13 Thread Paul J. Lucas

Sorry for not commenting earlier, but

Anyway, in thinking about this more, I don't think a filter should  
have any knowledge of its next filter.  When a request is received,  
the engine should have a list of filters, i.e., the list itself  
should be external to all the filters.


So, currently, you have:

Request -> F1 -> F2 -> ... -> Fn

I would prefer:

Request -> L1 -> L2 -> ... -> Ln

where Li is a node in a linked list and the element type of the list  
is Filter.  However, once you do that, there is no longer a need for  
Filter as a separate class: it's just an ordinary Restlet.   
Furthermore, whether a filter is "before" or "after" depends only on  
where it is in the list and is also not a property of a filter.  (If  
I wanted a single instance of some filter to be both before and  
after, I would simply insert the same instance twice in the list at  
different places.)


As for whether to continue upon error, each Restlet, upon insertion  
into the list, Restlet could have a method like:


boolean acceptStatus( Status s ) {
return s.isSuccess();
}

Hence, the default would be to abort continuation down the list of  
Restlets; however, if a Restlet wants to filter error responses, it  
would simply override acceptStatus().


- Paul


On Jan 13, 2008, at 6:51 AM, Jerome Louvel wrote:


Here are the details of the change:

"Filter.beforeHandle() and doHandle() methods can now indicates if the
processing should continue normal, go to the afterHandle() method  
directly

or stop immediately.

IMPORTANT NOTE: as it isn't possible to add a return parameter to an
existing method, the change can break existing filters. In this  
case, you
just need to return the "CONTINUE" constant from your method and  
use "int"

as return parameter."



Re: Aborting request in Filter

2008-01-10 Thread Paul J. Lucas
By the way, in the doHandle() method, if there isn't a next Restlet,  
the method sets the response to CLIENT_ERROR_NOT_FOUND.  Shouldn't  
that be SERVER_ERROR_INTERNAL because the programmer goofed by not  
setting a next Restlet?


- Paul


Re: Shutting down a server

2008-01-10 Thread Paul J. Lucas
I switched to using Jetty and I had the same problem -- the process  
didn't terminate. So I figured out that it was my fault by creating a  
deadlock.  I removed that and now the process terminates when calling  
System.exit(0).  So then I went and tried Simple again and it too now  
terminates.


I then tried removing the call to System.exit(0) to see if the  
process would exit naturally.  It doesn't with Simple and does with  
Jetty.  Hence, the bug with Simple seems confirmed.


Hypothetically, if I wanted to continue to use Simple, it is OK to  
call System.exit(0) and still terminate "gracefully"?


- Paul


On Jan 10, 2008, at 5:31 AM, Kevin Conaway wrote:

Bug the Simple developers.  I am absolutely astonished that they  
don't provide a clean way to shut down their server.


On Jan 10, 2008 2:59 AM, Paul J. Lucas < [EMAIL PROTECTED]> wrote:
Well, I just tried calling System.exit(0) and nothing happens: the
process doesn't exit.  FYI: I'm using the Simple HTTP server.  There
are a bunch of threads stuck in wait().

How can I shutdown the server and cause the process to exit?

- Paul


On Jan 9, 2008, at 11:43 PM, Paul J. Lucas wrote:

> When I start my server, I have:
>
>   component = new Component();
>   // ...
>   component.start();
>
> To shutdown a server, I assume I do:
>
>   component.stop();
>
> However, the process doesn't stop.  Should I then simply do:
>
>   System.exit( 0 );
>
> ?



Re: Aborting request in Filter

2008-01-10 Thread Paul J. Lucas
Well, if you want to post-process a request in error, you need to  
distinguish that case from the case where you don't want to post- 
process in error.


Another problem is that the current doHandle() calls next.handle()  
and that doesn't return a boolean to indicate whether to do post- 
processing in error.  So, even if you make doHandle() return a  
boolean, it's not clear what you return since it has no way to know  
whether it should continue (unless it checks the Status code).


There's also the case where, even if you return false from  
beforeHandle(), you might still want to call afterHandle(), no?


So if you really wanted to cover all cases, you'd have to do  
something like:


boolean beforeSucceeded = beforeHandle( request, response );
if ( beforeSucceeded )
doHandle( request, response );
afterHandle( beforeSucceeded, request, response );

If you don't want to post-process, then the implementation of  
afterHandle() can check the Status code itself and do nothing on error.


The added parameter of beforeSucceeded to afterHandle() would be  
needed to distinguish the case where beforeHandle() failed (and thus  
doHandle() was never called) vs. doHandle() failing.


- Paul


On Jan 10, 2008, at 12:08 AM, Jerome Louvel wrote:

You expose a good use case. The solution below has some drawbacks  
because you might want to post-process a request in error, for  
example to add a status representation like the StatusFilter do in  
NRE. Even the proposed test on doHandle() could be limiting (even  
if it does solve your issue).


Here is what I propose : let's add boolean return parameters to  
beforeHandle() and doHandle() that will determine whether the  
processing should continue with doHandle() or afterHandle()  
respectively. We can make this backward compatible easily and add  
it to 1.1 M2.


How does it sounds?


Re: Shutting down a server

2008-01-10 Thread Paul J. Lucas
Well, I just tried calling System.exit(0) and nothing happens: the  
process doesn't exit.  FYI: I'm using the Simple HTTP server.  There  
are a bunch of threads stuck in wait().


How can I shutdown the server and cause the process to exit?

- Paul


On Jan 9, 2008, at 11:43 PM, Paul J. Lucas wrote:


When I start my server, I have:

component = new Component();
// ...
component.start();

To shutdown a server, I assume I do:

component.stop();

However, the process doesn't stop.  Should I then simply do:

System.exit( 0 );

?


Shutting down a server

2008-01-09 Thread Paul J. Lucas

When I start my server, I have:

component = new Component();
// ...
component.start();

To shutdown a server, I assume I do:

component.stop();

However, the process doesn't stop.  Should I then simply do:

System.exit( 0 );

?

- Paul


Re: Aborting request in Filter

2008-01-09 Thread Paul J. Lucas

At a minimum, handle() should be something like:

public void handle( Request request, Response response ) {
init( request, response );
beforeHandle( request, response );
if ( response.getStatus().isSuccess() ) {
doHandle( request, response );
if ( response.getStatus().isSuccess() )
afterHandle( request, response );
}
}

although I'd still prefer the use of exceptions.

- Paul


On Jan 9, 2008, at 10:23 PM, Paul J. Lucas wrote:

And to make matters worse, Filter.handle() is final, so I can't  
override it to fix it.  Sigh


On Jan 9, 2008, at 10:12 PM, Paul J. Lucas wrote:

If I write my own filter and use its beforeHandler(), I would like,  
upon some catastrophe, to abort the entire request and return some  
client error code.


Unfortunately, it doesn't appear that the API for Filter allows  
aborting a request.  True?


This is another good case for using exceptions.


Re: Aborting request in Filter

2008-01-09 Thread Paul J. Lucas
And to make matters worse, Filter.handle() is final, so I can't  
override it to fix it.  Sigh


- Paul

On Jan 9, 2008, at 10:12 PM, Paul J. Lucas wrote:

If I write my own filter and use its beforeHandler(), I would like,  
upon some catastrophe, to abort the entire request and return some  
client error code.


Unfortunately, it doesn't appear that the API for Filter allows  
aborting a request.  True?


This is another good case for using exceptions.


Aborting request in Filter

2008-01-09 Thread Paul J. Lucas
If I write my own filter and use its beforeHandler(), I would like,  
upon some catastrophe, to abort the entire request and return some  
client error code.


Unfortunately, it doesn't appear that the API for Filter allows  
aborting a request.  True?


This is another good case for using exceptions.

- Paul


Re: The alphanum algorithm

2007-12-19 Thread Paul J. Lucas

On Dec 19, 2007, at 10:50 AM, Rob Heittman wrote:

Specifically because this is a pretty straightforward idea to  
implement, it's likely that any version I type in is going to look  
substantially similar to what the original author typed in.  Is the  
fact that I typed it with reference to the idea, instead of  
actually bitwise copying it from an implementation, enough to  
satisfy copyright?


Again, as long as you didn't look at the original source, it's  
irrelevant what your code looks like (in theory).  FYI: copyright  
protects only the expression of an idea, not the idea itself.  To  
protect an idea itself, you need a patent.  However, algorithms  
aren't patentable.


I said "in theory" because if you were sued for copyright  
infringement and it turns out that your code looks astonishingly  
similar to the original, a jury might not believe you even if you  
truthfully didn't look at the original.


However, for such a small amount of code and, in the grand scheme of  
things, code that doesn't really matter, I doubt any author would  
spend lots of time and money suing you especially since, aside from  
preventing continued infringement on your part, he wouldn't gain  
anything (monetarily or otherwise, really).


- Paul


Re: The alphanum algorithm

2007-12-19 Thread Paul J. Lucas
How can I possibly know whether Rob looked at the code or not?  It  
wouldn't be lying if he didn't.  If he did, then somebody else who  
hasn't looked at the code would need to volunteer to do it instead.


- Paul


On Dec 19, 2007, at 12:47 PM, David Koelle wrote:

But at this point, doing such a thing would amount to lying,  
wouldn't you agree?


Paul J. Lucas  mac.com> writes:

As long as you do a "clean room" implementation, i.e., you'd swear
under oath that you didn't look at the original code, it doesn't
matter how much it resembles the original.


Re: The alphanum algorithm

2007-12-19 Thread Paul J. Lucas

On Dec 19, 2007, at 11:13 AM, Rob Heittman wrote:

I have concerns about doing an independent implementation because  
it would likely bear substantial resemblance to yours.


As long as you do a "clean room" implementation, i.e., you'd swear  
under oath that you didn't look at the original code, it doesn't  
matter how much it resembles the original.


- Paul


Re: The alphanum algorithm

2007-12-19 Thread Paul J. Lucas

On Dec 19, 2007, at 8:57 AM, Jerome Louvel wrote:

However, there appear to be three authors/contributors, so we would  
need to get the agreement and JCA of all of them which complicates  
things a bit.


Given the algorithm description in English, just write the code  
yourself from scratch and the copyright issue becomes moot.  This  
algorithm isn't exactly rocket science.


- Paul


Limiting threads

2007-12-17 Thread Paul J. Lucas
Is it possible to limit the number of threads that Restlet uses/spawns  
in servicing requests?


- Paul


Restlet and Flickr

2007-12-05 Thread Paul J. Lucas
Has anybody done a Flickr client using Restlet?  If so, details  
appreciated.  Or, failing that, being pointed in the right direction  
on how to do it (what classes to derive from) would be good.


I've been looking at the Restlet code and the thing that strikes me  
as wrong is that the core classes have a small, finite number of  
authentication schemes hard-coded into them, e.g., NMTL and AWS.   
IMHO, there should be no authentication schemes hard-coded.  There  
should be an interface and instead a set of bundled ones, but there's  
no reason, for example, why SecurityUtils should know anything about  
the "X-Amz-Date" HTTP header.


- Paul


Re: Exceptions in general

2007-12-05 Thread Paul J. Lucas

On Dec 5, 2007, at 9:14 AM, Paul J. Lucas wrote:


On Dec 4, 2007, at 3:03 AM, Stian Soiland wrote:


On 12/3/07, Paul J. Lucas <[EMAIL PROTECTED]> wrote:


Funny, because java.io.FileNotFoundException is derived from
IOException.  So clearly there's precedent.


Did you notice the "io" package name? :-) The exceptions here are
about resources, not IO.


So what?  java.io.IOException means *any* exception with *any* I/O,  
be it file, socket, keyboard, courier pigeon, whatever.


If RestletException were to exist, then *any* exception with *any*  
resource, be it a file on a local disk, or some other abstract  
resource, would be appropriate.  Would calling it ResourceException  
make it make more sense to you?


I forgot to add the bit required for the mental leap: since some of  
the things you do with resources is serve them to the client (via  
GET), get new ones from the client (via POST), or update them (via  
PUT), then those -- almost always -- involve I/O of some kind.   
Therefore, it's not unreasonable to derive RestletException from  
IOException.


- Paul


Re: Exceptions in general

2007-12-05 Thread Paul J. Lucas

On Dec 4, 2007, at 3:03 AM, Stian Soiland wrote:


On 12/3/07, Paul J. Lucas <[EMAIL PROTECTED]> wrote:


Funny, because java.io.FileNotFoundException is derived from
IOException.  So clearly there's precedent.


Did you notice the "io" package name? :-) The exceptions here are
about resources, not IO.


So what?  java.io.IOException means *any* exception with *any* I/O,  
be it file, socket, keyboard, courier pigeon, whatever.


If RestletException were to exist, then *any* exception with *any*  
resource, be it a file on a local disk, or some other abstract  
resource, would be appropriate.  Would calling it ResourceException  
make it make more sense to you?


- Paul


Re: Lightweight alternative to Reference

2007-12-04 Thread Paul J. Lucas

On Dec 4, 2007, at 6:50 AM, Jerome Louvel wrote:

... we could still add a fluent ReferenceBuilder, which would  
be ... much faster as one single buffer would be necessary (with a  
status int flag).


I don't understand why some are obsessing about performance of  
building URIs.  It doesn't matter.  It's not a bottleneck.  Any  
performance gain is negligible.


- Paul


Re: Exceptions in general

2007-12-02 Thread Paul J. Lucas

On Dec 2, 2007, at 11:50 AM, Toby Thain wrote:


On 29-Nov-07, at 3:06 PM, Paul J. Lucas wrote:


On Nov 28, 2007, at 11:31 PM, Sumit Lohia wrote:

Also I can code against interfaces that know nothing about  
Restlets so don't
have to add 'throws RestletException' even though the  
implementation might

throw a derived exception like NotFoundException.


RestletException could conceivably be derived from IOException.   
An interface that didn't anticipate that an implementation might  
need to do some kind of I/O as part of said implementation wasn't  
designed with sufficient foresight, IMHO.


Maybe I misunderstood... But surely you can't mean an exception  
with semantics such as 'http resource not found' (or forbidden,  
etc) - because those are not i/o related but resource related.


Funny, because java.io.FileNotFoundException is derived from  
IOException.  So clearly there's precedent.


What kind of thing would a RestletException subclassed from  
IOException be used for?


The same things as if it weren't derived from IOException that have  
already been mentioned.  However, if it is derived from IOException,  
it will integrate better with existing APIs.


- Paul


Re: RESTClient

2007-11-30 Thread Paul J. Lucas

On Nov 30, 2007, at 6:05 AM, Lars Heuer wrote:


RESTClient is a Java platform client application to test RESTful
webservices. 


IMHO, command-line test tools are better because they're far more  
easily automated.  I just write Perl script wrappers around curl.


- Paul


Re: Lightweight alternative to Reference

2007-11-29 Thread Paul J. Lucas

On Nov 29, 2007, at 4:52 PM, Tim Peierls wrote:

Abstractly, though, would you rather see ReferenceBuilderException  
checked or unchecked in the following:


  try {
  Reference ref =  
ReferenceBuilder.appendBar("myBar").appendFoo("myFoo");

  // do something with ref
  } catch (ReferenceBuilderException e) {
  // myBad: foo must come before bar
  // clean up
  // ? throw e;
  }

Programmer was wrong -- this should be unchecked, right?


How do you know the programmer was wrong?  How does the implementor of  
ReferenceBuilder know whether the data was supplied by the programmer  
or the user of the program?  If the latter, it's the user who is wrong  
in which case the programmer must deal with that.  Therefore: checked  
exception.


In general, IMHO, you've got to have a really, really good reason to  
make an exception unchecked.  "Because it's easier" isn't a good reason.


- Paul


Re: Lightweight alternative to Reference

2007-11-29 Thread Paul J. Lucas

On Nov 29, 2007, at 4:32 PM, Rob Heittman wrote:

The warnings to the user (cough Checked Exceptions /cough) should  
come in when you try to confess the builder into a URI, Reference,  
or String and it doesn't contain enough pieces and parts to have  
meaning.


If, as the implementor, you want to be lazy, simply use java.net.URI  
to do the work using the:


URI(String scheme, String userInfo, String host, int port, String  
path, String query, String fragment)


constructor and reuse java.net.URISyntaxException as-is.  (There's no  
need to invent another exception when the one included in the JDK will  
work just fine.)


- Paul


Re: Lightweight alternative to Reference

2007-11-29 Thread Paul J. Lucas

On Nov 29, 2007, at 3:18 PM, Jerome Louvel wrote:

It could have methods starting with "append" like the StringBuilder  
class,

and follow the Reference naming convention. For example it could have:

 - appendScheme(String scheme)
 - appendSchemeSpecificPart(String ssp)
 - appendFragment(String fragment)
 - appendHierarchicalPart(String ssp)
 - appendAuthority(String authority)
 - appendPath(String path)
 - appendSegment(String segment)
 - appendMatrixParam(String name, String value)
 - appendQuery(String query)
 - appendQueryParam(String name, String value)


Except it's not "append": it's "insert into the right place" or "set".


It should force the reference to be built in the correct order so an
efficient StringBuilder could be used internally and should guide the
developer with clear warning messages when parts are not appended  
in the

right order.


Why should it enforce the order?  The burden should be on the  
implementor, not the user.  Don't use a StringBuilder: use simple  
fields:


class URI {
private String scheme;
private String host;
// ...
}

- Paul


Re: Exceptions in general

2007-11-29 Thread Paul J. Lucas

On Nov 29, 2007, at 6:30 AM, Tim Peierls wrote:

However, I don't have a concrete proposal, and I don't see an easy  
way to do this without breaking code for 1.1m1 users.


Personally, I'd prefer to break an API rather than have to live with  
a hacked API forever.  Since Restlet is currently a 1.x API, it's  
presumably in its infancy.  Now is the time to rework it to make it  
better even if it means breaking some people's code.  If they don't  
want to upgrade, well, they have the option of not doing so.


- Paul


Re: Exceptions in general

2007-11-29 Thread Paul J. Lucas

On Nov 28, 2007, at 11:31 PM, Sumit Lohia wrote:

I have done something similar in my project but the exception  
hierarchy is
unchecked. This allows me to use the same set of exceptions in my  
DAO code,
and Controller code and not have to add 'throws RestletException'  
everywhere.


The entire point of checked exceptions is that you catch and deal  
with them.  The problem with a lot of software is that programmers  
don't like dealing with errors because they're "a pain" or messy to  
deal with.  Well, dealing with the real world is often messy.


Unchecked exceptions should be reserved for truly "exceptional,"  
circumstances that can happen at any time.


Also, in this case, it's the Restlet framework that would have to  
catch them, not code you write (generally).


Also I can code against interfaces that know nothing about Restlets  
so don't
have to add 'throws RestletException' even though the  
implementation might

throw a derived exception like NotFoundException.


RestletException could conceivably be derived from IOException.  An  
interface that didn't anticipate that an implementation might need to  
do some kind of I/O as part of said implementation wasn't designed  
with sufficient foresight, IMHO.


I also have a StatusService that converts these exceptions to the  
appropriate HTTP error code and it works wonderfully.


That sounds like a good idea, however.

- Paul


Re: ConverterService architecture

2007-11-28 Thread Paul J. Lucas

The problems with this are:

1. I don't want a single converter object to convert more than one  
thing.  Each converter should convert exactly one thing.


2. Your code doesn't take into account the fact that Foo may be  
derived from Bar (and therefore might call the method you're not  
expecting).


- Paul


On Nov 28, 2007, at 3:12 PM, Kevin Conaway wrote:


You could do it via reflection:

import java.lang.reflect.*;
public class ConverterService {

public void convert(Object o) throws Exception{

for (Method m : getClass().getDeclaredMethods()) {
if (m.getName().equals("handle")) {
Class paramType = m.getParameterTypes()[0];
if (paramType.isInstance(o)) {
m.invoke(this, o);
}
}
}

}

public void handle(Foo foo) {
System.out.println("Converting foo");
}

public void handle(Bar bar) {
System.out.println("Converting bar");
}

public void handle(Baz baz) {
System.out.println("Converting baz");
}

public static void main(String [] args) throws Exception {
ConverterService c = new ConverterService();

c.convert(new Foo());
c.convert(new Bar());
c.convert(new Baz());
}
}

class Foo { }

class Bar { }

class Baz { }


Re: ConverterService architecture

2007-11-28 Thread Paul J. Lucas

On Nov 28, 2007, at 1:31 PM, Jason Terhune wrote:

I haven't actually tried this, but couldn't you just overload the  
toObject()
and toRepresentation() methods?  Doesn't Java do the work of  
choosing the

method with the most specific argument?

For example:
public class ConverterService extends ConverterService {
 public Foo toObject(FooRepresentation fr);

 public FooRepresentation toRepresentation(Foo f);
}


But the base class can't specify the infinite number of derived  
classes as arguments to an infinite number of methods.


- Paul


Re: Exceptions in general

2007-11-27 Thread Paul J. Lucas

On Nov 27, 2007, at 1:38 PM, Jerome Louvel wrote:

One advantage of using the response's status is that this  
information is

part of the uniform interface and can easily cross the JVM boundaries
without affecting the calling code.


I'm not quite sure what that means or why anyone would care about  
crossing JVM boundaries.  Can you elaborate?


If we used RestletExceptions 'in addition', we could break this  
uniformity

("a handle method given two parameters carrying all the communication
info"), having two ways to bubble up the same information.


But as it is now, it's like going back to programming in C where  
exiting from nested functions is tedious and error-prone.  For example:


public void handle( Request request, Response response ) {
// ...
T result = otherFunc( /* ... */, response );
if ( result == null ) {
// otherFunc() must have failed
return;
}
}

If otherFunc() can fail in one of several ways, well, in order to set  
the Response's status correctly, I have to pass the Response along.   
Upon return, I have to check the result explicitly for failure and  
return.


If RestletException existed, code such as the above is simplified,  
less tedious to write, and less error-prone.


Another example is the fact that connectors use various types of  
exceptions
(Simple, Jetty, etc.) so we would loose client code portability if  
these

exceptions weren't converted into uniform statuses.


Yes, the *Restlet* framework code would catch the exception and  
transform it into setting the status of the Response.  The point of  
any framework is to present an easier, more convenient API to the user  
than using the raw, underlying API directly.


A funny thing is that if I were to use J2EE's HttpServlet, the doGet()  
method is declared to throw ServletException.


- Paul


Re: ConverterService architecture

2007-11-26 Thread Paul J. Lucas

On Nov 26, 2007, at 2:33 AM, Jerome Louvel wrote:

Your suggestion regarding the map of ConverterService is  
interesting. However, how would you handle the reverse conversion  
(from Representation to Object) ?


Also using a map.  For both conversion directions, you allow for the  
possibility of subclasses, e.g.:


public class ConverterServiceMap extends ConverterService {
// ...

public Object toObject( Representation rep ) {
for ( Class c = rep.getClass(); c != Object.class;
  c = c.getSuperclass() ) {
final ConverterService cs = m_toObjMap.get( c );
if ( cs != null )
return cs.toObject( rep );
}
return super.toObject( rep );
}
}

Sometimes the list of available variants is closely related to the  
processing resource, so it may be that the Resource subclass is the  
best place to handle such conversions.


Sometimes, yes.  But other times, you could have several resources/ 
services that all share a common format so it would be nice to write  
the conversion in a single place.


My vote for now is to keep ConverterService deprecated in 1.1  
instead of refactoring it.


:-(

- Paul


Exceptions in general

2007-11-23 Thread Paul J. Lucas
Why doesn't the Restlet framework make more use of exceptions?  Why  
should I have to do something like this:


if ( /* disaster */ ) {
response.setStatus( CLIENT_ERROR_WHATEVER, "message" );
return;
}

when I could do something like this:

if ( /* disaster */ )
throw new RestletException( CLIENT_ERROR_WHATEVER, "message" );

if RestletException existed?  Why doesn't RestletException (or  
something like it) exist?


If this existed, then the Message.getEntityAs*() methods could be  
declared to throw it.  As it is, getEntityAsSax() catches and  
discards an IOException.  That doesn't seem good.


- Paul


Throwing exceptions in ConverterService methods

2007-11-23 Thread Paul J. Lucas
OK, so I want to convert an entity having the MediaType of  
TEXT_URI_LIST into an Object, say a List where each URL is an  
element of the list.  I derive from ConverterService and override  
toObject().  Inside that method, I want to read the representation  
line-by-line, so I call Representation.toStream() then use an  
InputStreamReader and a BufferedReader.


But what do I do about IOExceptions?  The toObject() method is  
declared to throw no exceptions.  Or if I catch the exceptions  
myself, I have no way to call setStatus() on the response to indicate  
that the conversion failed any why.


The ConverterService API doesn't seem that useable.

- Paul


ConverterService architecture

2007-11-23 Thread Paul J. Lucas
The current architecture of ConverterService is such that if I want  
to convert to/from an object of a given class, I subclass  
ConverterService.  Well, what if I want to convert to/from several  
classes?  In my subclass, I could do an:


if ( obj instanceof MyClass1 ) {
// ...
} else if ( obj instanceof MyClass2 ) {
// ...
} else ...

which is (a) tedious and (b) means I have to have my subclass know  
about lots of classes (bad design, IMHO).


So instead, why doesn't Application instead have a:

Map

so then the code to to conversion would look up the right  
ConverterService based on the class of the object being converted?


- Paul


Why not Reference.getQueryAsObject?

2007-11-23 Thread Paul J. Lucas
If Message.getEntityAsObject() exists, why doesn't  
Reference.getQueryAsObject() exist?  I want to turn a query (via a  
Form) into an Object using a ConverterService.  (I'm converting a  
query into an Object now, but doing it my own way since the framework  
apparently provides no "right way" of doing this.)


- Paul


Why can't empty directories be deleted?

2007-11-22 Thread Paul J. Lucas
In FileClientHelper.java, line 492, there's code that forbids the  
deletion of an *empty* directory.  Why?  Why not just delete it?


In the mean time, to be able to delete empty directories, do I have  
to override Recource.handleDelete()?


- Paul


Re: Implementing COPY and MOVE

2007-11-19 Thread Paul J. Lucas

On Nov 19, 2007, at 8:12 PM, Paul J. Lucas wrote:

I've figured out that to do this "right", yes: you do need to extend  
DirectoryResource.  The problem with that is that Engine insists on  
creating an instance of DirectoryResource and not an instance of  
one's derived class.  So that means one has to subclass Engine and  
then figure out how to get engineClassName in Engine.getInstance()  
be one's own derived class.  (Is there an easy way to do that?)   
Anyway, it seems like a lot of messy work.


I just discovered that Directory.findTarget() is what's used to create  
an instance of DirectoryResource.  OK, so if I derived from Directory  
and override findTarget(), I can return an instance of  
MyDirectoryResource that implements:


allowCopy()
allowMove()
handleCopy()
handleMove()

I then wrote MyDirectoryResource.copyOrMove():

private void copyOrMove( boolean isMove ) {
final Request request = getRequest();
final Response response = getResponse();

final String destHeader =
RestletUtil.getHeaderValue( request, "Destination" );
final String overwrite =
RestletUtil.getHeaderValue( request, "Overwrite" );
if ( destHeader == null || overwrite == null ) {
response.setStatus( CLIENT_ERROR_BAD_REQUEST );
return;
}

try {
new URI( destHeader );
}
catch ( URISyntaxException e ) {
response.setStatus( CLIENT_ERROR_BAD_REQUEST,  
e.getMessage() );

return;
}

final String serverRoot = MyServer.getServerRootDirectory();

final String sourcePath =  
request.getResourceRef().getRemainingPart();

final File sourceFile = new File( serverRoot + sourcePath );
if ( !sourceFile.exists() ) {
response.setStatus( CLIENT_ERROR_NOT_FOUND );
return;
}

Status successStatus = SUCCESS_CREATED;

final String id =  
request.getResourceRef().getBaseRef().getIdentifier();

String destPath = destHeader.substring( id.length() );
final File targetFile = new File( serverRoot + destPath );

if ( targetFile.exists() ) {
if ( !overwrite.equals( "T" ) ) {
response.setStatus(
CLIENT_ERROR_PRECONDITION_FAILED,
"Destination already exists and Overwrite is not  
'T'"

);
return;
}
if ( !targetFile.canWrite() ) {
response.setStatus(
CLIENT_ERROR_LOCKED,
"Destination can not be overwritten"
);
return;
}
successStatus = SUCCESS_NO_CONTENT;
}
try {
FileUtil.copyFile( sourceFile, targetFile );
if ( isMove )
sourceFile.delete();// TODO: check return value
response.setStatus( successStatus );
}
catch ( IOException e ) {
response.setStatus( SERVER_ERROR_INTERNAL,  
e.getMessage() );

}
}

This seems to work just fine.  Comments?

I'd prefer to leverage Directory's ability to transform an "http" URI  
into a "file" URI so I could easily transform destHeader into a  
LocalReference then call getFile() on it, but it's not clear how to do  
that.  How does one do that?


- Paul


Implementing COPY and MOVE (Was: Converting "http" to "file" scheme)

2007-11-19 Thread Paul J. Lucas

On Nov 19, 2007, at 6:51 AM, Rob Heittman wrote:

In my noodling with DAV method support, COPY and MOVE are especially  
challenging to implement. By extending Directory and friends, you  
can model a COPY as a GET and a PUT, and a MOVE as a GET, DELETE,  
and PUT, but this is messy, not atomic in the right ways, and not  
very performant. Really you need to have COPY and MOVE supported  
down through the client as well. This is a lot easier if you just  
check out trunk and hack on it, than by trying to extend everything  
and coerce Restlet to use the extended classes.


I've figured out that to do this "right", yes: you do need to extend  
DirectoryResource.  The problem with that is that Engine insists on  
creating an instance of DirectoryResource and not an instance of one's  
derived class.  So that means one has to subclass Engine and then  
figure out how to get engineClassName in Engine.getInstance() be one's  
own derived class.  (Is there an easy way to do that?)  Anyway, it  
seems like a lot of messy work.


Aside: Why does Engine have a lone createDirectoryResource() method at  
all?  It seems like overly-tight coupling.  Why isn't there an easier- 
to-alter Factor pattern for creating directory resources?


But something that would go a long way toward implementing COPY and  
MOVE would be simply to provide stubs for them, specifically:


1. Add COPY and MOVE to Method.
2. Add allowCopy() and allowMove() to Resource.

Of course, I'm a newbie.  Would doing just items 1 and 2 above be good  
enough to allow even a simple implementation of COPY and MOVE?


- Paul


Just using Simple?

2007-11-19 Thread Paul J. Lucas
Given what I want to do (described previously), I'm now wondering if I  
need to use Restlet at all.  I have been using Restlet on top of the  
Simple web server.  Given what I want to do, could I just get by using  
Simple directly and not use Restlet at all?  What does using Restlet  
buy me?


- Paul


Re: Converting "http" to "file" scheme

2007-11-19 Thread Paul J. Lucas

On Nov 19, 2007, at 6:51 AM, Rob Heittman wrote:


Or maybe Paul can figure out a way to do it without the mess.


Right now, I'm still trying to get my head around all this.  It's not  
totally clear to me when things should be a Restlet or a Resource;  
whether one should derive from Directory or DirectoryResource; what  
Helpers are exactly and when to use/derive from them.


For example, in my tinkering, I tried deriving from  
DirectoryResource.  I then attached MyResource to a router like:


router.attach( "/foo", MyResource.class );

The problem with that is that MyResource has no no-argument  
constructor (because DirecoryResource doesn't), so you get a  
NoSuchMethodException because the framework wants a no-argument  
constructor.  OK, so that's not the way to do anything.


For my application, I need to do 3 classes of things: simple file  
manipulation (create, delete, update, copy, move, i.e., WebDAV-like  
stuff); image manipulation (get, scale, convert, etc.); and image  
metadata (get, put).  In all cases, I need to convert http-style URLs  
to local file-style URLs.  Jerome mentioned that Directory does this,  
but it's unclear how to leverage that fact.


For example, the metadata part is sort-of simple.  Given a URL like:

http://server/metadata/path/to/image.jpg

when using GET, you should get an XML document back containing the  
metadata of the image rather than the image itself.  I'm guessing  
this can be done with a Filter (?).


Anyway, so it's unclear whether I'll be able to figure out how to  
implement COPY and MOVE without the mess.  (I do have to implement  
*something* to do copy/move.  Ideally, I'd like it to work just like  
WebDAV; but if I can't figure it out, I'll have to do something else.)


- Paul


Converting "http" to "file" scheme

2007-11-18 Thread Paul J. Lucas

When a client specifies a URL like:

http://server/path/to/file

how do I convert that into a "file" URI:

file://localhost/path/to/root/path/to/file

?

The context is in trying to implement the "Destination" header for a  
WebDAV COPY or MOVE method.  The client specifies the destination as  
an absolute URI.  Obviously I need to map it to the local filesystem.


- Paul


One Directory for entire tree?

2007-11-18 Thread Paul J. Lucas
I was playing around with trying to derive from Directory to  
implement the WebDAV COPY and MOVE methods.  (How feasible is that?)   
One of the first things I did was to call setModifiable() based on  
whether the directory is actually writable (File.canWrite()).  This  
worked fine.


I then wondered about subdirectories.  It seems that the single  
instance of Directory is used for all directories and files under the  
root and therefore isModifiable() returns the status of the root  
directory for all subdirectories and files.  That seems wrong.  Why  
isn't a new instance of Directory created for every subdirectory and  
file so each will return whether *it* is modifiable?


Currently, if isModifiable() returns false during the handling of a  
DELETE method, the status is (correctly) METHOD_NOT_ALLOWED.  But for  
all subdirectories and files, the status is (incorrectly, IMHO)  
INTERNAL_SERVER_ERROR.  The status of METHOD_NOT_ALLOWED should be  
returned for *any* directory or file if it's not modifiable.


- Paul


Restlet 1.2 (Was: Easier way to get an HTTP header?)

2007-11-18 Thread Paul J. Lucas

On Nov 17, 2007, at 2:42 PM, Rob Heittman wrote:


It, and other "full WebDAV" stuff is targeted to land in Restlet 1.2.


When is 1.2 targeted to be released?

- Paul


Re: Easier way to get an HTTP header?

2007-11-17 Thread Paul J. Lucas

On Nov 17, 2007, at 2:42 PM, Rob Heittman wrote:


The non-standard header mechanism is the way to go for Destination:
and Overwrite: and such for the moment.


By which you mean the way I've already shown in code?  Or something  
else?


- Paul


Re: Easier way to get an HTTP header?

2007-11-17 Thread Paul J. Lucas

On Nov 17, 2007, at 12:28 PM, Rob Heittman wrote:


Which header do you need specifically (or what information are you
trying to convey)?  There may be a less clunky way to do it.


In addition to everything else I've outlined, I want to implement the  
WebDAV COPY and MOVE methods that take the Destination and Overwrite  
headers.


- Paul


Easier way to get an HTTP header?

2007-11-17 Thread Paul J. Lucas

To get the value of an HTTP header, it seems as though I have to do:

Form f = (Form)request.getAttributes().get( ATTRIBUTE_HEADERS );
String value = f.getFirstValue( "MyHeader" );

That seems rather... cumbersome.  Is there an easier way?

- Paul


Re: New user: guidance for server?

2007-11-15 Thread Paul J. Lucas

On Nov 15, 2007, at 1:24 PM, Rob Heittman wrote:

For the resizing and conversion operations, that's a larger question  
with some design decisions involved. Here, I think you are combining  
a command ("rescale image {uri-fragment} to maximum dimension {n}")  
with a resource retrieval operation (GET {uri-of-rescaled-image}).  
The approach I'd choose -- in fact, have chosen in actual  
implementations -- is to separate these steps.


Well, my thinking was that the original image is the resource and  
either a different scale or a different format is merely a different  
representation of the resource.  But you're saying to treat the  
original image as static and have a separate service (each with its  
own URL) that performs some transformation on the original image, yes?


FYI: my server will not rescale/reformat any image at any URL on the  
Internet, but instead will only rescale/reformat images it itself  
serves.


- Paul


Re: New user: guidance for server?

2007-11-15 Thread Paul J. Lucas

As I mentioned, I've already read the tutorial.

Perhaps I should elaborate further.  I'm not ONLY managing static  
files.  I also eventually want to have functionality for doing things  
like:


1. Thumbnail creation, i.e., rescale an image such that its largest  
dimension does not exceed N:


http://server/path/to/image.jpg&maxdimension=100

2. Image format conversion, e.g. original image is Canon RAW, client  
wants JPEG:


http://server/path/to/image.cr2&format=jpeg

3. Caching of items 1 & 2.

Regarding the suggestion to look at the Directory class, if I wanted  
to provide directory listings in XML, I assume then that I could  
derive from it and override getIndexRepresentation() and  
getIndexVariants(), yes?


- Paul


On Nov 15, 2007, at 11:02 AM, Rob Heittman wrote:



I think this is what you want:

http://www.restlet.org/documentation/1.0/tutorial#part06


- Original Message -
From: "Paul J. Lucas" <[EMAIL PROTECTED]>
To: discuss@restlet.tigris.org
Sent: Thursday, November 15, 2007 1:05:56 PM (GMT-0500) America/ 
New_York

Subject: New user: guidance for server?

Hi -

I'm new to Restlet.  I want to create a simple server that serves the
contents of directories and images in those directories.  URLs would
be as you would expect:

* Get contents of directory:
http://server/path/to/dir/

* Get image in directory:
http://server/path/to/dir/image.jpg

Additionally, clients would be able to create and delete new
directories and images therein.

I've read the tutorial, looked at sample code, and even read the
O'Reilly book, but it's still not clear what the "right" approach is.

One way is to have an ImageService class derived from Restlet and
attach this to the server's default host.  Another way is to have an
ImageResource class service derived from Resource and attach this to a
Router.  It's not clear to me which is the "right" way of doing what I
want.

Any guidance would be appreciated.  Thanks.

- Paul


New user: guidance for server?

2007-11-15 Thread Paul J. Lucas

Hi -

I'm new to Restlet.  I want to create a simple server that serves the  
contents of directories and images in those directories.  URLs would  
be as you would expect:


* Get contents of directory:
http://server/path/to/dir/

* Get image in directory:
http://server/path/to/dir/image.jpg

Additionally, clients would be able to create and delete new  
directories and images therein.


I've read the tutorial, looked at sample code, and even read the  
O'Reilly book, but it's still not clear what the "right" approach is.


One way is to have an ImageService class derived from Restlet and  
attach this to the server's default host.  Another way is to have an  
ImageResource class service derived from Resource and attach this to a  
Router.  It's not clear to me which is the "right" way of doing what I  
want.


Any guidance would be appreciated.  Thanks.

- Paul