All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.groovy.debug.GroovyBreakpointStratifier Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.modules.groovy.debug;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.codehaus.groovy.ast.ASTNode;
import org.netbeans.api.debugger.jpda.JPDABreakpoint;
import org.netbeans.api.debugger.jpda.LineBreakpoint;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.modules.groovy.editor.api.ASTUtils;
import org.netbeans.modules.groovy.editor.api.AstPath;
import org.netbeans.modules.groovy.editor.api.parser.GroovyLanguage;
import org.netbeans.modules.groovy.editor.api.parser.GroovyParserResult;
import org.netbeans.modules.parsing.api.ParserManager;
import org.netbeans.modules.parsing.api.ResultIterator;
import org.netbeans.modules.parsing.api.Source;
import org.netbeans.modules.parsing.api.UserTask;
import org.netbeans.modules.parsing.spi.ParseException;
import org.netbeans.spi.debugger.jpda.BreakpointStratifier;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.filesystems.URLMapper;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider;

/**
 * Modifies breakpoints to adapt to the Groovy stratum.
 *
 * @author Martin Janicek
 */
@ServiceProvider(service = BreakpointStratifier.class)
public final class GroovyBreakpointStratifier implements BreakpointStratifier {

    public final static String GROOVY_STRATUM = "Groovy"; //NOI18N
    private static final Logger LOGGER = Logger.getLogger(GroovyBreakpointStratifier.class.getName());

    public GroovyBreakpointStratifier() {
    }

    /**
     * Creates a new breakpoint for the given parameters.
     *
     * @param url a url
     * @param lineNumber a line number
     * @return a new breakpoint for given parameters
     */
    @Override
    @Messages("CTL_Default_Print_Text=Breakpoint reached at line {lineNumber} in {groovyName} by thread {threadName}.")
    public void stratify(JPDABreakpoint breakpoint) {
        if (breakpoint instanceof LineBreakpoint) {
            LineBreakpoint lb = (LineBreakpoint) breakpoint;
            String url = lb.getURL();
            FileObject fo = getFileObjectFromUrl(url);
            if (fo != null && GroovyLanguage.GROOVY_MIME_TYPE.equals(fo.getMIMEType())) {
                int lineNumber = lb.getLineNumber();
                String groovyName = fo.getNameExt();
                String pt = Bundle.CTL_Default_Print_Text();
                String printText = pt.replace("{groovyName}", (groovyName != null) ? groovyName : "?"); // NOI18N
                String groovyPath = getGroovyPath(url, fo);

                lb.setStratum(GROOVY_STRATUM);
                lb.setSourceName(groovyName);
                lb.setSourcePath(groovyPath);
                lb.setPreferredClassName(findGroovyClassName(groovyPath, fo, lineNumber));
                lb.setPrintText(printText);
            }
        }
    }

    private static FileObject getFileObjectFromUrl(String url) {

        FileObject fo = null;

        try {
            fo = URLMapper.findFileObject(new URL(url));
        } catch (MalformedURLException e) {
            //noop
        }
        return fo;
    }

    private static String findGroovyClassName(String relativePath, FileObject fo, int lineNumber) {
        Source source = Source.create(fo);
        String[] className = new String[] { null };
        try {
            ParserManager.parse(Collections.singleton(source), new UserTask() {
                public @Override void run(ResultIterator resultIterator) throws Exception {
                    GroovyParserResult result = ASTUtils.getParseResult(resultIterator.getParserResult());
                    ASTNode root = ASTUtils.getRoot(result);
                    AstPath path = new AstPath(root, lineNumber, 0);
                    className[0] = ASTUtils.getFqnName(path);
                }
            });
        } catch (ParseException ex) {
        }
        if (className[0] != null) {
            return className[0];
        } else {
            return getClassFilter(relativePath);
        }
    }

    private static String getClassFilter(String relativePath) {
        if (relativePath == null) {
            return "";
        }

        int dot = relativePath.lastIndexOf('.');
        if (dot > 0) {
            relativePath = relativePath.substring(0, dot);
        }
        return relativePath.replace('/', '.') + "*";
    }

    private static String getGroovyPath(String url, FileObject fo) {
        if (fo != null) {
            String relativePath;
            ClassPath cp = ClassPath.getClassPath(fo, ClassPath.SOURCE);
            if (cp != null) {
                FileObject root = cp.findOwnerRoot(fo);
                if (root != null) {
                    relativePath = FileUtil.getRelativePath(root, fo);
                } else {
                    // Suppose the current folder
                    relativePath = fo.getNameExt();
                }
            } else {
                LOGGER.log(Level.FINE, "No classpath for {0}", url);
                // Suppose the current folder
                relativePath = fo.getNameExt();
                return relativePath;
            }
            return relativePath;
        }
        return url;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy