| /** |
| * Copyright (c) 2011, 2014 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Florian Pirchner - Initial implementation |
| */ |
| package org.eclipse.osbp.vaaclipse.addons.problems.views; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Timer; |
| import java.util.TimerTask; |
| |
| import javax.annotation.PostConstruct; |
| import javax.annotation.PreDestroy; |
| import javax.inject.Inject; |
| |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.e4.core.services.events.IEventBroker; |
| import org.eclipse.e4.ui.model.application.MApplication; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; |
| import org.eclipse.e4.ui.workbench.modeling.EPartService; |
| import org.eclipse.osbp.runtime.common.i18n.II18nService; |
| import org.eclipse.osbp.runtime.common.validation.IStatus; |
| import org.eclipse.osbp.runtime.common.validation.IStatus.Severity; |
| import org.eclipse.osbp.vaaclipse.addons.common.api.IE4Topics; |
| import org.eclipse.osbp.vaaclipse.addons.common.api.ResourceUtil; |
| import org.eclipse.osbp.vaaclipse.addons.common.api.status.IStatusManager; |
| import org.eclipse.osbp.vaaclipse.addons.common.api.status.IStatusScope; |
| import org.osgi.service.event.Event; |
| import org.osgi.service.event.EventHandler; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.vaadin.data.Property; |
| import com.vaadin.data.Property.ValueChangeEvent; |
| import com.vaadin.data.util.BeanItemContainer; |
| import com.vaadin.event.ItemClickEvent; |
| import com.vaadin.server.Resource; |
| import com.vaadin.shared.ui.label.ContentMode; |
| import com.vaadin.ui.Label; |
| import com.vaadin.ui.Table; |
| import com.vaadin.ui.Table.ColumnHeaderMode; |
| import com.vaadin.ui.Table.RowHeaderMode; |
| import com.vaadin.ui.UI; |
| import com.vaadin.ui.VerticalLayout; |
| |
| /** |
| * View that shows problems. |
| */ |
| public class ProblemsView { |
| |
| /** The Constant LOGGER. */ |
| private static final Logger LOGGER = LoggerFactory |
| .getLogger(ProblemsView.class); |
| |
| /** The parent. */ |
| private final VerticalLayout parent; |
| |
| /** The eclipse context. */ |
| @SuppressWarnings("unused") |
| private final IEclipseContext eclipseContext; |
| |
| /** The status manager. */ |
| @Inject |
| private IStatusManager statusManager; |
| |
| /** The part service. */ |
| @Inject |
| private EPartService partService; |
| |
| /** The event broker. */ |
| @Inject |
| private IEventBroker eventBroker; |
| |
| /** The i18n service. */ |
| @Inject |
| private II18nService i18nService; |
| |
| /** The table. */ |
| private Table table; |
| |
| /** The container. */ |
| private BeanItemContainer<StatusBean> container; |
| |
| /** The current timer. */ |
| private Timer currentTimer; |
| |
| /** The changed validations handler. */ |
| private EventHandler changedValidationsHandler; |
| |
| /** The changed scope handler. */ |
| private EventHandler changedScopeHandler; |
| |
| /** The view mode. */ |
| private Mode viewMode = Mode.FOLLOW_ACTIVE_PART; |
| |
| /** The freezed scope. */ |
| private IStatusScope freezedScope; |
| |
| /** The detail label. */ |
| private Label detailLabel; |
| |
| /** |
| * Instantiates a new problems view. |
| * |
| * @param parent |
| * the parent |
| * @param eclipseContext |
| * the eclipse context |
| * @param app |
| * the app |
| */ |
| @Inject |
| public ProblemsView(VerticalLayout parent, IEclipseContext eclipseContext, |
| MApplication app) { |
| this.parent = parent; |
| this.eclipseContext = eclipseContext; |
| } |
| |
| /** |
| * Inits the. |
| */ |
| @SuppressWarnings("serial") |
| @PostConstruct |
| protected void init() { |
| |
| table = new Table(); |
| table.setSelectable(true); |
| table.setSizeFull(); |
| parent.addComponent(table); |
| |
| container = new BeanItemContainer<StatusBean>(StatusBean.class); |
| table.setContainerDataSource(container); |
| |
| table.setVisibleColumns(new Object[] { "message", "fieldName", |
| "partName", "bundleSymbolicName", "severity", "messagePath", |
| "creatorClass", "messageCode" }); |
| table.setColumnCollapsingAllowed(true); |
| table.setColumnCollapsed("bundleSymbolicName", true); |
| table.setColumnCollapsed("severity", true); |
| table.setColumnCollapsed("creatorClass", true); |
| table.setColumnCollapsed("messageCode", true); |
| |
| table.setRowHeaderMode(RowHeaderMode.ICON_ONLY); |
| table.setItemIconPropertyId("severityImage"); |
| |
| table.setColumnHeaderMode(ColumnHeaderMode.EXPLICIT_DEFAULTS_ID); |
| Locale locale = UI.getCurrent().getLocale(); |
| table.setColumnHeader("message", |
| toViewI18n("message", i18nService, locale)); |
| table.setColumnHeader("fieldName", |
| toViewI18n("fieldName", i18nService, locale)); |
| table.setColumnHeader("partName", |
| toViewI18n("partName", i18nService, locale)); |
| table.setColumnHeader("bundleSymbolicName", |
| toViewI18n("bundleSymbolicName", i18nService, locale)); |
| table.setColumnHeader("severity", |
| toViewI18n("severity", i18nService, locale)); |
| table.setColumnHeader("messagePath", |
| toViewI18n("messagePath", i18nService, locale)); |
| table.setColumnHeader("creatorClass", |
| toViewI18n("creatorClass", i18nService, locale)); |
| table.setColumnHeader("messageCode", |
| toViewI18n("messageCode", i18nService, locale)); |
| |
| table.addItemClickListener(new ItemClickEvent.ItemClickListener() { |
| @Override |
| public void itemClick(ItemClickEvent event) { |
| if (event.isDoubleClick()) { |
| focusStatus(event); |
| } |
| } |
| }); |
| |
| table.addValueChangeListener(new Property.ValueChangeListener() { |
| @Override |
| public void valueChange(ValueChangeEvent event) { |
| showDetailMessage((StatusBean) event.getProperty().getValue()); |
| } |
| }); |
| |
| detailLabel = new Label(); |
| detailLabel.setPrimaryStyleName("detailmessage"); |
| detailLabel.setContentMode(ContentMode.HTML); |
| detailLabel.setSizeFull(); |
| parent.addComponent(detailLabel); |
| |
| parent.setExpandRatio(table, 0.85f); |
| parent.setExpandRatio(detailLabel, 0.15f); |
| |
| // initialize the view mode |
| setMode(viewMode); |
| |
| // handle changed validation scopes |
| // |
| changedScopeHandler = new EventHandler() { |
| @Override |
| public void handleEvent(Event event) { |
| switch (viewMode) { |
| case FREEZE_SCOPE: |
| // only refresh contents if the changed scope is the freezed |
| // scope |
| IStatusScope scope = getScopeFromEvent(event); |
| if (freezedScope == scope) { |
| refreshContent(); |
| } |
| break; |
| case FOLLOW_ACTIVE_PART: |
| case SHOW_ALL: |
| default: |
| refreshContent(); |
| break; |
| } |
| } |
| }; |
| |
| // handle changes in validation results |
| // |
| eventBroker.subscribe( |
| IE4Topics.StatusManagerEvents.ACTIVE_SCOPE_CHANGED_TOPIC, |
| changedScopeHandler); |
| changedValidationsHandler = new EventHandler() { |
| @Override |
| public void handleEvent(Event event) { |
| switch (viewMode) { |
| case FREEZE_SCOPE: |
| // only refresh contents if the changed scope is the freezed |
| // scope |
| IStatusScope scope = getScopeFromEvent(event); |
| if (freezedScope == scope) { |
| refreshContent(); |
| } |
| break; |
| case FOLLOW_ACTIVE_PART: |
| case SHOW_ALL: |
| default: |
| refreshContent(); |
| break; |
| } |
| } |
| }; |
| |
| eventBroker.subscribe( |
| IE4Topics.StatusManagerEvents.VALIDATIONS_CHANGED_TOPIC, |
| changedValidationsHandler); |
| } |
| |
| /** |
| * To view i18n. |
| * |
| * @param key |
| * the key |
| * @param i18nService |
| * the i18n service |
| * @param locale |
| * the locale |
| * @return the string |
| */ |
| private static String toViewI18n(String key, II18nService i18nService, |
| Locale locale) { |
| String result = i18nService.getValue( |
| "org.eclipse.osbp.vaaclipse.addons.application.views.ProblemsView." |
| + key, locale); |
| if (result == null || result.equals("")) { |
| return key; |
| } |
| |
| return result; |
| } |
| |
| /** |
| * To common i18n. |
| * |
| * @param key |
| * the key |
| * @param i18nService |
| * the i18n service |
| * @param locale |
| * the locale |
| * @return the string |
| */ |
| private static String toCommonI18n(String key, II18nService i18nService, |
| Locale locale) { |
| if (key == null) { |
| return ""; |
| } |
| String result = i18nService.getValue(key, locale); |
| if (result == null || result.equals("")) { |
| return key; |
| } |
| |
| return result; |
| } |
| |
| /** |
| * Shows the detail message. |
| * |
| * @param statusBean |
| * the status bean |
| */ |
| protected void showDetailMessage(StatusBean statusBean) { |
| if (statusBean != null) { |
| detailLabel.setValue(statusBean.getMessage().getValue()); |
| } else { |
| detailLabel.setValue(null); |
| } |
| } |
| |
| /** |
| * Tries to put the focus to the field involved in the problem. |
| * |
| * @param event |
| * the event |
| */ |
| protected void focusStatus(ItemClickEvent event) { |
| StatusBean status = (StatusBean) event.getItemId(); |
| |
| String mPartId = status.getPartId(); |
| if (mPartId != null && !mPartId.equals("")) { |
| MPart mPart = partService.findPart(mPartId); |
| if (mPart != null) { |
| partService.bringToTop(mPart); |
| partService.activate(mPart); |
| |
| String fieldId = status.getFieldId(); |
| if (fieldId != null && !fieldId.equals("")) { |
| // send a focus field event to the mpart |
| eventBroker.post(IE4Topics.PartEvents.FOCUS_FIELD_TOPIC, |
| createFocusFieldEvent(mPartId, fieldId)); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Creates an event to focus a field in a MPart. |
| * |
| * @param mPartId |
| * the m part id |
| * @param fieldId |
| * the field id |
| * @return the map |
| */ |
| protected Map<String, Object> createFocusFieldEvent(String mPartId, |
| String fieldId) { |
| Map<String, Object> properties = new HashMap<String, Object>(); |
| properties.put(IE4Topics.PartEvents.PROP_MPART_ID, mPartId); |
| properties.put(IE4Topics.PartEvents.PROP_FIELD_ID, fieldId); |
| return properties; |
| } |
| |
| /** |
| * Refreshes the content of the active MPart. |
| */ |
| protected void refreshContent() { |
| if (table == null || table.getUI() == null) { |
| return; |
| } |
| |
| synchronized (this) { |
| // Wait for 250ms before refreshing the table. Most probably several |
| // validation events will |
| // arrive in the next milliseconds |
| if (currentTimer == null) { |
| currentTimer = new Timer(); |
| currentTimer.schedule(new TimerTask() { |
| @Override |
| public void run() { |
| table.getUI().accessSynchronously(new Runnable() { |
| @Override |
| public void run() { |
| container.removeAllItems(); |
| if (viewMode == Mode.FOLLOW_ACTIVE_PART |
| || viewMode == Mode.FREEZE_SCOPE) { |
| IStatusScope scope = statusManager |
| .getActiveScope(); |
| if (scope != null) { |
| container.addAll(mapStatus(scope)); |
| } |
| } else if (viewMode == Mode.SHOW_ALL) { |
| container.addAll(mapStatus(statusManager)); |
| } |
| |
| detailLabel.setValue(""); |
| |
| LOGGER.debug("Table refreshed."); |
| resetTimer(); |
| } |
| }); |
| } |
| }, 250); |
| LOGGER.debug("Scheduled Table-Refresh-Timer."); |
| } else { |
| LOGGER.debug("Timer already active."); |
| } |
| } |
| } |
| |
| /** |
| * Reset timer. |
| */ |
| protected void resetTimer() { |
| synchronized (this) { |
| currentTimer = null; |
| } |
| } |
| |
| /** |
| * Map status. |
| * |
| * @param scope |
| * the scope |
| * @return the list |
| */ |
| protected List<StatusBean> mapStatus(IStatusScope scope) { |
| List<StatusBean> result = new ArrayList<ProblemsView.StatusBean>(); |
| for (IStatus status : scope.getAllStatus()) { |
| result.add(StatusBean.create(status, i18nService, |
| parent.getLocale())); |
| } |
| return result; |
| } |
| |
| /** |
| * Map status. |
| * |
| * @param manager |
| * the manager |
| * @return the list |
| */ |
| protected List<StatusBean> mapStatus(IStatusManager manager) { |
| List<StatusBean> result = new ArrayList<ProblemsView.StatusBean>(); |
| for (IStatus status : manager.getAllScopeStatus()) { |
| result.add(StatusBean.create(status, i18nService, |
| parent.getLocale())); |
| } |
| return result; |
| } |
| |
| /** |
| * Sets the mode. |
| * |
| * @param mode |
| * the new mode |
| */ |
| public void setMode(Mode mode) { |
| switch (mode) { |
| case FREEZE_SCOPE: |
| this.freezedScope = statusManager.getActiveScope(); |
| break; |
| case FOLLOW_ACTIVE_PART: |
| case SHOW_ALL: |
| this.freezedScope = null; |
| } |
| |
| this.viewMode = mode; |
| |
| refreshContent(); |
| } |
| |
| /** |
| * Dispose. |
| */ |
| @PreDestroy |
| protected void dispose() { |
| eventBroker.unsubscribe(changedScopeHandler); |
| eventBroker.unsubscribe(changedValidationsHandler); |
| |
| changedScopeHandler = null; |
| changedValidationsHandler = null; |
| table = null; |
| container = null; |
| } |
| |
| /** |
| * Gets the scope from event. |
| * |
| * @param event |
| * the event |
| * @return the scope from event |
| */ |
| protected IStatusScope getScopeFromEvent(Event event) { |
| @SuppressWarnings("unchecked") |
| Map<String, Object> props = (Map<String, Object>) event |
| .getProperty(IEventBroker.DATA); |
| IStatusScope scope = (IStatusScope) props |
| .get(IE4Topics.StatusManagerEvents.ACTIVE_SCOPE_CHANGED_TOPIC); |
| return scope; |
| } |
| |
| /** |
| * The mode of the view. |
| */ |
| public enum Mode { |
| |
| /** Follows the active MPart. */ |
| FOLLOW_ACTIVE_PART, |
| |
| /** Only shows messages for the current scope. */ |
| FREEZE_SCOPE, |
| |
| /** Show all messages. */ |
| SHOW_ALL |
| } |
| |
| /** |
| * The Class StatusBean. |
| */ |
| public static class StatusBean { |
| |
| /** The severity image. */ |
| @SuppressWarnings("unused") |
| private Resource severityImage; |
| |
| /** The severity. */ |
| private Severity severity; |
| |
| /** The bundle symbolic name. */ |
| private String bundleSymbolicName; |
| |
| /** The message code. */ |
| private String messageCode; |
| |
| /** The message. */ |
| private Label message; |
| |
| /** The exception. */ |
| private Exception exception; |
| |
| /** The part id. */ |
| private String partId; |
| |
| /** The field id. */ |
| private String fieldId; |
| |
| /** The part name. */ |
| private String partName; |
| |
| /** The field name. */ |
| private String fieldName; |
| |
| /** The message path. */ |
| private String messagePath; |
| |
| /** The creator class. */ |
| private String creatorClass; |
| |
| /** |
| * Creates the. |
| * |
| * @param status |
| * the status |
| * @param i18nService |
| * the i18n service |
| * @param locale |
| * the locale |
| * @return the status bean |
| */ |
| public static StatusBean create(IStatus status, |
| II18nService i18nService, Locale locale) { |
| StatusBean bean = new StatusBean(); |
| bean.severity = status.getSeverity(); |
| bean.bundleSymbolicName = status.getBundleSymblicName(); |
| bean.messageCode = status.getCode(); |
| bean.message = new Label(status.getMessage(), ContentMode.HTML); |
| bean.exception = status.getException(); |
| |
| bean.partId = (String) status |
| .getProperty(IStatus.PROP_UI_APPLICATION_ID); |
| bean.fieldId = (String) status.getProperty(IStatus.PROP_FIELD_ID); |
| String fieldI18nKey = (String) status |
| .getProperty(IStatus.PROP_FIELD_I18N_KEY); |
| |
| bean.partName = toCommonI18n(bean.partId, i18nService, UI |
| .getCurrent().getLocale()); |
| if (fieldI18nKey != null && !fieldI18nKey.equals("")) { |
| bean.fieldName = toCommonI18n(fieldI18nKey, i18nService, UI |
| .getCurrent().getLocale()); |
| } else { |
| bean.fieldName = toCommonI18n(bean.fieldId, i18nService, UI |
| .getCurrent().getLocale()); |
| } |
| |
| bean.creatorClass = (String) status |
| .getProperty(IStatus.PROP_CREATOR); |
| bean.messagePath = (String) status |
| .getProperty(IStatus.PROP_JAVAX_PROPERTY_PATH); |
| |
| return bean; |
| } |
| |
| /** |
| * Gets the severity image. |
| * |
| * @return the severityImage |
| */ |
| @SuppressWarnings("incomplete-switch") |
| public Resource getSeverityImage() { |
| switch (severity) { |
| case OK: |
| case INFO: |
| return ResourceUtil |
| .getResource("platform:/plugin/org.eclipse.osbp.vaaclipse.addons.application/images/info_tsk.png"); |
| case WARNING: |
| return ResourceUtil |
| .getResource("platform:/plugin/org.eclipse.osbp.vaaclipse.addons.application/images/warn_tsk.png"); |
| case ERROR: |
| case CRITICAL: |
| case SYSTEMERROR: |
| return ResourceUtil |
| .getResource("platform:/plugin/org.eclipse.osbp.vaaclipse.addons.application/images/error_tsk.png"); |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Sets the severity image. |
| * |
| * @param severityImage |
| * the severityImage to set |
| */ |
| public void setSeverityImage(Resource severityImage) { |
| this.severityImage = severityImage; |
| } |
| |
| /** |
| * Gets the severity. |
| * |
| * @return the severity |
| */ |
| public Severity getSeverity() { |
| return severity; |
| } |
| |
| /** |
| * Sets the severity. |
| * |
| * @param severity |
| * the severity to set |
| */ |
| public void setSeverity(Severity severity) { |
| this.severity = severity; |
| } |
| |
| /** |
| * Gets the bundle symbolic name. |
| * |
| * @return the bundleSymbolicName |
| */ |
| public String getBundleSymbolicName() { |
| return bundleSymbolicName; |
| } |
| |
| /** |
| * Sets the bundle symbolic name. |
| * |
| * @param bundleSymbolicName |
| * the bundleSymbolicName to set |
| */ |
| public void setBundleSymbolicName(String bundleSymbolicName) { |
| this.bundleSymbolicName = bundleSymbolicName; |
| } |
| |
| /** |
| * Gets the message. |
| * |
| * @return the message |
| */ |
| public Label getMessage() { |
| return message; |
| } |
| |
| /** |
| * Sets the message. |
| * |
| * @param message |
| * the message to set |
| */ |
| public void setMessage(Label message) { |
| this.message = message; |
| } |
| |
| /** |
| * Gets the exception. |
| * |
| * @return the exception |
| */ |
| public Exception getException() { |
| return exception; |
| } |
| |
| /** |
| * Sets the exception. |
| * |
| * @param exception |
| * the exception to set |
| */ |
| public void setException(Exception exception) { |
| this.exception = exception; |
| } |
| |
| /** |
| * Gets the part id. |
| * |
| * @return the partId |
| */ |
| public String getPartId() { |
| return partId; |
| } |
| |
| /** |
| * Sets the part id. |
| * |
| * @param partId |
| * the partId to set |
| */ |
| public void setPartId(String partId) { |
| this.partId = partId; |
| } |
| |
| /** |
| * Gets the field id. |
| * |
| * @return the fieldId |
| */ |
| public String getFieldId() { |
| return fieldId; |
| } |
| |
| /** |
| * Sets the field id. |
| * |
| * @param fieldId |
| * the fieldId to set |
| */ |
| public void setFieldId(String fieldId) { |
| this.fieldId = fieldId; |
| } |
| |
| /** |
| * Gets the part name. |
| * |
| * @return the partName |
| */ |
| public String getPartName() { |
| return partName; |
| } |
| |
| /** |
| * Sets the part name. |
| * |
| * @param partName |
| * the partName to set |
| */ |
| public void setPartName(String partName) { |
| this.partName = partName; |
| } |
| |
| /** |
| * Gets the field name. |
| * |
| * @return the fieldName |
| */ |
| public String getFieldName() { |
| return fieldName; |
| } |
| |
| /** |
| * Sets the field name. |
| * |
| * @param fieldName |
| * the fieldName to set |
| */ |
| public void setFieldName(String fieldName) { |
| this.fieldName = fieldName; |
| } |
| |
| /** |
| * Gets the message path. |
| * |
| * @return the messagePath |
| */ |
| public String getMessagePath() { |
| return messagePath; |
| } |
| |
| /** |
| * Sets the message path. |
| * |
| * @param messagePath |
| * the messagePath to set |
| */ |
| public void setMessagePath(String messagePath) { |
| this.messagePath = messagePath; |
| } |
| |
| /** |
| * Gets the message code. |
| * |
| * @return the messageCode |
| */ |
| public String getMessageCode() { |
| return messageCode; |
| } |
| |
| /** |
| * Sets the message code. |
| * |
| * @param messageCode |
| * the messageCode to set |
| */ |
| public void setMessageCode(String messageCode) { |
| this.messageCode = messageCode; |
| } |
| |
| /** |
| * Gets the creator class. |
| * |
| * @return the creatorClass |
| */ |
| public String getCreatorClass() { |
| return creatorClass; |
| } |
| |
| /** |
| * Sets the creator class. |
| * |
| * @param creatorClass |
| * the creatorClass to set |
| */ |
| public void setCreatorClass(String creatorClass) { |
| this.creatorClass = creatorClass; |
| } |
| |
| } |
| |
| } |