001    /*
002     * Created on Jul 16, 2008
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005     * in compliance with the License. You may obtain a copy of the License at
006     *
007     * http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software distributed under the License
010     * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011     * or implied. See the License for the specific language governing permissions and limitations under
012     * the License.
013     *
014     * Copyright @2008-2010 the original author or authors.
015     */
016    package org.fest.swing.core.matcher;
017    
018    import static java.lang.String.valueOf;
019    import static org.fest.util.Strings.concat;
020    
021    import java.awt.Dialog;
022    import java.util.regex.Pattern;
023    
024    import org.fest.swing.annotation.RunsInCurrentThread;
025    
026    /**
027     * Understands matching a <code>{@link Dialog}</code> by name, title and visibility on the screen.
028     *
029     * @author Alex Ruiz
030     */
031    public final class DialogMatcher extends NamedComponentMatcherTemplate<Dialog> {
032    
033      private Object title;
034    
035      /**
036       * Creates a new <code>{@link DialogMatcher}</code> that matches a <code>{@link Dialog}</code> that:
037       * <ol>
038       * <li>has a matching name</li>
039       * <li>(optionally) has matching title</li>
040       * <li>(optionally) is showing on the screen</li>
041       * <p>
042       * The following code listing shows how to match a <code>{@link Dialog}</code> by name and title:
043       * <pre>
044       * DialogMatcher m = {@link #withName(String) withName}("saveFile").{@link #andTitle(String) andTitle}("Save File");
045       * </pre>
046       * </p>
047       * <p>
048       * The following code listing shows how to match a <code>{@link Dialog}</code>, that should be showing on the screen,
049       * by name and title:
050       * <pre>
051       * DialogMatcher m = {@link #withName(String) withName}("saveFile").{@link #andTitle(String) andTitle}("Save File").{@link #andShowing() andShowing}();
052       * </pre>
053       * </p>
054       * @param name the id to match.
055       * @return the created matcher.
056       */
057      public static DialogMatcher withName(String name) {
058        return new DialogMatcher(name, ANY);
059      }
060    
061      /**
062       * Creates a new <code>{@link DialogMatcher}</code> that matches a <code>{@link Dialog}</code> by its title.
063       * <p>
064       * The following code listing shows how to match a <code>{@link Dialog}</code> title:
065       * <pre>
066       * DialogMatcher m = {@link #withTitle(String) withTitle}("Save File");
067       * </pre>
068       * </p>
069       * <p>
070       * The following code listing shows how to match a <code>{@link Dialog}</code>, that should be showing on the screen,
071       * by title:
072       * <pre>
073       * DialogMatcher m = {@link #withTitle(String) withTitle}("Save File").{@link #andShowing() andShowing}();
074       * </pre>
075       * </p>
076       * @param title the title to match. It can be a regular expression.
077       * @return the created matcher.
078       */
079      public static DialogMatcher withTitle(String title) {
080        return new DialogMatcher(ANY, title);
081      }
082    
083      /**
084       * Creates a new <code>{@link DialogMatcher}</code> that matches a <code>{@link Dialog}</code> by its title.
085       * <p>
086       * The following code listing shows how to match a <code>{@link Dialog}</code> title, using a regular expression
087       * pattern:
088       * <pre>
089       * DialogMatcher m = {@link #withTitle(Pattern) withTitle}(Pattern.compile("Sav.*"));
090       * </pre>
091       * </p>
092       * <p>
093       * The following code listing shows how to match a <code>{@link Dialog}</code>, that should be showing on the screen,
094       * by title, using a regular expression pattern:
095       * <pre>
096       * DialogMatcher m = {@link #withTitle(Pattern) withTitle}(Pattern.compile("Sav.*")).{@link #andShowing() andShowing}();
097       * </pre>
098       * </p>
099       * @param titlePattern the regular expression pattern to match.
100       * @return the created matcher.
101       * @since 1.2
102       */
103      public static DialogMatcher withTitle(Pattern titlePattern) {
104        return new DialogMatcher(ANY, titlePattern);
105      }
106    
107      /**
108       * Creates a new <code>{@link DialogMatcher}</code> that matches any <code>{@link Dialog}</code>.
109       * @return the created matcher.
110       */
111      public static DialogMatcher any() {
112        return new DialogMatcher(ANY, ANY);
113      }
114    
115      private DialogMatcher(Object name, Object title) {
116        super(Dialog.class, name);
117        this.title = title;
118      }
119    
120      /**
121       * Specifies the title to match. If this matcher was created using <code>{@link #withTitle(String)}</code> or
122       * <code>{@link #withTitle(Pattern)}</code>, this method will simply update the title to match.
123       * @param newTitle the new title to match. It can be a regular expression.
124       * @return this matcher.
125       */
126      public DialogMatcher andTitle(String newTitle) {
127        title = newTitle;
128        return this;
129      }
130    
131    
132      /**
133       * Specifies the title to match. If this matcher was created using <code>{@link #withTitle(String)}</code>, or
134       * <code>{@link #withTitle(Pattern)}</code> this method will simply update the title to match.
135       * @param titlePattern the regular expression pattern to match.
136       * @return this matcher.
137       * @since 1.2
138       */
139      public DialogMatcher andTitle(Pattern titlePattern) {
140        title = titlePattern;
141        return this;
142      }
143    
144      /**
145       * Indicates that the <code>{@link Dialog}</code> to match should be showing on the screen.
146       * @return this matcher.
147       */
148      public DialogMatcher andShowing() {
149        requireShowing(true);
150        return this;
151      }
152    
153      /**
154       * Indicates whether:
155       * <ul>
156       * <li>the name of the given <code>Dialog</code> is equal to the name in this matcher, and</li>
157       * <li>the title of the given <code>Dialog</code> matches the text (or pattern) in this matcher</li>
158       * </ul>
159       * <p>
160       * <b>Note:</b> This method is <b>not</b> guaranteed to be executed in the event dispatch thread (EDT.) Clients are
161       * responsible for calling this method from the EDT.
162       * </p>
163       * @param dialog the <code>Dialog</code> to match.
164       * @return <code>true</code> if the <code>Dialog</code> matches the search criteria in this matcher.
165       */
166      @RunsInCurrentThread
167      protected boolean isMatching(Dialog dialog) {
168        if (!isNameMatching(dialog.getName())) return false;
169        return arePropertyValuesMatching(title, dialog.getTitle());
170      }
171    
172      @Override public String toString() {
173        return concat(
174            getClass().getName(), "[",
175            "name=", quotedName(), ", ",
176            "title=", quoted(title), ", ",
177            "requireShowing=", valueOf(requireShowing()),
178            "]"
179        );
180      }
181    }