001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.spi.gototest;
043:
044: import org.openide.filesystems.FileObject;
045:
046: /**
047: * Interface implemented by actions that can locate a test for a given source file,
048: * or vice versa.
049: *
050: * @author Tor Norbye
051: */
052: public interface TestLocator {
053: enum FileType {
054: /** The file is a test class */
055: TEST,
056: /** The file is a tested class */
057: TESTED,
058: /** The file is neither a test nor a tested file */
059: NEITHER
060: }
061:
062: /**
063: * Return whether this TestLocator applies for the given file.
064: * Only one TestLocator should apply for a given filetype.
065: *
066: * @param fo The FileObject to be considered
067: * @return True iff the given file object is applicable for this TestLocator
068: */
069: boolean appliesTo(FileObject fo);
070:
071: /**
072: * This method determines whether the file-search mechanism should be synchronous
073: * or asynchronous. If asynchronous, {@link #findOpposite(FileObject)} will be called
074: * to compute the result directly. If it is false, {@link #findOpposite(FileObject,LocationListener)}
075: * will be called instead.
076: *
077: * @return True iff the search should be asynchronous, where {@link findOpposite(FileObject,LocationListener)}
078: * is called.
079: */
080: boolean asynchronous();
081:
082: /**
083: * Compute the opposite file's location.
084: * @param fo The FileObject to search for an opposite file for
085: * @param caretOffset The caret offset in the current file, or -1 if unknown.
086: * Can be used to aid finding the opposite file. (For example, a TestLocator
087: * implementation can use it to determine the class around the caret offset
088: * and then use its own code index to locate a corresponding class based on
089: * class patterns rather than file names and locations.
090: * @return The {@link Location} of the opposite file, or {@link Location#NONE} if
091: * no such file can be found
092: */
093: LocationResult findOpposite(FileObject fo, int caretOffset);
094:
095: /**
096: * Compute the opposite file's location. This method will only be called
097: * if {@link #asynchronous} is true. When the result is found, the implementation
098: * of this method should call the given callback with the correct location
099: * or error message.
100: * @param fo The file object whose opposite file we want to find
101: * @param caretOffset The caret offset in the current file, or -1 if unknown.
102: * Can be used to aid finding the opposite file. (For example, a TestLocator
103: * implementation can use it to determine the class around the caret offset
104: * and then use its own code index to locate a corresponding class based on
105: * class patterns rather than file names and locations.
106: * @param callback The callback to call when the opposite file is found or an
107: * appropriate error message is known.
108: */
109: void findOpposite(FileObject fo, int caretOffset,
110: LocationListener callback);
111:
112: /**
113: * Decide what type of file is being edited (which will be used to enable either
114: * the Go To Test action or the Go To Tested action).
115: * For a JUnit test for example, the {@link FileType#TEST} FileType should be returned
116: * and as a consequence the "Go To Tested Class" action will be enabled.
117: * This method will only be called for files that {@link #appliesTo} this FileObject.
118: *
119: * @param fo The FileObject currently being edited or selected
120: * @return {@link FileType#TEST} for files that are tests,
121: * {@link FileType#TESTED} for files that aren't tests but (probably) have associated
122: * tests, and {@link FileType#NEITHER} for all other files where the Go To
123: * action will be disabled.
124: */
125: FileType getFileType(FileObject fo);
126:
127: /**
128: * Interface implemented by findOpposite callbacks. If findOpposite needs
129: * to work asynchronously, it can return null instead of a location, and operate
130: * on the callback instead.
131: */
132: public interface LocationListener {
133: void foundLocation(FileObject fo, LocationResult location);
134: }
135:
136: /**
137: * A class to hold the location of a test or tested class; objects of this type
138: * are returned from {@link TestLocator@findOpposite}.
139: */
140: public static class LocationResult {
141: private FileObject file;
142: private int offset;
143: private String error;
144:
145: /**
146: * Construct a Location from a given file and offset.
147: * @param file The FileObject of the opposite file.
148: * @param offset The offset in the file, or -1 if the offset
149: * is unknown.
150: */
151: public LocationResult(FileObject file, int offset) {
152: this .file = file;
153: this .offset = offset;
154: }
155:
156: /**
157: * Construct an invalid location with a given error message.
158: * @param error The error message
159: */
160: public LocationResult(String error) {
161: this .error = error;
162: }
163:
164: /**
165: * Get the FileObject associated with this location
166: * @return The FileObject for this location, or null if
167: * this is an invalid location. In that case, consult
168: * {@link #getErrorMessage} for more information.
169: */
170: public FileObject getFileObject() {
171: return file;
172: }
173:
174: /**
175: * Get the offset associated with this location, if any.
176: * @return The offset for this location, or -1 if the offset
177: * is not known.
178: */
179: public int getOffset() {
180: return offset;
181: }
182:
183: /**
184: * Return the error message for the failure to find a given file
185: * location.
186: * @return The localized error message
187: */
188: public String getErrorMessage() {
189: return error;
190: }
191: }
192: }
|