/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.portal.portlet.enterprise;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.StringReader;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.deegree.enterprise.control.AbstractListener;
import org.deegree.enterprise.control.FormEvent;
import org.deegree.enterprise.control.RPCMember;
import org.deegree.enterprise.control.RPCStruct;
import org.deegree.enterprise.control.RPCWebEvent;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.BasicUUIDFactory;
import org.deegree.framework.util.StringTools;
import org.deegree.framework.xml.XMLFragment;
import org.deegree.model.spatialschema.Envelope;
import org.deegree.model.spatialschema.GMLGeometryAdapter;
import org.deegree.model.spatialschema.GeometryFactory;
import org.deegree.model.spatialschema.Point;
import org.deegree.ogcwebservices.OGCWebServiceException;
import org.deegree.ogcwebservices.wmps.WMPService;
import org.deegree.ogcwebservices.wmps.WMPServiceFactory;
import org.deegree.ogcwebservices.wmps.configuration.WMPSConfiguration;
import org.deegree.ogcwebservices.wmps.configuration.WMPSConfigurationDocument;
import org.deegree.ogcwebservices.wmps.operation.PrintMap;
import org.deegree.ogcwebservices.wmps.operation.PrintMapResponse;
import org.deegree.portal.PortalException;
import org.deegree.portal.context.Layer;
import org.deegree.portal.context.ViewContext;
import org.deegree.portal.portlet.modules.actions.IGeoPortalPortletPerform;
/**
* performs a print request/event by creating a PDF document from
* the current map
*
*
* @version $Revision: 1.9 $
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
* @author last edited by: $Author: poth $
*
* @version 1.0. $Revision: 1.9 $, $Date: 2006/10/12 15:46:19 $
*
* @since 2.0
*/
public class PrintListener extends AbstractListener {
private static ILogger LOG = LoggerFactory.getLogger( PrintListener.class );
/**
* @param e
*/
public void actionPerformed( FormEvent e ) {
RPCWebEvent rpc = (RPCWebEvent) e;
try {
validate( rpc );
} catch ( Exception ex ) {
LOG.logError( ex.getMessage(), ex );
gotoErrorPage( ex.getMessage() );
}
ViewContext vc = getViewContext( rpc );
if ( vc == null ) {
LOG.logError( "no valid ViewContext available; maybe your session has reached tieout limit" );
gotoErrorPage("no valid ViewContext available; maybe your session has reached tieout limit" );
setNextPage( "igeoportal/error.jsp" );
return;
}
try {
printMap( vc, rpc );
} catch ( Exception ex ) {
ex.printStackTrace();
LOG.logError( ex.getMessage(), ex );
gotoErrorPage( ex.getMessage() );
setNextPage( "igeoportal/error.jsp" );
}
}
/**
*
* @param vc
* @param rpc
* @throws PortalException
*/
private void printMap( ViewContext vc, RPCWebEvent rpc )
throws PortalException {
String template = readRequestTemplate();
template = fillTemplate( vc, rpc, template );
StringReader sr = new StringReader( template );
XMLFragment xml = new XMLFragment();
try {
xml.load( sr, XMLFragment.DEFAULT_URL );
} catch ( Exception e ) {
LOG.logError( e.getMessage(), e );
throw new PortalException( "could not create a DOM object from PrintMap request Template", e );
}
PrintMap printMap = null;
try {
printMap =PrintMap.create( xml.getRootElement() );
} catch ( Exception e ) {
LOG.logError( e.getMessage(), e );
throw new PortalException( "could not parse PrintMap request.", e );
}
if ( !WMPServiceFactory.isInitialized() ) {
WMPSConfiguration wmpsConf = readWMPSConfiguration();
WMPServiceFactory.setConfiguration( wmpsConf );
}
WMPService wmps = WMPServiceFactory.getService();
Object result = null;
try {
result = wmps.doService( printMap );
} catch ( OGCWebServiceException e ) {
e.printStackTrace();
LOG.logError( "could not perform PrintMap request ", e );
throw new PortalException( "could not perform PrintMap request ", e );
}
if ( result instanceof PrintMapResponse ) {
// TODO
// handle result from asynchronous request processing
} else {
forwardPDF( result );
}
}
private void forwardPDF( Object result )
throws PortalException {
// must be a byte array
String tempDir = getInitParameter( "TEMPDIR" );
if ( !tempDir.endsWith("/") ) {
tempDir = tempDir + '/';
}
if ( tempDir.startsWith("/") ) {
tempDir = tempDir.substring( 1, tempDir.length() );
}
BasicUUIDFactory fac = new BasicUUIDFactory();
ServletContext sc = ( (HttpServletRequest) this.getRequest() ).getSession( true ).getServletContext();
String s = StringTools.concat( 200, sc.getRealPath( tempDir ), '/',
fac.createUUID().toANSIidentifier(), ".pdf" );
try {
RandomAccessFile raf = new RandomAccessFile( s, "rw" );
raf.write( (byte[])result );
raf.close();
} catch ( Exception e ) {
e.printStackTrace();
LOG.logError( "could not write temporary pdf file: " + s, e );
throw new PortalException( "could not write temporary pdf file: " + s, e );
}
getRequest().setAttribute( "PDF", StringTools.concat( 200, tempDir,
fac.createUUID().toANSIidentifier(), ".pdf" ) );
}
/**
* reads WMPS configuration from the source defined in the listeners
* init parameters ( 'WMPSCONFIG' )
*
* @return
* @throws PortalException
*/
private WMPSConfiguration readWMPSConfiguration()
throws PortalException {
String config = getInitParameter( "WMPSCONFIG" );
if ( config == null ) {
throw new PortalException( "no WMPS configuration defined for PrintListener" );
}
File file = new File( config );
if ( !file.isAbsolute() ) {
ServletContext sc = ( (HttpServletRequest) this.getRequest() ).getSession( true ).getServletContext();
file = new File( sc.getRealPath( config ) );
}
WMPSConfiguration wmpsConf = null;
try {
WMPSConfigurationDocument wmpsConfDoc = new WMPSConfigurationDocument();
wmpsConfDoc.load( file.toURL() );
wmpsConf = wmpsConfDoc.parseConfiguration();
} catch ( Exception e ) {
LOG.logError( "could not read/create WMPSConfiguration: " + file, e );
throw new PortalException( "could not read/create WMPSConfiguration: " + file, e );
}
return wmpsConf;
}
/**
* fills the passed PrintMap request template with required values
* @param vc
* @param rpc
* @param template
* @return
*/
private String fillTemplate( ViewContext vc, RPCWebEvent rpc, String template ) {
// set boundingbox/envelope
Point[] points = vc.getGeneral().getBoundingBox();
Envelope env = GeometryFactory.createEnvelope( points[0].getX(), points[0].getY(),
points[1].getX(), points[1].getY(),
points[0].getCoordinateSystem() );
String envS = GMLGeometryAdapter.exportAsEnvelope( env ).toString();
template = StringTools.replace( template, "$ENV$", envS, false );
// set layers
StringBuffer lys = new StringBuffer( 1000 );
Layer[] layers = vc.getLayerList().getLayers();
for ( int i = 0; i < layers.length; i++ ) {
if ( !layers[i].isHidden() ) {
lys.append( "<sld:NamedLayer>" );
lys.append( "<sld:Named>" );
lys.append( layers[i] );
lys.append( "</sld:Named>" );
lys.append( "<sld:NamedStyle>" );
lys.append( "<sld:Named>" );
lys.append( layers[i].getStyleList().getCurrentStyle().getName() );
lys.append( "</sld:Named>" );
lys.append( "</sld:NamedStyle>" );
lys.append( "</sld:NamedLayer>" );
}
}
template = StringTools.replace( template, "$LAYERS$", lys.toString(), false );
// set print template
RPCStruct struct = (RPCStruct) rpc.getRPCMethodCall().getParameters()[0].getValue();
String printTemplate = (String)struct.getMember( "TEMPLATE" ).getValue();
template = StringTools.replace( template, "$TEMPLATE$", printTemplate, false );
// set text area values
StringBuffer ta = new StringBuffer( 1000 );
RPCMember[] members = struct.getMembers();
for ( int i = 0; i < members.length; i++ ) {
if ( members[i].getName().startsWith( "TA:" ) ) {
ta.append( "<TextArea>" );
ta.append( "<Name>" );
ta.append( members[i].getName().substring( 3, members[i].getName().length() ) );
ta.append( "</Name>" );
ta.append( "<Text>" );
ta.append( members[i].getValue() );
ta.append( "</Text>" );
ta.append( "</TextArea>" );
}
}
template = StringTools.replace( template, "$TEXTAREAS$", ta.toString(), false );
return template;
}
/**
* read PrintMap request template from the source defined in the listeners
* init parameters ( 'PRINTMAPTEMPLATE' )
* @return
* @throws PortalException
*/
private String readRequestTemplate()
throws PortalException {
String reqTemplate = getInitParameter( "PRINTMAPTEMPLATE" );
if ( reqTemplate == null ) {
throw new PortalException( "not PrintMap request template defined for PrintListener" );
}
File file = new File( reqTemplate );
if ( !file.isAbsolute() ) {
ServletContext sc = ( (HttpServletRequest) this.getRequest() ).getSession( true ).getServletContext();
file = new File( sc.getRealPath( reqTemplate ) );
}
byte[] b;
try {
RandomAccessFile raf = new RandomAccessFile( file, "r" );
b = new byte[(int) raf.length()];
raf.read( b );
raf.close();
} catch ( IOException e ) {
String s = "Could not read PrintMap request template: " + file;
LOG.logError( s, e );
throw new PortalException( s );
}
return new String( b );
}
/**
* reads the view context to print from the users session
* @param rpc
* @return
*/
private ViewContext getViewContext( RPCWebEvent rpc ) {
RPCStruct struct = (RPCStruct) rpc.getRPCMethodCall().getParameters()[0].getValue();
String mmid = (String) struct.getMember( "MAPMODELID" ).getValue();
HttpSession session = ( (HttpServletRequest) getRequest() ).getSession();
return IGeoPortalPortletPerform.getCurrentViewContext( session, mmid );
}
/**
* validates the incoming request/RPC if conatins all required elements
* @param rpc
* @throws PortalException
*/
private void validate( RPCWebEvent rpc )
throws PortalException {
RPCStruct struct = (RPCStruct) rpc.getRPCMethodCall().getParameters()[0].getValue();
if ( struct.getMember( "TEMPLATE" ) == null ) {
throw new PortalException( "struct member: 'TEMPLATE' must be set" );
}
if ( struct.getMember( "MAPMODELID" ) == null ) {
throw new PortalException( "struct member: 'MAPMODELID' must be set" );
}
}
}
/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: PrintListener.java,v $
Revision 1.9 2006/10/12 15:46:19 poth
adaption required to avoid allocating larger amounts of memory for each user session when using several WMC documents
Revision 1.8 2006/06/07 12:37:51 deshmukh
Reset the changes made to the WMPS.
Revision 1.6 2006/05/19 07:23:56 poth
bug fixes
Revision 1.5 2006/05/18 16:50:04 poth
*** empty log message ***
Revision 1.4 2006/05/17 17:05:44 poth
implementation completed (not tested)
********************************************************************** */