-
-
Save ralfbattenfeld/1028220 to your computer and use it in GitHub Desktop.
Settings filters in a webapp descriptor | |
--------------------------------------- | |
First Option using up() for jumping back to the parent node: Second option using type information | |
String desc = create(WebApp30Descriptor.class) String desc = create(WebAppDescriptor.class) | |
.filter() .filter(type(Filter.class) | |
.setFilterClass("org.dot.clazz") .name("name") | |
.setFilterName("name").up() .className("org.dot.clazz") ) | |
.filterMapping() .filterMapping(type(FilterMapping.class) | |
.setFilterName("name") .filterName("name") | |
.setUrlPattern("mapping").up() .urlPattern("http://someLink") ) | |
.exportAsString(); .exportAsString(); | |
Impressive proposal!
My concern here is that some types are deriving from the root node, e.g. the descriptor. This is fine as long as the subtype is not used somewhere else. For example, the servlet type is defined in the web-common schema, used in the webapp and webfragment descriptor. How do we model this in your approach? I think, it is important to respect the re-usable nature of the schema definition.
A Type that has a SubType, define a common Type as its Sub.
In the example above, a WebAppDescriptor can take any Type that extends WebAppType as its SubType.
Being this will be generated from the XSDs, let's do a quick review base on those names:
WebAppDescriptor
.add(WebCommonType)
WebFragmentDescriptor
.add(WebCommonType)
Servlet extends WebCommonType
ServletMapping extends WebCommonType
Filter extends WebCommonType
FilterMapping extends WebCommonType
SessionConfig extends WebCommonType
Listener extends WebCommonType
Thanks Aslak for the clarification. I am sitting right now in a boring classroom:-(
When I look the second time to your proposal, I have the feeling that this approach is complex.
I prefer simpler solutions, if possible.
You mentioned that some some classes are created manually. Can you count how many classes are manually created? I truly believe that the majority of the classes (api and impl) must be generated. Otherwise this will be a never ending project.
The generation is a one time thing right, so the generation will generate the TypeBuilder's as well, but possible as just empty interfaces.
I think it will be hard to generate the convenience methods for the TypeBuilders, since that is very much up to the type and what is possible based on what other things we have around and information not available in the XSD. So a Type's TypeBuilder can be manually extended as we see fit, but only as helpers for creating a Type.
So to explain from the Example:
// ServletBuilder interface is generated from the XSD as part of the Servlet Type
public interface ServletBuilder extends WebAppTypeBuilder
{
// The convenience method from() is added manually after generation
Servlet from(Class<? extends Servlet> servlet);
}
That should give us a fully generated core Model based on the XSD, but with a opening to do manual adjustments to the Type creation.
Hi All
I am after the education trip in the nice Caribbean for two weeks. Sun, beach, everything is beautiful. But I wanted to say that I have my laptop with me and a will proceed with more testing work. I am thinking of a generated test cases to cover more of the functionalities. This is independent of the API discussion. In the meanwhile, the transformation is now integrated into maven. I had to choose a better maven xml plugin.
Option 2 - Details
Basic Types
The 'mother' interface for the Top Level Node.
All 'elements' are of a Type<R, B>, a generic contruct of something that has associated a Read-Only-View (TypeReader) and a Builder view(TypeBuilder). Type being the Write view will in most cases also extend the Read-Only-View(TypeReader)
This is the Read-Only-View of a Type. Used in e.g. get operations so the Types state can be passed on without having to worry about it changing.
A Builder is a way to create a Type. This would be a seperated 'factory' interface if you will, and can contain convinience methods for creating a specific type.
This describs that a Type can have SubTypes, e.g. WebAppDescriptor.add(WebAppType)
The Read-Only-View of the SubTypes, e.g. WebAppDescriptor.get(WebAppType)
The Type and TypeReader are generated from the xsd source, while the TypeBuilder is left for manual impl on a pr type basis. Not all Types will have any logical build helpers.
Usage
So, a specific Descriptor impl would look something like this:
And for a SubType of WebApp, e.g. Servlet it could look like this:
Now we have a clear seperation between read and write operations, and also a clear seperation between 'pure' generated model and the convenience/helper view for creating the Type.
When we want to create a the complete model manually, we can do the following:
And when we want to Read it, or pass it on to someone else, we can use the Read-Only-View:
We have multiple convenience methods for creating a Servlet Type, e.g. we can extract name and className directly from a Class<? extends Servlet>
See https://gist.github.com/1025597#file_web_app_descriptor_proto_with_builder.java for complete source..
ps. I'm having some issues with the Generics that I hvaen't quite figured out how is suppose to work yet, but..