| /* |
| * 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.cpplite.project; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| import java.util.stream.Collectors; |
| import org.netbeans.api.extexecution.ExecutionDescriptor; |
| import org.netbeans.api.extexecution.ExecutionService; |
| import org.netbeans.api.extexecution.print.ConvertedLine; |
| import org.netbeans.api.extexecution.print.LineConvertor; |
| import org.netbeans.api.project.ProjectUtils; |
| import org.netbeans.modules.cpplite.debugger.api.Debugger; |
| import org.netbeans.modules.cpplite.project.runner.Runner; |
| import org.netbeans.spi.project.ActionProvider; |
| import org.openide.LifecycleManager; |
| import org.openide.cookies.LineCookie; |
| import org.openide.filesystems.FileObject; |
| import org.openide.filesystems.FileUtil; |
| import org.openide.modules.InstalledFileLocator; |
| import org.openide.text.Line; |
| import org.openide.util.Lookup; |
| import org.openide.windows.OutputEvent; |
| import org.openide.windows.OutputListener; |
| |
| /** |
| * |
| * @author lahvac |
| */ |
| public class ActionProviderImpl implements ActionProvider { |
| private static final String[] SUPPORTED_ACTIONS = { |
| COMMAND_BUILD, |
| COMMAND_CLEAN, |
| COMMAND_REBUILD, |
| COMMAND_RUN, |
| COMMAND_DEBUG, |
| }; |
| |
| private final CPPLiteProject prj; |
| |
| public ActionProviderImpl(CPPLiteProject prj) { |
| this.prj = prj; |
| } |
| |
| @Override |
| @SuppressWarnings("ReturnOfCollectionOrArrayField") |
| public String[] getSupportedActions() { |
| return SUPPORTED_ACTIONS; |
| } |
| |
| private static final Pattern ERROR_LINE = Pattern.compile("(.*):(\\d+):(\\d+):.*"); |
| |
| @Override |
| public void invokeAction(String command, Lookup context) throws IllegalArgumentException { |
| BuildConfiguration config = prj.getActiveBuildConfiguration(); |
| File module = InstalledFileLocator.getDefault().locate("modules/org-netbeans-modules-cpplite-project.jar", "org.netbeans.modules.cpplite.project", false); |
| ExecutionDescriptor executionDescriptor = new ExecutionDescriptor() |
| .showProgress(true) |
| .showSuspended(true) |
| .frontWindowOnError(true) |
| .controllable(true) |
| .errConvertorFactory(() -> new ErrorLineConvertor()) |
| .outConvertorFactory(() -> new ErrorLineConvertor()); |
| ExecutionService.newService(() -> { |
| LifecycleManager.getDefault().saveAll(); |
| if (COMMAND_DEBUG.equals(command)) { |
| List<List<String>> executablesFor = config.executablesFor(COMMAND_RUN); |
| return Debugger.startInDebugger(executablesFor.get(0), FileUtil.toFile(prj.getProjectDirectory())); |
| } |
| List<List<String>> executablesFor; |
| if (COMMAND_REBUILD.equals(command)) { |
| executablesFor = new ArrayList<>(); |
| executablesFor.addAll(config.executablesFor(COMMAND_CLEAN)); |
| executablesFor.addAll(config.executablesFor(COMMAND_BUILD)); |
| } else { |
| executablesFor = config.executablesFor(command); |
| } |
| String arg = executablesFor.stream().map(c -> quote(c.stream().map(p -> quote(p)).collect(Collectors.joining(" ")))).collect(Collectors.joining(" ")); |
| return new ProcessBuilder("java", "-classpath", module.getAbsolutePath(), Runner.class.getName(), arg).directory(FileUtil.toFile(prj.getProjectDirectory())).start(); |
| }, executionDescriptor, ProjectUtils.getInformation(prj).getDisplayName() + " - " + command).run(); |
| } |
| |
| private static String quote(String s) { |
| return s.replace("_", "_u_").replace(" ", "_s_"); |
| } |
| |
| @Override |
| public boolean isActionEnabled(String command, Lookup context) throws IllegalArgumentException { |
| if (COMMAND_DEBUG.equals(command)) { |
| return isActionEnabled(COMMAND_RUN, context); |
| } else if (COMMAND_REBUILD.equals(command)) { |
| return isActionEnabled(COMMAND_CLEAN, context) && isActionEnabled(COMMAND_BUILD, context); |
| } else { |
| return prj.getActiveBuildConfiguration().executablesFor(command) != null; |
| } |
| } |
| |
| private static class ErrorLineConvertor implements LineConvertor { |
| |
| @Override |
| public List<ConvertedLine> convert(String line) { |
| Matcher matcher = ERROR_LINE.matcher(line); |
| if (matcher.matches()) { |
| String fileName = matcher.group(1); |
| int lineNum = Integer.parseInt(matcher.group(2)) - 1; |
| int columnNum = Integer.parseInt(matcher.group(3)) - 1; |
| return Collections.singletonList(ConvertedLine.forText(line, new OutputListener() { |
| @Override |
| public void outputLineSelected(OutputEvent ev) {} |
| @Override |
| public void outputLineAction(OutputEvent ev) { |
| FileObject file = FileUtil.toFileObject(new File(fileName)); |
| if (file == null) { |
| //TODO |
| return; |
| } |
| LineCookie lc = file.getLookup().lookup(LineCookie.class); |
| lc.getLineSet().getCurrent(lineNum).show(Line.ShowOpenType.OPEN, Line.ShowVisibilityType.FOCUS, columnNum); |
| } |
| @Override |
| public void outputLineCleared(OutputEvent ev) {} |
| })); |
| } |
| return Collections.singletonList(ConvertedLine.forText(line, null)); |
| } |
| } |
| |
| } |