Re: Some API related questions
Thanks Jerome for lending an ear. How can I best get to what you have already done? Should I wait for the next b-release or a nightly release (that would be cool)? I will need to change my classes now :) I will comment on/pursue these issues after I have used what's been done. Cheers Piyush On 8/9/06, Jerome Louvel [EMAIL PROTECTED] wrote: Hi Piyush, [..] Now we are talking taste here but I think Java packages aren't a very good example because some of them are there since jdk 1.0 and can't be refactored without breaking thousands of apps ..I am pretty sure that the Sun Java API gurus don't sleep easy at night :) Good argument, I buy that...and I do want to get some rest this night ;-) We are building something new here so we can be a little more adventurous. And my opinion is that having more packages isn't a sin packages are there to organize classes and help in avoiding to create cyclical dependencies .. I agree, it's a matter of finding the right balance between too many classes per packages and too many 'empty' packages. so a default package may be needed grouping all the default implementations .. or maybe another package hierarchy? I think I'd like to keep defaut/abstract implementations close to their interface. But I'm open to adapting the packages structure if needed. One thing I wanted to ask too was why do you have Enum implementing Interfaces? Is that something you saw being done someplace? Enums are Enums and by implementing interfaces you are trying to bridge the gap between Enum and Class that was created in 1.5 in order to make the distinction clear. My intent was to leverage the enumeration introduced in 1.5. So I started adding enums for methods, statuses, media types, etc. But then I realized that I couldn't enumerate all the potential media types, etc. So I thought about a way to allow usage of enums while preserving the extensibility. The only way I found was to introduce interfaces implemented by both enums and default classes. The problem is that I opened the Pandora box: if you get a media type, you can't switch it because you have to work from the interface... OK, I will refactor all this into single classes with static members for common values. That should greatly reduce the size of the data package. And I have seen some empty marker interfaces (Data and ControlData) and as per Joshua Bloch (and I totally agree) empty marker interfaces usually lead to problems later ... Good point, I was not initially sure if those REST concepts would need an equivalent Java artifact. For now, I've removed all of them and we'll see if/why we need them back down the road. Did you file a bug report on that or did you use an existing one? I have the opinion this isn't a wise move as how will I accomplish adding servers that aren't DefaultServers (That is what ServerMap does) to the components? You missed the fact that ServerMap extends WrapperMapString, Server and implements MapString, Server. So you can do put(name, myServer). In addition, I've changed the ServerMap's implementation to use directly the Factory instead of using the DefaultServer. Same thing for ClientMap. And the ServerMap from connector package creates an unnecessary dependency on WrapperMap in package data. If you were to remove all those collection wrappers to another package collections or util (if you want to take java's example) you remove these unencessary dependencies between your core packages... I don't see an issue in having a dependency between connector and data as data elements are naturally exchanged between components using connectors. For example, you need the Client.post(String uri, Representation input) method. However, I agree that we shouldn't have cyclical dependencies, like from data to connector or component. We'll also remove the dependency from connector to component later. In the end we should have this dependency tree: org.restlet.component +- org.restlet.connector +- org.restlet +- org.restlet.data Create a package org.restlet.spi (Service provider interface) and move Factory there. This package now can have dependency on org.restlet and org.component and honestly on all the rest of them too .. no problem :) Having just one Factory class, let's see if we can get rid of an additional spi package. Best regards, Jerome
RE: Some API related questions
Hi Piyush, There is a snapshot containing the latest changes at: http://www.restlet.org/downloads/current.zip Best regards, Jerome -Message d'origine- De : Piyush Purang [mailto:[EMAIL PROTECTED] Envoyé : jeudi 10 août 2006 11:35 À : discuss@restlet.tigris.org Objet : Re: Some API related questions Thanks Jerome for lending an ear. How can I best get to what you have already done? Should I wait for the next b-release or a nightly release (that would be cool)? I will need to change my classes now :) I will comment on/pursue these issues after I have used what's been done. Cheers Piyush On 8/9/06, Jerome Louvel [EMAIL PROTECTED] wrote: Hi Piyush, [..] Now we are talking taste here but I think Java packages aren't a very good example because some of them are there since jdk 1.0 and can't be refactored without breaking thousands of apps ..I am pretty sure that the Sun Java API gurus don't sleep easy at night :) Good argument, I buy that...and I do want to get some rest this night ;-) We are building something new here so we can be a little more adventurous. And my opinion is that having more packages isn't a sin packages are there to organize classes and help in avoiding to create cyclical dependencies .. I agree, it's a matter of finding the right balance between too many classes per packages and too many 'empty' packages. so a default package may be needed grouping all the default implementations .. or maybe another package hierarchy? I think I'd like to keep defaut/abstract implementations close to their interface. But I'm open to adapting the packages structure if needed. One thing I wanted to ask too was why do you have Enum implementing Interfaces? Is that something you saw being done someplace? Enums are Enums and by implementing interfaces you are trying to bridge the gap between Enum and Class that was created in 1.5 in order to make the distinction clear. My intent was to leverage the enumeration introduced in 1.5. So I started adding enums for methods, statuses, media types, etc. But then I realized that I couldn't enumerate all the potential media types, etc. So I thought about a way to allow usage of enums while preserving the extensibility. The only way I found was to introduce interfaces implemented by both enums and default classes. The problem is that I opened the Pandora box: if you get a media type, you can't switch it because you have to work from the interface... OK, I will refactor all this into single classes with static members for common values. That should greatly reduce the size of the data package. And I have seen some empty marker interfaces (Data and ControlData) and as per Joshua Bloch (and I totally agree) empty marker interfaces usually lead to problems later ... Good point, I was not initially sure if those REST concepts would need an equivalent Java artifact. For now, I've removed all of them and we'll see if/why we need them back down the road. Did you file a bug report on that or did you use an existing one? I have the opinion this isn't a wise move as how will I accomplish adding servers that aren't DefaultServers (That is what ServerMap does) to the components? You missed the fact that ServerMap extends WrapperMapString, Server and implements MapString, Server. So you can do put(name, myServer). In addition, I've changed the ServerMap's implementation to use directly the Factory instead of using the DefaultServer. Same thing for ClientMap. And the ServerMap from connector package creates an unnecessary dependency on WrapperMap in package data. If you were to remove all those collection wrappers to another package collections or util (if you want to take java's example) you remove these unencessary dependencies between your core packages... I don't see an issue in having a dependency between connector and data as data elements are naturally exchanged between components using connectors. For example, you need the Client.post(String uri, Representation input) method. However, I agree that we shouldn't have cyclical dependencies, like from data to connector or component. We'll also remove the dependency from connector to component later. In the end we should have this dependency tree: org.restlet.component +- org.restlet.connector +- org.restlet +- org.restlet.data Create a package org.restlet.spi (Service provider interface) and move Factory there. This package now can have dependency on org.restlet and org.component and honestly on all the rest of them too .. no problem :) Having just one Factory class, let's see if we can get rid
Re: Some API related questions
Hi Jerome, 1) Why does org.restlet.data have so many classes? Couldn't they be divided into sub packages? See also remark 3. There is a simple reason which is that the REST style defines three and only three architectural elements: - Data Elements org.restlet.data - Connectors org.restlet.connector - Components org.restlet.component http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm I agree that the data package contains many artifacts (about 60), but compared to Java's packages it's not abnormal. And I'd like to keep the API as simple as possible and for me limiting the number of needed packages is important. In comparison: - java.lang : 95 artifacts - java.util : 86 artifacts - ... One thing I couldn't get rid of in the data package is the numerous Default* classes and associated interfaces, because that the only way I found to leverage the Java 5 enumerations (Encodings, Methods, etc.) while preserving the extensibility (Encoding, Method interfaces, etc.). Maybe I should have gone with a single class (Encoding, Method, etc.) whith some static constants for common values instead... What do you think? Now we are talking taste here but I think Java packages aren't a very good example because some of them are there since jdk 1.0 and can't be refactored without breaking thousands of apps ..I am pretty sure that the Sun Java API gurus don't sleep easy at night :) We are building something new here so we can be a little more adventurous. And my opinion is that having more packages isn't a sin packages are there to organize classes and help in avoiding to create cyclical dependencies .. so a default package may be needed grouping all the default implementations .. or maybe another package hierarchy? One thing I wanted to ask too was why do you have Enum implementing Interfaces? Is that something you saw being done someplace? Enums are Enums and by implementing interfaces you are trying to bridge the gap between Enum and Class that was created in 1.5 in order to make the distinction clear. And I have seen some empty marker interfaces (Data and ControlData) and as per Joshua Bloch (and I totally agree) empty marker interfaces usually lead to problems later ... 2) Is the implementation of Map component.getServers() using a ServerMap in RestletContainer advisable? For example I wanted to work with components in general and then when time came to add servers to components I had to look at the code for RestletContainer to try and figure it all out. The issue here is: what justifies the presence of the ServerMap? If it was just added to ease implemntation then maybe a rethink is needed. Ooops, it's a bug, I forgot to change the signature of the interface. Fixed in SVN: Component.getServers() now returns a ServerMap. Did you file a bug report on that or did you use an existing one? I have the opinion this isn't a wise move as how will I accomplish adding servers that aren't DefaultServers (That is what ServerMap does) to the components? And the ServerMap from connector package creates an unnecessary dependency on WrapperMap in package data. If you were to remove all those collection wrappers to another package collections or util (if you want to take java's example) you remove these unencessary dependencies between your core packages... 3) classes don't respect package boundaries.. i.e. there are cyclical dependencies. The main culprits are the abstract implementations if they could be moved someplace else the packages will be nicely layered. Example: AbstractRestlet has knowledge of Component form the component package. I personally feel that the org.restlet package shouldn't be aware of the org.restlet.component package ideally the dependency graph should look something like org.restlet.connector -- org.restlet.data ^ ^ | | org.restlet -- ^ | org.restlet.component You bring up very good points. With the introduction of the Restlet Application artifact, we will be able to cleanly achieve this separation. Indeed, a Restlet should have no direct knowledge of its owner component. Restlet.owner property will be removed. We will use instead a context object that will expose some services to Restlets. Those services will be implemented by the container in any way it wants. The only remaining dependency from org.restlet to org.restlet.component will be in org.restlet.Factory, which is fine I guess. Create a package org.restlet.spi (Service provider interface) and move Factory there. This package now can have dependency on org.restlet and org.component and honestly on all the rest of them too .. no problem :) Cheers Piyush
RE: Some API related questions
Hi Piyush, [..] Now we are talking taste here but I think Java packages aren't a very good example because some of them are there since jdk 1.0 and can't be refactored without breaking thousands of apps ..I am pretty sure that the Sun Java API gurus don't sleep easy at night :) Good argument, I buy that...and I do want to get some rest this night ;-) We are building something new here so we can be a little more adventurous. And my opinion is that having more packages isn't a sin packages are there to organize classes and help in avoiding to create cyclical dependencies .. I agree, it's a matter of finding the right balance between too many classes per packages and too many 'empty' packages. so a default package may be needed grouping all the default implementations .. or maybe another package hierarchy? I think I'd like to keep defaut/abstract implementations close to their interface. But I'm open to adapting the packages structure if needed. One thing I wanted to ask too was why do you have Enum implementing Interfaces? Is that something you saw being done someplace? Enums are Enums and by implementing interfaces you are trying to bridge the gap between Enum and Class that was created in 1.5 in order to make the distinction clear. My intent was to leverage the enumeration introduced in 1.5. So I started adding enums for methods, statuses, media types, etc. But then I realized that I couldn't enumerate all the potential media types, etc. So I thought about a way to allow usage of enums while preserving the extensibility. The only way I found was to introduce interfaces implemented by both enums and default classes. The problem is that I opened the Pandora box: if you get a media type, you can't switch it because you have to work from the interface... OK, I will refactor all this into single classes with static members for common values. That should greatly reduce the size of the data package. And I have seen some empty marker interfaces (Data and ControlData) and as per Joshua Bloch (and I totally agree) empty marker interfaces usually lead to problems later ... Good point, I was not initially sure if those REST concepts would need an equivalent Java artifact. For now, I've removed all of them and we'll see if/why we need them back down the road. Did you file a bug report on that or did you use an existing one? I have the opinion this isn't a wise move as how will I accomplish adding servers that aren't DefaultServers (That is what ServerMap does) to the components? You missed the fact that ServerMap extends WrapperMapString, Server and implements MapString, Server. So you can do put(name, myServer). In addition, I've changed the ServerMap's implementation to use directly the Factory instead of using the DefaultServer. Same thing for ClientMap. And the ServerMap from connector package creates an unnecessary dependency on WrapperMap in package data. If you were to remove all those collection wrappers to another package collections or util (if you want to take java's example) you remove these unencessary dependencies between your core packages... I don't see an issue in having a dependency between connector and data as data elements are naturally exchanged between components using connectors. For example, you need the Client.post(String uri, Representation input) method. However, I agree that we shouldn't have cyclical dependencies, like from data to connector or component. We'll also remove the dependency from connector to component later. In the end we should have this dependency tree: org.restlet.component +- org.restlet.connector +- org.restlet +- org.restlet.data Create a package org.restlet.spi (Service provider interface) and move Factory there. This package now can have dependency on org.restlet and org.component and honestly on all the rest of them too .. no problem :) Having just one Factory class, let's see if we can get rid of an additional spi package. Best regards, Jerome
RE: Some API related questions
Hi Piyush, 1) Why does org.restlet.data have so many classes? Couldn't they be divided into sub packages? See also remark 3. There is a simple reason which is that the REST style defines three and only three architectural elements: - Data Elements org.restlet.data - Connectors org.restlet.connector - Components org.restlet.component http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm I agree that the data package contains many artifacts (about 60), but compared to Java's packages it's not abnormal. And I'd like to keep the API as simple as possible and for me limiting the number of needed packages is important. In comparison: - java.lang : 95 artifacts - java.util : 86 artifacts - ... One thing I couldn't get rid of in the data package is the numerous Default* classes and associated interfaces, because that the only way I found to leverage the Java 5 enumerations (Encodings, Methods, etc.) while preserving the extensibility (Encoding, Method interfaces, etc.). Maybe I should have gone with a single class (Encoding, Method, etc.) whith some static constants for common values instead... What do you think? 2) Is the implementation of Map component.getServers() using a ServerMap in RestletContainer advisable? For example I wanted to work with components in general and then when time came to add servers to components I had to look at the code for RestletContainer to try and figure it all out. The issue here is: what justifies the presence of the ServerMap? If it was just added to ease implemntation then maybe a rethink is needed. Ooops, it's a bug, I forgot to change the signature of the interface. Fixed in SVN: Component.getServers() now returns a ServerMap. 3) classes don't respect package boundaries.. i.e. there are cyclical dependencies. The main culprits are the abstract implementations if they could be moved someplace else the packages will be nicely layered. Example: AbstractRestlet has knowledge of Component form the component package. I personally feel that the org.restlet package shouldn't be aware of the org.restlet.component package ideally the dependency graph should look something like org.restlet.connector -- org.restlet.data ^ ^ | | org.restlet -- ^ | org.restlet.component You bring up very good points. With the introduction of the Restlet Application artifact, we will be able to cleanly achieve this separation. Indeed, a Restlet should have no direct knowledge of its owner component. Restlet.owner property will be removed. We will use instead a context object that will expose some services to Restlets. Those services will be implemented by the container in any way it wants. The only remaining dependency from org.restlet to org.restlet.component will be in org.restlet.Factory, which is fine I guess. Best regards, Jerome