001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/ogcwebservices/wmps/WMPSDatabase.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005       Department of Geography, University of Bonn
006     and
007       lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035    ----------------------------------------------------------------------------*/
036    
037    package org.deegree.ogcwebservices.wmps;
038    
039    import java.awt.Color;
040    import java.io.ByteArrayInputStream;
041    import java.io.ByteArrayOutputStream;
042    import java.io.IOException;
043    import java.io.ObjectInputStream;
044    import java.io.ObjectOutputStream;
045    import java.sql.Connection;
046    import java.sql.PreparedStatement;
047    import java.sql.ResultSet;
048    import java.sql.SQLException;
049    import java.sql.Statement;
050    import java.sql.Timestamp;
051    import java.sql.Types;
052    import java.util.HashMap;
053    import java.util.Map;
054    
055    import org.deegree.framework.log.ILogger;
056    import org.deegree.framework.log.LoggerFactory;
057    import org.deegree.framework.util.StringTools;
058    import org.deegree.io.DBConnectionPool;
059    import org.deegree.model.crs.CRSFactory;
060    import org.deegree.model.crs.CoordinateSystem;
061    import org.deegree.model.crs.UnknownCRSException;
062    import org.deegree.model.spatialschema.Envelope;
063    import org.deegree.model.spatialschema.GeometryFactory;
064    import org.deegree.model.spatialschema.Point;
065    import org.deegree.ogcwebservices.wmps.configuration.CacheDatabase;
066    import org.deegree.ogcwebservices.wmps.operation.PrintMap;
067    import org.deegree.ogcwebservices.wmps.operation.TextArea;
068    import org.deegree.ogcwebservices.wms.operation.GetMap.Layer;
069    
070    /**
071     * Provides database functionalities for the wmps.
072     *
073     * @author <a href="mailto:deshmukh@lat-lon.de">Anup Deshmukh</a>
074     *
075     * @author last edited by: $Author: mschneider $
076     *
077     * @version 2.0, $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
078     *
079     * @since 2.0
080     */
081    
082    public class WMPSDatabase {
083    
084        private static final String WMPS_REQUEST_STORAGE_TABLE = "WMPS_REQUESTS";
085    
086        private static ILogger LOG = LoggerFactory.getLogger( WMPSDatabase.class );
087    
088        private CacheDatabase cacheDatabase;
089    
090        private DBConnectionPool pool;
091    
092        /**
093         * Creates a new WMPSDatabase instance.
094         *
095         * @param cacheDatabase
096         * @throws Exception
097         */
098        public WMPSDatabase( CacheDatabase cacheDatabase ) throws Exception {
099    
100            this.cacheDatabase = cacheDatabase;
101            this.pool = DBConnectionPool.getInstance();
102        }
103    
104        /**
105         * Creates a table, if no table exists. Used only for the HSQLDb
106         *
107         * @param connection
108         * @throws SQLException
109         * @throws PrintMapServiceException
110         */
111        private void createTable( Connection connection )
112                                throws SQLException {
113            /*
114             * PrintMap table structure
115             * id,processed,timestamp,version,layers,srs,boundingbox,center,scaledenominator,
116             * transparent,bgcolor,title,copyright,legend,scaleBar,note,template,emailaddress,
117             * textAreas,vendor
118             */
119            StringBuffer sqlCreateQuery = new StringBuffer( 500 );
120            sqlCreateQuery.append( "CREATE TABLE " ).append( WMPS_REQUEST_STORAGE_TABLE ).append( " ( " );
121            sqlCreateQuery.append( "id VARCHAR(15), " ).append( "processed VARCHAR(10), " );
122            sqlCreateQuery.append( "timestamp BIGINT, " ).append( "version VARCHAR(10), " );
123            sqlCreateQuery.append( "layers BINARY, " ).append( "srs VARCHAR(15), " );
124            sqlCreateQuery.append( "boundingbox VARCHAR(100), " ).append( "center VARCHAR(50), " );
125            sqlCreateQuery.append( "scaledenominator INTEGER, " ).append( "transparent BOOLEAN, " );
126            sqlCreateQuery.append( "bgcolor VARCHAR(10), " ).append( "title VARCHAR(100), " );
127            sqlCreateQuery.append( "copyright VARCHAR(50), " ).append( "legend BOOLEAN, " );
128            sqlCreateQuery.append( "scaleBar BOOLEAN, " ).append( "note VARCHAR(200), " );
129            sqlCreateQuery.append( "template VARCHAR(30), " ).append( "emailaddress VARCHAR(30), " );
130            sqlCreateQuery.append( "textAreas BINARY, " ).append( "vendor BINARY, " );
131            sqlCreateQuery.append( "PRIMARY KEY(id,timestamp) );" );
132    
133            String sqlTableCreation = sqlCreateQuery.toString();
134    
135            try {
136                Statement statement = connection.createStatement();
137                statement.execute( sqlTableCreation );
138                statement.close();
139            } catch ( SQLException e ) {
140                if ( !e.getMessage().startsWith( "Table already" ) ) {
141                    LOG.logError( e.getMessage(), e );
142                    throw new SQLException( "Unable to create a table for the sql command '" + sqlTableCreation + "'."
143                                            + e.getMessage() );
144                }
145            }
146    
147        }
148    
149        /**
150         * Inserts data into the table. Each incomming request is stored in the db.
151         *
152         * @param connection
153         * @param request
154         * @throws IOException
155         * @throws PrintMapServiceException
156         * @throws IOException
157         */
158        public void insertData( Connection connection, PrintMap request )
159                                throws PrintMapServiceException, IOException {
160    
161            /*
162             * PrintMap table structure
163             * id,processed,timestamp,version,layers,srs,boundingbox,center,scaledenominator,
164             * transparent,bgcolor,title,copyright,legend,scaleBar,note,template,emailaddress,
165             * textAreas,vendor
166             */
167            try {
168    
169                String id = request.getId();
170                String version = request.getVersion();
171                Layer[] layers = request.getLayers();
172                String srs = request.getSRS();
173                Envelope bbox = request.getBBOX();
174                Point center = request.getCenter();
175                int scaleDenominator = request.getScaleDenominator();
176                boolean transparent = request.getTransparent();
177                Color bgColor = request.getBGColor();
178                String title = request.getTitle();
179                String copyright = request.getCopyright();
180                boolean legend = request.getLegend();
181                boolean scaleBar = request.getScaleBar();
182                String note = request.getNote();
183                String template = request.getTemplate();
184                String emailAddress = request.getEmailAddress();
185                TextArea[] textAreas = request.getTextAreas();
186    
187                Map<String, String> vendorSpecificParams = request.getVendorSpecificParameters();
188                if ( vendorSpecificParams == null ) {
189                    vendorSpecificParams = new HashMap<String, String>();
190                }
191                long timestamp = request.getTimestamp().getTime();
192                String processed = "FALSE";
193    
194                String sql = StringTools.concat( 200, "INSERT INTO ", WMPS_REQUEST_STORAGE_TABLE,
195                                                 " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" );
196                PreparedStatement statement = connection.prepareStatement( sql );
197    
198                /*
199                 * PrintMap table structure
200                 * id,processed,timestamp,version,layers,srs,boundingbox,center,scaledenominator,
201                 * transparent,bgcolor,title,copyright,legend,scaleBar,note,template,emailaddress,
202                 * textAreas,vendor
203                 */
204                statement.setString( 1, id );
205                statement.setString( 2, processed );
206                statement.setLong( 3, timestamp );
207                statement.setString( 4, version );
208                statement.setBytes( 5, serialize( layers ) );
209                statement.setString( 6, srs );
210                if ( bbox != null ) {
211                    String bboxString = StringTools.concat( 200, bbox.getMin().getX(), ',', bbox.getMin().getY(), ',',
212                                                            bbox.getMax().getX(), ',', bbox.getMax().getY(), ',',
213                                                            bbox.getCoordinateSystem().getPrefixedName() );
214                    statement.setString( 7, bboxString );
215                } else {
216                    statement.setNull( 7, Types.VARCHAR );
217                }
218                if ( center != null ) {
219                    String centerString = StringTools.concat( 200, center.getX(), ',', center.getY(), ',',
220                                                              center.getCoordinateSystem().getPrefixedName() );
221                    statement.setString( 8, centerString );
222                } else {
223                    statement.setNull( 8, Types.VARCHAR );
224                }
225                statement.setInt( 9, scaleDenominator );
226                statement.setBoolean( 10, transparent );
227                if ( bgColor != null ) {
228                    String color = convertColorToHexString( bgColor );
229                    statement.setString( 11, color );
230                }
231                statement.setString( 12, title );
232                statement.setString( 13, copyright );
233                statement.setBoolean( 14, legend );
234                statement.setBoolean( 15, scaleBar );
235                statement.setString( 16, note );
236                statement.setString( 17, template );
237                statement.setString( 18, emailAddress );
238                statement.setBytes( 19, serialize( textAreas ) );
239    
240                if ( vendorSpecificParams != null ) {
241                    statement.setBytes( 20, serialize( vendorSpecificParams ) );
242                }
243    
244                statement.execute();
245                connection.commit();
246                statement.close();
247    
248            } catch ( SQLException e ) {
249                LOG.logError( e.getMessage(), e );
250                throw new PrintMapServiceException( "Error inserting data into the '" + WMPS_REQUEST_STORAGE_TABLE
251                                                    + "' table. " + e.getMessage() );
252            }
253    
254        }
255    
256        /**
257         * Creates a valid db connection with properties read from the configuration file.
258         *
259         * @return Connection
260         * @throws Exception
261         */
262        public Connection acquireConnection()
263                                throws Exception {
264    
265            String driver = this.cacheDatabase.getDriver();
266            String url = this.cacheDatabase.getUrl();
267            if ( this.pool == null ) {
268                this.pool = DBConnectionPool.getInstance();
269            }
270            Connection conn = this.pool.acquireConnection( driver, url, this.cacheDatabase.getUser(),
271                                                           this.cacheDatabase.getPassword() );
272    
273            try {
274                if ( driver.equals( "org.hsqldb.jdbcDriver" ) ) {
275                    createTable( conn );
276                }
277            } catch ( SQLException e ) {
278                LOG.logError( e.getMessage(), e );
279                throw new Exception( "Unable to build a valid connection to the 'hsqldb' "
280                                     + "database for the connection string '" + url + "'. " + e.getMessage() );
281            }
282    
283            return conn;
284        }
285    
286        /**
287         * Releases the current database connection.
288         *
289         * @param connection
290         * @throws SQLException
291         */
292        protected void releaseConnection( Connection connection )
293                                throws SQLException {
294    
295            try {
296                if ( this.pool != null ) {
297                    this.pool.releaseConnection( connection, this.cacheDatabase.getDriver(), this.cacheDatabase.getUrl(),
298                                                 this.cacheDatabase.getUser(), this.cacheDatabase.getPassword() );
299                }
300            } catch ( Exception e ) {
301                LOG.logError( e.getMessage(), e );
302                throw new SQLException( "Error releasing the open connection. " + e.getMessage() );
303            }
304    
305        }
306    
307        /**
308         * Select the PrintMap request that has been in the databank for the longest time. i.e the first
309         * in queue to be processed.
310         *
311         * @param connection
312         * @return PrintMap
313         * @throws PrintMapServiceException
314         */
315        public PrintMap selectPrintMapRequest( Connection connection )
316                                throws PrintMapServiceException {
317    
318            String sql = StringTools.concat( 200, "SELECT MAX( timestamp ) FROM ", WMPS_REQUEST_STORAGE_TABLE,
319                                             " WHERE processed = 'FALSE' " );
320            String selectionSQL = StringTools.concat( 200, "SELECT id, timestamp FROM ", WMPS_REQUEST_STORAGE_TABLE,
321                                                      " WHERE timestamp = (", sql, ");" );
322            String firstInQueue = null;
323            long timeStamp = -1;
324            try {
325                Statement statement = connection.createStatement();
326                ResultSet results = statement.executeQuery( selectionSQL );
327                while ( results.next() ) {
328                    firstInQueue = results.getString( "id" );
329                    timeStamp = results.getLong( 2 );
330                }
331                results.close();
332                statement.close();
333            } catch ( SQLException e ) {
334                LOG.logError( e.getMessage(), e );
335                throw new PrintMapServiceException( "Error retrieving data from the 'WMPSPrintMap' table for the "
336                                                    + "selectionSQL statement '" + selectionSQL + "'. " + e.getMessage() );
337            }
338    
339            return getPrintMapRequest( connection, firstInQueue, timeStamp );
340    
341        }
342    
343        /**
344         * Retrieve the PrintMap request from the DB for the id and convert the byte array back to a
345         * PrintMap request instance.
346         *
347         * @param connection
348         * @param firstInQueue
349         * @param timestamp
350         * @return PrintMapRequest
351         * @throws PrintMapServiceException
352         */
353        private PrintMap getPrintMapRequest( Connection connection, String firstInQueue, long timestamp )
354                                throws PrintMapServiceException {
355    
356            PrintMap request = null;
357            if ( firstInQueue == null ) {
358                return request;
359            }
360    
361            /*
362             * PrintMap table structure
363             * id,version,layers,srs,boundingBox,center,scaleDenominator,transparent,bgColor,title,copyright,
364             * legend,scaleBar,note,template,emailaddress,textAreas
365             */
366            String selectRequest = StringTools.concat( 400, "SELECT id, version, layers, srs, boundingbox, center,",
367                                                       "scaledenominator, transparent, bgcolor, title, copyright,",
368                                                       "legend, scalebar, note, template, emailaddress, ",
369                                                       "textAreas, vendor FROM ", WMPS_REQUEST_STORAGE_TABLE,
370                                                       " WHERE id='", firstInQueue, "' ", "AND timestamp=", timestamp );
371    
372            try {
373                Statement statement = connection.createStatement();
374    
375                ResultSet results = statement.executeQuery( selectRequest );
376    
377                while ( results.next() ) {
378                    String id = results.getString( 1 );
379                    String version = results.getString( 2 );
380                    byte[] b = results.getBytes( 3 );
381                    Layer[] layers = null;
382                    if ( b != null ) {
383                        Object object = deserialize( b );
384                        if ( object != null ) {
385                            layers = (Layer[]) object;
386                        }
387                    }
388                    String srs = results.getString( 4 );
389                    String bboxString = results.getString( 5 );
390                    Envelope bbox = null;
391                    if ( bboxString != null ) {
392                        String[] bboxArray = StringTools.toArray( bboxString, ",", false );
393                        if ( bboxArray.length == 5 ) {
394                            double minX = Double.valueOf( bboxArray[0] ).doubleValue();
395                            double minY = Double.valueOf( bboxArray[1] ).doubleValue();
396                            double maxX = Double.valueOf( bboxArray[2] ).doubleValue();
397                            double maxY = Double.valueOf( bboxArray[3] ).doubleValue();
398                            CoordinateSystem crs;
399                            try {
400                                crs = CRSFactory.create( bboxArray[4] );
401                            } catch ( UnknownCRSException e ) {
402                                throw new PrintMapServiceException( e.getMessage() );
403                            }
404                            bbox = GeometryFactory.createEnvelope( minX, minY, maxX, maxY, crs );
405                        }
406                    }
407                    String centerString = results.getString( 6 );
408                    Point center = null;
409                    if ( centerString != null ) {
410                        String[] centerArray = StringTools.toArray( centerString, ",", false );
411                        if ( centerArray.length == 3 ) {
412                            double x = Double.valueOf( centerArray[0] ).doubleValue();
413                            double y = Double.valueOf( centerArray[1] ).doubleValue();
414                            try {
415                                CoordinateSystem crs = CRSFactory.create( centerArray[2] );
416                                center = GeometryFactory.createPoint( x, y, crs );
417                            } catch ( UnknownCRSException e ) {
418                                throw new PrintMapServiceException( e.getMessage() );
419                            }
420                        }
421                    }
422                    /*
423                     * "scaledenominator, transparent, bgcolor, title, copyright,legend, scalebar, note,
424                     * template, emailaddress, textAreas, vendorspecificparams
425                     */
426                    int scaleDenominator = results.getInt( 7 );
427                    boolean transparent = results.getBoolean( 8 );
428                    String bgColorString = results.getString( 9 );
429                    Color bgColor = null;
430                    if ( bgColorString != null ) {
431                        bgColor = convertStringToColor( bgColorString );
432                    }
433                    String title = results.getString( 10 );
434                    String copyright = results.getString( 11 );
435                    boolean legend = results.getBoolean( 12 );
436                    boolean scaleBar = results.getBoolean( 13 );
437                    String note = results.getString( 14 );
438                    String template = results.getString( 15 );
439                    String emailAddress = results.getString( 16 );
440                    b = results.getBytes( 17 );
441                    TextArea[] textAreas = null;
442                    if ( b != null ) {
443                        Object object = deserialize( b );
444                        if ( object != null ) {
445                            textAreas = (TextArea[]) object;
446                        }
447                    }
448                    b = results.getBytes( 18 );
449                    Map<String, String> vendorSpecificParameters = (Map<String, String>) deserialize( b );
450    
451                    request = PrintMap.create( id, version, layers, srs, bbox, center, scaleDenominator, transparent,
452                                               bgColor, title, copyright, legend, scaleBar, note, template, emailAddress,
453                                               new Timestamp( timestamp ), textAreas, vendorSpecificParameters );
454                }
455                statement.close();
456    
457            } catch ( SQLException e ) {
458                LOG.logError( e.getMessage(), e );
459                throw new PrintMapServiceException( "Error executing the sql statement '" + selectRequest + "'. "
460                                                    + e.getMessage() );
461            } catch ( IOException e ) {
462                LOG.logError( e.getMessage(), e );
463                throw new PrintMapServiceException( "Error deserializing the result set. " + e.getMessage() );
464            } catch ( ClassNotFoundException e ) {
465                LOG.logError( e.getMessage(), e );
466                throw new PrintMapServiceException( "Error deserializing the result set. " + e.getMessage() );
467            }
468    
469            return request;
470        }
471    
472        /**
473         * Updating the processed field in the db to signify that the PrintMap request has been
474         * successfully carried out.
475         *
476         * @param connection
477         * @param id
478         * @param timeStamp
479         * @param state
480         * @throws SQLException
481         */
482        public void updateDB( Connection connection, String id, Timestamp timeStamp, String state )
483                                throws SQLException {
484    
485            String updateSQL = StringTools.concat( 200, "UPDATE ", WMPS_REQUEST_STORAGE_TABLE, " SET processed='", state,
486                                                   "' WHERE id='", id, "' AND timestamp=", timeStamp.getTime() );
487    
488            try {
489    
490                Statement statement = connection.createStatement();
491                int i = statement.executeUpdate( updateSQL );
492                if ( i == 0 ) {
493                    // TODO is this not an error?
494                } else if ( i == -1 ) {
495                    String s = StringTools.concat( 200, "Error executing the update statement. Could not update row in ",
496                                                   "the DB for id='", id, "and timestamp='", timeStamp, '.' );
497                    throw new SQLException( s );
498                }
499                connection.commit();
500                statement.close();
501    
502            } catch ( SQLException e ) {
503                LOG.logError( e.getMessage(), e );
504                String s = StringTools.concat( 200, "Error executing the update statement. Could not update row ",
505                                               "in the DB for id='", id, "and timestamp='", timeStamp, ". ", e.getMessage() );
506                throw new SQLException( s );
507            }
508    
509        }
510    
511        /**
512         * Convert the object to a byte array.
513         *
514         * @param object
515         * @return byte[]
516         * @throws IOException
517         */
518        private synchronized byte[] serialize( Object object )
519                                throws IOException {
520    
521            byte[] b = null;
522            ByteArrayOutputStream bos = new ByteArrayOutputStream( 10000 );
523            try {
524                ObjectOutputStream oos = new ObjectOutputStream( bos );
525                oos.writeObject( object );
526                oos.close();
527            } catch ( IOException e ) {
528                LOG.logError( e.getMessage(), e );
529                throw new IOException( "Error converting the current object to an array of bytes. " + e.getMessage() );
530            }
531            b = bos.toByteArray();
532            bos.close();
533    
534            return b;
535    
536        }
537    
538        /**
539         * Reserialize the byte array to a PrintMap instance.
540         *
541         * @param b
542         * @return Object
543         * @throws IOException
544         * @throws ClassNotFoundException
545         */
546        private synchronized Object deserialize( byte[] b )
547                                throws IOException, ClassNotFoundException {
548    
549            Object object = null;
550            try {
551                ByteArrayInputStream bai = new ByteArrayInputStream( b );
552                ObjectInputStream in = new ObjectInputStream( bai );
553                object = in.readObject();
554                in.close();
555            } catch ( IOException e ) {
556                LOG.logError( e.getMessage(), e );
557                throw new IOException( "Error opening ObjectInputStream to reserialize the byte "
558                                       + "array back to the original instance. " + e.getMessage() );
559            } catch ( ClassNotFoundException e ) {
560                LOG.logError( e.getMessage(), e );
561                throw new ClassNotFoundException( "Error recasting the ObjectInputStream "
562                                                  + "retrieved Object to the original instance. "
563                                                  + "The wrong data may have been stored in the DB "
564                                                  + "or the DB instance is inconsistent. " + e.getMessage() );
565            }
566    
567            return object;
568        }
569    
570        /**
571         * Convert a "#FFFFFF" hex string to a Color. If the color specification is bad, an attempt will
572         * be made to fix it up.
573         *
574         * @param value
575         * @return Color
576         */
577        private Color hexToColor( String value ) {
578    
579            if ( value.startsWith( "#" ) ) {
580                String digits = value.substring( 1, Math.min( value.length(), 7 ) );
581                String hstr = "0x" + digits;
582                return Color.decode( hstr );
583            }
584            return null;
585    
586        }
587    
588        /**
589         * Convert a color string "RED" or "#NNNNNN" to a Color. Note: This will only convert the
590         * HTML3.2 colors strings or string of length 7 otherwise, it will return Color.white.
591         *
592         * @param str
593         * @return Color
594         */
595        private Color convertStringToColor( String str ) {
596    
597            if ( str != null ) {
598                if ( str.charAt( 0 ) == '#' ) {
599                    return hexToColor( str );
600                } else if ( str.equalsIgnoreCase( "Black" ) ) {
601                    return hexToColor( "#000000" );
602                } else if ( str.equalsIgnoreCase( "Silver" ) ) {
603                    return hexToColor( "#C0C0C0" );
604                } else if ( str.equalsIgnoreCase( "Gray" ) ) {
605                    return hexToColor( "#808080" );
606                } else if ( str.equalsIgnoreCase( "White" ) ) {
607                    return hexToColor( "#FFFFFF" );
608                } else if ( str.equalsIgnoreCase( "Maroon" ) ) {
609                    return hexToColor( "#800000" );
610                } else if ( str.equalsIgnoreCase( "Red" ) ) {
611                    return hexToColor( "#FF0000" );
612                } else if ( str.equalsIgnoreCase( "Purple" ) ) {
613                    return hexToColor( "#800080" );
614                } else if ( str.equalsIgnoreCase( "Fuchsia" ) ) {
615                    return hexToColor( "#FF00FF" );
616                } else if ( str.equalsIgnoreCase( "Green" ) ) {
617                    return hexToColor( "#008000" );
618                } else if ( str.equalsIgnoreCase( "Lime" ) ) {
619                    return hexToColor( "#00FF00" );
620                } else if ( str.equalsIgnoreCase( "Olive" ) ) {
621                    return hexToColor( "#808000" );
622                } else if ( str.equalsIgnoreCase( "Yellow" ) ) {
623                    return hexToColor( "#FFFF00" );
624                } else if ( str.equalsIgnoreCase( "Navy" ) ) {
625                    return hexToColor( "#000080" );
626                } else if ( str.equalsIgnoreCase( "Blue" ) ) {
627                    return hexToColor( "#0000FF" );
628                } else if ( str.equalsIgnoreCase( "Teal" ) ) {
629                    return hexToColor( "#008080" );
630                } else if ( str.equalsIgnoreCase( "Aqua" ) ) {
631                    return hexToColor( "#00FFFF" );
632                }
633            }
634            return null;
635        }
636    
637        /**
638         * convert a color to its hex string.
639         *
640         * @param c
641         * @return String
642         */
643        private String convertColorToHexString( Color c ) {
644            String str = Integer.toHexString( c.getRGB() & 0xFFFFFF );
645            return ( "#" + "000000".substring( str.length() ) + str.toUpperCase() );
646        }
647    
648    }