Hi Rastislav,

Your proposal to use ResourceManager makes sense for me.
CatalogXmlSchemaURIResolver is also used in ReflectionServiceFactoryBean and in 
JibxSchemaHelper classes. I guess it should be replaced to 
ResourceManagerXmlSchemaURIResolver as well.

I am thinking also about the possibility to register custom URIResolver through 
CXF bus mechanism, but it can be further step.
Feel free to create Jira Issue and attach your patch.

Regards,
Andrei.

> -----Original Message-----
> From: Rastislav Cesnek [mailto:[email protected]]
> Sent: Samstag, 23. März 2013 00:05
> To: [email protected]
> Cc: Andrei Shakirin; Daniel Kulp
> Subject: Re: Dynamic service from WSDL+imports loaded from database
> 
> Thanks for answer Andrei.
> 
> I know the cleanest way would be the URL protocol handler (e.g.
> "dbresource://whatever). Also due to the fact that a lot of code everywhere
> just creates URLs trying to get to a resource and if the protocol is not 
> valid -
> bad luck.
> 
> However, as there is the ResourceManager component in CXF, it would be
> nice if it would be used consistently everywhere.
> As it is a nice feature to allow the user to write a custom resource resolver
> which can do so based on a string location which does not necessarily have to
> be a URL.
> 
> I experimented with the following change and it seems to do what I need
> (although I did not fully evaluate whether there are potential side
> implications). Of course, there is my custom resource resolver registered
> with the ResourceManager as I mentioned in previous mail.
> 
> In org.apache.cxf.wsdl11.SchemaUtil:
> 
> $ svn diff rt/core/src/main/java/org/apache/cxf/wsdl11/SchemaUtil.java
> Index: rt/core/src/main/java/org/apache/cxf/wsdl11/SchemaUtil.java
> ==========================================================
> =========
> --- rt/core/src/main/java/org/apache/cxf/wsdl11/SchemaUtil.java
> (revision 1449715)
> +++ rt/core/src/main/java/org/apache/cxf/wsdl11/SchemaUtil.java (working
> copy)
> @@ -126,8 +126,8 @@
>                          String systemId = def.getDocumentBaseURI() + 
> "#types" +
> schemaCount;
> 
>                          schemaCol.setBaseUri(def.getDocumentBaseURI());
> -                        CatalogXmlSchemaURIResolver schemaResolver =
> -                            new CatalogXmlSchemaURIResolver(bus);
> +                        ResourceManagerXmlSchemaURIResolver
> schemaResolver =
> +                                       new
> ResourceManagerXmlSchemaURIResolver(bus);
>                          schemaCol.setSchemaResolver(schemaResolver);
> 
>                          XmlSchema xmlSchema = schemaCol.read(schemaElem,
> systemId);
> 
> 
> And then the quite simple implementation of
> ResourceManagerXmlSchemaURIResolver:
> 
> package org.apache.cxf.wsdl11;
> 
> import java.io.InputStream;
> import java.net.URL;
> import java.util.Map;
> 
> import org.apache.cxf.Bus;
> import org.apache.cxf.catalog.CatalogXmlSchemaURIResolver;
> import org.apache.cxf.resource.ResourceManager;
> import org.apache.ws.commons.schema.resolver.URIResolver;
> import org.xml.sax.InputSource;
> 
> public class ResourceManagerXmlSchemaURIResolver implements
> URIResolver {
>     private CatalogXmlSchemaURIResolver parent;
>     private Bus bus;
> 
>     public ResourceManagerXmlSchemaURIResolver(
>             CatalogXmlSchemaURIResolver parent, Bus bus) {
>         this.parent = parent;
>         this.bus = bus;
>     }
> 
>     public ResourceManagerXmlSchemaURIResolver(Bus bus) {
>         this(new CatalogXmlSchemaURIResolver(bus), bus);
>     }
> 
>     @Override
>     public InputSource resolveEntity(String targetNamespace,
>             String schemaLocation, String baseUri) {
>         InputSource src = getInputSource(schemaLocation);
>         if (src == null) {
>             src = parent
>                     .resolveEntity(targetNamespace, schemaLocation, baseUri);
>         }
>         return src;
>     }
> 
>     private InputSource getInputSource(String schemaLocation) {
>         InputStream ins = bus.getExtension(ResourceManager.class)
>                 .getResourceAsStream(schemaLocation);
>         if (ins == null) {
>             return null;
>         } else {
>             InputSource is = new InputSource(ins);
>             is.setSystemId(schemaLocation);
>             is.setPublicId(schemaLocation);
> 
>             URL url =
> bus.getExtension(ResourceManager.class).resolveResource(
>                     schemaLocation, URL.class);
>             if (url != null) {
>                 is.setSystemId(url.toString());
>                 is.setPublicId(url.toString());
>             }
>             return is;
>         }
>     }
> 
>     public Map<? extends String, ? extends String> getResolvedMap() {
>         Map<String, String> resolvedMap = parent.getResolvedMap();
>         return resolvedMap;
>     }
> 
> }
> 
> 
> On 22. 3. 2013 10:09, Andrei Shakirin wrote:
> > Hi Rastislav,
> >
> > To be honest, I have resolved the similar case only through self-contained
> WSDL (all schemas are embedded into WSDL).
> > Anyway I find the topic quite interesting. Perhaps Dan can give you some
> more entry points to digging.
> >
> > Regards,
> > Andrei.
> >
> >
> >> -----Original Message-----
> >> From: Rastislav Cesnek [mailto:[email protected]]
> >> Sent: Dienstag, 19. März 2013 16:16
> >> To: [email protected]
> >> Subject: Dynamic service from WSDL+imports loaded from database
> >>
> >> HI all.
> >>
> >> I am trying to tweak CXF into a very dynamic scenario, where services
> >> would be published dynamically from a priori unknown WSLDs uploaded
> >> at run time (together with an interpreted service implementation).
> >>
> >> Basically, I already have some idea about the dynamic publish (using
> >> custom Invoker and custom DataBinding, etc.).
> >>
> >> What I concept-proofed right now is loading the WSDLs + its imports
> >> from database.
> >>
> >> Here I stumble upon some show stoppers, when I try to create
> >> ServiceInfos from a definition like:
> >> WSDLServiceBuilder builder = new WSDLServiceBuilder(bus);
> >> List<ServiceInfo> serviceInfos = builder.buildServices(definition);
> >>
> >> The problem is that I am able to read the Definition while serving
> >> the content as I wish (from DB, 2 approaches desribed below),
> >> however, the WSDLServiceBuilder fails when it tries to get the
> >> schemas (I cannot find a possibility to tweak the resource resolving
> >> here, as there is a CatalogXmlSchemaURIResolver hard-registered as
> >> schema collection
> >> resolver):
> >>
> >> org.apache.ws.commons.schema.XmlSchemaException: Unable to locate
> >> imported document at 'db#RootXSD.xsd', relative to
> >> 'db#SubWSDL.wsdl#types1'.
> >> at
> >> org.apache.cxf.catalog.CatalogXmlSchemaURIResolver.resolveEntity(Cata
> >> log
> >> XmlSchemaURIResolver.java:76)
> >> at
> >>
> org.apache.ws.commons.schema.SchemaBuilder.resolveXmlSchema(Schem
> >> aBuilder.java:684)
> >> at
> >>
> org.apache.ws.commons.schema.SchemaBuilder.handleImport(SchemaBuild
> >> er.java:538)
> >> at
> >>
> org.apache.ws.commons.schema.SchemaBuilder.handleSchemaElementChil
> >> d(SchemaBuilder.java:1513)
> >> at
> >>
> org.apache.ws.commons.schema.SchemaBuilder.handleXmlSchemaElement
> >> (SchemaBuilder.java:659)
> >> at
> >>
> org.apache.ws.commons.schema.XmlSchemaCollection.read(XmlSchemaColl
> >> ection.java:540)
> >> at
> >>
> org.apache.cxf.common.xmlschema.SchemaCollection.read(SchemaCollectio
> >> n.java:129)
> >> at
> >> org.apache.cxf.wsdl11.SchemaUtil.extractSchema(SchemaUtil.java:133)
> >> at org.apache.cxf.wsdl11.SchemaUtil.getSchemas(SchemaUtil.java:81)
> >> at org.apache.cxf.wsdl11.SchemaUtil.getSchemas(SchemaUtil.java:65)
> >> at org.apache.cxf.wsdl11.SchemaUtil.getSchemas(SchemaUtil.java:60)
> >> at
> >>
> org.apache.cxf.wsdl11.WSDLServiceBuilder.getSchemas(WSDLServiceBuilde
> >> r
> >> .java:372)
> >>
> >> Any ideas? Can anything like this be done?
> >>
> >>
> >> Basically, for the Definition reading, I tried two approaches which
> >> both
> >> work:
> >>
> >> 1) Implementing and registering a CustomResourceResolver with the
> >> ResourceManager in the Bus and using standard
> >> WSDLManager.getDefinition(String url) method.
> >> In the CustomResourceResolver:
> >> - in "public InputStream getAsStream(String name)" I recognize the
> >> resource name (like "db#name") name and provide na InputSream.
> >> - in "public <T> T resolve(String resourceName, Class<T> resourceType)"
> >> I always return null (for the URL), so the systemId/publicId of the
> >> constructed InputSource stays in the "db#name" form.
> >>
> >> 2) Copying some code from CXF and implementing custom WSDLLocator
> and
> >> doing completely custom definition reading like:
> >> WSDLManager wsdlManager = bus.getExtension(WSDLManager.class);
> >> WSDLFactory wsdlFactory = wsdlManager.getWSDLFactory();
> >> ExtensionRegistry extensionRegistry =
> >> wsdlManager.getExtensionRegistry();
> >>
> >> WSDLReader reader = wsdlFactory.newWSDLReader();
> >> reader.setFeature("javax.wsdl.verbose", false);
> >> reader.setFeature("javax.wsdl.importDocuments", true);
> >> reader.setExtensionRegistry(extensionRegistry);
> >>
> >> CatalogWSDLLocator catLocator = new CatalogWSDLLocator(url, bus);
> >> CustomDelegatingWSDLLocator = new
> CustomDelegatingWSDLLocator(url,
> >> catLocator, bus); Definition def = reader.readWSDL(wsdlLocator);
> >> wsdlManager.addDefinition(url, def); In the
> >> CustomDelegatingWSDLLocator I do similar stuff like in the
> >> CustomResourceResolver, i.e. provide InputSource or delegate and
> >> return an URI (which again stays in the form "db#name" and gets set
> >> to
> >> systemId/publicId) or delegate.
> >>
> >> This works charming and the definition is read.
> >>
> >>
> >> I considered using custom URL protocol handler but this is a
> >> show-stopper too, as the application runs on JEE server, where I
> >> cannot register a custom protocol handler easily (usually, a
> >> URLStreamHandlerFactory is already set and it cannot be set a second
> >> time). The option to use the system environment property
> >> -Djava.protocol.handler.pkgs is also cumbersome as it requires installing
> classes/modules deep into the server/java core.
> >>
> >> Please, notice that Whitestein Slovakia has moved to a new location.
> >> Prosím, všimnite si že Whitestein Slovensko sa presťahovalo na novú
> adresu.
> >>
> >> --
> >> Rastislav Cesnek | [email protected] Senior Software Engineer |
> >> Advanced Technologies Whitestein Technologies s.r.o. |
> >> www.whitestein.com Moskovska 13 | 811 08 Bratislava-Staré Mesto |
> >> Slovak Republic Main +421 2 5443-5502 | Fax +421 2 5443-5512
> 
> Please, notice that Whitestein Slovakia has moved to a new location.
> Prosím, všimnite si že Whitestein Slovensko sa presťahovalo na novú adresu.
> 
> --
> Rastislav Cesnek | [email protected]
> Senior Software Engineer | Advanced Technologies Whitestein Technologies
> s.r.o. | www.whitestein.com Moskovska 13 | 811 08 Bratislava-Staré Mesto |
> Slovak Republic Main +421 2 5443-5502 | Fax +421 2 5443-5512

Reply via email to