001    //$HeadURL: svn+ssh://mschneider@svn.wald.intevation.org/deegree/base/trunk/src/org/deegree/io/datastore/sql/wherebuilder/AbstractPropertyNode.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    package org.deegree.io.datastore.sql.wherebuilder;
044    
045    import java.util.ArrayList;
046    import java.util.List;
047    
048    /**
049     * Represents a <code>String</code> that may contain special symbols (wildCard, singleChar, escape) as a list of its
050     * parts ({@link SpecialCharStringPart}).
051     * <p>
052     * The internal representation needs no escape symbols.
053     * 
054     * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </a>
055     * @author last edited by: $Author: mschneider $
056     * 
057     * @version $Revision: 6588 $, $Date: 2007-04-11 17:31:29 +0200 (Mi, 11 Apr 2007) $
058     */
059    public class SpecialCharString {
060    
061        private List<SpecialCharStringPart> parts;
062    
063        private String wildCard;
064    
065        private String singleChar;
066    
067        private String escape;
068    
069        /**
070         * Constructs a new <code>SpecialCharString</code> instance from the given parameters.
071         * 
072         * @param encodedString
073         * @param wildCard
074         * @param singleChar
075         * @param escape
076         */
077        public SpecialCharString( String encodedString, String wildCard, String singleChar, String escape ) {
078            this.wildCard = wildCard;
079            this.singleChar = singleChar;
080            this.escape = escape;
081            this.parts = decode( encodedString );
082        }
083    
084        /**
085         * Decodes the given <code>String</code> to a representation that contains explicit objects to represent wildCard
086         * and singleChar symbols and has no escape symbols.
087         * 
088         * @param text
089         *            encoded <code>String</code>, may contain wildCard, singleChar and escape symbols
090         * @return decoded text
091         */
092        private List<SpecialCharStringPart> decode( String text ) {
093    
094            List<SpecialCharStringPart> parts = new ArrayList<SpecialCharStringPart>( text.length() );
095    
096            boolean escapeMode = false;
097    
098            StringBuffer sb = null;
099            while ( text.length() > 0 ) {
100                if ( escapeMode ) {
101                    if ( sb == null ) {
102                        sb = new StringBuffer();
103                    }
104                    sb.append( text.charAt( 0 ) );
105                    text = text.substring( 1 );
106                    escapeMode = false;
107                } else {
108                    if ( text.startsWith( wildCard ) ) {
109                        if ( sb != null ) {
110                            parts.add( new PlainText( sb.toString() ) );
111                            sb = null;
112                        }
113                        parts.add( new WildCard() );
114                        text = text.substring( wildCard.length() );
115                    } else if ( text.startsWith( singleChar ) ) {
116                        if ( sb != null ) {
117                            parts.add( new PlainText( sb.toString() ) );
118                            sb = null;
119                        }
120                        parts.add( new SingleChar() );
121                        text = text.substring( singleChar.length() );
122                    } else if ( text.startsWith( escape ) ) {
123                        text = text.substring( escape.length() );
124                        escapeMode = true;
125                    } else {
126                        if ( sb == null ) {
127                            sb = new StringBuffer();
128                        }
129                        sb.append( text.charAt( 0 ) );
130                        text = text.substring( 1 );
131                    }
132                }
133            }
134    
135            if ( sb != null ) {
136                parts.add( new PlainText( sb.toString() ) );
137            }
138            return parts;
139        }
140    
141        /**
142         * Returns an encoding that is suitable for arguments of "IS LIKE"-clauses in SQL.
143         * <p>
144         * This means:
145         * <ul>
146         * <li>wildCard: encoded as the '%'-character</li>
147         * <li>singleChar: encoded as the '_'-character</li>
148         * <li>escape: encoded as the '\'-character</li>
149         * </ul>
150         * 
151         * @return encoded string
152         */
153        public String toSQLStyle() {
154            StringBuffer sb = new StringBuffer();
155            for ( SpecialCharStringPart part : parts ) {
156                sb.append( part.toSQLStyle() );
157            }
158            return sb.toString();
159        }
160    
161        /**
162         * Returns an encoding that is suitable for arguments of "IS LIKE"-clauses in SQL.
163         * <p>
164         * This means:
165         * <ul>
166         * <li>wildCard: encoded as the '%'-character</li>
167         * <li>singleChar: encoded as the '_'-character</li>
168         * <li>escape: encoded as the '\'-character</li>
169         * </ul>
170         * 
171         * @param toLowerCase
172         *            true means: convert to lowercase letters
173         * @return encoded string
174         */
175        public String toSQLStyle( boolean toLowerCase ) {
176            StringBuffer sb = new StringBuffer();
177            for ( SpecialCharStringPart part : parts ) {
178                sb.append( part.toSQLStyle( toLowerCase ) );
179            }
180            return sb.toString();
181        }
182    
183        @Override
184        public String toString() {
185            StringBuffer sb = new StringBuffer();
186            for ( SpecialCharStringPart part : parts ) {
187                sb.append( part.toString() );
188                sb.append( '\n' );
189            }
190            return sb.toString();
191        }
192    }