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