001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/wmps/DefaultRequestManager.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2006 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstr. 19
030     53115 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041    
042     ---------------------------------------------------------------------------*/
043    package org.deegree.ogcwebservices.wmps;
044    
045    import java.sql.Connection;
046    
047    import javax.mail.internet.AddressException;
048    import javax.mail.internet.InternetAddress;
049    
050    import org.deegree.framework.log.ILogger;
051    import org.deegree.framework.log.LoggerFactory;
052    import org.deegree.framework.mail.EMailMessage;
053    import org.deegree.framework.mail.MailHelper;
054    import org.deegree.framework.mail.MailMessage;
055    import org.deegree.framework.mail.SendMailException;
056    import org.deegree.framework.mail.UnknownMimeTypeException;
057    import org.deegree.framework.xml.NamespaceContext;
058    import org.deegree.framework.xml.XMLFragment;
059    import org.deegree.framework.xml.XMLParsingException;
060    import org.deegree.framework.xml.XMLTools;
061    import org.deegree.ogcbase.CommonNamespaces;
062    import org.deegree.ogcwebservices.OGCWebServiceException;
063    import org.deegree.ogcwebservices.wmps.configuration.CacheDatabase;
064    import org.deegree.ogcwebservices.wmps.configuration.WMPSConfiguration;
065    import org.deegree.ogcwebservices.wmps.operation.PrintMap;
066    import org.deegree.ogcwebservices.wmps.operation.PrintMapResponse;
067    import org.deegree.ogcwebservices.wmps.operation.PrintMapResponseDocument;
068    import org.w3c.dom.Element;
069    
070    /**
071     * Default Handler to save the PrintMap requests to the 'HSQLDB' and send email after processing the
072     * request.
073     * 
074     * @author <a href="mailto:deshmukh@lat-lon.de">Anup Deshmukh</a>
075     * @author last edited by: $Author:wanhoff$
076     * 
077     * @version $Revision: 6289 $, $Date:20.03.2007$
078     */
079    public class DefaultRequestManager implements RequestManager {
080    
081        private static final ILogger LOG = LoggerFactory.getLogger( DefaultRequestManager.class );
082    
083        protected static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
084    
085        private WMPSConfiguration configuration;
086    
087        private final String MIMETYPE = "text/html";
088    
089        private PrintMap request;
090    
091        /**
092         * Creates a new DefaultRequestManager instance.
093         * 
094         * @param configuration
095         * @param request
096         *            request to perform
097         */
098        public DefaultRequestManager( WMPSConfiguration configuration, PrintMap request ) {
099            this.configuration = configuration;
100            this.request = request;
101        }
102    
103        /**
104         * returns the configuration used by the handler
105         * 
106         * @return WMPSConfiguration
107         */
108        public WMPSConfiguration getConfiguration() {
109            return this.configuration;
110    
111        }
112    
113        /**
114         * returns the request used by the handler
115         * 
116         * @return PrintMap request
117         */
118        public PrintMap getRequest() {
119            return this.request;
120    
121        }
122    
123        /**
124         * Opens a connection to a database based on the properties file in the resources directory and
125         * saves the current PrintMap request in the table for later access.
126         * 
127         * @throws OGCWebServiceException
128         */
129        public synchronized void saveRequestToDB()
130                                throws OGCWebServiceException {
131    
132            try {
133                CacheDatabase cacheDatabase = this.configuration.getDeegreeParams().getCacheDatabase();
134                WMPSDatabase dbConnection = new WMPSDatabase( cacheDatabase );
135                Connection connection = dbConnection.acquireConnection();
136                dbConnection.insertData( connection, this.request );
137                dbConnection.releaseConnection( connection );
138            } catch ( Exception e ) {
139                LOG.logError( e.getMessage(), e );
140                throw new OGCWebServiceException( "Error creating a 'WMPSDatabase' object and setting "
141                                                  + "up a connection. " + e.getMessage() );
142            }
143    
144        }
145    
146        /**
147         * Send an intial response back to the user, depending on whether the request has been
148         * successfull saved in the DB or not. The email address from the request is used to send the
149         * reply.
150         * 
151         * @param message
152         * @param success
153         *            to denote whether the operation was a success or not
154         * @return PrintMapResponseDocument
155         * @throws OGCWebServiceException
156         */
157        public PrintMapResponseDocument createInitialResponse( String message )
158                                throws OGCWebServiceException {
159    
160            // before the print operation is finished stage.
161            PrintMapResponse initialResponse = new PrintMapResponse( this.request.getId(),
162                                                                     this.request.getEmailAddress(),
163                                                                     this.request.getTimestamp(),
164                                                                     this.request.getTimestamp(),
165                                                                     message, "" );
166    
167            PrintMapResponseDocument document;
168            try {
169                document = XMLFactory.export( initialResponse );
170    
171            } catch ( XMLParsingException e ) {
172                LOG.logError( e.getMessage(), e );
173                String msg = "Error creating a 'PrintMapResponseDocument' object."
174                             + " Please check the 'WMPSInitialResponseTemplate' for XML errors. "
175                             + e.getMessage();
176                throw new OGCWebServiceException( msg );
177            }
178    
179            return document;
180        }
181    
182        /**
183         * Send an Email to the address provided in the PrintMap request.
184         * 
185         * @param response
186         * @throws OGCWebServiceException
187         */
188        public void sendEmail( PrintMapResponseDocument response )
189                                throws OGCWebServiceException {
190    
191            XMLFragment doc = new XMLFragment( response.getRootElement() );
192            Element root = doc.getRootElement();
193            String id = root.getAttribute( "id" );
194            String toEmailAddress = null;
195            String timestamp = null;
196            String message = null;
197            // String processingTime = null;
198            try {
199                String xPath = "deegreewmps:EmailAddress";
200                toEmailAddress = XMLTools.getRequiredNodeAsString( root, xPath, nsContext );
201                if ( !isValidEmailAddress( toEmailAddress ) ) {
202                    throw new PrintMapServiceException( "Incorrect email address '" + toEmailAddress
203                                                        + "' in the PrintMap request. Please enter a "
204                                                        + "valid email address before trying again. " );
205                }
206                timestamp = XMLTools.getRequiredNodeAsString( root, "deegreewmps:Timestamp", nsContext );
207                message = XMLTools.getRequiredNodeAsString( root, "deegreewmps:Message", nsContext );
208                xPath = "deegreewmps:ExpectedProcessingTime";
209                // TODO
210                // processingTime = XMLTools.getNodeAsString( root, xPath, nsContext, null );
211            } catch ( XMLParsingException e ) {
212                LOG.logError( e.getMessage(), e );
213                throw new OGCWebServiceException( "Error parsing the initial response document to "
214                                                  + "retrieve the email address and "
215                                                  + "'PrintMap' request id. " + e.getMessage() );
216            }
217            String fromEmailAddress = this.configuration.getDeegreeParams().getPrintMapParam().getAdminMailAddress();
218    
219            if ( !isValidEmailAddress( fromEmailAddress ) ) {
220                throw new PrintMapServiceException( "Incorrect email address '" + fromEmailAddress
221                                                    + "' in the 'WMPSPrintMap.properties' "
222                                                    + "file. Please enter a valid email address "
223                                                    + "before trying again. " );
224            }
225            String subject = "PrintMap Notification: " + id + ' ' + timestamp;
226    
227            MailMessage email;
228            try {
229                email = new EMailMessage( fromEmailAddress, toEmailAddress, subject, message,
230                                          this.MIMETYPE );
231            } catch ( UnknownMimeTypeException e ) {
232                throw new OGCWebServiceException( "Unknown mime type set." + e );
233            }
234            String mailHost = this.configuration.getDeegreeParams().getPrintMapParam().getMailHost();
235            try {
236    
237                MailHelper.createAndSendMail( email, mailHost );
238            } catch ( SendMailException e ) {
239                LOG.logError( e.getMessage(), e );
240                throw new OGCWebServiceException( "Error sending an email notification on '"
241                                                  + toEmailAddress + "' for the server configuration '"
242                                                  + mailHost + "'. " + e.getMessage() );
243            }
244    
245        }
246    
247        /**
248         * Check if the email address is valid and has a valid name and domain string.
249         * 
250         * @param aEmailAddress
251         * @return boolean
252         */
253        private boolean hasNameAndDomain( String aEmailAddress ) {
254    
255            String[] tokens = aEmailAddress.split( "@" );
256            return tokens.length == 2 && ( ( tokens[0] != null ) || ( tokens[0] != "" ) )
257                   && ( ( tokens[1] != null ) || ( tokens[1] != "" ) );
258        }
259    
260        /**
261         * Check email add validity.
262         * 
263         * @param aEmailAddress
264         * @return boolean
265         */
266        private boolean isValidEmailAddress( String aEmailAddress ) {
267    
268            String status = "VALID";
269            if ( aEmailAddress == null )
270                status = "NOTVALID";
271    
272            try {
273                new InternetAddress( aEmailAddress );
274                if ( !hasNameAndDomain( aEmailAddress ) ) {
275                    status = "NOTVALID";
276                }
277            } catch ( AddressException ex ) {
278                status = "NOTVALID " + ex.getMessage();
279            }
280    
281            return status.startsWith( "VALID" );
282        }
283    
284        /**
285         * Export the PrintMap service final response to a PrintMapResponseDocument.
286         * 
287         * @param message
288         * @param exception
289         * @return PrintMapResponseDocument
290         * @throws OGCWebServiceException
291         */
292        public PrintMapResponseDocument createFinalResponse( String message, String exception )
293                                throws OGCWebServiceException {
294    
295            PrintMapResponse finalResponse = new PrintMapResponse( this.request.getId(),
296                                                                   this.request.getEmailAddress(),
297                                                                   this.request.getTimestamp(),
298                                                                   this.request.getTimestamp(),
299                                                                   message, exception );
300    
301            PrintMapResponseDocument document;
302            try {
303                document = XMLFactory.export( finalResponse );
304    
305            } catch ( XMLParsingException e ) {
306                LOG.logError( e.getMessage(), e );
307                String msg = "Error creating a 'PrintMapResponseDocument' object."
308                             + " Please check the 'WMPSInitialResponseTemplate' for XML errors. "
309                             + e.getMessage();
310                throw new OGCWebServiceException( msg );
311            }
312    
313            return document;
314        }
315    }