EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.iapi.util]

COVERAGE SUMMARY FOR SOURCE FILE [IdUtil.java]

nameclass, %method, %block, %line, %
IdUtil.java100% (1/1)92%  (23/25)81%  (670/825)79%  (159.4/203)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class IdUtil100% (1/1)92%  (23/25)81%  (670/825)79%  (159.4/203)
IdUtil (): void 0%   (0/1)0%   (0/3)0%   (0/1)
appendId (String, String): String 100% (1/1)100% (15/15)100% (3/3)
deleteId (String, String): String 100% (1/1)96%  (44/46)95%  (9.5/10)
delimitId (String): String 100% (1/1)90%  (37/41)90%  (9/10)
dups (String []): String 100% (1/1)95%  (40/42)94%  (7.5/8)
idChar (boolean, int): boolean 100% (1/1)95%  (41/43)86%  (6/7)
idOnList (String, String): boolean 100% (1/1)100% (25/25)100% (5/5)
intersect (String [], String []): String 100% (1/1)100% (51/51)100% (6/6)
mkIdList (String []): String 100% (1/1)86%  (24/28)87%  (4.3/5)
mkIdListAsEntered (String []): String 100% (1/1)100% (27/27)100% (5/5)
mkQualifiedName (String []): String 100% (1/1)100% (28/28)100% (5/5)
mkQualifiedName (String, String): String 100% (1/1)84%  (16/19)67%  (2/3)
parseDbClassPath (String, boolean): String [][] 100% (1/1)63%  (46/73)65%  (15/23)
parseId (String): String 100% (1/1)100% (14/14)100% (4/4)
parseId (StringReader, boolean, boolean): String 100% (1/1)74%  (23/31)70%  (7/10)
parseIdList (String): String [] 100% (1/1)100% (17/17)100% (5/5)
parseIdList (StringReader, boolean): String [] 100% (1/1)68%  (40/59)66%  (12.6/19)
parseQId (StringReader, boolean): String 100% (1/1)84%  (52/62)82%  (14.8/18)
parseQualifiedName (String, boolean): String [] 100% (1/1)100% (13/13)100% (4/4)
parseQualifiedName (StringReader, boolean): String [] 100% (1/1)88%  (38/43)86%  (12/14)
parseUnQId (StringReader, boolean, boolean): String 100% (1/1)93%  (41/44)97%  (8.7/9)
pruneDups (String): String 0%   (0/1)0%   (0/53)0%   (0/11)
vectorToIdList (Vector, boolean): String 100% (1/1)100% (20/20)100% (6/6)
verifyEmpty (Reader): void 100% (1/1)64%  (9/14)67%  (4/6)
verifyListEmpty (StringReader): void 100% (1/1)64%  (9/14)67%  (4/6)

