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