Java tutorial
/******************************************************************************* * Copyright (c) Apr 21, 2012 NetXForge. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> * * Contributors: Christophe Bouhier - initial API and implementation and/or * initial documentation *******************************************************************************/ package com.netxforge.netxstudio.screens.f4; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.util.Arrays; import java.util.Date; import java.util.List; import javax.xml.datatype.XMLGregorianCalendar; import org.eclipse.core.databinding.conversion.IConverter; import org.eclipse.core.databinding.observable.IObservable; import org.eclipse.core.databinding.observable.list.IObservableList; import org.eclipse.core.databinding.observable.map.IObservableMap; import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory; import org.eclipse.core.databinding.observable.value.ComputedValue; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.util.CommitException; import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.emf.databinding.EMFDataBindingContext; import org.eclipse.emf.databinding.EMFObservables; import org.eclipse.emf.databinding.EMFProperties; import org.eclipse.emf.databinding.EMFUpdateValueStrategy; import org.eclipse.emf.databinding.FeaturePath; import org.eclipse.emf.databinding.IEMFListProperty; import org.eclipse.emf.databinding.IEMFValueProperty; import org.eclipse.emf.databinding.edit.EMFEditProperties; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.databinding.swt.SWTObservables; import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; import org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider; import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider; import org.eclipse.jface.databinding.viewers.TreeStructureAdvisor; import org.eclipse.jface.databinding.viewers.ViewerProperties; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.CellLabelProvider; import org.eclipse.jface.viewers.ColumnViewer; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.window.ToolTip; import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.inject.Inject; import com.netxforge.base.NonModelUtils; import com.netxforge.netxstudio.common.model.StudioUtils; import com.netxforge.netxstudio.data.importer.IMetricValueImporter; import com.netxforge.netxstudio.generics.DateTimeRange; import com.netxforge.netxstudio.generics.GenericsPackage; import com.netxforge.netxstudio.generics.Value; import com.netxforge.netxstudio.library.NetXResource; import com.netxforge.netxstudio.metrics.MappingRecord; import com.netxforge.netxstudio.metrics.MappingStatistic; import com.netxforge.netxstudio.metrics.MetricSource; import com.netxforge.netxstudio.metrics.MetricsPackage; import com.netxforge.netxstudio.screens.AbstractScreen; import com.netxforge.netxstudio.screens.editing.commands.WarningDeleteCommand; import com.netxforge.netxstudio.screens.editing.tables.CDOElementComparer; import com.netxforge.screens.editing.base.IDataScreenInjection; import com.netxforge.screens.editing.base.actions.BaseSelectionListenerAction; import com.netxforge.screens.editing.base.actions.clipboard.ClipboardService; /** * A screen presenting {@link MetricSource} mapping statistics * * @author Christophe Bouhier */ public class MappingStatistics extends AbstractScreen implements IDataScreenInjection { private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); private Form frmMappingStatistics; private MetricSource metricSource; private Text txtTotalRecords; private Text txtStartDateTime; private Text txtEndDateTime; private Text txtTotalValues; private Text txtTotalFailedValues; private Text txtMessage; private TableViewer tblViewerRecords; private CleanStatsAction cleanStatsAction; private TreeViewer statisticsTreeViewer; private Tree statisticsTree; private Table recordsTable; @SuppressWarnings("unused") @Inject private ClipboardService clipboard; private Text txtMetricStartDateTime; private Text txtMetricEndDateTime; /** * Create the composite. * * @param parent * @param style */ public MappingStatistics(Composite parent, int style) { super(parent, style); addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { toolkit.dispose(); } }); toolkit.adapt(this); toolkit.paintBordersFor(this); // buildUI(); } /** * Copies the selected records as text to the clipboard.... * * @author Christophe * */ class CopyMappingErrorAction extends BaseSelectionListenerAction { protected CopyMappingErrorAction(String text) { super(text); } /* * (non-Javadoc) * * @see com.netxforge.netxstudio.screens.editing.actions. * BaseSelectionListenerAction * #updateSelection(org.eclipse.jface.viewers.IStructuredSelection) */ @Override protected boolean updateSelection(IStructuredSelection selection) { Object firstElement = selection.getFirstElement(); return firstElement instanceof MappingRecord; } /* * (non-Javadoc) * * @see org.eclipse.jface.action.Action#run() */ @Override public void run() { IStructuredSelection structuredSelection = this.getStructuredSelection(); Object firstElement = structuredSelection.getFirstElement(); if (firstElement instanceof MappingRecord) { System.out.println(" yeah valid action for this object"); } } } private void buildUI() { setLayout(new FillLayout(SWT.HORIZONTAL)); frmMappingStatistics = toolkit.createForm(this); frmMappingStatistics.setSeparatorVisible(true); toolkit.paintBordersFor(frmMappingStatistics); frmMappingStatistics.setText("Mapping Statistics: " + metricSource.getName()); frmMappingStatistics.getBody().setLayout(new FormLayout()); cleanStatsAction = new CleanStatsAction("Clean up..."); frmMappingStatistics.getMenuManager().add(cleanStatsAction); SashForm sashForm = new SashForm(frmMappingStatistics.getBody(), SWT.NONE); FormData fd_sashForm = new FormData(); fd_sashForm.bottom = new FormAttachment(100, -12); fd_sashForm.right = new FormAttachment(100, -12); fd_sashForm.top = new FormAttachment(0, 12); fd_sashForm.left = new FormAttachment(0, 12); sashForm.setLayoutData(fd_sashForm); toolkit.adapt(sashForm); toolkit.paintBordersFor(sashForm); Section sctnStatistics = toolkit.createSection(sashForm, Section.EXPANDED | Section.TITLE_BAR); toolkit.paintBordersFor(sctnStatistics); sctnStatistics.setText("Statistics"); Composite cmpSelector = toolkit.createComposite(sctnStatistics, SWT.NONE); toolkit.paintBordersFor(cmpSelector); sctnStatistics.setClient(cmpSelector); cmpSelector.setLayout(new FillLayout(SWT.HORIZONTAL)); statisticsTreeViewer = new TreeViewer(cmpSelector, SWT.BORDER | SWT.MULTI); statisticsTreeViewer.setUseHashlookup(true); statisticsTreeViewer.setComparer(new CDOElementComparer()); statisticsTree = statisticsTreeViewer.getTree(); toolkit.paintBordersFor(statisticsTree); // statisticsListViewer = new ListViewer(cmpSelector, SWT.BORDER // | SWT.V_SCROLL); // TODO, convert to an action. Menu menu = new Menu(statisticsTreeViewer.getTree()); statisticsTreeViewer.getTree().setMenu(menu); MenuItem mntmMore = new MenuItem(menu, SWT.NONE); mntmMore.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // Show the period etc.. ISelection selection = statisticsTreeViewer.getSelection(); if (selection instanceof IStructuredSelection) { Object o = ((IStructuredSelection) selection).getFirstElement(); if (o instanceof MappingStatistic) { // Create a predicate for filtering the values within a // range. MappingStatistic mappingStatistics = (MappingStatistic) o; final int targetIntervalHint = mappingStatistics.getIntervalEstimate(); Resource metricResource = editingService.getData(MetricsPackage.Literals.METRIC); List<NetXResource> resourcesInMetricSource = StudioUtils .resourcesInMetricSource(metricResource.getContents(), metricSource); if (resourcesInMetricSource.isEmpty()) { System.out.println("No resources for this metricsource"); return; } DateTimeRange dtr = mappingStatistics.getPeriodEstimate(); System.out.println("VALUES FOR PERIOD:"); System.out.println("FROM=" + NonModelUtils.dateAndTime(dtr.getBegin())); System.out.println("TO=" + NonModelUtils.dateAndTime(dtr.getEnd())); int valueCount = 0; for (NetXResource res : resourcesInMetricSource) { System.out.println("values for resource: " + res.getShortName() + "on Component" + res.getComponentRef().getName()); List<Value> values = StudioUtils.valuesForIntervalKindAndPeriod(res, targetIntervalHint, null, dtr); if (values.size() > 0) { valueCount += values.size(); System.out.println("number of values " + Iterables.size(values)); for (Value v : values) { System.out.println( NonModelUtils.fromXMLDate(v.getTimeStamp()) + ":" + v.getValue()); } } } System.out.println("total values for this import = " + valueCount); } } } }); mntmMore.setText("Values..."); MenuItem mntmDelete = new MenuItem(menu, SWT.NONE); mntmDelete.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // Show the period etc.. ISelection selection = statisticsTreeViewer.getSelection(); if (selection instanceof IStructuredSelection) { Object o = ((IStructuredSelection) selection).getFirstElement(); if (o instanceof MappingStatistic) { MappingStatistic mappingStatistics = (MappingStatistic) o; final int targetIntervalHint = mappingStatistics.getIntervalEstimate(); Resource metricResource = editingService.getData(MetricsPackage.Literals.METRIC); List<NetXResource> resourcesInMetricSource = StudioUtils .resourcesInMetricSource(metricResource.getContents(), metricSource); DateTimeRange dtr = mappingStatistics.getPeriodEstimate(); for (NetXResource res : resourcesInMetricSource) { List<Value> values = StudioUtils.valuesForIntervalKindAndPeriod(res, targetIntervalHint, null, dtr); if (values.size() > 0) { WarningDeleteCommand dc = new WarningDeleteCommand( editingService.getEditingDomain(), values); editingService.getEditingDomain().getCommandStack().execute(dc); } } } } } }); mntmDelete.setText("Purge import..."); Section sctnSummary = toolkit.createSection(sashForm, Section.EXPANDED | Section.TITLE_BAR); toolkit.paintBordersFor(sctnSummary); sctnSummary.setText("Summary"); Composite composite = toolkit.createComposite(sctnSummary, SWT.NONE); toolkit.paintBordersFor(composite); sctnSummary.setClient(composite); composite.setLayout(new GridLayout(2, false)); Label lblStatus = toolkit.createLabel(composite, "Status:", SWT.NONE); lblStatus.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1)); txtMessage = toolkit.createText(composite, "New Text", SWT.READ_ONLY | SWT.WRAP | SWT.MULTI | SWT.V_SCROLL); txtMessage.setText(""); GridData gd_txtMessage = new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1); gd_txtMessage.heightHint = 93; txtMessage.setLayoutData(gd_txtMessage); // RUN PERIOD Label lblStartDatetime = toolkit.createLabel(composite, "Start Date/Time:", SWT.NONE); lblStartDatetime.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); txtStartDateTime = toolkit.createText(composite, "New Text", SWT.READ_ONLY); txtStartDateTime.setText(""); txtStartDateTime.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); Label lblEndDatetime = toolkit.createLabel(composite, "End Date/Time:", SWT.NONE); lblEndDatetime.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); txtEndDateTime = toolkit.createText(composite, "New Text", SWT.READ_ONLY); txtEndDateTime.setText(""); txtEndDateTime.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); // METRIC PERIOD ESTIMATE. Label lblStartMetricDatetime = toolkit.createLabel(composite, "Metrics start:", SWT.NONE); lblStartMetricDatetime.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); txtMetricStartDateTime = toolkit.createText(composite, "New Text", SWT.READ_ONLY); txtMetricStartDateTime.setText(""); txtMetricStartDateTime.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); Label lblEndMetricDatetime = toolkit.createLabel(composite, "Metrics end:", SWT.NONE); lblEndMetricDatetime.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); txtMetricEndDateTime = toolkit.createText(composite, "New Text", SWT.READ_ONLY); txtMetricEndDateTime.setText(""); txtMetricEndDateTime.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); // RECORDS Label lblTotalRecordsProcessed = toolkit.createLabel(composite, "Total rows processed: ", SWT.NONE); lblTotalRecordsProcessed.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); txtTotalRecords = toolkit.createText(composite, "New Text", SWT.READ_ONLY); txtTotalRecords.setText(""); txtTotalRecords.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); Label lblTotalExpectedValues = toolkit.createLabel(composite, "Total values:", SWT.NONE); lblTotalExpectedValues.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); txtTotalValues = toolkit.createText(composite, "New Text", SWT.READ_ONLY); txtTotalValues.setText(""); txtTotalValues.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); txtTotalValues.setToolTipText("Total values is the # of metrics * the number of rows"); Label lblTotalFailedValues = toolkit.createLabel(composite, "Total Failed Values", SWT.NONE); lblTotalFailedValues.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); txtTotalFailedValues = toolkit.createText(composite, "New Text", SWT.READ_ONLY); txtTotalFailedValues.setText(""); txtTotalFailedValues.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); // Composite filler = toolkit.createComposite(composite, SWT.NONE); // GridData gd_filler = new GridData(SWT.LEFT, SWT.CENTER, false, false, // 2, 1); // gd_filler.heightHint = 30; // filler.setLayoutData(gd_filler); // toolkit.paintBordersFor(filler); tblViewerRecords = new TableViewer(composite, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI); recordsTable = tblViewerRecords.getTable(); recordsTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true, 2, 1)); recordsTable.setLinesVisible(true); recordsTable.setHeaderVisible(true); toolkit.paintBordersFor(recordsTable); MappingRecordErrorToolTipSupport.enableFor(tblViewerRecords, ToolTip.NO_RECREATE); TableViewerColumn tableViewerColumn = new TableViewerColumn(tblViewerRecords, SWT.NONE); TableColumn tblclmnNewColumn = tableViewerColumn.getColumn(); tblclmnNewColumn.setWidth(40); tblclmnNewColumn.setText("Count"); TableViewerColumn tableViewerColumn_1 = new TableViewerColumn(tblViewerRecords, SWT.NONE); TableColumn tblclmnColumn = tableViewerColumn_1.getColumn(); tblclmnColumn.setWidth(40); tblclmnColumn.setText("Column"); TableViewerColumn tableViewerColumn_2 = new TableViewerColumn(tblViewerRecords, SWT.NONE); TableColumn tblclmnMessage = tableViewerColumn_2.getColumn(); tblclmnMessage.setWidth(400); tblclmnMessage.setText("Message"); sashForm.setWeights(new int[] { 3, 7 }); } class CleanStatsAction extends Action { public CleanStatsAction(String text) { super(text); } @Override public void run() { if (metricSource.getStatistics().isEmpty()) { return; } boolean openQuestion = MessageDialog.openQuestion(MappingStatistics.this.getShell(), "Clean previous statistics", "When pressing OK, the statistics for this metric source will be cleared\nThis action can not be reverted"); if (openQuestion) { // yes selected. // Should also delete all contained objects like // MappingRecord etc.. CDOView cdoView = metricSource.cdoView(); if (cdoView instanceof CDOTransaction) { CDOTransaction cdoTransaction = (CDOTransaction) cdoView; try { cdoTransaction.lockObjects(metricSource.getStatistics(), LockType.WRITE, 1000); metricSource.getStatistics().clear(); cdoTransaction.unlockObjects(metricSource.getStatistics(), LockType.WRITE); cdoTransaction.commit(); } catch (InterruptedException e) { // we are interrupted. e.printStackTrace(); } catch (CommitException e) { // we can not commit. e.printStackTrace(); } } // DeleteCommand dc = new DeleteCommand( // editingService.getEditingDomain(), // metricSource.getStatistics()); // editingService.getEditingDomain().getCommandStack().execute(dc); // // if (editingService.isDirty()) { // editingService.doSave(new NullProgressMonitor()); // } } } } public EMFDataBindingContext initDataBindings_() { EMFDataBindingContext bindingContext = new EMFDataBindingContext(); ObservableListTreeContentProvider treeContentProvider = new ObservableListTreeContentProvider( new IObservableFactory() { private IEMFListProperty subStatisticsObservableProperty = EMFEditProperties.list( editingService.getEditingDomain(), MetricsPackage.Literals.MAPPING_STATISTIC__SUB_STATISTICS); public IObservable createObservable(Object target) { IObservable ol = null; if (target instanceof IObservableList) { ol = (IObservable) target; } else if (target instanceof MappingStatistic) { ol = subStatisticsObservableProperty.observe(target); } return ol; } }, new TreeStructureAdvisor() { @Override public Object getParent(Object element) { if (element instanceof EObject) { EObject eo = (EObject) element; if (eo.eContainer() != null) { return eo.eContainer(); } } return null; } @Override public Boolean hasChildren(Object element) { if (element instanceof MappingStatistic) { return ((MappingStatistic) element).getSubStatistics().size() > 0 ? Boolean.TRUE : null; } return super.hasChildren(element); } }); statisticsTreeViewer.setContentProvider(treeContentProvider); IObservableMap[] observeMaps = EMFObservables.observeMaps(treeContentProvider.getKnownElements(), new EStructuralFeature[] { MetricsPackage.Literals.MAPPING_STATISTIC__MESSAGE }); statisticsTreeViewer.setLabelProvider(new StatisticObservableMapLabelProvider(observeMaps)); // Cool, observer the whole resource. IEMFListProperty l = EMFProperties.list(MetricsPackage.Literals.METRIC_SOURCE__STATISTICS); IObservableList metricSourceObservableList = l.observe(metricSource); statisticsTreeViewer.setInput(metricSourceObservableList); /** * Set a comparator to sort our columns, only sort the objects of type * */ statisticsTreeViewer.setComparator(new ViewerComparator() { /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.ViewerComparator#category(java.lang * .Object) */ @Override public int category(Object element) { // Set categories for our objects, only interrested in Service // flows for now. if (element instanceof MappingStatistic) return 1; return super.category(element); } /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse * .jface.viewers.Viewer, java.lang.Object, java.lang.Object) */ @Override public int compare(Viewer viewer, Object e1, Object e2) { int cat1 = category(e1); int cat2 = category(e2); if (cat1 != cat2) { return cat1 - cat2; } if (e1 instanceof MappingStatistic && e2 instanceof MappingStatistic) { MappingStatistic ms1 = (MappingStatistic) e1; MappingStatistic ms2 = (MappingStatistic) e2; if (ms1.eIsSet(MetricsPackage.Literals.MAPPING_STATISTIC__MAPPING_DURATION) && ms2.eIsSet(MetricsPackage.Literals.MAPPING_STATISTIC__MAPPING_DURATION)) { return ms2.getMappingDuration().getBegin().compare(ms1.getMappingDuration().getBegin()); } } return 0; // Do not compare other types. // return super.compare(viewer, e1, e2); } }); final IObservableValue selectionObservable = ViewerProperties.singleSelection() .observe(statisticsTreeViewer); // Observables for a single selection. IObservableValue messageObservable = SWTObservables.observeText(this.txtMessage, SWT.None); IObservableValue totalRecordsObservable = SWTObservables.observeText(this.txtTotalRecords, SWT.None); IObservableValue startTimeObservable = SWTObservables.observeText(this.txtStartDateTime, SWT.None); IObservableValue endTimeObservable = SWTObservables.observeText(this.txtEndDateTime, SWT.None); IObservableValue metricStartTimeObservable = SWTObservables.observeText(this.txtMetricStartDateTime, SWT.None); IObservableValue metricEndTimeObservable = SWTObservables.observeText(this.txtMetricEndDateTime, SWT.None); IObservableValue totalExpectedValuesObservable = SWTObservables.observeText(this.txtTotalValues, SWT.None); IObservableValue totalFailedValuesObservable = SWTObservables.observeText(this.txtTotalFailedValues, SWT.None); IEMFValueProperty messageProperty = EMFProperties.value(MetricsPackage.Literals.MAPPING_STATISTIC__MESSAGE); final IEMFValueProperty totalRecordsProperty = EMFProperties .value(MetricsPackage.Literals.MAPPING_STATISTIC__TOTAL_RECORDS); IEMFValueProperty startDateTimeProperty = EMFProperties .value(FeaturePath.fromList(MetricsPackage.Literals.MAPPING_STATISTIC__MAPPING_DURATION, GenericsPackage.Literals.DATE_TIME_RANGE__BEGIN)); IEMFValueProperty endDateTimeProperty = EMFProperties .value(FeaturePath.fromList(MetricsPackage.Literals.MAPPING_STATISTIC__MAPPING_DURATION, GenericsPackage.Literals.DATE_TIME_RANGE__END)); IEMFValueProperty metricStartDateTimeProperty = EMFProperties .value(FeaturePath.fromList(MetricsPackage.Literals.MAPPING_STATISTIC__PERIOD_ESTIMATE, GenericsPackage.Literals.DATE_TIME_RANGE__BEGIN)); IEMFValueProperty metricEndDateTimeProperty = EMFProperties .value(FeaturePath.fromList(MetricsPackage.Literals.MAPPING_STATISTIC__PERIOD_ESTIMATE, GenericsPackage.Literals.DATE_TIME_RANGE__END)); ComputedValue computedTotalExpectedValue = new ComputedValue() { @Override protected Object calculate() { Object value = totalRecordsProperty.observeDetail(selectionObservable).getValue(); if (value instanceof Integer) { return new Integer(StudioUtils.metricsInMetricSource(metricSource).size() * (Integer) value) .toString(); } return 0; } }; ComputedValue computedTotalFailedValue = new ComputedValue() { @Override protected Object calculate() { Object selectedObject = selectionObservable.getValue(); // recursively compute for sub-statistics. if (selectedObject instanceof MappingStatistic) { return new Integer(StudioUtils.mappingFailedCount((MappingStatistic) selectedObject)) .toString(); } return 0; } }; EMFUpdateValueStrategy modelToTargetStrategy = new EMFUpdateValueStrategy(); modelToTargetStrategy.setConverter(new ModelDateConverter()); bindingContext.bindValue(messageObservable, messageProperty.observeDetail(selectionObservable)); bindingContext.bindValue(totalRecordsObservable, totalRecordsProperty.observeDetail(selectionObservable)); bindingContext.bindValue(startTimeObservable, startDateTimeProperty.observeDetail(selectionObservable), null, modelToTargetStrategy); bindingContext.bindValue(endTimeObservable, endDateTimeProperty.observeDetail(selectionObservable), null, modelToTargetStrategy); bindingContext.bindValue(metricStartTimeObservable, metricStartDateTimeProperty.observeDetail(selectionObservable), null, modelToTargetStrategy); bindingContext.bindValue(metricEndTimeObservable, metricEndDateTimeProperty.observeDetail(selectionObservable), null, modelToTargetStrategy); bindingContext.bindValue(totalExpectedValuesObservable, computedTotalExpectedValue); bindingContext.bindValue(totalFailedValuesObservable, computedTotalFailedValue); // bindingContext.bindValue(totalExpectedValuesObservable, // computedTotalExpectedValue, new UpdateValueStrategy(false, // UpdateValueStrategy.POLICY_NEVER), null); // // bindingContext.bindValue(totalFailedValuesObservable, // computedTotalFailedValue, new UpdateValueStrategy(false, // UpdateValueStrategy.POLICY_NEVER), null); ObservableListContentProvider recordsContentProvider = new ObservableListContentProvider(); tblViewerRecords.setContentProvider(recordsContentProvider); // IObservableMap[] recordsObserveMaps = EMFObservables.observeMaps( // listContentProvider.getKnownElements(), // new EStructuralFeature[] { // MetricsPackage.Literals.MAPPING_RECORD__ROW, // MetricsPackage.Literals.MAPPING_RECORD__COLUMN, // MetricsPackage.Literals.MAPPING_RECORD__MESSAGE, }); tblViewerRecords.setLabelProvider(new RecordsObservableMapLabelProvider()); IEMFListProperty recordsProperty = EMFProperties .list(MetricsPackage.Literals.MAPPING_STATISTIC__FAILED_RECORDS); tblViewerRecords.setInput(recordsProperty.observeDetail(selectionObservable)); return bindingContext; } class ModelDateConverter implements IConverter { public Object getFromType() { return XMLGregorianCalendar.class; } public Object getToType() { return String.class; } public Object convert(Object fromObject) { if (fromObject instanceof XMLGregorianCalendar) { Date d = NonModelUtils.fromXMLDate((XMLGregorianCalendar) fromObject); return NonModelUtils.date(d) + " @ " + NonModelUtils.time(d); } return null; } } class RecordsObservableMapLabelProvider extends CellLabelProvider { public abstract class MappingRecordErrorProcessor { String errorDescription; public int code(String code) { try { Integer codeAsInt = new Integer(code); return codeAsInt; } catch (NumberFormatException nfe) { // Mapping error code not supported (Old Format); return -1; } } /** * @param mr * @param sb */ public String spiltMappingRecordMsg(MappingRecord mr, StringBuilder sb) { StringReader stringReader = new StringReader(mr.getMessage()); BufferedReader bufferedReader = new BufferedReader(stringReader); try { String line; boolean firstLine = true; while ((line = bufferedReader.readLine()) != null) { String[] split = line.split(":"); if (firstLine) { // This should be the error code. String string = split[0]; int code = code(string); if (code != -1) { errorDescription = IMetricValueImporter.IMPORT_ERROR_TEXT[code]; String[] reducedWithoutError = Arrays.copyOfRange(split, 1, split.length); processErrorDescription(sb, errorDescription); processLinesHeader(sb, code); processLines(sb, reducedWithoutError); } else { sb.append(string); } firstLine = false; } else { processLines(sb, split); } } } catch (IOException e) { } return sb.toString(); } /** * Process the error lines header. Pass on the the error type. * * @param sb * @param code */ protected abstract void processLinesHeader(StringBuilder sb, int code); protected abstract void processErrorDescription(StringBuilder sb, String errorDescription); protected abstract void processLines(StringBuilder sb, String[] splits); public String getErrorDescription() { return errorDescription; } } public String getToolTipText(Object element) { if (element instanceof MappingRecord) { MappingRecord mr = (MappingRecord) element; StringBuilder sb = new StringBuilder(); sb.append("<html><body>"); sb.append("<table>"); new MappingRecordErrorProcessor() { @Override protected void processErrorDescription(StringBuilder sb, String errorDescription) { sb.append("<tr>" + errorDescription + "</tr>"); } @Override protected void processLines(StringBuilder sb, String[] splits) { sb.append("<tr>"); for (int i = 0; i < splits.length; i++) { String s = splits[i]; sb.append("<td>" + s + "</td>"); } sb.append("</tr>"); } @Override protected void processLinesHeader(StringBuilder sb, int errorCode) { switch (errorCode) { case 0: case 1: case 2: sb.append("<th>#</th><th>Id type</th><th>Property</th><th>Value</th><th>Pattern</th>"); } } }.spiltMappingRecordMsg(mr, sb); sb.append("</table>"); sb.append("</body></html>"); return sb.toString(); } else { return null; } } public Point getToolTipShift(Object object) { return new Point(5, 5); } public int getToolTipDisplayDelayTime(Object object) { return 500; } public int getToolTipTimeDisplayed(Object object) { return 10000; } @Override public void update(ViewerCell cell) { int columnIndex = cell.getColumnIndex(); Object element = cell.getElement(); if (element instanceof MappingRecord) { MappingRecord mr = (MappingRecord) element; switch (columnIndex) { case 0: { String count = new Long(mr.getCount()).toString(); cell.setText(count); } break; case 1: { String column = mr.getColumn(); if (column != null) { if (column.equals("-1")) { cell.setText("N/A"); } else { cell.setText(column); } } } break; case 2: { StringBuilder sb = new StringBuilder(); new MappingRecordErrorProcessor() { @Override protected void processErrorDescription(StringBuilder sb, String errorDescription) { sb.append(errorDescription + " "); } @Override protected void processLines(StringBuilder sb, String[] splits) { for (String s : splits) { sb.append(s + " - "); } } @Override protected void processLinesHeader(StringBuilder sb, int string) { // DO NOTHING. } }.spiltMappingRecordMsg(mr, sb); cell.setText(sb.toString()); } break; } } } } private static class MappingRecordErrorToolTipSupport extends ColumnViewerToolTipSupport { protected MappingRecordErrorToolTipSupport(ColumnViewer viewer, int style, boolean manualActivation) { super(viewer, style, manualActivation); } protected Composite createToolTipContentArea(Event event, Composite parent) { Composite comp = new Composite(parent, SWT.NONE); GridLayout l = new GridLayout(1, false); l.horizontalSpacing = 0; l.marginWidth = 0; l.marginHeight = 0; l.verticalSpacing = 0; String tooltipText = getText(event); // System.out.println(tooltipText.length()); comp.setLayout(l); Browser browser = new Browser(comp, SWT.BORDER); browser.setText(tooltipText); browser.setLayoutData(new GridData(400, 300)); return comp; } public boolean isHideOnMouseDown() { return false; } public static final void enableFor(ColumnViewer viewer, int style) { new MappingRecordErrorToolTipSupport(viewer, style, false); } } class StatisticObservableMapLabelProvider extends ObservableMapLabelProvider { public StatisticObservableMapLabelProvider(IObservableMap[] attributeMaps) { super(attributeMaps); } @Override public String getText(Object element) { if (element instanceof MappingStatistic) { MappingStatistic s = (MappingStatistic) element; StringBuilder sb = new StringBuilder(); if (s.eIsSet(MetricsPackage.Literals.MAPPING_STATISTIC__MAPPING_DURATION)) { DateTimeRange durationEstimate = s.getMappingDuration(); if (durationEstimate.getBegin() != null && durationEstimate.getEnd() != null) { Date start = StudioUtils.begin(durationEstimate); Date end = StudioUtils.end(durationEstimate); if (s.eContainer() != null && !(s.eContainer() instanceof MappingStatistic)) { // we are the parent. sb.append("Scan started on: " + NonModelUtils.date(start) + " @ " + NonModelUtils.time(start)); } else { long ms = (end.getTime() - start.getTime()); sb.append("Duration : " + (ms > 1000 ? (ms / 1000 + " (sec) : ") : ms + " (ms) ") + "ended on " + NonModelUtils.date(start) + " @ " + NonModelUtils.timeAndSeconds(end)); } } } else { sb.append(s.getMessage()); } sb.append(" , Total rows=[" + s.getTotalRecords() + "]"); return sb.toString(); } return super.getText(element); } } public void disposeData() { // N/A } public void injectData(Object owner, Object object) { if (object instanceof MetricSource) { metricSource = (MetricSource) object; } buildUI(); registerFocus(this); this.initDataBindings_(); } public void addData() { // N/A Read-only view. } public Viewer getViewer() { return this.statisticsTreeViewer; } @Override public Viewer[] getViewers() { return new Viewer[] { statisticsTreeViewer, tblViewerRecords }; } /* * (non-Javadoc) * * @see com.netxforge.netxstudio.screens.AbstractScreenImpl# * resolveSelectionProviderFromWidget(java.lang.Object) */ @Override protected ISelectionProvider resolveSelectionProviderFromWidget(Object widget) { if (widget == statisticsTree) { return statisticsTreeViewer; } else if (widget == recordsTable) { return tblViewerRecords; } return super.resolveSelectionProviderFromWidget(widget); } List<IAction> actionList = Lists.newArrayList(); /* * (non-Javadoc) * * @see com.netxforge.netxstudio.screens.AbstractScreenImpl#getActions() */ @Override public IAction[] getActions() { if (actionList.size() == 0) { actionList.add(new CopyMappingErrorAction("Copy error...")); } IAction[] actions = new IAction[actionList.size()]; actionList.toArray(actions); return actions; } @Override public boolean isValid() { return true; } public Form getScreenForm() { return this.frmMappingStatistics; } public String getScreenName() { return "Mapping Statistics"; } }