1/*
2 
3   Derby - Class com.ihost.cs.IdUtil
4 
5   Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.iapi.util;
22 
23import org.apache.derby.iapi.reference.Attribute;
24import org.apache.derby.iapi.reference.SQLState;
25import org.apache.derby.iapi.reference.Property;
26import org.apache.derby.iapi.error.StandardException;
27import java.io.IOException;
28import java.io.StringReader;
29import java.util.Vector;
30import java.util.HashSet;
31import java.util.Properties;
32 
33/**
34  Utility class for parsing and producing string representations of
35  ids. This class supports both delimited and un-delimited ids.
36 
37  <P>The syntax for an id follows. 
38  <PRE>
39      id := delim-id | unDelim-id
40 
41          delim-id := "[""|[any char but quote]]+"
42          undelim-id := (a-z|A-Z|anyunicodeletter)[a-z|A-Z|_|0-9|anyunicodeletter|anyunicodedigit]*
43 
44          In the syntax braces show grouping. '*' means repeat 0 or more times.
45          '|' means or. '+' means repeat 1 or more times. 
46  </PRE>
47 
48  <P>In addition this class provides support for qualified names. A qualified name
49  is a dot (.) separated list of ids.
50 
51  <P>Limitations:
52  <OL>
53  <LI>Unicode escape sequences in ids are not supported.
54  <LI>Escape sequences (\n...) are not supported.
55  </OL>
56  */
57public abstract class IdUtil
58{
59        /**
60          Delimit the identifier provided.
61          @return the delimited identifier.
62          */
63        public static String delimitId(String id)
64        {
65                StringBuffer quotedBuffer = new StringBuffer();
66                quotedBuffer.append('\"');
67            char[] charArray = id.toCharArray();
68 
69                for (int ix = 0; ix < charArray.length; ix++){
70                        char currentChar = charArray[ix];
71                        quotedBuffer.append(currentChar);
72                        if (currentChar == '\"')
73                                quotedBuffer.append('\"');
74                }
75                quotedBuffer.append('\"');
76                
77                return quotedBuffer.toString();
78        }
79 
80        /**
81          Produce a delimited two part qualified name from two
82          un-delimited identifiers.
83          @return the result.
84          */
85        public static String mkQualifiedName(String id1,
86                                                                                 String id2)
87        {
88        if( null == id1)
89            return delimitId(id2);
90                return
91                        delimitId(id1) +
92                        "." +
93                        delimitId(id2);
94        }
95 
96        /**
97          Make a string form of a qualified name from the array of ids provided.
98          */
99        public static String mkQualifiedName(String[] ids)
100        {
101                StringBuffer sb = new StringBuffer();
102                for (int ix=0; ix < ids.length; ix++)
103                {
104                        if (ix!=0) sb.append(".");
105                        sb.append(delimitId(ids[ix]));
106                }
107                return sb.toString();
108        }
109 
110        /**
111          Scan a qualified name from the String provided. Raise an excepion
112          if the string does not contain a qualified name.
113      
114      @param s The string to be parsed
115      @param normalizeToUpper If true then undelimited names are converted to upper case (the ANSI standard). If false then undelimited names are converted to lower case (used when the source database is Informix Foundation).
116      @return An array of strings made by breaking the input string at its dots, '.'.
117          @exception StandardException Oops
118          */
119        public static String[] parseQualifiedName(String s, boolean normalizeToUpper)
120                 throws StandardException
121        {
122                StringReader r = new StringReader(s);
123                String[] qName = parseQualifiedName(r, normalizeToUpper);
124                verifyEmpty(r);
125                return qName;
126        }
127 
128        /**
129          Scan a qualified name from a StringReader. Return an array
130          of Strings with 1 entry per name scanned. Raise an exception
131          if the StringReader does not contain a valid qualified name.
132 
133      @param r A StringReader for the string to be parsed
134      @param normalizeToUpper If true then undelimited names are converted to upper case (the ANSI standard). If false then undelimited names are converted to lower case (used when the source database is Informix Foundation).
135      @return An array of strings made by breaking the input string at its dots, '.'.
136          @exception StandardException Oops
137          */
138        public static String[] parseQualifiedName(StringReader r, boolean normalizeToUpper)
139                 throws StandardException
140        {
141                Vector v = new Vector();
142                while (true)
143                {
144                        String thisId = parseId(r,true, normalizeToUpper);
145                        v.addElement(thisId);
146                        int dot;
147 
148                        try {
149                                r.mark(0);
150                                dot = r.read();
151                                if (dot != '.')
152                                {
153                                        if (dot!=-1) r.reset();
154                                        break;
155                                }
156                        }
157 
158                        catch (IOException ioe){
159                                throw StandardException.newException(SQLState.ID_PARSE_ERROR,ioe);
160                        }
161                }
162                String[] result = new String[v.size()];
163                v.copyInto(result);
164                return result;
165        }
166        
167        /**
168          Convert the String provided to an ID. Throw an exception
169          iff the string does not contain only a valid external form
170          for an id. This is a convenience routine that simply
171          uses getId(StringReader) to do the work.
172          
173          <P> See the header for getId below for restrictions.
174          
175          @exception StandardException Oops
176          */
177        public static String parseId(String s)
178                 throws StandardException
179        {
180                StringReader r = new StringReader(s);
181                String id = parseId(r,true, true);
182                verifyEmpty(r);
183                return id;
184        }
185 
186        /**
187          Read an id from the StringReader provided.
188 
189 
190          @param normalize true means return ids in nomral form, false means
191                return them as they were entered.
192 
193          <P>
194          Raise an exception if the first thing in the StringReader
195          is not a valid id.
196 
197          @exception StandardException Ooops.
198          */
199        public static String parseId(StringReader r, boolean normalize, boolean normalizeToUpper)
200                 throws StandardException
201        {
202                try {
203                        r.mark(0);
204                        int c = r.read();
205                        if (c == -1)  //id can't be 0-length
206                                throw StandardException.newException(SQLState.ID_PARSE_ERROR);
207                         r.reset();
208                        if (c == '"')
209                                return parseQId(r,normalize);
210                        else
211                                return parseUnQId(r,normalize, normalizeToUpper);
212                }
213 
214                catch (IOException ioe){
215                        throw StandardException.newException(SQLState.ID_PARSE_ERROR,ioe);
216                }
217        }
218 
219        private static String parseUnQId(StringReader r, boolean normalize, boolean normalizeToUpper)
220                 throws IOException,StandardException
221        {
222                StringBuffer b = new StringBuffer();
223                int c;
224                boolean first;
225                //
226                for(first = true; ; first=false)
227                {
228                        r.mark(0);
229                        if (idChar(first,c=r.read()))
230                                b.append((char)c);
231                        else
232                                break;
233                }
234                if (c != -1) r.reset();
235 
236                if (normalize)
237                        return normalizeToUpper ? StringUtil.SQLToUpperCase(b.toString()) : StringUtil.SQLToLowerCase(b.toString());
238                else
239                        return b.toString();
240        }
241 
242 
243        private static boolean idChar(boolean first,int c)
244        {
245                if (((c>='a' && c<='z') || (c>='A' && c<='Z')) ||
246                        (!first &&(c>='0' && c<='9')) || (!first &&c =='_') )
247                        return true;
248                else if (Character.isLetter((char) c))
249                        return true;
250                else if (!first && Character.isDigit((char) c))
251                        return true;
252                return false;
253        }
254        private static String parseQId(StringReader r,boolean normalize)
255                 throws IOException,StandardException
256        {
257                StringBuffer b = new StringBuffer();
258                int c = r.read();
259                if (c != '"') throw StandardException.newException(SQLState.ID_PARSE_ERROR);
260                while (true)
261                {
262                        c=r.read();
263                        if (c == '"')
264                        {
265                                r.mark(0);
266                                int c2 = r.read();
267                                if (c2 != '"')
268                                {
269                                        if (c2!=-1)r.reset();
270                                        break;
271                                }
272                        }
273                        else if (c == -1)
274                                throw StandardException.newException(SQLState.ID_PARSE_ERROR);
275                        
276                        b.append((char)c);
277                }
278 
279                if (b.length() == 0) //id can't be 0-length
280                        throw StandardException.newException(SQLState.ID_PARSE_ERROR);
281 
282                if (normalize)
283                        return b.toString();
284                else
285                        return delimitId(b.toString()); //Put the quotes back.
286        }
287 
288        private static void verifyEmpty(java.io.Reader r)
289                 throws StandardException
290        {
291                try {
292                        if (r.read() != -1)
293                                throw StandardException.newException(SQLState.ID_PARSE_ERROR);
294                }
295 
296                catch (IOException ioe){
297                        throw StandardException.newException(SQLState.ID_PARSE_ERROR,ioe);
298                }                        
299        }
300        /**Index of the schema name in a jar name on a db classpath*/
301        public static final int DBCP_SCHEMA_NAME = 0;
302        /**Index of the sql jar name in a jar name on a db classpath*/
303        public static final int DBCP_SQL_JAR_NAME = 1;
304        
305        /**
306          Scan a database classpath from the string provided. This returns
307          an array with one qualified name per entry on the classpath. The
308          constants above describe the content of the returned names. This 
309          raises an an exception if the string does not contain a valid database 
310          class path.
311  <PRE>
312      classpath := item[:item]*
313          item := id.id
314          
315          In the syntax braces ([]) show grouping. '*' means repeat 0 or more times.
316          The syntax for id is defined in IdUtil.
317  </PRE>
318          <BR>
319          Classpath returned is a two part name.          <BR>
320          If the class path is empty then this returns an array
321          of zero length.
322 
323          @exception StandardException Oops
324          */
325        public static String[][] parseDbClassPath(String input, boolean normalizeToUpper)
326                 throws StandardException
327        {
328                //As a special case we accept a zero length dbclasspath.
329                if (input.length() == 0)
330                        return new String[0][];
331 
332                Vector v = new Vector();
333                java.io.StringReader r = new java.io.StringReader(input);
334                //
335                while (true)
336                {
337                        try {
338                                String[] thisQName = IdUtil.parseQualifiedName(r, normalizeToUpper);
339                                if (thisQName.length != 2)
340                                        throw StandardException.newException(SQLState.DB_CLASS_PATH_PARSE_ERROR,input);
341 
342                                v.addElement(thisQName); 
343                                int delim = r.read();
344                                if (delim != ':')
345                                {
346                                        if (delim!=-1)
347                                                throw StandardException.newException(SQLState.DB_CLASS_PATH_PARSE_ERROR,input);
348                                        break;
349                                }
350                        }
351                        
352                        catch (StandardException se){
353                            if (se.getMessageId().equals(SQLState.ID_PARSE_ERROR))
354                                        throw StandardException.newException(SQLState.DB_CLASS_PATH_PARSE_ERROR,
355                                                                                                                 se,input);
356                                else
357                                        throw se;
358                        }
359                        
360                        catch (IOException ioe){
361                                throw StandardException.newException(SQLState.DB_CLASS_PATH_PARSE_ERROR,ioe,input);
362                        }
363                }
364                String[][] result = new String[v.size()][];
365                v.copyInto(result);
366                return result;
367        }
368 
369 
370        /*
371        ** Methods that operate on lists of identifiers.
372        */
373 
374 
375        /**
376          Scan a list of ids from the string provided. This returns
377          an array with id per entry. This raises an an exception if
378          the string does not contain a valid list of names.
379 
380          @exception StandardException Oops
381          */
382        public static String[] parseIdList(String p)
383                 throws StandardException
384        {
385                if (p==null) return null;
386                StringReader r = new StringReader(p);
387                String[] result = parseIdList(r, true);
388                verifyListEmpty(r);
389                return result;
390        }
391        
392        
393        /**
394          Parse an idList. 
395 
396          @param normalize true means return ids in nomral form, false means
397                return them as they were entered.
398 
399          @exception StandardException Oops
400          */
401        private static String[] parseIdList(StringReader r, boolean normalize)
402                 throws StandardException
403        {
404                Vector v = new Vector();
405                while (true)
406                {
407                        int delim;
408                        try {
409                                String thisId = IdUtil.parseId(r,normalize, true);
410                                v.addElement(thisId);
411                                r.mark(0);
412                                delim = r.read();
413                                if (delim != ',')
414                                {
415                                        if (delim!=-1) r.reset();
416                                        break;
417                                }
418                        }
419                        
420                        catch (StandardException se){
421                                if (se.getMessageId().equals(SQLState.ID_LIST_PARSE_ERROR))
422                                        throw StandardException.newException(SQLState.ID_LIST_PARSE_ERROR,se);
423                                else
424                                        throw se;
425                        }
426                        
427                        catch (IOException ioe){
428                                throw StandardException.newException(SQLState.ID_LIST_PARSE_ERROR,ioe);
429                        }
430                }
431                if (v.size() == 0) return null;
432                String[] result = new String[v.size()];
433                v.copyInto(result);
434                return result;
435        }
436 
437        /**
438          Return an IdList with all the ids that in l1 and l2
439          or null if not ids are on both lists.
440 
441          @param l1 An array of ids in normal form
442          @param l2 An array of ids in nomral form
443          */
444        public static String intersect(String[] l1, String[] l2)
445        {
446                if (l1 == null || l2 == null) return null;
447                HashSet h = new HashSet();
448                for(int ix=0;ix<l2.length;ix++) h.add(l2[ix]); 
449                Vector v = new Vector();
450                for(int ix=0;ix<l1.length;ix++) if (h.contains(l1[ix])) v.addElement(l1[ix]);
451                return vectorToIdList(v,true); 
452        }
453 
454        /**
455          Return an idList in external form with one id for every 
456          element of v. If v has no elements, return null.
457 
458          @param normal True means the ids in v are in normal form
459                 and false means they are in external form.
460          */
461        private static String vectorToIdList(Vector v,boolean normal)
462        {
463                if (v.size() == 0) return null;
464                String[] a = new String[v.size()];
465                v.copyInto(a);
466                if (normal)
467                        return mkIdList(a);
468                else
469                        return mkIdListAsEntered(a);
470        }
471 
472        /**
473         * Map userName to authorizationId
474         * 
475         * @exception StandardException on error
476         */
477        public static String getUserAuthorizationId(String userName) throws StandardException
478        {
479                try {
480                        return parseId(userName);
481                }
482                catch (StandardException se) {
483                        throw StandardException.newException(SQLState.AUTH_INVALID_USER_NAME, userName);
484                }
485        }
486 
487        /**
488         * Get user name from URL properties. Handles the case of "" user.
489         * 
490         * @exception StandardException on error
491         */
492        public static String getUserNameFromURLProps(Properties params)
493        {
494                String userName = params.getProperty(Attribute.USERNAME_ATTR,
495                                                        Property.DEFAULT_USER_NAME);
496                if (userName.equals(""))
497                        userName = Property.DEFAULT_USER_NAME;
498 
499                return userName;
500        }
501 
502        /**
503          Return an IdList with all the ids that are repeated
504          in l.
505 
506          @param l a list of ids in normal form.
507          */
508        public static String dups(String[] l)
509        {
510                if (l == null) return null;
511                HashSet h = new HashSet();
512                Vector v = new Vector();
513                for(int ix=0;ix<l.length;ix++)
514                {
515                        if (!h.contains(l[ix]))
516                                h.add(l[ix]);
517                        else
518                                v.addElement(l[ix]);
519                }
520                return vectorToIdList(v,true);
521        }
522        
523        /**
524          Return an IdList with all the duplicate ids removed
525          @param l a list of ids in external form.
526          @exception StandardException Oops.
527          */
528        public static String pruneDups(String l) throws StandardException
529        {
530                if (l == null) return null;
531                String[] normal_a = parseIdList(l);
532                StringReader r = new StringReader(l);
533                String[] external_a = parseIdList(r,false);
534                HashSet h = new HashSet();
535                Vector v = new Vector();
536                for(int ix=0;ix<normal_a.length;ix++)
537                {
538                        if (!h.contains(normal_a[ix]))
539                        {
540                                h.add(normal_a[ix]);
541                                v.addElement(external_a[ix]);
542                        }
543                }
544                return vectorToIdList(v,false);
545        }
546 
547        /**
548          Produce a string form of an idList from an array of
549          normalized ids.
550          */
551        public static String mkIdList(String[] ids)
552        {
553                StringBuffer sb = new StringBuffer();
554                for (int ix=0;ix<ids.length; ix++)
555                {
556                        if (ix != 0) sb.append(",");
557                        sb.append(IdUtil.delimitId(ids[ix]));
558                }
559                return sb.toString();
560        }
561 
562        /**
563          Produce an id list from an array of ids in external form
564          */
565        private static String mkIdListAsEntered(String[] externalIds )
566        {
567                StringBuffer sb = new StringBuffer();
568                for (int ix=0;ix<externalIds.length; ix++)
569                {
570                        if (ix != 0) sb.append(",");
571                        sb.append(externalIds[ix]);
572                }
573                return sb.toString();
574        }
575 
576        private static void verifyListEmpty(StringReader r)
577                 throws StandardException
578        {
579                try {
580                        if (r.read() != -1)
581                                throw StandardException.newException(SQLState.ID_LIST_PARSE_ERROR);
582                }
583 
584                catch (IOException ioe){
585                        throw StandardException.newException(SQLState.ID_LIST_PARSE_ERROR,ioe);
586                }
587                
588 
589        }
590 
591        /**
592          Return true if the id provided is on the list provided.
593          @param id an id in normal form
594          @param        list a list of ids in external form.
595          @exception StandardException oops.
596          */
597        public static boolean idOnList(String id, String list)
598                 throws StandardException
599        {
600                if (list==null) return false;
601                String[] list_a = parseIdList(list);
602                for (int ix=0; ix < list_a.length; ix++)
603                        if (id.equals(list_a[ix])) return true;
604                return false;
605        }
606 
607        /**
608          Delete an id from a list of ids.
609          @param id an id in normal form (quotes removed, upshifted)
610          @param list a comma separated list of ids in external
611                 form (possibly delmited or not upshifted).
612          @return the list with the id deleted or null if the
613            resulting list has no ids. If 'id' is not on 'list'
614                this returns list unchanged.
615                                 
616          @exception StandardException oops.
617          */
618        public static String deleteId(String id, String list)
619                 throws StandardException
620        {
621                if (list==null) return null;
622                Vector v = new Vector();
623                StringReader r = new StringReader(list);
624                String[] enteredList_a = parseIdList(r,false);
625                //
626                //Loop through enteredList element by element
627                //removing elements that match id. Before we
628                //compare we parse each id in list to convert
629                //to normal form.
630                for (int ix=0; ix < enteredList_a.length; ix++)
631                        if (!id.equals(IdUtil.parseId(enteredList_a[ix])))
632                                v.addElement(enteredList_a[ix]);
633                if (v.size() == 0)
634                        return null;
635                else
636                        return vectorToIdList(v,false);
637        }
638 
639 
640        /**
641          Append an id in external form.
642          @return the list with the id appended. 
643          @exception StandardException oops
644          */
645        public static String appendId(String id, String list)
646                 throws StandardException
647        {
648                if (list==null)
649                        return id;
650                else
651                        return list+","+id;
652        }
653}

[all classes][org.apache.derby.iapi.util]
EMMA 2.0.5312 (C) Vladimir Roubtsov