package eu.jucy.gui.logviewer; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; import logger.LoggerFactory; import org.apache.log4j.Logger; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DateTime; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import uc.DCClient; import uc.PI; import uc.database.DBLogger; import uc.database.IDatabase; import uc.database.ILogEntry; import uihelpers.CommandButton; import uihelpers.SUIJob; import uihelpers.TableViewerAdministrator; import uihelpers.TableViewerAdministrator.ColumnDescriptor; import eu.jucy.gui.ApplicationWorkbenchWindowAdvisor; import eu.jucy.gui.GUIPI; import eu.jucy.gui.ISearchableEditor; import eu.jucy.gui.Lang; import eu.jucy.gui.UCEditor; import eu.jucy.gui.logviewer.LogViewerHandlers.ExportAllLogs; public class LogViewerEditor extends UCEditor implements ISearchableEditor { public static final String ID = "eu.jucy.gui.logviewer"; private static Logger logger = LoggerFactory.make(); // private static final int hitsPerPage = 500; private TableViewer tableViewer; private Table table; private StyledText styledText; private DateTime calendar; private TableViewerAdministrator<DBLogger> tva; private DBLogger dbLogger; // private List<LogViewerActions> actions; private Label countLabel; private Composite linkComp; // private int page = 0; private volatile long currentTime = System.currentTimeMillis(); private int totalcount; private String lastSearch; private int lastHit = -1; @Override public void createPartControl(Composite parent) { final GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 2; parent.setLayout(gridLayout); tableViewer = new TableViewer(parent, SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER| SWT.V_SCROLL ); table = tableViewer.getTable(); table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true)); tva = new TableViewerAdministrator<DBLogger>( tableViewer, Collections.singletonList(new LogEntityNameCol()), GUIPI.logViewerTable,0); tva.apply(); final Composite comp = new Composite(parent,SWT.BORDER); final GridLayout gridLayout_0 = new GridLayout(); gridLayout_0.numColumns = 1; comp.setLayout(gridLayout_0); comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 2)); styledText = new StyledText(comp, SWT.BORDER| SWT.V_SCROLL | SWT.WRAP); styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); final Composite belowText = new Composite(comp,SWT.BORDER); final GridLayout gridLayout_b = new GridLayout(); gridLayout_b.numColumns = 3; belowText.setLayout(gridLayout_b); belowText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); countLabel = new Label(belowText,SWT.NONE); countLabel.setLayoutData(new GridData(100, SWT.DEFAULT)); Label distLabel = new Label(belowText,SWT.NONE); distLabel.setLayoutData(new GridData(100, SWT.DEFAULT)); linkComp = new Composite(belowText,SWT.NONE); linkComp.setLayout(new RowLayout()); /*final GridLayout gridLayout_l = new GridLayout(); gridLayout_l.numColumns = 3; belowText.setLayout(gridLayout_l); */ linkComp.setLayoutData(new GridData(SWT.LEFT,SWT.FILL,true,false)); final Composite composite = new Composite(parent, SWT.NONE); final GridLayout gridLayout_1 = new GridLayout(); gridLayout_1.numColumns = 2; composite.setLayout(gridLayout_1); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); final Button pruneButton = new Button(composite, SWT.NONE); pruneButton.setText(Lang.PruneAllOlderThan); calendar = new DateTime(composite, SWT.DATE|SWT.DROP_DOWN); pruneButton.addSelectionListener (new SelectionAdapter () { public void widgetSelected (SelectionEvent e) { final Calendar cal = Calendar.getInstance(); cal.set(calendar.getYear(), calendar.getMonth(), calendar.getDay()); final DCClient dcc = ApplicationWorkbenchWindowAdvisor.get(); new Job(Lang.DeleteLog) { @Override protected IStatus run(IProgressMonitor monitor) { dcc.getDatabase() .pruneLogentrys(null, cal.getTime(),monitor); new SUIJob(calendar) { @Override public void run() { setCalendarToday(); update(true,false); } }; return Status.OK_STATUS; } }.schedule(); } }); Calendar cal = Calendar.getInstance(); cal.add(Calendar.MONTH, -6); //prune all older than 6 Months as default.. calendar.setDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); final Button exportAll = new Button(composite,SWT.NONE); CommandButton.setCommandToButton(ExportAllLogs.COMMAND_ID, exportAll, getSite(), false); // exportAll.setText("Export All Logs"); // exportAll.addSelectionListener (new SelectionAdapter () { // public void widgetSelected (SelectionEvent e) { // Export.exportAll(); // } // }); tableViewer.setContentProvider(new LogViewerContentProvider()); tableViewer.setInput(ApplicationWorkbenchWindowAdvisor.get().getDatabase()); tableViewer.addPostSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection iss = (IStructuredSelection)selection; DBLogger newl= (DBLogger)iss.getFirstElement(); if (newl != null && (newl != dbLogger)) { dbLogger = newl; setCalendarToday(); update(false,false); } } } }); tableViewer.getTable().getColumn(0).pack(); // makeActions(); getSite().setSelectionProvider(tableViewer); createContextPopup(tableViewer); setControlsForFontAndColour(tableViewer.getTable(),styledText,calendar); logger.debug("Editor Created"); } void setFilter(final DBLogger logger) { tableViewer.addFilter(new DBViewerFilter(logger)); } void removeFilter(DBLogger logger) { if (!tableViewer.getTable().isDisposed()) { tableViewer.removeFilter(new DBViewerFilter(logger)); } } private static class DBViewerFilter extends ViewerFilter { private final DBLogger dbLogger; public DBViewerFilter(DBLogger dbLogger) { super(); this.dbLogger = dbLogger; } @Override public boolean select(Viewer viewer, Object parentElement,Object element) { return !dbLogger.equals(element); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((dbLogger == null) ? 0 : dbLogger.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; DBViewerFilter other = (DBViewerFilter) obj; if (dbLogger == null) { if (other.dbLogger != null) return false; } else if (!dbLogger.equals(other.dbLogger)) return false; return true; } } @Override public void dispose() { // for (LogViewerActions action: actions) { // action.dispose(); // } // actions.clear(); super.dispose(); } private void setCalendarToday() { currentTime = getTodayMillis(); } private long getTodayMillis() { Calendar cal = Calendar.getInstance(); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); // long round = TimeUnit.DAYS.toMillis(1); // long todayMillis = (System.currentTimeMillis()/round) * round; // TimeZone tz = cal.getTimeZone(); return cal.getTimeInMillis(); } @Override public void setFocus() { tableViewer.getTable().setFocus(); } private void createLinks() { for (Control c : linkComp.getChildren()) { c.dispose(); } String date = new SimpleDateFormat("dd.MM.yy").format(currentTime); List<String> s = new ArrayList<String>(Arrays.asList("-5","˂","</A> "+date+" <A>","˃","+5","˃˃")); //these are no normal < > chars !! long base = currentTime; long day = TimeUnit.DAYS.toMillis(1); List<Long> pageInt = new ArrayList<Long>( Arrays.asList( base - 5*day,base-day,base,base+day,base+5*day,getTodayMillis())); for (int i=0; i < s.size(); i++) { final Link link = new Link(linkComp, SWT.NONE); link.setText(" <A>"+s.get(i)+"</A> "); link.setData(pageInt.get(i)); link.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { long dayInMillis = (Long)link.getData(); if (dayInMillis > getTodayMillis()) { dayInMillis = getTodayMillis(); } // if (page >= getNrOFPages()) { // page = getNrOFPages()-1; // } changeToDay(dayInMillis); } }); } linkComp.layout(); linkComp.pack(); // link.setSize(140, 40); } private void changeToDay(long dayInMillis) { if (currentTime != dayInMillis) { boolean forward = currentTime < dayInMillis; currentTime = dayInMillis; update(false,forward); } } private void changeToSameDayAs(long timestamp) { Calendar stamp = Calendar.getInstance(); stamp.setTimeInMillis(timestamp); stamp.set(Calendar.HOUR_OF_DAY, 0); stamp.set(Calendar.MINUTE, 0); stamp.set(Calendar.SECOND, 0); stamp.set(Calendar.MILLISECOND, 0); changeToDay(stamp.getTimeInMillis()); } // private int getNrOFPages() { // return totalcount/hitsPerPage + (totalcount % hitsPerPage == 0 ? 0:1) ; // } public void update(boolean both,final boolean forwardDirection) { if (tableViewer.getTable().isDisposed()) { return; } if (both) { tableViewer.refresh(); } styledText.setText(""); if (dbLogger != null) { Job job = new Job("Loading logs "+dbLogger.getName()) { @Override protected IStatus run(IProgressMonitor monitor) { monitor.beginTask("Loading", IProgressMonitor.UNKNOWN); long today = currentTime, endOfDay= currentTime+TimeUnit.DAYS.toMillis(1); final List<ILogEntry> logs = dbLogger.loadLogEntrys(today, endOfDay); //hitsPerPage,hitsPerPage * page); if (logs.isEmpty()) { final long stamp = dbLogger.getFirstLogNextTo(forwardDirection?endOfDay:today, forwardDirection); new SUIJob(styledText) { @Override public void run() { if (stamp != -1) { changeToSameDayAs(stamp); } else { styledText.setText("No logs to display for this date"); } } }.schedule(); } else { Collections.reverse(logs); monitor.done(); new SUIJob(styledText) { @Override public void run() { setLogs(logs); } }.schedule(); } return Status.OK_STATUS; } }; job.schedule(); } } private void setLogs(List<ILogEntry> logs) { StringBuilder text = new StringBuilder(); SimpleDateFormat sdf = new SimpleDateFormat(PI.get(PI.logTimeStamps)); for (ILogEntry log:logs) { text.append(sdf.format(new Date(log.getDate()))) .append(log.getMessage()) .append('\n'); } styledText.setText(text.toString()); totalcount = dbLogger.countLogEntrys(); countLabel.setText(String.format(Lang.TotalMessages, totalcount)); countLabel.pack(); //offsetLabel.setText("Page: "+(page+1)+"/"+getNrOFPages()); //offsetLabel.pack(); createLinks(); } public void next() { if (lastSearch != null) { String text = styledText.getText().toLowerCase(); lastHit = text.indexOf(lastSearch, lastHit+1); if (lastHit != -1) { styledText.setSelection(lastHit, lastHit+ lastSearch.length()); } } } public void search(String searchString) { searchString = searchString.toLowerCase(); if (!searchString.equals(lastSearch)) { lastSearch = searchString; lastHit = -1; } next(); } public static class LogViewerContentProvider implements IStructuredContentProvider { public Object[] getElements(Object inputElement) { if (inputElement instanceof IDatabase) { return ((IDatabase)inputElement).getLogentitys().toArray(); } throw new IllegalStateException(); } public void dispose() {} public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} } public static class LogEntityNameCol extends ColumnDescriptor<DBLogger> { public LogEntityNameCol() { super(200, Lang.Name); } @Override public String getText(DBLogger x) { return x.getName(); } } }