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