1   package fi.jyu.mit.ohj2;
2    
3   /**
4    * Luokka wildmat-vertailuun, jossa jokereita ovat * ja ?
5    * @author Vesa Lappalainen, Markku Vire
6    * @version 1.0, 23.03.2002
7    */
8   public class WildChars { // NOPMD
9   
10    /**
11     * Palauttaa sisältääkö jono str jokerimekrkkejä * tai ?
12     * @param str jono jota tutkitaan
13     * @return sisältääkö jono (true) jokerimerkkejä vai ei (false)
14     * @example
15     * <pre name="test">
16     *  containsWildChars(null) === false;
17     *  containsWildChars("*")  === true;
18     *  containsWildChars("?")  === true;
19     *  containsWildChars("a*b?c")  === true;
20     * </pre>
21     */
22    public static boolean containsWildChars(String str)
23    {
24      if (str == null)  return false;
25      return (str.indexOf('*') >= 0 || str.indexOf('?') >= 0);
26    }
27  
28    /**
29     * Apumetodi wildmat-aliohjelman toteuttamiseksi
30     * @param str  tutkittava jono
31     * @param mask maski johon verrataan
32     * @param strIndex   indeksi jonossa, josta aloitetaan vertailu
33     * @param maskIndex  indeksi maskissa, josta aloitetaan vertailu
34     * @return ovatko samat (true) vai ei (false) jokeri-mielessä
35     * @example
36     */
37    private static boolean wildmat(String str, String mask, int strIndex, int maskIndex) { // NOPMD
38      if ( str == null || mask == null ) return ( str == null && mask == null );
39      int mi = maskIndex;
40      int si = strIndex;
41      
42      while ( mi < mask.length() ) {
43        char m = mask.charAt(mi);
44  
45        if ( m == '?' ) {
46          if (si >= str.length()) return false;
47        }
48        else if ( m == '*' ) {
49          mi++;
50          if ( mi < mask.length() )
51            while ( !wildmat(str, mask,si,mi) ) {
52              si++;
53              if ( si >= str.length() ) return false;
54            }
55          return true;
56        }
57        else if ( ( si >= str.length() ) || ( m != str.charAt(si) ) )
58          return false;
59  
60        si++; mi++;
61      }
62  
63      return ( si == str.length() );
64    }
65  
66    /**
67     *<pre>
68     * Funktiolla tutkitaan täsmääkö annettu jono verrattavaan maskiin.
69     * Maski saa sisältää seuraavia erikoismerkkejä:
70     *   * vastaa 0-n merkkiä
71     *   ? vastaa mitä tahansa yhtä merkkiä
72     *
73     * Algoritmi: Kysymysmerkki ja tavallinen kirjain normaalisti
74     *            Jos tulee vastaan tähti joka ei ole jonon lopussa,
75     *            niin ongelmahan on oikeastaan
76     *            (koska tähän asti kaikki on ollut oikein)
77     *            "Onko loppujono sama kuin toisen jonon loppu JOSTAKIN
78     *             kohdasta alkaen"?
79     *            Siis kokeillaan sovittaa loppujonoa aliohjelman itsensä
80     *            (rekursio) avulla kaikkiin mahdollisiin loppupaikkoihin.
81     * Esimerkki: str = "Kissa" maski = "*ss*" -> true
82     *                                = "*ss"  -> false
83     * </pre>
84     *
85     * @param str   jono jota tutkitaan
86     * @param mask  maski johon verrataan
87     * @return      onko samat (true) vai ei (false) maskin mielessä.
88     * 
89     * @example
90     * <pre name="test">
91     *    wildmat("kissa","kissa")           === true;
92     *    wildmat("kissa","kiss*")           === true;
93     *    wildmat("kissa","kss*")            === false;
94     *    wildmat("kissa","k*ss*")           === true;
95     *    wildmat("kissa","k***********ss*") === true;
96     *    wildmat("kissa","*iss*")           === true;
97     *    wildmat("kissa","*kiss*")          === true;
98     *    wildmat("kissa","*kissa*")         === true;
99     *    wildmat("kissa","*k?ss*")          === true;
100    *    wildmat("kissa","kass*")           === false;
101    *    wildmat("","*a")                   === false;
102    *    wildmat("","*")                    === true;
103    *    wildmat("","")                     === true;
104    *    wildmat("a","")                    === false;
105    *    wildmat("kissa","KISSA")           === false;
106    *    wildmat("k","k?")                  === false;
107    *    wildmat(null,null)                 === true;
108    *    wildmat("",null)                   === false;
109    *    wildmat(null,"")                   === false;
110    * 
111    * </pre>
112    */
113   public static boolean wildmat(String str, String mask) {
114     return wildmat(str,mask,0,0);
115   }
116 
117   /**
118    * Testaa ovatko kaksi merkkijonoa samat maskin mielessä 
119    * jos ne muutetaan isoille kirjaimille.
120    * @param str  tutkittava jono
121    * @param mask maski 
122    * @return true jos samat
123    * 
124    * @example
125    * <pre name="test">
126    *   onkoSamat("kissa","KISSA") === true;
127    *   onkoSamat("KISSA","kissa") === true;
128    *   onkoSamat("kissa","kiss") === false;
129    *   onkoSamat("KISSA","ki*") === true;
130    *    
131    * </pre>
132    */
133   public static boolean onkoSamat(String str, String mask) {
134     return wildmat(str.toUpperCase(),mask.toUpperCase()); // NOPMD
135   }
136 
137 /*
138   static int wilderr = 0;
139 
140   private static  void wildtest(String s, String maski, boolean result) {
141     boolean ret = onkoSamat(s,maski);
142     System.out.print("\"" + s + "\"  \"" + maski + "\"  => " + ret);
143     if ( ret != result ) {
144       System.out.print("  VÄÄRIN!");
145       wilderr++;
146     }
147     System.out.println();
148   }
149 
150   public static void main(String[] args) {
151     wildtest("kissa","kissa",true);
152     wildtest("kissa","kiss*",true);
153     wildtest("kissa","kss*",false);
154     wildtest("kissa","k*ss*",true);
155     wildtest("kissa","k***********ss*",true);
156     wildtest("kissa","*iss*",true);
157     wildtest("kissa","*kiss*",true);
158     wildtest("kissa","*kissa*",true);
159     wildtest("kissa","*k?ss*",true);
160     wildtest("kissa","kass*",false);
161     wildtest("","*a",false);
162     wildtest("","*",true);
163     wildtest("","",true);
164     wildtest("a","",false);
165     wildtest("kissa","KISSA",true);
166     if ( wilderr == 0 ) System.out.println("Kaikki oikein :-)");
167     else  System.out.println(" VIRHEITÄ: " + wilderr);
168   }
169 */  
170 }
171