1.1 --- a/testng/nbproject/project.xml Sat Feb 04 14:25:18 2012 +0100
1.2 +++ b/testng/nbproject/project.xml Sat Feb 04 17:13:15 2012 +0100
1.3 @@ -2,7 +2,7 @@
1.4 <!--
1.5 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1.6
1.7 -Copyright © 2008-2011 Oracle and/or its affiliates. All rights reserved.
1.8 +Copyright © 2008-2012 Oracle and/or its affiliates. All rights reserved.
1.9
1.10
1.11 The contents of this file are subject to the terms of either the GNU
1.12 @@ -74,6 +74,15 @@
1.13 </run-dependency>
1.14 </dependency>
1.15 <dependency>
1.16 + <code-name-base>org.netbeans.api.progress</code-name-base>
1.17 + <build-prerequisite/>
1.18 + <compile-dependency/>
1.19 + <run-dependency>
1.20 + <release-version>1</release-version>
1.21 + <specification-version>1.27</specification-version>
1.22 + </run-dependency>
1.23 + </dependency>
1.24 + <dependency>
1.25 <code-name-base>org.netbeans.api.xml</code-name-base>
1.26 <build-prerequisite/>
1.27 <compile-dependency/>
1.28 @@ -100,6 +109,33 @@
1.29 </run-dependency>
1.30 </dependency>
1.31 <dependency>
1.32 + <code-name-base>org.netbeans.modules.editor</code-name-base>
1.33 + <build-prerequisite/>
1.34 + <compile-dependency/>
1.35 + <run-dependency>
1.36 + <release-version>3</release-version>
1.37 + <specification-version>1.60</specification-version>
1.38 + </run-dependency>
1.39 + </dependency>
1.40 + <dependency>
1.41 + <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
1.42 + <build-prerequisite/>
1.43 + <compile-dependency/>
1.44 + <run-dependency>
1.45 + <release-version>3</release-version>
1.46 + <specification-version>3.18</specification-version>
1.47 + </run-dependency>
1.48 + </dependency>
1.49 + <dependency>
1.50 + <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
1.51 + <build-prerequisite/>
1.52 + <compile-dependency/>
1.53 + <run-dependency>
1.54 + <release-version>1</release-version>
1.55 + <specification-version>1.54</specification-version>
1.56 + </run-dependency>
1.57 + </dependency>
1.58 + <dependency>
1.59 <code-name-base>org.netbeans.modules.extexecution</code-name-base>
1.60 <build-prerequisite/>
1.61 <compile-dependency/>
1.62 @@ -143,6 +179,24 @@
1.63 </run-dependency>
1.64 </dependency>
1.65 <dependency>
1.66 + <code-name-base>org.netbeans.modules.java.sourceui</code-name-base>
1.67 + <build-prerequisite/>
1.68 + <compile-dependency/>
1.69 + <run-dependency>
1.70 + <release-version>1</release-version>
1.71 + <specification-version>1.26</specification-version>
1.72 + </run-dependency>
1.73 + </dependency>
1.74 + <dependency>
1.75 + <code-name-base>org.netbeans.modules.lexer</code-name-base>
1.76 + <build-prerequisite/>
1.77 + <compile-dependency/>
1.78 + <run-dependency>
1.79 + <release-version>2</release-version>
1.80 + <specification-version>1.43</specification-version>
1.81 + </run-dependency>
1.82 + </dependency>
1.83 + <dependency>
1.84 <code-name-base>org.netbeans.modules.project.ant</code-name-base>
1.85 <build-prerequisite/>
1.86 <compile-dependency/>
1.87 @@ -179,6 +233,14 @@
1.88 </run-dependency>
1.89 </dependency>
1.90 <dependency>
1.91 + <code-name-base>org.netbeans.modules.xml.lexer</code-name-base>
1.92 + <build-prerequisite/>
1.93 + <compile-dependency/>
1.94 + <run-dependency>
1.95 + <specification-version>1.16</specification-version>
1.96 + </run-dependency>
1.97 + </dependency>
1.98 + <dependency>
1.99 <code-name-base>org.openide.awt</code-name-base>
1.100 <build-prerequisite/>
1.101 <compile-dependency/>
2.1 --- a/testng/src/org/netbeans/modules/contrib/testng/Bundle.properties Sat Feb 04 14:25:18 2012 +0100
2.2 +++ b/testng/src/org/netbeans/modules/contrib/testng/Bundle.properties Sat Feb 04 17:13:15 2012 +0100
2.3 @@ -1,6 +1,6 @@
2.4 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2.5 #
2.6 -# Copyright \u00a9 1997-2011 Oracle and/or its affiliates. All rights reserved.
2.7 +# Copyright \u00a9 1997-2012 Oracle and/or its affiliates. All rights reserved.
2.8 #
2.9 # The contents of this file are subject to the terms of either the GNU
2.10 # General Public License Version 2 only ("GPL") or the Common
2.11 @@ -48,3 +48,6 @@
2.12 Templates/TestNG/TestNGTest.java=TestNG Test Case
2.13 TestNG=TestNG 6.0.1
2.14 Loaders/text/x-testng+xml/Factories/org-netbeans-modules-contrib-testng-TestNGSuiteDataLoader.instance=TestNG Suite Files
2.15 +
2.16 +LBL_GoToDeclaration=Go to Declaration
2.17 +goto_source_source_not_found=Source file for {0} not found.
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/testng/src/org/netbeans/modules/contrib/testng/TestNGSuiteHyperlingProvider.java Sat Feb 04 17:13:15 2012 +0100
3.3 @@ -0,0 +1,342 @@
3.4 +/*
3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3.6 + *
3.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
3.8 + *
3.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
3.10 + * Other names may be trademarks of their respective owners.
3.11 + *
3.12 + * The contents of this file are subject to the terms of either the GNU
3.13 + * General Public License Version 2 only ("GPL") or the Common
3.14 + * Development and Distribution License("CDDL") (collectively, the
3.15 + * "License"). You may not use this file except in compliance with the
3.16 + * License. You can obtain a copy of the License at
3.17 + * http://www.netbeans.org/cddl-gplv2.html
3.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
3.19 + * specific language governing permissions and limitations under the
3.20 + * License. When distributing the software, include this License Header
3.21 + * Notice in each file and include the License file at
3.22 + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
3.23 + * particular file as subject to the "Classpath" exception as provided
3.24 + * by Oracle in the GPL Version 2 section of the License file that
3.25 + * accompanied this code. If applicable, add the following below the
3.26 + * License Header, with the fields enclosed by brackets [] replaced by
3.27 + * your own identifying information:
3.28 + * "Portions Copyrighted [year] [name of copyright owner]"
3.29 + *
3.30 + * If you wish your version of this file to be governed by only the CDDL
3.31 + * or only the GPL Version 2, indicate your decision by adding
3.32 + * "[Contributor] elects to include this software in this distribution
3.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
3.34 + * single choice of license, a recipient has the option to distribute
3.35 + * your version of this file under either the CDDL, the GPL Version 2 or
3.36 + * to extend the choice of license to its licensees as provided above.
3.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
3.38 + * Version 2 license, then the option applies only if the new code is
3.39 + * made subject to such option by the copyright holder.
3.40 + *
3.41 + * Contributor(s):
3.42 + *
3.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
3.44 + */
3.45 +package org.netbeans.modules.contrib.testng;
3.46 +
3.47 +import java.io.File;
3.48 +import java.io.IOException;
3.49 +import java.text.MessageFormat;
3.50 +import java.util.Collections;
3.51 +import java.util.List;
3.52 +import java.util.Map;
3.53 +import java.util.concurrent.ConcurrentHashMap;
3.54 +import java.util.concurrent.atomic.AtomicBoolean;
3.55 +import javax.lang.model.element.Element;
3.56 +import javax.lang.model.element.ElementKind;
3.57 +import javax.lang.model.element.TypeElement;
3.58 +import javax.swing.text.Document;
3.59 +import javax.swing.text.JTextComponent;
3.60 +import javax.swing.text.StyledDocument;
3.61 +import org.netbeans.api.editor.EditorRegistry;
3.62 +import org.netbeans.api.java.source.ClasspathInfo;
3.63 +import org.netbeans.api.java.source.CompilationController;
3.64 +import org.netbeans.api.java.source.JavaSource;
3.65 +import org.netbeans.api.java.source.Task;
3.66 +import org.netbeans.api.java.source.ui.ElementOpen;
3.67 +import org.netbeans.api.lexer.Token;
3.68 +import org.netbeans.api.lexer.TokenHierarchy;
3.69 +import org.netbeans.api.lexer.TokenSequence;
3.70 +import org.netbeans.api.progress.ProgressUtils;
3.71 +import org.netbeans.api.xml.lexer.XMLTokenId;
3.72 +import org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider;
3.73 +import org.netbeans.modules.editor.NbEditorUtilities;
3.74 +import org.openide.awt.StatusDisplayer;
3.75 +import org.openide.cookies.OpenCookie;
3.76 +import org.openide.filesystems.FileObject;
3.77 +import org.openide.filesystems.FileUtil;
3.78 +import org.openide.loaders.DataObject;
3.79 +import org.openide.loaders.DataObjectNotFoundException;
3.80 +import org.openide.nodes.Node;
3.81 +import org.openide.util.Exceptions;
3.82 +import org.openide.util.NbBundle;
3.83 +
3.84 +/**
3.85 + *
3.86 + * @author lukas
3.87 + */
3.88 +public class TestNGSuiteHyperlingProvider implements HyperlinkProvider {
3.89 +
3.90 + private int startOffset;
3.91 + private int endOffset;
3.92 + private String file;
3.93 + private String method;
3.94 + private LinkType targetType;
3.95 + private static final Map<String, LinkType> linkMap = new ConcurrentHashMap<String, LinkType>();
3.96 +
3.97 + private enum LinkType {
3.98 +
3.99 + RESOURCE,
3.100 + JAVA_SOURCE;
3.101 + }
3.102 +
3.103 + static {
3.104 + linkMap.put("suite-file#path", LinkType.RESOURCE);
3.105 + linkMap.put("class#name", LinkType.JAVA_SOURCE);
3.106 + linkMap.put("listener#class-name", LinkType.JAVA_SOURCE);
3.107 + linkMap.put("selector-class#name", LinkType.JAVA_SOURCE);
3.108 + linkMap.put("include#name", LinkType.JAVA_SOURCE);
3.109 + linkMap.put("exclude#name", LinkType.JAVA_SOURCE);
3.110 +// linkMap.put("class/methods/include#name", LinkType.JAVA_SOURCE);
3.111 +// linkMap.put("class/methods/exclude#name", LinkType.JAVA_SOURCE);
3.112 + }
3.113 +
3.114 + public TestNGSuiteHyperlingProvider() {
3.115 + }
3.116 +
3.117 + public boolean isHyperlinkPoint(Document doc, int offset) {
3.118 + JTextComponent target = EditorRegistry.lastFocusedComponent();
3.119 + final StyledDocument styledDoc = (StyledDocument) target.getDocument();
3.120 + if (styledDoc == null) {
3.121 + return false;
3.122 + }
3.123 +
3.124 + // Work only with the open editor
3.125 + //and the editor has to be the active component:
3.126 + if ((target == null) || (target.getDocument() != doc)) {
3.127 + return false;
3.128 + }
3.129 +
3.130 + TokenHierarchy hi = TokenHierarchy.get(doc);
3.131 + TokenSequence<XMLTokenId> ts = hi.tokenSequence(XMLTokenId.language());
3.132 + ts.move(offset);
3.133 + ts.moveNext();
3.134 + Token<XMLTokenId> tok = ts.token();
3.135 + if (tok != null) {
3.136 + int tokOffset = ts.offset();
3.137 + Token<XMLTokenId> t = getAttribute(ts);
3.138 + if (t == null) {
3.139 + return false;
3.140 + }
3.141 + String xpath = "#" + t.text().toString();
3.142 + t = getParentElement(ts);
3.143 + xpath = getElementName(t) + xpath;
3.144 +
3.145 + targetType = linkMap.get(xpath);
3.146 + if (targetType == null) {
3.147 + return false;
3.148 + }
3.149 +
3.150 + if (xpath.startsWith("include") || xpath.startsWith("exclude")) {
3.151 + t = getParentElement(ts);
3.152 + if ("methods".equals(getElementName(t))) {
3.153 + method = tok.text().toString();
3.154 + getParentElement(ts); // <class ...> element
3.155 + file = getAttributeValue(ts, "name");
3.156 + } else {
3.157 + return false;
3.158 + }
3.159 + } else {
3.160 + method = null;
3.161 + }
3.162 + startOffset = tokOffset + 1;
3.163 + endOffset = startOffset + tok.text().length() - 2;
3.164 + if (method == null) {
3.165 + file = tok.text().subSequence(1, tok.text().length() - 1).toString();
3.166 + } else {
3.167 + method = method.substring(1, method.length() - 1);
3.168 + }
3.169 + return true;
3.170 + }
3.171 + return false;
3.172 + }
3.173 +
3.174 + public int[] getHyperlinkSpan(Document doc, int offset) {
3.175 + JTextComponent target = EditorRegistry.lastFocusedComponent();
3.176 + final StyledDocument styledDoc = (StyledDocument) target.getDocument();
3.177 + if (styledDoc == null) {
3.178 + return null;
3.179 + }
3.180 +
3.181 + // Return the position, which was set in the isHyperlink method:
3.182 + return new int[]{startOffset, endOffset};
3.183 + }
3.184 +
3.185 + public void performClickAction(final Document doc, final int offset) {
3.186 + final AtomicBoolean cancel = new AtomicBoolean();
3.187 + ProgressUtils.runOffEventDispatchThread(new Runnable() {
3.188 +
3.189 + public void run() {
3.190 + performGoTo(doc, offset, file, method, targetType, cancel);
3.191 + }
3.192 + }, NbBundle.getMessage(TestNGSuiteHyperlingProvider.class, "LBL_GoToDeclaration"), cancel, false);
3.193 + }
3.194 +
3.195 + private Token<XMLTokenId> getAttribute(TokenSequence<XMLTokenId> ts) {
3.196 + Token<XMLTokenId> tok = ts.token();
3.197 + if (tok.id() == XMLTokenId.VALUE) {
3.198 + while (ts.movePrevious()) {
3.199 + tok = ts.token();
3.200 + switch (tok.id()) {
3.201 + case ARGUMENT:
3.202 + return tok;
3.203 + case OPERATOR:
3.204 + case EOL:
3.205 + case ERROR:
3.206 + case WS:
3.207 + continue;
3.208 + default:
3.209 + return null;
3.210 + }
3.211 + }
3.212 + }
3.213 + return null;
3.214 + }
3.215 +
3.216 + private Token<XMLTokenId> getParentElement(TokenSequence<XMLTokenId> ts) {
3.217 + int depth = 0;
3.218 + while (ts.movePrevious()) {
3.219 + Token<XMLTokenId> prev = ts.token();
3.220 + switch (prev.id()) {
3.221 + case TAG:
3.222 + if (prev.text().length() == 1) {
3.223 + continue;
3.224 + }
3.225 + if (prev.text().toString().contains("/")) {
3.226 + depth++;
3.227 + continue;
3.228 + }
3.229 + depth--;
3.230 + if (depth == -1) {
3.231 + return prev;
3.232 + }
3.233 + continue;
3.234 + default:
3.235 + continue;
3.236 + }
3.237 + }
3.238 + return null;
3.239 + }
3.240 +
3.241 + private String getElementName(Token<XMLTokenId> tok) {
3.242 + return tok.text().toString().substring(1);
3.243 + }
3.244 +
3.245 + private String getAttributeValue(TokenSequence<XMLTokenId> ts, String name) {
3.246 + boolean readValue = false;
3.247 + while (ts.moveNext()) {
3.248 + Token<XMLTokenId> next = ts.token();
3.249 +
3.250 + switch (next.id()) {
3.251 + case ARGUMENT:
3.252 + if (name.equals(next.text().toString())) {
3.253 + readValue = true;
3.254 + }
3.255 + continue;
3.256 + case VALUE:
3.257 + if (readValue) {
3.258 + CharSequence val = next.text().subSequence(1, next.text().length() - 1);
3.259 + return val.toString();
3.260 + }
3.261 + continue;
3.262 + case OPERATOR:
3.263 + case EOL:
3.264 + case ERROR:
3.265 + case WS:
3.266 + continue;
3.267 + default:
3.268 + return null;
3.269 + }
3.270 + }
3.271 + return null;
3.272 + }
3.273 +
3.274 + private void performGoTo(Document doc, int offset, final String file, final String method, final LinkType type, AtomicBoolean cancel) {
3.275 + switch (type) {
3.276 + case RESOURCE:
3.277 + FileObject fo = NbEditorUtilities.getFileObject(doc);
3.278 + File target = new File(file);
3.279 + FileObject targetFO;
3.280 + if (target.isAbsolute()) {
3.281 + targetFO = FileUtil.toFileObject(FileUtil.normalizeFile(target));
3.282 + } else {
3.283 + targetFO = fo.getParent().getFileObject(file);
3.284 + }
3.285 + if (targetFO.isData() && targetFO.isValid() && !targetFO.isVirtual()) {
3.286 + openInEditor(targetFO);
3.287 + } else {
3.288 + String key = "goto_source_source_not_found"; //NOI18N
3.289 + String msg = NbBundle.getMessage(TestNGSuiteHyperlingProvider.class, key);
3.290 + StatusDisplayer.getDefault().setStatusText(MessageFormat.format(msg, new Object[]{file}));
3.291 + }
3.292 + break;
3.293 + case JAVA_SOURCE:
3.294 + final ClasspathInfo cp = ClasspathInfo.create(doc);
3.295 + JavaSource js = JavaSource.create(cp, Collections.EMPTY_LIST);
3.296 + try {
3.297 + js.runUserActionTask(new Task<CompilationController>() {
3.298 +
3.299 + @Override
3.300 + public void run(CompilationController cc) throws Exception {
3.301 + cc.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);
3.302 + Element element = cc.getElements().getTypeElement(file.trim());
3.303 + if (element != null) {
3.304 + if (method != null) {
3.305 + List<? extends Element> enclosedElements = cc.getElements().getAllMembers((TypeElement) element);
3.306 + for (Element e : enclosedElements) {
3.307 + if (e.getKind() == ElementKind.METHOD) {
3.308 + if (e.getSimpleName().toString().equals(method)) {
3.309 + element = e;
3.310 + break;
3.311 + }
3.312 + }
3.313 + }
3.314 + }
3.315 + if (!ElementOpen.open(cp, element)) {
3.316 + String key = "goto_source_source_not_found"; //NOI18N
3.317 + String msg = NbBundle.getMessage(TestNGSuiteHyperlingProvider.class, key);
3.318 + StatusDisplayer.getDefault().setStatusText(MessageFormat.format(msg, new Object[]{file}));
3.319 + }
3.320 + }
3.321 + }
3.322 + }, false);
3.323 + } catch (IOException ex) {
3.324 + Exceptions.printStackTrace(ex);
3.325 + }
3.326 + break;
3.327 + }
3.328 + }
3.329 +
3.330 + private void openInEditor(FileObject fo) {
3.331 + DataObject dobj;
3.332 + try {
3.333 + dobj = DataObject.find(fo);
3.334 + } catch (DataObjectNotFoundException e) {
3.335 + Exceptions.printStackTrace(e);
3.336 + return;
3.337 + }
3.338 + if (dobj != null) {
3.339 + Node.Cookie cookie = dobj.getLookup().lookup(OpenCookie.class);
3.340 + if (cookie != null) {
3.341 + ((OpenCookie) cookie).open();
3.342 + }
3.343 + }
3.344 + }
3.345 +}
4.1 --- a/testng/src/org/netbeans/modules/contrib/testng/resources/layer.xml Sat Feb 04 14:25:18 2012 +0100
4.2 +++ b/testng/src/org/netbeans/modules/contrib/testng/resources/layer.xml Sat Feb 04 17:13:15 2012 +0100
4.3 @@ -51,6 +51,14 @@
4.4 </folder>
4.5 </folder>
4.6 </folder>
4.7 + <folder name="x-testng+xml">
4.8 + <folder name="HyperlinkProviders">
4.9 + <file name="TestNGSuiteHyperlingProvider.instance">
4.10 + <attr name="instanceClass" stringvalue="org.netbeans.modules.contrib.testng.TestNGSuiteHyperlingProvider"/>
4.11 + <attr name="instanceOf" stringvalue="org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider"/>
4.12 + </file>
4.13 + </folder>
4.14 + </folder>
4.15 </folder>
4.16 </folder>
4.17 <folder name="Loaders">