Changeset 6100 for trunk

Show
Ignore:
Timestamp:
01/04/12 18:30:23 (5 months ago)
Author:
mtld
Message:

make stub generation available to external consumers via ServletContext?

Location:
trunk/pustefix-webservices/pustefix-webservices-core/src/main/java/org/pustefixframework/webservices
Files:
1 added
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/pustefix-webservices/pustefix-webservices-core/src/main/java/org/pustefixframework/webservices/ServiceRuntime.java

    r5854 r6100  
    2121import java.io.ByteArrayOutputStream; 
    2222import java.io.IOException; 
     23import java.io.OutputStream; 
     24import java.lang.reflect.Method; 
    2325import java.util.HashMap; 
    2426import java.util.Map; 
    2527 
     28import javax.servlet.ServletContext; 
    2629import javax.servlet.http.HttpServletRequest; 
    2730import javax.servlet.http.HttpServletResponse; 
     
    3942import org.pustefixframework.webservices.utils.RecordingResponseWrapper; 
    4043import org.springframework.aop.framework.Advised; 
     44import org.springframework.beans.factory.DisposableBean; 
     45import org.springframework.web.context.ServletContextAware; 
    4146 
    4247import de.schlund.pfixcore.auth.AuthConstraint; 
     
    4853 * @author mleidig@schlund.de 
    4954 */ 
    50 public class ServiceRuntime { 
     55public class ServiceRuntime implements ServletContextAware, DisposableBean { 
    5156         
    5257    private final static Logger LOG=Logger.getLogger(ServiceRuntime.class); 
     
    6974    private ServerContextImpl serverContext; 
    7075    private ContextImpl context; 
     76     
     77    private ServiceStubProvider serviceStubProvider; 
     78    private ServletContext servletContext; 
    7179     
    7280    public ServiceRuntime() { 
     
    7785    }    
    7886         
     87    public void setServletContext(ServletContext servletContext) { 
     88        this.servletContext = servletContext; 
     89        //make ServiceStubProvider available to external consumers via ServletContext 
     90        this.serviceStubProvider = new ServiceStubProvider(this); 
     91        servletContext.setAttribute(ServiceStubProvider.class.getName(), serviceStubProvider); 
     92    } 
     93     
     94    public void destroy() throws Exception { 
     95        servletContext.removeAttribute(ServiceStubProvider.class.getName()); 
     96    } 
     97     
    7998    public ServiceDescriptorCache getServiceDescriptorCache() { 
    8099        return srvDescCache; 
     
    294313    public void getStub(HttpServletRequest req,HttpServletResponse res) throws ServiceException, IOException { 
    295314         
    296         long t1=System.currentTimeMillis(); 
    297          
    298315        String nameParam=req.getParameter("name"); 
    299316        if(nameParam==null) throw new ServiceException("Missing parameter: name"); 
     
    324341        } 
    325342         
     343        FileCacheData data = generateStub(services, serviceType, req.getContextPath()); 
     344         
     345        String etag=req.getHeader("If-None-Match"); 
     346        if(etag!=null && etag.equals(data.getMD5())) { 
     347            res.setStatus(HttpServletResponse.SC_NOT_MODIFIED); 
     348        } else { 
     349            res.setContentType("text/plain");     
     350            res.setContentLength(data.getBytes().length); 
     351            res.setHeader("ETag",data.getMD5()); 
     352            res.getOutputStream().write(data.getBytes()); 
     353            res.getOutputStream().close(); 
     354        } 
     355    } 
     356     
     357    private FileCacheData generateStub(ServiceConfig[] services, String serviceType, String contextPath) throws ServiceException, IOException { 
     358         
    326359        StringBuilder sb=new StringBuilder(); 
    327         for(String serviceName:serviceNames) { 
    328             sb.append(serviceName); 
     360        for(ServiceConfig service:services) { 
     361            sb.append(service.getName()); 
    329362            sb.append(" "); 
    330363        } 
     
    340373                ByteArrayOutputStream bout=new ByteArrayOutputStream(); 
    341374                for(int i=0;i<services.length;i++) { 
    342                     String requestPath = req.getContextPath() + services[i].getGlobalServiceConfig().getRequestPath(); 
     375                    String requestPath = contextPath + services[i].getGlobalServiceConfig().getRequestPath(); 
    343376                    stubGen.generateStub(services[i], requestPath, bout); 
    344377                    if(i<services.length-1) bout.write("\n\n".getBytes()); 
     
    353386        } 
    354387         
    355         long t2=System.currentTimeMillis(); 
    356         if(LOG.isDebugEnabled()) LOG.debug("Retrieved stub for '"+cacheKey+"' (Time: "+(t2-t1)+"ms)"); 
    357          
    358         String etag=req.getHeader("If-None-Match"); 
    359         if(etag!=null && etag.equals(data.getMD5())) { 
    360             res.setStatus(HttpServletResponse.SC_NOT_MODIFIED); 
    361         } else { 
    362             res.setContentType("text/plain");     
    363             res.setContentLength(data.getBytes().length); 
    364             res.setHeader("ETag",data.getMD5()); 
    365             res.getOutputStream().write(data.getBytes()); 
    366             res.getOutputStream().close(); 
    367         } 
     388        return data; 
     389    } 
     390     
     391    public void generateStub(String[] serviceNames, String serviceType, OutputStream out) throws ServiceException, IOException { 
     392         
     393        serviceType = serviceType.toUpperCase(); 
     394         
     395        String contextPath; 
     396        //try to get context path from ServletContext, which is only directly supported since Servlet API 2.5 
     397        //this workaround uses reflection utilizing that Tomcat since 5.5.16 already implements this method internally  
     398        try { 
     399            Method meth = servletContext.getClass().getMethod("getContextPath"); 
     400            contextPath = (String)meth.invoke(servletContext); 
     401        } catch(Exception x) { 
     402            throw new RuntimeException("Your servlet container doesn't support getting the context path from the ServletContext. " + 
     403                    "You should upgrade to a version supporting Servlet API 2.5 or newer - or at least a container internally " + 
     404                    "implementing ServletContext.getContextPath()."); 
     405        } 
     406         
     407        ServiceConfig[] services=new ServiceConfig[serviceNames.length]; 
     408        for(int i=0;i<serviceNames.length;i++) { 
     409            ServiceConfig service=appServiceRegistry.getService(serviceNames[i]); 
     410            if(service==null) throw new ServiceException("Service not found: "+serviceNames[i]); 
     411            services[i]=service; 
     412        } 
     413         
     414        FileCacheData data = generateStub(services, serviceType, contextPath); 
     415        out.write(data.getBytes()); 
    368416    } 
    369417