package com.onpositive.gae.tools.core;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.jface.text.rules.IPartitionTokenScanner;
import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.VerticalRuler;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsoleDocumentPartitioner;
import org.eclipse.ui.console.TextConsole;
import org.eclipse.ui.console.TextConsoleViewer;
import org.eclipse.ui.internal.console.ConsoleDocument;
import org.eclipse.ui.internal.console.ConsoleManager;
import org.eclipse.ui.internal.console.PatternMatchListener;
import org.eclipse.ui.part.ViewPart;
import com.google.appengine.tools.admin.AppAdmin.LogSeverity;
import com.onpositive.commons.elements.AbstractUIElement;
import com.onpositive.commons.elements.Container;
import com.onpositive.commons.ui.appearance.HorizontalLayouter;
import com.onpositive.commons.ui.appearance.IContainerLayoutManager;
import com.onpositive.commons.ui.appearance.OneElementOnLineLayouter;
import com.onpositive.commons.ui.dialogs.InputElementDialog;
import com.onpositive.commons.ui.dialogs.PopupDialogWidgetCreator;
import com.onpositive.commons.ui.dialogs.TitledDialog;
import com.onpositive.commons.ui.viewers.FilterMode;
import com.onpositive.commons.ui.viewers.IFilter;
import com.onpositive.commons.ui.viewers.ViewerConfiguration;
import com.onpositive.gae.tools.Activator;
import com.onpositive.semantic.model.api.property.IOrderListener;
import com.onpositive.semantic.model.api.property.IOrderMaintainer;
import com.onpositive.semantic.model.api.property.adapters.IRealmProvider;
import com.onpositive.semantic.model.api.property.adapters.ITextLabelProvider;
import com.onpositive.semantic.model.api.property.java.annotations.Caption;
import com.onpositive.semantic.model.api.property.java.annotations.LabelLookup;
import com.onpositive.semantic.model.api.property.java.annotations.OrderMaintainer;
import com.onpositive.semantic.model.api.property.java.annotations.RealmProvider;
import com.onpositive.semantic.model.api.property.java.annotations.Required;
import com.onpositive.semantic.model.api.property.java.annotations.TextLabel;
import com.onpositive.semantic.model.binding.Binding;
import com.onpositive.semantic.model.binding.IBinding;
import com.onpositive.semantic.model.realm.IRealm;
import com.onpositive.semantic.model.realm.OrderedRealm;
import com.onpositive.semantic.model.realm.Realm;
import com.onpositive.semantic.model.ui.property.editors.ButtonSelector;
import com.onpositive.semantic.model.ui.property.editors.DisposeBindingListener;
import com.onpositive.semantic.model.ui.property.editors.OneLineTextElement;
import com.onpositive.semantic.model.ui.property.editors.structured.ComboEnumeratedValueSelector;
public class LogViewPart extends ViewPart {
private static final String[] STRINGS = new String[] { "Critical", "Error", "Warning", "Info",
"Debug" };
private LogViewer logViewer;
private String currentLogs = "";
public LogViewPart() {
}
boolean horizontal;
int limit=1000;
@Caption("Days to fetch:")
@Required(value="0")
int days=7;
@Caption("Minimal severity to fetch")
@Required(value="2")
@RealmProvider(MyRealmClass.class)
@TextLabel(providerClass=MyLabelProvider.class)
int minSeverityToFetch=4;
int currentSeverity=0;
public static class MyLabelProvider implements ITextLabelProvider{
public String getDescription(Object object) {
return getText(object);
}
public String getText(Object object) {
return STRINGS[(Integer)object];
}
}
public static class MyRealmClass implements IRealmProvider<Integer>{
public IRealm<Integer> getRealm(IBinding model) {
OrderedRealm<Integer>res=new OrderedRealm<Integer>();
for (int a=0;a<STRINGS.length;a++){
res.add(a);
}
return res;
}
}
public void init(IViewSite site, IMemento memento) throws PartInitException {
super.init(site, memento);
if (memento != null) {
Boolean boolean1 = memento.getBoolean("horizontal");
if (boolean1 != null) {
horizontal = boolean1;
}
Integer integer = memento.getInteger("limit");
if (integer!=null){
limit=integer;
}
integer = memento.getInteger("days");
if (integer!=null){
days=integer;
}
integer = memento.getInteger("minSeverityToFetch");
if (integer!=null){
minSeverityToFetch=integer;
}
integer = memento.getInteger("currentSeverity");
if (integer!=null){
currentSeverity=integer;
}
}
}
public void saveState(IMemento memento) {
memento.putBoolean("horizontal", horizontal);
memento.putInteger("limit", limit);
memento.putInteger("days", days);
memento.putInteger("minSeverityToFetch", minSeverityToFetch);
memento.putInteger("currentSeverity", currentSeverity);
super.saveState(memento);
}
public class MM extends FastPartitioner implements
IConsoleDocumentPartitioner {
private TextConsole console;
public MM(TextConsole console) {
super(new RuleBasedPartitionScanner(),
new String[] { IDocument.DEFAULT_CONTENT_TYPE });
this.console = console;
}
public StyleRange[] getStyleRanges(int offset, int length) {
try {
IRegion lineInformation = console.getDocument()
.getLineInformationOfOffset(offset);
String string = console.getDocument().get(
lineInformation.getOffset(),
lineInformation.getLength());
if (string.trim().startsWith("at")) {
return new StyleRange[] { new StyleRange(offset, length,
Display.getDefault().getSystemColor(SWT.COLOR_RED),
null) };
}
} catch (BadLocationException e) {
Activator.log(e);
}
return new StyleRange[] {};
}
public boolean isReadOnly(int offset) {
return true;
}
}
String filterText;
long lastModified;
public void createPartControl(Composite parent) {
GridLayout layout = new GridLayout(1, false);
layout.marginWidth = 0;
layout.marginHeight = 0;
parent.setLayout(layout);
Composite topBar = new Composite(parent, SWT.NONE);
GridLayout layout2 = new GridLayout(6, false);
layout2.marginHeight = 3;
topBar.setLayout(layout2);
Label ls = new Label(topBar, SWT.NONE);
ls.setText("Filter:");
final Text filter = new Text(topBar, SWT.BORDER);
filter.addModifyListener(new ModifyListener(){
public void modifyText(ModifyEvent e) {
filterText=filter.getText().trim();
final long currentTimeMillis = System.currentTimeMillis();
lastModified=currentTimeMillis;
Display.getCurrent().timerExec(500,new Runnable(){
public void run() {
if (lastModified==currentTimeMillis){
logViewer.getTreeViewer().getTree().setRedraw(false);
logViewer.getTreeViewer().refresh();
logViewer.getTreeViewer().getTree().setRedraw(true);
logViewer.getTreeViewer().getTree().redraw();
}
}
});
}
});
Label sev = new Label(topBar, SWT.NONE);
sev.setText("Minimum Severity is:");
final Combo m = new Combo(topBar, SWT.READ_ONLY);
final String[] items = STRINGS;
m.setItems(items);
m.select(items.length - 1);
m.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
currentSeverity=items.length-1-m.getSelectionIndex();
logViewer.getTreeViewer().getTree().setRedraw(false);
logViewer.getTreeViewer().refresh();
logViewer.getTreeViewer().getTree().setRedraw(true);
}
});
filter.setLayoutData(GridDataFactory.fillDefaults().grab(true, false)
.create());
topBar.setLayoutData(GridDataFactory.fillDefaults().grab(true, false)
.create());
final SashForm owner = new SashForm(parent, SWT.VERTICAL);
owner.setLayoutData(GridDataFactory.fillDefaults().grab(true, true)
.create());
Composite c = new Composite(owner, SWT.NONE);
c.setLayout(new FillLayout());
logViewer = new LogViewer(c);
logViewer.configure(new ViewerConfiguration("Message", "",
new LogViewerContentProvider(), new FilterMode[] {}, false,
false, LogViewColumn.getLogColumns()));
logViewer.getTreeViewer().addFilter(new ViewerFilter() {
public boolean select(Viewer viewer, Object parentElement, Object element) {
boolean cm = cm(element);
if (!cm){
if (element instanceof LogItem){
LogItem z=(LogItem) element;
ILogItem[] parts = z.getParts();
for (ILogItem m:parts){
if (cm(m)){
return true;
}
}
}
else{
if (cm(parentElement)){
return true;
}
}
}
return cm;
}
});
final TextConsole console = new TextConsole("console",
"javaStackTraceConsole", null, false) {
public String getType() {
return super.getType();
}
protected IConsoleDocumentPartitioner getPartitioner() {
return new MM(this);
}
};
final TextConsoleViewer sv = new TextConsoleViewer(owner, console);
ConsolePlugin.getDefault().getConsoleManager()
.createPatternMatchListeners(console);
IDocument document = console.getDocument();
document.setDocumentPartitioner(new MM(console));
logViewer.setFilter(new IFilter(){
public boolean accept(Object o) {
return true;
}
public Point match(String text) {
if (filterText!=null&&filterText.length()>0){
int indexOf = text.indexOf(filterText);
if (indexOf!=-1){
return new Point(indexOf,filterText.length());
}
}
return new Point(0,0);
}
});
sv.getTextWidget().setEditable(false);
// sv.setDocument(document);
// sv.getTextWidget().setFont(JFaceResources.getTextFont());
logViewer.getSelectionProvider().addSelectionChangedListener(
new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
if (!event.getSelection().isEmpty()) {
IStructuredSelection sm = (IStructuredSelection) event
.getSelection();
Object firstElement = sm.getFirstElement();
ILogItem item = (ILogItem) firstElement;
sv.getDocument().set(item.getMessage());
Display.getCurrent().asyncExec(new Runnable() {
public void run() {
sv.getTextWidget().redraw();
}
});
}
}
});
owner.setWeights(new int[] { 30, 50 });
IMenuManager menuManager = getViewSite().getActionBars()
.getMenuManager();
menuManager.add(new Action("Settings") {
public void run() {
final Binding bnd=new Binding(LogViewPart.this);
bnd.setAutoCommit(false);
bnd.setReadOnly(false);
Container r=new Container();
IContainerLayoutManager ca=new OneElementOnLineLayouter();
OneLineTextElement<Integer>str=new OneLineTextElement<Integer>(bnd.getBinding("days"));
ComboEnumeratedValueSelector<Integer>sev=new ComboEnumeratedValueSelector<Integer>();
sev.setOrdered(true);
sev.setBinding(bnd.getBinding("minSeverityToFetch"));
r.add(str);
r.add(sev);
Container buttons=new Container();
HorizontalLayouter horizontalLayouter = new HorizontalLayouter();
buttons.setLayoutManager(horizontalLayouter);
r.add(buttons);
final InputElementDialog inputElementDialog = new InputElementDialog(bnd,r,"Settings","you may configure settings here");
ButtonSelector bs=new ButtonSelector();
bs.setValue(new Runnable() {
public void run() {
bnd.commit();
inputElementDialog.close();
}
});
bs.setText("Apply");
buttons.add(bs);
ButtonSelector bs1=new ButtonSelector();
bs1.setValue(new Runnable() {
public void run() {
inputElementDialog.close();
}
});
//buttons.add(bs);
buttons.add(bs1);
bs1.setText("Cancel");
r.setLayoutManager(ca);
DisposeBindingListener.linkBindingLifeCycle(bnd, r);
inputElementDialog.open();
}
});
menuManager.update(true);
IToolBarManager toolBarManager = getViewSite().getActionBars()
.getToolBarManager();
toolBarManager.add(new Action("Export Log") {
{
setImageDescriptor(Activator.imageDescriptorFromPlugin(
Activator.PLUGIN_ID, "/icons/export_log.gif"));
}
public void run() {
FileDialog dlg = new FileDialog(Display.getCurrent()
.getActiveShell(), SWT.SAVE);
dlg.setText("Export log to:");
String open = dlg.open();
if (open != null) {
try {
FileOutputStream s = new FileOutputStream(open);
BufferedWriter bf = new BufferedWriter(
new OutputStreamWriter(s));
try {
bf.append(currentLogs);
bf.close();
} catch (Exception e) {
MessageDialog.openError(Display.getCurrent()
.getActiveShell(), "Error", e.getMessage());
}
} catch (FileNotFoundException e) {
MessageDialog.openError(Display.getCurrent()
.getActiveShell(), "Error", e.getMessage());
}
}
}
});
toolBarManager.add(new Action("Import Log") {
{
setImageDescriptor(Activator.imageDescriptorFromPlugin(
Activator.PLUGIN_ID, "/icons/import_log.gif"));
}
public void run() {
FileDialog dlg = new FileDialog(Display.getCurrent()
.getActiveShell(), SWT.OPEN);
dlg.setText("Open log from");
String open = dlg.open();
if (open != null) {
try {
FileInputStream s = new FileInputStream(open);
BufferedReader bf = new BufferedReader(
new InputStreamReader(s));
StringBuilder bld = new StringBuilder();
;
ArrayList<LogItem> result = new ArrayList<LogItem>();
try {
while (true) {
try {
String str = bf.readLine();
if (str == null) {
break;
}
try {
result.add(new LogItem(str));
} catch (Exception e) {
e.printStackTrace();
}
bld.append(str);
bld.append('\n');
} catch (IOException e) {
MessageDialog.openError(Display
.getCurrent().getActiveShell(),
"Error", e.getMessage());
}
}
logViewer.setInput(result
.toArray(new LogItem[result.size()]));
currentLogs = bld.toString();
} catch (Exception e) {
MessageDialog.openError(Display.getCurrent()
.getActiveShell(), "Error", e.getMessage());
}
} catch (FileNotFoundException e) {
MessageDialog.openError(Display.getCurrent()
.getActiveShell(), "Error", e.getMessage());
}
}
}
});
sync = new Action("Sync with Server") {
{
setImageDescriptor(Activator.imageDescriptorFromPlugin(
Activator.PLUGIN_ID, "/icons/refresh.gif"));
}
public void run() {
refreshLog(currentProject);
}
};
menuManager.add(new Separator());
Action action = new Action("Split horizontally",
IAction.AS_RADIO_BUTTON) {
{
setImageDescriptor(Activator.imageDescriptorFromPlugin(
Activator.PLUGIN_ID, "icons/horizontalOrientation.gif"));
}
public void run() {
owner.setOrientation(SWT.HORIZONTAL);
logViewer.getTreeViewer().getTree().layout(true, true);
}
};
action.setChecked(owner.getOrientation() == SWT.HORIZONTAL);
menuManager.add(action);
menuManager
.add(new Action("Split vertically", IAction.AS_RADIO_BUTTON) {
{
setImageDescriptor(Activator.imageDescriptorFromPlugin(
Activator.PLUGIN_ID,
"icons/verticalOrientation.gif"));
setChecked(owner.getOrientation() == SWT.VERTICAL);
}
public void run() {
owner.setOrientation(SWT.VERTICAL);
logViewer.getTreeViewer().getTree().layout(true, true);
}
});
sync.setEnabled(false);
toolBarManager.add(sync);
toolBarManager.update(true);
}
public void setFocus() {
}
String logContent;
IJavaProject currentProject;
private Action sync;
public void setProject(IJavaProject javaGaeProject) {
this.currentProject = javaGaeProject;
sync.setEnabled(javaGaeProject != null);
refreshLog(javaGaeProject);
}
private void refreshLog(IJavaProject javaGaeProject) {
final FetchLogsJob fetchLogsJob = new FetchLogsJob(javaGaeProject,
"Fetch logs", days, LogSeverity.values()[STRINGS.length-1-minSeverityToFetch]);
fetchLogsJob.addJobChangeListener(new JobChangeAdapter() {
public void done(IJobChangeEvent event) {
if (event.getResult().isOK()) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
LogItem[] result = fetchLogsJob.getLogs();
logViewer.setInput(result);
currentLogs = fetchLogsJob.getLogContent();
}
});
}
super.done(event);
}
});
fetchLogsJob.schedule();
}
public void setUrl(String url, boolean debug) {
}
private boolean cm(Object element) {
if (element instanceof ILogItem){
ILogItem c=(ILogItem) element;
if (c.getSeverity()<currentSeverity){
return false;
}
if (filterText!=null&&filterText.length()!=0){
if (c.getMessage().indexOf(filterText)==-1)
{
return false;
}
}
}
return true;
}
}