001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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: apoth $
076     *
077     * @version 2.0, $Revision: 21175 $, $Date: 2009-12-02 15:24:50 +0100 (Mi, 02 Dez 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(50), " ).append( "processed VARCHAR(10), " );
122            sqlCreateQuery.append( "timestamp BIGINT, " ).append( "version VARCHAR(10), " );
123            sqlCreateQuery.append( "layers BINARY, " ).append( "srs VARCHAR(150), " );
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(300), " );
127            sqlCreateQuery.append( "copyright VARCHAR(150), " ).append( "legend BOOLEAN, " );
128            sqlCreateQuery.append( "scaleBar BOOLEAN, " ).append( "note VARCHAR(800), " );
129            sqlCreateQuery.append( "template VARCHAR(30), " ).append( "emailaddress VARCHAR(150), " );
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                // hack to support DPI
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() + "&" + request.getDpi();
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        @SuppressWarnings("unchecked")
354        private PrintMap getPrintMapRequest( Connection connection, String firstInQueue, long timestamp )
355                                throws PrintMapServiceException {
356    
357            PrintMap request = null;
358            if ( firstInQueue == null ) {
359                return request;
360            }
361    
362            /*
363             * PrintMap table structure
364             * id,version,layers,srs,boundingBox,center,scaleDenominator,transparent,bgColor,title,copyright,
365             * legend,scaleBar,note,template,emailaddress,textAreas
366             */
367            String selectRequest = StringTools.concat( 400, "SELECT id, version, layers, srs, boundingbox, center,",
368                                                       "scaledenominator, transparent, bgcolor, title, copyright,",
369                                                       "legend, scalebar, note, template, emailaddress, ",
370                                                       "textAreas, vendor FROM ", WMPS_REQUEST_STORAGE_TABLE,
371                                                       " WHERE id='", firstInQueue, "' ", "AND timestamp=", timestamp );
372    
373            try {
374                Statement statement = connection.createStatement();
375    
376                ResultSet results = statement.executeQuery( selectRequest );
377    
378                while ( results.next() ) {
379                    String id = results.getString( 1 );                
380                    String version = results.getString( 2 );
381                    byte[] b = results.getBytes( 3 );
382                    Layer[] layers = null;
383                    if ( b != null ) {
384                        Object object = deserialize( b );
385                        if ( object != null ) {
386                            layers = (Layer[]) object;
387                        }
388                    }
389                    String srs = results.getString( 4 );
390                    String bboxString = results.getString( 5 );
391                    Envelope bbox = null;
392                    if ( bboxString != null ) {
393                        String[] bboxArray = StringTools.toArray( bboxString, ",", false );
394                        if ( bboxArray.length == 5 ) {
395                            double minX = Double.valueOf( bboxArray[0] ).doubleValue();
396                            double minY = Double.valueOf( bboxArray[1] ).doubleValue();
397                            double maxX = Double.valueOf( bboxArray[2] ).doubleValue();
398                            double maxY = Double.valueOf( bboxArray[3] ).doubleValue();
399                            CoordinateSystem crs;
400                            try {
401                                crs = CRSFactory.create( bboxArray[4] );
402                            } catch ( UnknownCRSException e ) {
403                                throw new PrintMapServiceException( e.getMessage() );
404                            }
405                            bbox = GeometryFactory.createEnvelope( minX, minY, maxX, maxY, crs );
406                        }
407                    }
408                    String centerString = results.getString( 6 );
409                    Point center = null;
410                    if ( centerString != null ) {
411                        String[] centerArray = StringTools.toArray( centerString, ",", false );
412                        if ( centerArray.length == 3 ) {
413                            double x = Double.valueOf( centerArray[0] ).doubleValue();
414                            double y = Double.valueOf( centerArray[1] ).doubleValue();
415                            try {
416                                CoordinateSystem crs = CRSFactory.create( centerArray[2] );
417                                center = GeometryFactory.createPoint( x, y, crs );
418                            } catch ( UnknownCRSException e ) {
419                                throw new PrintMapServiceException( e.getMessage() );
420                            }
421                        }
422                    }
423                    /*
424                     * "scaledenominator, transparent, bgcolor, title, copyright,legend, scalebar, note,
425                     * template, emailaddress, textAreas, vendorspecificparams
426                     */
427                    int scaleDenominator = results.getInt( 7 );
428                    boolean transparent = results.getBoolean( 8 );
429                    String bgColorString = results.getString( 9 );
430                    Color bgColor = null;
431                    if ( bgColorString != null ) {
432                        bgColor = convertStringToColor( bgColorString );
433                    }
434                    String title = results.getString( 10 );
435                    String copyright = results.getString( 11 );
436                    boolean legend = results.getBoolean( 12 );
437                    boolean scaleBar = results.getBoolean( 13 );
438                    String note = results.getString( 14 );
439                    String template = results.getString( 15 );
440                    // hack to support DPI
441                    String[] tmp = StringTools.toArray( template, "&", false );
442                    template = tmp[0];
443                    int dpi = -1;
444                    if ( tmp.length == 2 ) {
445                        dpi = Integer.parseInt( tmp[1] );
446                    }
447                    String emailAddress = results.getString( 16 );
448                    b = results.getBytes( 17 );
449                    TextArea[] textAreas = null;
450                    if ( b != null ) {
451                        Object object = deserialize( b );
452                        if ( object != null ) {
453                            textAreas = (TextArea[]) object;
454                        }
455                    }
456                    b = results.getBytes( 18 );
457                    Map<String, String> vendorSpecificParameters = (Map<String, String>) deserialize( b );
458    
459                    request = PrintMap.create( id, version, layers, srs, bbox, center, scaleDenominator, transparent,
460                                               bgColor, title, copyright, legend, scaleBar, note, template, emailAddress,
461                                               new Timestamp( timestamp ), textAreas, dpi, vendorSpecificParameters );
462                }
463                statement.close();
464    
465            } catch ( SQLException e ) {
466                LOG.logError( e.getMessage(), e );
467                throw new PrintMapServiceException( "Error executing the sql statement '" + selectRequest + "'. "
468                                                    + e.getMessage() );
469            } catch ( IOException e ) {
470                LOG.logError( e.getMessage(), e );
471                throw new PrintMapServiceException( "Error deserializing the result set. " + e.getMessage() );
472            } catch ( ClassNotFoundException e ) {
473                LOG.logError( e.getMessage(), e );
474                throw new PrintMapServiceException( "Error deserializing the result set. " + e.getMessage() );
475            }
476    
477            return request;
478        }
479    
480        /**
481         * Updating the processed field in the db to signify that the PrintMap request has been
482         * successfully carried out.
483         *
484         * @param connection
485         * @param id
486         * @param timeStamp
487         * @param state
488         * @throws SQLException
489         */
490        public void updateDB( Connection connection, String id, Timestamp timeStamp, String state )
491                                throws SQLException {
492    
493            String updateSQL = StringTools.concat( 200, "UPDATE ", WMPS_REQUEST_STORAGE_TABLE, " SET processed='", state,
494                                                   "' WHERE id='", id, "' AND timestamp=", timeStamp.getTime() );
495    
496            try {
497    
498                Statement statement = connection.createStatement();
499                int i = statement.executeUpdate( updateSQL );
500                if ( i == 0 ) {
501                    // TODO is this not an error?
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    }