package com.onpositive.gae.profiler;
import java.util.ArrayList;
import java.util.Arrays;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PlatformUI;
import com.onpositive.gae.tools.UIUtils;
import com.onpositive.gae.tools.deploy.CheckTools;
import com.onpositive.gae.tools.deploy.ConfigureTools;
public class StartProfilingAction extends Action implements IWorkbenchWindowActionDelegate {
private static final String BUILDER = "com.onpositive.profiler.gae.builder";
public StartProfilingAction(){
setText("Enable profiling instrumentation");
}
public void dispose() {
}
public void init(IWorkbenchWindow window) {
}
public void run(IAction action) {
run();
}
public void run() {
final IJavaProject javaGaeProject = UIUtils.getJavaGaeProject();
if (javaGaeProject == null) {
return;
}
try {
IClasspathEntry[] rawClasspath = javaGaeProject.getResolvedClasspath(true);
boolean found=false;
for (IClasspathEntry e:rawClasspath){
if (e.getEntryKind()==IClasspathEntry.CPE_LIBRARY){
IPath p=e.getPath();
String portableString = p.toPortableString();
String PREFIX = "appengine-java-sdk-";
int l=portableString.indexOf(PREFIX);
if(l!=-1){
int k=portableString.indexOf('/', l+PREFIX.length());
String version=portableString.substring(l+PREFIX.length(),k);
if (version.charAt(0)=='1'){
version=version.substring(2);
try{
int lastIndexOf = version.lastIndexOf('.');
if (lastIndexOf>1){
version=version.substring(0,lastIndexOf);
}
double parseDouble = Double.parseDouble(version);
if (parseDouble>=2.6){
found=true;
}
}catch (Exception ex) {
//ignore it
}
}
else{
found=true;
}
}
}
}
if (!found){
MessageDialog.openError(Display.getCurrent().getActiveShell(), "Error ","AppEngine Profiler requires AppEngine Java SDK version 1.2.6 or greater");
return;
}
} catch (JavaModelException e1) {
Activator.getDefault().log(e1);
}
try {
final IProjectDescription description = javaGaeProject.getProject()
.getDescription();
if (!new CheckTools("Installing profiling", javaGaeProject,
Activator.getDefault().getBundle()).doCheck()) {
boolean openConfirm = MessageDialog
.openConfirm(
Display.getCurrent().getActiveShell(),
"Project should be configured to add OnPositive Profiler Support",
"Do you want to configure project to add OnPositive Profiler Support now?");
if (openConfirm) {
ConfigureTools configureTools = new ConfigureTools(
"Installing profiling", javaGaeProject, Activator
.getDefault().getBundle(),false);
PlatformUI.getWorkbench().getProgressService()
.showInDialog(
Display.getCurrent().getActiveShell(),
configureTools);
configureTools
.addJobChangeListener(new IJobChangeListener() {
public void sleeping(IJobChangeEvent event) {
}
public void scheduled(IJobChangeEvent event) {
}
public void running(IJobChangeEvent event) {
}
public void done(IJobChangeEvent event) {
enableBuilder(javaGaeProject, description);
}
public void awake(IJobChangeEvent event) {
}
public void aboutToRun(IJobChangeEvent event) {
}
});
configureTools.schedule();
}
} else {
enableBuilder(javaGaeProject, description);
}
} catch (Exception e) {
Activator.getDefault().log(e);
}
}
public void selectionChanged(IAction action, ISelection selection) {
}
private void enableBuilder(final IJavaProject javaGaeProject,
final IProjectDescription description) {
try {
ICommand[] buildSpec = description.getBuildSpec();
for (ICommand m : buildSpec) {
if (m.getBuilderName().equals(BUILDER)) {
return;
}
}
ArrayList<ICommand> arrayList = new ArrayList<ICommand>(Arrays
.asList(buildSpec));
ICommand newCommand = description.newCommand();
newCommand.setBuilderName(BUILDER);
arrayList.add(newCommand);
description.setBuildSpec(arrayList.toArray(new ICommand[arrayList
.size()]));
javaGaeProject.getProject().setDescription(description,
new NullProgressMonitor());
rebuild(javaGaeProject);
ProfilerDecorator.changed(javaGaeProject);
Display.getDefault().syncExec(new Runnable() {
public void run() {
MessageDialog.openInformation(Display.getCurrent().getActiveShell(), "Note", "You should deploy your application to Google App Engine to profile it\n or restart local server if you would like to profile local application.");
}
});
} catch (Exception e) {
Activator.getDefault().log(e);
MessageDialog.openError(Display.getDefault().getActiveShell(),
"Error during configuring profiling for '"
+ javaGaeProject.getElementName() + "'", e
.getMessage());
}
}
public static void rebuild(final IJavaProject javaGaeProject) {
Job job = new Job("Enabling profiler support") {
protected IStatus run(IProgressMonitor monitor) {
synchronized (StartProfilingAction.class) {
try {
// javaGaeProject.getProject().build(
// IncrementalProjectBuilder.CLEAN_BUILD,
// new NullProgressMonitor());
javaGaeProject.getProject().build(
IncrementalProjectBuilder.FULL_BUILD,
new NullProgressMonitor());
} catch (CoreException e) {
return Status.CANCEL_STATUS;
}
}
return Status.OK_STATUS;
}
};
IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace()
.getRuleFactory();
ISchedulingRule rule = ruleFactory.buildRule();
job.setRule(rule);
job.schedule();
}
}