cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r1127991 - in /cxf/trunk: rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/ systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/ systests/jaxrs/src/test/resourc...
Date Thu, 26 May 2011 16:56:16 GMT
Author: sergeyb
Date: Thu May 26 16:56:16 2011
New Revision: 1127991

URL: http://svn.apache.org/viewvc?rev=1127991&view=rev
Log:
[CXF-3549] Initial support for serving external schemas

Added:
    cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/schemas/book.xsd   (with props)
Modified:
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestPreprocessor.java
    cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
    cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java
    cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestPreprocessor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestPreprocessor.java?rev=1127991&r1=1127990&r2=1127991&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestPreprocessor.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/RequestPreprocessor.java
Thu May 26 16:56:16 2011
@@ -177,22 +177,33 @@ public class RequestPreprocessor {
      * we will need to save the list of ClassResourceInfos on the EndpointInfo though
      */
     public Response checkMetadataRequest(Message m) {
+        String originalRequestURI = (String)m.get(Message.REQUEST_URI);
         String query = (String)m.get(Message.QUERY_STRING);
         if (query != null && query.contains(WadlGenerator.WADL_QUERY)) {
-            String requestURI = getValueWithoutSlash((String)m.get(Message.REQUEST_URI));
+            String requestURI = getValueWithoutSlash(originalRequestURI);
             String baseAddress = getValueWithoutSlash(HttpUtils.getBaseAddress(m));
             if (baseAddress.equals(requestURI)) {
-                List<ProviderInfo<RequestHandler>> shs = ProviderFactory.getInstance(m).getRequestHandlers();
-                // this is actually being tested by ProviderFactory unit tests but just in
case
-                // WadlGenerator, the custom or default one, must be the first one
-                if (shs.size() > 0 && shs.get(0).getProvider() instanceof WadlGenerator)
{
-                    return shs.get(0).getProvider().handleRequest(m, null);
-                }
+                return handleMetadataRequest(m);
             }
+        } else if (originalRequestURI.endsWith(".xsd")) {
+            // trying WADLGenerator which may be caching schema resources won't
+            // interfere with custom schema handlers if any
+            return handleMetadataRequest(m);
         }
         return null;
     }
     
+    private Response handleMetadataRequest(Message m) { 
+        List<ProviderInfo<RequestHandler>> shs = ProviderFactory.getInstance(m).getRequestHandlers();
+        // this is actually being tested by ProviderFactory unit tests but just in case
+        // WadlGenerator, the custom or default one, must be the first one
+        if (shs.size() > 0 && shs.get(0).getProvider() instanceof WadlGenerator)
{
+            return shs.get(0).getProvider().handleRequest(m, null);
+        } else {
+            return null;
+        }
+    }
+    
     private static String getValueWithoutSlash(String value) {
         return value.endsWith("/") ? value.substring(0, value.length() - 1) : value;
     }

Modified: cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java?rev=1127991&r1=1127990&r2=1127991&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
(original)
+++ cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
Thu May 26 16:56:16 2011
@@ -40,6 +40,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Logger;
 
 import javax.ws.rs.WebApplicationException;
@@ -127,6 +128,10 @@ public class WadlGenerator implements Re
     private List<String> externalSchemasCache;
     private List<URI> externalSchemaLinks;
     private Map<String, List<String>> externalQnamesMap;
+    
+    private ConcurrentHashMap<String, String> schemaLocationMap = 
+        new ConcurrentHashMap<String, String>();
+        
     private ElementQNameResolver resolver;
     private List<String> privateAddresses;
     private String applicationTitle;
@@ -158,6 +163,15 @@ public class WadlGenerator implements Re
 
         UriInfo ui = new UriInfoImpl(m);
         if (!ui.getQueryParameters().containsKey(WADL_QUERY)) {
+            if (!schemaLocationMap.isEmpty()) {
+                String path = ui.getPath(false);
+                if (path.startsWith("/") && path.length() > 0) {
+                    path = path.substring(1);
+                }
+                if (schemaLocationMap.containsKey(path)) {
+                    return getExistingSchema(m, ui, path);
+                }
+            }
             return null;
         }
 
@@ -666,14 +680,24 @@ public class WadlGenerator implements Re
                 try {
                     InputStream is = ResourceUtils.getResourceStream(loc, (Bus)ep.get(Bus.class.getName()));
                     if (is != null) {
-                        Element docEl = DOMUtils.readXml(is).getDocumentElement();
-                        List<Element> resourceEls = DOMUtils.getChildrenWithName(docEl,

+                        Element appEl = DOMUtils.readXml(is).getDocumentElement();
+                        
+                        List<Element> grammarEls = DOMUtils.getChildrenWithName(appEl,

+                                                                                WadlGenerator.WADL_NS,

+                                                                                "grammars");
+                        if (grammarEls.size() == 1) {
+                            handleSchemaRefs(DOMUtils.getChildrenWithName(grammarEls.get(0),

+                                WadlGenerator.WADL_NS, "include"), "href", loc, "", ui);
+                        }
+                        
+                        List<Element> resourceEls = DOMUtils.getChildrenWithName(appEl,

                                                                                  WadlGenerator.WADL_NS,

                                                                                  "resources");
                         if (resourceEls.size() == 1) {
                             DOMUtils.setAttribute(resourceEls.get(0), "base", getBaseURI(ui));
-                            return Response.ok().type(mt).entity(new DOMSource(docEl)).build();
+                            return Response.ok().type(mt).entity(new DOMSource(appEl)).build();
                         }
+                        
                     }
                 } catch (Exception ex) {
                     throw new WebApplicationException(ex, 400);
@@ -682,7 +706,46 @@ public class WadlGenerator implements Re
         }
         return null;
     }
+    
+    //TODO: deal with caching later on
+    public Response getExistingSchema(Message m, UriInfo ui, String href) {
+        String loc = schemaLocationMap.get(href);
+        Endpoint ep = m.getExchange().get(Endpoint.class);
+        if (ep != null && loc != null) {
+            try {
+                InputStream is = ResourceUtils.getResourceStream(loc, (Bus)ep.get(Bus.class.getName()));
+                if (is != null) {
+                    Element docEl = DOMUtils.readXml(is).getDocumentElement();
+                    handleSchemaRefs(DOMUtils.getChildrenWithName(docEl, 
+                        XmlSchemaConstants.XSD_NAMESPACE_URI, "import"), "schemaLocation",
loc, href, ui);
+                    handleSchemaRefs(DOMUtils.getChildrenWithName(docEl, 
+                        XmlSchemaConstants.XSD_NAMESPACE_URI, "include"), "schemaLocation",
loc, href, ui);
+                    return Response.ok().type(MediaType.APPLICATION_XML_TYPE).entity(
+                        new DOMSource(docEl)).build();
+                }
+            } catch (Exception ex) {
+                throw new WebApplicationException(ex, 400);
+            }
+            
+        }
+        return null;
+    }
 
+    private void handleSchemaRefs(List<Element> schemaRefEls, String attrName, 
+                                  String parentDocLoc, String parentRef, UriInfo ui) {
+        int index = parentDocLoc.lastIndexOf('/');
+        parentDocLoc = index == -1 ? parentDocLoc : parentDocLoc.substring(0, index + 1);
+        
+        index = parentRef.lastIndexOf('/');
+        parentRef = index == -1 ? "" : parentRef.substring(0, index + 1);    
+        
+        for (Element schemaRefEl : schemaRefEls) {
+            String href = schemaRefEl.getAttribute(attrName);
+            String actualRef = parentRef + href;
+            schemaLocationMap.put(actualRef, parentDocLoc + href);    
+            DOMUtils.setAttribute(schemaRefEl, attrName, getBaseURI(ui) + "/" + actualRef);
+        }
+    }
 
     private void generateQName(StringBuilder sb,
                                ElementQNameResolver qnameResolver,
@@ -999,8 +1062,6 @@ public class WadlGenerator implements Re
         externalQnamesMap.put(targetNs, Arrays.asList(elementNames));
         String schemaValue = source.getNode("/xs:schema", nsMap, String.class);
         externalSchemasCache.add(schemaValue);
-        
-        
     }
     
     public void setUseJaxbContextForQnames(boolean checkJaxbOnly) {
@@ -1046,7 +1107,13 @@ public class WadlGenerator implements Re
         externalSchemaLinks = new LinkedList<URI>();
         for (String s : externalLinks) {
             try {
-                externalSchemaLinks.add(URI.create(s));
+                String href = s;
+                if (href.startsWith("classpath:")) {
+                    int index = href.lastIndexOf('/');
+                    href = index == -1 ? href.substring(9) : href.substring(index + 1);
+                    schemaLocationMap.put(href, s);
+                }
+                externalSchemaLinks.add(URI.create(href));
             } catch (Exception ex) {
                 LOG.warning("Not a valid URI : " + s);
                 externalSchemaLinks = null;
@@ -1071,6 +1138,7 @@ public class WadlGenerator implements Re
                 XMLSource source = new XMLSource(new ByteArrayInputStream(s.getBytes()));
                 source.setBuffering(true);
                 Map<String, String> locs = getLocationsMap(source, "import", links,
ui);
+                locs.putAll(getLocationsMap(source, "include", links, ui));
                 String actualSchema = !locs.isEmpty() ? transformSchema(s, locs) : s;
                 theSchemas.add(actualSchema);
             }

Modified: cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java?rev=1127991&r1=1127990&r2=1127991&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java
(original)
+++ cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java
Thu May 26 16:56:16 2011
@@ -42,6 +42,7 @@ import org.apache.commons.httpclient.Htt
 import org.apache.commons.httpclient.methods.FileRequestEntity;
 import org.apache.commons.httpclient.methods.PostMethod;
 import org.apache.commons.httpclient.methods.RequestEntity;
+import org.apache.cxf.common.xmlschema.XmlSchemaConstants;
 import org.apache.cxf.helpers.DOMUtils;
 import org.apache.cxf.helpers.IOUtils;
 import org.apache.cxf.io.CachedOutputStream;
@@ -98,13 +99,43 @@ public class JAXRSClientServerSpringBook
     @Test
     public void testGetWadlFromWadlLocation() throws Exception {
         String address = "http://localhost:" + PORT + "/the/generated";    
-        checkWadlResourcesInfo(address, address + "/bookstore", 1);
+        checkWadlResourcesInfo(address, address + "/bookstore", "/schemas/book.xsd", 1);
+    
+        checkSchemas(address, "/schemas/book.xsd", "/schemas/chapter.xsd", "include");
+        checkSchemas(address, "/schemas/chapter.xsd", null, null);
+    }
+    
+    @Test
+    public void testGetGeneratedWadlWithExternalSchemas() throws Exception {
+        String address = "http://localhost:" + PORT + "/the/bookstore";    
+        checkWadlResourcesInfo(address, address, "/book.xsd", 1);
+    
+        checkSchemas(address, "/book.xsd", "/bookid.xsd", "import");
+        checkSchemas(address, "/bookid.xsd", null, null);
+    }
+    
+    private void checkSchemas(String address, String schemaSegment, 
+                              String includedSchema,
+                              String refAttrName) throws Exception {
+        WebClient client = WebClient.create(address + schemaSegment);
+        WebClient.getConfig(client).getHttpConduit().getClient().setReceiveTimeout(10000000L);
+        Document doc = DOMUtils.readXml(new InputStreamReader(client.get(InputStream.class),
"UTF-8"));
+        Element root = doc.getDocumentElement();
+        assertEquals(XmlSchemaConstants.XSD_NAMESPACE_URI, root.getNamespaceURI());
+        assertEquals("schema", root.getLocalName());
+        if (includedSchema != null) {
+            List<Element> includeEls = DOMUtils.getChildrenWithName(root, 
+                         XmlSchemaConstants.XSD_NAMESPACE_URI, refAttrName);
+            assertEquals(1, includeEls.size());
+            String href = includeEls.get(0).getAttribute("schemaLocation");
+            assertEquals(address + includedSchema, href);
+        }
         
     }
     
-    private void checkWadlResourcesInfo(String baseURI, String requestURI, int size) throws
Exception {
+    private void checkWadlResourcesInfo(String baseURI, String requestURI, 
+                                        String schemaRef, int size) throws Exception {
         WebClient client = WebClient.create(requestURI + "?_wadl&_type=xml");
-        WebClient.getConfig(client).getHttpConduit().getClient().setReceiveTimeout(10000000L);
         Document doc = DOMUtils.readXml(new InputStreamReader(client.get(InputStream.class),
"UTF-8"));
         Element root = doc.getDocumentElement();
         assertEquals(WadlGenerator.WADL_NS, root.getNamespaceURI());
@@ -116,7 +147,7 @@ public class JAXRSClientServerSpringBook
                                                                 WadlGenerator.WADL_NS, "include");
         assertEquals(1, includeEls.size());
         String href = includeEls.get(0).getAttribute("href");
-        assertEquals("schemas/book.xsd", href);
+        assertEquals(baseURI + schemaRef, href);
         List<Element> resourcesEls = DOMUtils.getChildrenWithName(root, 
                                                                   WadlGenerator.WADL_NS,
"resources");
         assertEquals(1, resourcesEls.size());

Modified: cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml?rev=1127991&r1=1127990&r2=1127991&view=diff
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml (original)
+++ cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml Thu May 26 16:56:16
2011
@@ -52,6 +52,13 @@ http://cxf.apache.org/schemas/core.xsd">
     <jaxrs:providers>
        <ref bean="jaxbProvider"/>
        <ref bean="jsonProvider"/>
+       <bean class="org.apache.cxf.jaxrs.model.wadl.WadlGenerator">
+           <property name="externalLinks">
+               <list>
+                  <value>classpath:/WEB-INF/schemas/book.xsd</value>
+               </list>
+           </property>
+       </bean>
     </jaxrs:providers>
   </jaxrs:server>
 

Added: cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/schemas/book.xsd
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/schemas/book.xsd?rev=1127991&view=auto
==============================================================================
--- cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/schemas/book.xsd (added)
+++ cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/schemas/book.xsd Thu May 26
16:56:16 2011
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+ 
+  http://www.apache.org/licenses/LICENSE-2.0
+ 
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/books" 
+  xmlns:tns="http://www.example.org/books" xmlns:bookids="http://www.example.org/books/id"
elementFormDefault="qualified">
+  <xs:import namespace="http://www.example.org/books/id"
+             schemaLocation="bookid.xsd"/>
+  <element name="Book">  
+     <complexType>
+       <sequence>
+        <element name="name" type="xs:string"/>
+        <element name="id" type="bookids:bid"/>
+       </sequence> 
+     </complexType>
+  </element>
+</schema>
\ No newline at end of file

Propchange: cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/schemas/book.xsd
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/schemas/book.xsd
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/schemas/book.xsd
------------------------------------------------------------------------------
    svn:mime-type = text/xml



Mime
View raw message