Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to use custom phar file instead of the included version #10

Merged
merged 2 commits into from Mar 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions META-INF/plugin.xml
Expand Up @@ -29,6 +29,8 @@
<depends>com.intellij.modules.platform</depends>

<extensions defaultExtensionNs="com.intellij">
<projectConfigurable instance="hal.phpmetrics.idea.settings.SettingsForm" groupId="tools" />
<projectService serviceImplementation="hal.phpmetrics.idea.Settings" />
<!-- Add your extensions here -->
</extensions>

Expand Down
Binary file modified PhpMetrics plugin.jar
Binary file not shown.
107 changes: 18 additions & 89 deletions src/java/hal/phpmetrics/idea/RunPhpMetricsAction.java
Expand Up @@ -7,88 +7,52 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.io.InputStreamReader;
import java.io.BufferedReader;

import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.ui.awt.RelativePoint;
import hal.phpmetrics.idea.runner.CliRunner;
import hal.phpmetrics.idea.runner.ResultListener;
import hal.phpmetrics.idea.runner.OnEventDispatchThread;

public class RunPhpMetricsAction extends AnAction {

private Project project;

public void actionPerformed(AnActionEvent e) {
public void actionPerformed(final AnActionEvent e) {

project = e.getProject();
if(project == null) {
Project project = e.getProject();
if (project == null) {
return;
}

inform(e, "PhpMetrics started. Your browser will be run in few minutes....", MessageType.INFO);

VirtualFile currentDirectory = PlatformDataKeys.VIRTUAL_FILE.getData(e.getDataContext());
try {
CliRunner cliRunner = new CliRunner(Settings.getInstance(project).pathToBinary);
final File destination = File.createTempFile("phpmetrics-idea", ".html");
String[] command = new String[]{"--report-html=" + destination, currentDirectory.getPath()};

File phar = getExternalPath("/phar/phpmetrics.phar");

String[] commands = new String[]{"php", phar.getAbsolutePath(), "--report-html=" + destination, currentDirectory.getPath()};

Runtime runtime = Runtime.getRuntime();
final Process process = runtime.exec(commands);

new Thread() {
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
try {
while ((line = reader.readLine()) != null) {
}
} finally {
reader.close();
}

// open browser
BrowserUtil.browse(destination);

} catch (IOException ioe) {
ioe.printStackTrace();
}
cliRunner.run(command, new OnEventDispatchThread(new ResultListener() {
@Override
public void onSuccess(String output) {
BrowserUtil.browse(destination);
}
}.start();

new Thread() {
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = "";
try {
while ((line = reader.readLine()) != null) {
}
} finally {
reader.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
@Override
public void onError(String error, String output, int exitCode) {
inform(e, "An error occurred. Please verify your PhpMetrics installation\n" + output, MessageType.ERROR);
}
}.start();

}));
} catch (IOException e1) {
e1.printStackTrace();
}
}

public void inform(AnActionEvent e, String text, MessageType messageType) {
private void inform(AnActionEvent e, String text, MessageType messageType) {
StatusBar statusBar = WindowManager.getInstance()
.getStatusBar(PlatformDataKeys.PROJECT.getData(e.getDataContext()));
JBPopupFactory.getInstance()
Expand All @@ -98,39 +62,4 @@ public void inform(AnActionEvent e, String text, MessageType messageType) {
.show(RelativePoint.getCenterOf(statusBar.getComponent()),
Balloon.Position.atRight);
}



public File getExternalPath(String resource) {
File file = null;
URL res = getClass().getResource(resource);
if (res.toString().startsWith("jar:") ||res.toString().contains(".jar!")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile("tempfile", ".tmp");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];

while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
file.deleteOnExit();
} catch (IOException ex) {
ex.printStackTrace();
}
} else {
file = new File(res.getFile().toString().replace("%20", "\\ "));

if (!file.exists()) {
file = new File(res.getFile().toString().replace("%20", " "));
}
}

if (file != null && !file.exists()) {
throw new RuntimeException("Error: File " + file + " not found!");
}

return file;
}
}
33 changes: 33 additions & 0 deletions src/java/hal/phpmetrics/idea/Settings.java
@@ -0,0 +1,33 @@
package hal.phpmetrics.idea;

import com.intellij.openapi.components.*;
import com.intellij.openapi.project.Project;
import com.intellij.util.xmlb.XmlSerializerUtil;
import org.jetbrains.annotations.Nullable;

@State(
name = "PhpMetricsPluginSettings",
storages = {
@Storage(id = "default", file = StoragePathMacros.PROJECT_FILE),
@Storage(id = "dir", file = StoragePathMacros.PROJECT_CONFIG_DIR + "/phpmetrics.xml", scheme = StorageScheme.DIRECTORY_BASED)
}
)
public class Settings implements PersistentStateComponent<Settings> {

public String pathToBinary;

@Nullable
@Override
public Settings getState() {
return this;
}

@Override
public void loadState(Settings settings) {
XmlSerializerUtil.copyBean(settings, this);
}

public static Settings getInstance(Project project) {
return ServiceManager.getService(project, Settings.class);
}
}
98 changes: 98 additions & 0 deletions src/java/hal/phpmetrics/idea/runner/CliRunner.java
@@ -0,0 +1,98 @@
package hal.phpmetrics.idea.runner;

import java.io.*;
import java.net.URL;

public class CliRunner {

private String binPath;

private static String resultFromStream(InputStream stream) {
try {
String processResult = "";
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
while ((line = reader.readLine()) != null) {
processResult += line;
}
reader.close();
return processResult;
} catch (IOException exception) {
exception.printStackTrace();
}
return "";
}


public static CliRunner withIncludedPhar() {
return new CliRunner(null);
}

public CliRunner(String binPath) {
this.binPath = binPath;
}

public void run(String[] arguments, final ResultListener listener) {
final String[] command = new String[arguments.length + 2];
command[0] = "php";
command[1] = binPath != null ? binPath : getExternalPath("/phar/phpmetrics.phar");
System.arraycopy(arguments, 0, command, 2, arguments.length);

new Thread() {
@Override
public void run() {
try {
final Process process = Runtime.getRuntime().exec(command);
process.waitFor();

if (process.exitValue() == 0) {
listener.onSuccess(resultFromStream(process.getInputStream()));
return;
}

listener.onError(resultFromStream(process.getErrorStream()), resultFromStream(process.getInputStream()), process.exitValue());
} catch (IOException exception) {
exception.printStackTrace();
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}.start();
}

private String getExternalPath(String resource) throws NullPointerException {
File file = null;
URL res = getClass().getResource(resource);
if (res.toString().startsWith("jar:") ||res.toString().contains(".jar!")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile("tempfile", ".tmp");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];

while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
file.deleteOnExit();
} catch (IOException ex) {
ex.printStackTrace();
}
} else {
file = new File(res.getFile().replace("%20", "\\ "));

if (!file.exists()) {
file = new File(res.getFile().replace("%20", " "));
}
}

if (file != null && ! file.exists()) {
throw new RuntimeException("Error: File " + file + " not found!");
}
if (file == null) {
throw new RuntimeException("Error: Could not found the phpmetrics bin file");
}

return file.getAbsolutePath();
}
}
57 changes: 57 additions & 0 deletions src/java/hal/phpmetrics/idea/runner/OnEventDispatchThread.java
@@ -0,0 +1,57 @@
package hal.phpmetrics.idea.runner;

import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import org.jetbrains.annotations.NotNull;

import java.awt.*;

/**
* Decorator that allows to to run the listener from the event dispatch thread.
*
* It is just a convenience class.
* See http://www.jetbrains.org/intellij/sdk/docs/basics/architectural_overview/general_threading_rules.html for more
* information.
*/
public class OnEventDispatchThread implements ResultListener {
private Component modifiedComponent;
private ResultListener decorated;

public OnEventDispatchThread(@NotNull ResultListener decorated, @NotNull Component target) {
this.modifiedComponent = target;
this.decorated = decorated;
}

public OnEventDispatchThread(@NotNull ResultListener decorated) {
this.decorated = decorated;
}

@Override
public void onSuccess(final String output) {
final Application application = ApplicationManager.getApplication();
application.invokeLater(new Runnable() {
@Override
public void run() {
decorated.onSuccess(output);
}
}, modalityStateFor(modifiedComponent));
}

@Override
public void onError(final String error, final String output, final int exitCode) {
final Application application = ApplicationManager.getApplication();
application.invokeLater(new Runnable() {
@Override
public void run() {
decorated.onError(error, output, exitCode);
}
}, modalityStateFor(modifiedComponent));
}

private ModalityState modalityStateFor(Component component) {
return component != null
? ModalityState.stateForComponent(component)
: ModalityState.any();
}
}
6 changes: 6 additions & 0 deletions src/java/hal/phpmetrics/idea/runner/ResultListener.java
@@ -0,0 +1,6 @@
package hal.phpmetrics.idea.runner;

public interface ResultListener {
void onSuccess(String output);
void onError(String error, String output, int exitCode);
}