Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
fr.opensagres.xdocreport.document.web.AbstractProcessXDocReportServlet Maven / Gradle / Ivy
/**
* Copyright (C) 2011-2015 The XDocReport Team
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package fr.opensagres.xdocreport.document.web;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.URIResolver;
import fr.opensagres.xdocreport.converter.ConverterTypeTo;
import fr.opensagres.xdocreport.converter.IConverter;
import fr.opensagres.xdocreport.converter.IURIResolver;
import fr.opensagres.xdocreport.converter.MimeMapping;
import fr.opensagres.xdocreport.converter.Options;
import fr.opensagres.xdocreport.converter.OptionsHelper;
import fr.opensagres.xdocreport.converter.XDocConverterException;
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.core.utils.StringUtils;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.ProcessState;
import fr.opensagres.xdocreport.document.dump.DumperOptions;
import fr.opensagres.xdocreport.document.dump.IDumper;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.ITemplateEngine;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
/**
* Abstract XDoc Report servlet used to process report (generate report and remove report from cache).
*/
public abstract class AbstractProcessXDocReportServlet
extends BaseXDocReportServlet
implements XDocProcessServletConstants
{
private static final String TEXT_HTML_CONTENT_TYPE = "text/html";
private static final String WEB_URI_RESOLVER_DATA_KEY = WEBURIResolver.class.getName();
private static final long serialVersionUID = -4228326301636062279L;
// JSP files
private static final String ADMIN_JSP = "admin.jsp";
private boolean cacheOriginalDocument = false;
@Override
public void init( ServletConfig config )
throws ServletException
{
super.init( config );
this.cacheOriginalDocument = StringUtils.asBoolean( super.getInitParameter( "cacheOriginalDocument" ), false );
}
/**
* Handles all requests (by default).
*
* @param request HttpServletRequest object containing client request
* @param response HttpServletResponse object for the response
*/
protected void processRequest( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException
{
String dispatch = getDispatchParameter( request );
if ( REMOVE_DISPATCH.equals( dispatch ) )
{
doRemoveReport( request, response );
}
else
{
String entryName = getEntryName( request );
ProcessState processState = super.getProcessState( request );
if ( processState == null )
{
processState =
( StringUtils.isNotEmpty( entryName ) ) ? ProcessState.PREPROCESSED : ProcessState.GENERATED;
}
switch ( processState )
{
case ORIGINAL:
case PREPROCESSED:
doDocumentArchive( processState, entryName, request, response );
break;
case GENERATED:
doGenerateReport( entryName, request, response );
break;
}
}
}
/**
* Remove report from the registry.
*
* @param request
* @param response
* @throws IOException
*/
protected void doRemoveReport( HttpServletRequest request, HttpServletResponse response )
throws IOException
{
String reportId = getReportId( request );
if ( StringUtils.isNotEmpty( reportId ) )
{
getRegistry( request ).unregisterReport( reportId );
}
doRedirectAfterRemoveReport( request, response );
}
protected void doRedirectAfterRemoveReport( HttpServletRequest request, HttpServletResponse response )
throws IOException
{
response.sendRedirect( ADMIN_JSP );
}
protected void doDocumentArchive( ProcessState state, String entryName, HttpServletRequest request,
HttpServletResponse response )
throws IOException, ServletException
{
if ( StringUtils.isEmpty( entryName ) )
{
doSaveReport( state, request, response );
}
else
{
doSaveEntry( state, entryName, request, response );
}
}
/**
* Save document archive of the report.
*
* @param processState
* @param request
* @param response
* @throws IOException
* @throws ServletException
*/
protected void doSaveReport( ProcessState processState, HttpServletRequest request, HttpServletResponse response )
throws IOException, ServletException
{
try
{
IXDocReport report = getReport( request );
if ( report != null )
{
// 2) Prepare HTTP response content type
prepareHTTPResponse( report.getId(), report.getMimeMapping(), request, response );
try
{
report.save( processState, response.getOutputStream() );
}
catch ( XDocReportException e )
{
throw new ServletException( e );
}
}
}
catch ( XDocReportException e )
{
throw new ServletException( e );
}
}
/**
* Extract entry from a report.
*
* @param processState
* @param request
* @param response
* @throws IOException
* @throws ServletException
*/
protected void doSaveEntry( ProcessState processState, String entryName, HttpServletRequest request,
HttpServletResponse response )
throws IOException, ServletException
{
try
{
IXDocReport report = getReport( request );
if ( report != null )
{
try
{
// 2) Prepare HTTP response content type
prepareHTTPResponse( report.getId(), entryName, request, response );
report.saveEntry( entryName, processState, response.getOutputStream() );
}
catch ( XDocReportException e )
{
throw new ServletException( e );
}
}
}
catch ( XDocReportException e )
{
throw new ServletException( e );
}
}
protected boolean doGenerateReport( String entryName, HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException
{
IXDocReport report = null;
IContext context = null;
DumperOptions dumperOptions = null;
try
{
// 1) Get XDoc report
report = getReport( request );
if ( report == null )
{
throw new XDocReportException( "Cannot get XDoc Report for the HTTP request" );
}
Options options = getOptionsConverter( report, request );
dumperOptions = getOptionsDumper( report, request );
if ( options == null )
{
// 2) Prepare Java model context
context = report.createContext();
populateContext( context, report.getId(), request );
// 3) Generate report
doProcessReport( report, context, entryName, dumperOptions, request, response );
}
else
{
ITemplateEngine templateEngine = report.getTemplateEngine();
if ( templateEngine != null )
{
// 2) Prepare Java model context
context = report.createContext();
populateContext( context, report.getId(), request );
}
// Generate and convert report.
doProcessReportWithConverter( report, context, options, dumperOptions, request, response );
}
return true;
}
catch ( Exception e )
{
/*
* call the error handler to let the derived class do something useful with this failure.
*/
error( report, context, dumperOptions, request, response, e );
return false;
}
}
/**
* Generate report with process.
*
* @param report
* @param entryName
* @param dumperOptions
* @param request
* @param response
* @throws XDocReportException
* @throws IOException
*/
private void doProcessReport( IXDocReport report, IContext context, String entryName, DumperOptions dumperOptions,
HttpServletRequest request, HttpServletResponse response )
throws XDocReportException, IOException
{
if ( StringUtils.isEmpty( entryName ) )
{
if ( dumperOptions != null )
{
// dump must be done
// 2) Get dumper
IDumper dumper = report.getDumper( dumperOptions );
// 3) Prepare HTTP response content type
prepareHTTPResponse( report.getId(), dumper.getMimeMapping(), request, response );
// 4) Generate dump
report.dump( context, dumperOptions, response.getOutputStream() );
}
else
{
// 2) Prepare HTTP response content type
prepareHTTPResponse( report.getId(), report.getMimeMapping(), request, response );
// 3) Generate report
report.process( context, response.getOutputStream() );
}
}
else
{
// 2) Prepare HTTP response content type
prepareHTTPResponse( report.getId(), entryName, request, response );
// 3) Generate report
report.process( context, entryName, response.getOutputStream() );
}
}
/**
* Generate report with conversion.
*
* @param report
* @param options
* @param dumperOptions
* @param request
* @param response
* @throws XDocReportException
* @throws IOException
* @throws XDocConverterException
*/
private void doProcessReportWithConverter( IXDocReport report, IContext context, Options options,
DumperOptions dumperOptions, HttpServletRequest request,
HttpServletResponse response )
throws XDocReportException, IOException, XDocConverterException
{
if ( dumperOptions != null )
{
// 2) Get dumper
IDumper dumper = report.getDumper( dumperOptions );
// 3) Prepare HTTP response content type
prepareHTTPResponse( report.getId(), dumper.getMimeMapping(), request, response );
// 4) Generate dump
report.dump( context, dumperOptions, response.getOutputStream() );
}
else
{
// 2) Get converter
IConverter converter = report.getConverter( options );
// 3) Prepare HTTP response content type
prepareHTTPResponse( report.getId(), converter.getMimeMapping(), request, response );
// 4) Generate report with conversion
report.convert( context, options, response.getOutputStream() );
}
}
// ----------------- Get Report
/**
* @param request
* @return
* @throws IOException
* @throws XDocReportException
*/
protected IXDocReport getReport( HttpServletRequest request )
throws IOException, XDocReportException
{
XDocReportRegistry registry = getRegistry( request );
// 1) Get report id
String reportId = getReportId( request );
if ( StringUtils.isNotEmpty( reportId ) )
{
// Search if report is cached in the registry
IXDocReport report = registry.getReport( reportId );
if ( report != null )
{
return report;
}
}
return loadReport( reportId, registry, request );
}
/**
* Load report.
*
* @param reportId
* @param registry
* @param request
* @return
* @throws IOException
* @throws XDocReportException
*/
protected IXDocReport loadReport( String reportId, XDocReportRegistry registry, HttpServletRequest request )
throws IOException, XDocReportException
{
// 2) Get sourceStream
InputStream sourceStream = getSourceStream( reportId, request );
if ( sourceStream == null )
{
throw new XDocReportException( "Input stream is null with reportId=" + reportId );
}
IXDocReport report = null;
// 3) Get template engine to use for the report
ITemplateEngine templateEngine = null;
boolean cacheReport = isCacheReport( reportId, request );
String templateEngineKind = getTemplateEngineKind( reportId, request );
if ( StringUtils.isNotEmpty( templateEngineKind ) )
{
// 3.1) Load report with template engine kind
report = registry.loadReport( sourceStream, reportId, templateEngineKind, cacheReport );
}
else
{
// 3.1) Load report with template engine
templateEngine = getTemplateEngine( reportId, request );
report = registry.loadReport( sourceStream, reportId, templateEngine, cacheReport );
}
// 6) Set FieldsMetaData
FieldsMetadata fieldsMetadata = getFieldsMetadata( reportId, request );
report.setFieldsMetadata( fieldsMetadata );
// 7) Set cache
report.setCacheOriginalDocument( isCacheOriginalDocument( reportId, request ) );
return report;
}
/**
* Returns true if the report with the given id must be cached and false otherwise.
*
* @param reportId the report id.
* @param request the HTTP request.
* @return true if the report with the given id must be cached and false otherwise.
*/
protected boolean isCacheReport( String reportId, HttpServletRequest request )
{
return true;
}
/**
* Returns true if the original document "template" document with the given id must be cached and false otherwise.
*
* @param reportId the report id.
* @param request the HTTP request.
* @return true if the original document "template" document with the given id must be cached and false otherwise.
*/
protected boolean isCacheOriginalDocument( String reportId, HttpServletRequest request )
{
return cacheOriginalDocument;
}
/**
* Returns the fields metadata to use for the report.
*
* @param reportId the report id.
* @param request the HTTP request.
* @return
*/
protected FieldsMetadata getFieldsMetadata( String reportId, HttpServletRequest request )
{
return null;
}
/**
* Invoked when there is an error thrown in any part of doRequest() processing.
*
* Default will send a simple HTML response indicating there was a problem.
*
* @param dumperOptions
* @param context
* @param report
* @param request original HttpServletRequest from servlet container.
* @param response HttpServletResponse object from servlet container.
* @param cause Exception that was thrown by some other part of process.
*/
protected void error( IXDocReport report, IContext context, DumperOptions dumperOptions,
HttpServletRequest request, HttpServletResponse response, Exception cause )
throws ServletException, IOException
{
if ( response.isCommitted() )
{
throw new ServletException( cause );
}
response.setContentType( TEXT_HTML_CONTENT_TYPE );
StringBuilder html = new StringBuilder();
html.append( "" );
html.append( "Error " );
html.append( "" );
html.append( "XDocReport Servlet: Error report generation " );
html.append( "" );
String why = cause.getMessage();
if ( why != null && why.trim().length() > 0 )
{
html.append( why );
html.append( " " );
}
StringWriter sw = new StringWriter();
cause.printStackTrace( new PrintWriter( sw ) );
html.append( sw.toString() );
html.append( " " );
html.append( "" );
html.append( "" );
response.getOutputStream().print( html.toString() );
}
/**
* Returns the converter id.
*
* @param request
* @return
*/
protected String getConverterId( IXDocReport report, HttpServletRequest request )
{
return (String) request.getParameter( CONVERTER_ID_HTTP_PARAM );
}
/**
* Returns the options for the converter.
*
* @param report the report.
* @param request the HTTP request.
* @return
*/
protected Options getOptionsConverter( IXDocReport report, HttpServletRequest request )
{
final String converterId = getConverterId( report, request );
if ( StringUtils.isEmpty( converterId ) )
{
return null;
}
Options options = null;
int index = converterId.lastIndexOf( '_' );
if ( index != -1 )
{
String to = converterId.substring( 0, index );
String via = converterId.substring( index + 1, converterId.length() );
options = Options.getTo( to ).via( via );
}
else
{
options = Options.getTo( converterId );
}
prepareOptions( options, report, converterId, request );
return options;
}
/**
* Initialize converter options with default settings.
*
* @param options the options converter.
* @param report the report.
* @param converterId the converter id.
* @param request the HTTP request.
*/
protected void prepareOptions( Options options, IXDocReport report, String converterId, HttpServletRequest request )
{
// Set Web URI resolver for FO or XHTML
if ( ConverterTypeTo.FO.name().equals( options.getTo() )
|| ConverterTypeTo.XHTML.name().equals( options.getTo() ) )
{
OptionsHelper.setURIResolver( options, createWEBURIResolver( report, converterId, request ) );
}
// Encoding
String fontEncoding = getFontEncoding( report, converterId, request );
if ( StringUtils.isNotEmpty( fontEncoding ) )
{
OptionsHelper.setFontEncoding( options, fontEncoding );
}
}
/**
* Create the WEB {@link URIResolver} used to manage image with XHTML converter.
*
* @param report the report.
* @param converterId the converter id.
* @param request the HTTP request.
* @return
*/
public IURIResolver createWEBURIResolver( IXDocReport report, String converterId, HttpServletRequest request )
{
WEBURIResolver resolver = report.getData( WEB_URI_RESOLVER_DATA_KEY );
if ( resolver == null )
{
resolver = new WEBURIResolver( report.getId(), request );
report.setData( WEB_URI_RESOLVER_DATA_KEY, resolver );
}
return resolver;
}
/**
* Returns the dumper options from the HTTP request and null otherwise.
*
* @param report the report.
* @param request the HTTP request.
* @return
*/
protected DumperOptions getOptionsDumper( IXDocReport report, HttpServletRequest request )
{
final String kind = getDumperKind( report, request );
if ( StringUtils.isEmpty( kind ) )
{
return null;
}
DumperOptions options = new DumperOptions( kind );
return options;
}
/**
* Returns the dumper kind from the HTTP request.
*
* @param report the report.
* @param request the HTTP request.
* @return
*/
protected String getDumperKind( IXDocReport report, HttpServletRequest request )
{
return (String) request.getParameter( DUMPER_KIND_HTTP_PARAM );
}
/**
* Returns the encoding to use for converter.
*
* @param request
* @return
*/
protected String getFontEncoding( IXDocReport report, String converterId, HttpServletRequest request )
{
return (String) request.getParameter( FONT_ENCODING_HTTP_PARAM );
}
@Override
protected boolean isGenerateContentDisposition( String reportId, MimeMapping mimeMapping, HttpServletRequest request )
{
return !VIEW_DISPATCH.equals( getDispatchParameter( request ) );
}
/**
* Returns input stream of the report to load identified with reportId
.
*
* @param reportId report id.
* @param request Http servlet request context.
* @return
* @throws IOException
* @throws XDocReportException
*/
protected abstract InputStream getSourceStream( String reportId, HttpServletRequest request )
throws IOException, XDocReportException;
/**
* Put the Java model in the context for the report reportId
.
*
* @param context XDocReport context to register Java data model.
* @param reportId report id.
* @param request Http servlet request context.
* @throws IOException
* @throws XDocReportException
*/
protected abstract void populateContext( IContext context, String reportId, HttpServletRequest request )
throws IOException, XDocReportException;
}