blob: 601cce7232f70a8e045aa3e7eac494a8df3524bc [file] [log] [blame]
package org.eclipse.osbp.utils.vaadin.problems;
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.PreDestroy;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent;
import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherCommand;
import org.eclipse.osbp.runtime.common.event.IEventDispatcher;
import org.eclipse.osbp.runtime.common.validation.IStatus;
import org.eclipse.osbp.runtime.common.validation.IStatus.Severity;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
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.EventHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.Component;
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;
public class ProblemsViewContent extends VerticalLayout { // NOSONAR
private static final String MESSAGE_CODE = "messageCode";
private static final String CREATOR_CLASS = "creatorClass";
private static final String MESSAGE_PATH = "messagePath";
private static final String SEVERITY = "severity";
private static final String BUNDLE_SYMBOLIC_NAME = "bundleSymbolicName";
private static final String PART_NAME = "partName";
private static final String FIELD_NAME = "fieldName";
private static final String MESSAGE = "message";
/**
*
*/
private static final long serialVersionUID = -8512352376339527845L;
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory.getLogger(ProblemsViewContent.class);
/** The status manager. */
private transient IStatusManager statusManager;
/** The part service. */
private transient EPartService partService;
/** The event broker. */
private transient IEventBroker eventBroker;
/** The table. */
private Table table;
/** The container. */
private BeanItemContainer<StatusBean> container;
/** The current timer. */
private transient Timer currentTimer;
/** The changed validations handler. */
private transient EventHandler changedValidationsHandler;
/** The changed scope handler. */
private transient EventHandler changedScopeHandler;
/** The detail label. */
private Label detailLabel;
private Locale locale;
private transient IDSLMetadataService dslMetadataService;
private String sender;
private String topic;
private transient IEventDispatcher eventDispatcher;
private MPerspective perspective;
/**
* Inits the view content.
*
* @param locale
* the locale
* @return the vertical layout
*/
@SuppressWarnings("serial")
public Component createComponents(IEclipseContext eclipseContext, Locale locale, String sender, String topic) {
this.sender = sender;
this.topic = topic;
eventDispatcher = eclipseContext.get(IEventDispatcher.class);
dslMetadataService = eclipseContext.get(IDSLMetadataService.class);
statusManager = eclipseContext.get(IStatusManager.class);
partService = eclipseContext.get(EPartService.class);
eventBroker = eclipseContext.get(IEventBroker.class);
perspective = eclipseContext.get(MPerspective.class);
this.locale = locale;
VerticalLayout parent = new VerticalLayout();
table = new Table();
table.setSelectable(true);
table.setSizeFull();
table.setPageLength(5);
parent.addComponent(table);
container = new BeanItemContainer<>(StatusBean.class);
table.setContainerDataSource(container);
table.setVisibleColumns(MESSAGE, FIELD_NAME, PART_NAME, BUNDLE_SYMBOLIC_NAME, SEVERITY, MESSAGE_PATH,
CREATOR_CLASS, MESSAGE_CODE);
table.setColumnCollapsingAllowed(true);
table.setColumnCollapsed(SEVERITY, true);
table.setColumnCollapsed(BUNDLE_SYMBOLIC_NAME, true);
table.setColumnCollapsed(MESSAGE_PATH, true);
table.setColumnCollapsed(CREATOR_CLASS, true);
table.setColumnCollapsed(MESSAGE_CODE, true);
table.setRowHeaderMode(RowHeaderMode.ICON_ONLY);
table.setItemIconPropertyId("severityImage");
table.setColumnHeaderMode(ColumnHeaderMode.EXPLICIT_DEFAULTS_ID);
table.setColumnHeader(MESSAGE, dslMetadataService.translate(locale.toLanguageTag(), MESSAGE));
table.setColumnHeader(FIELD_NAME, dslMetadataService.translate(locale.toLanguageTag(), FIELD_NAME));
table.setColumnHeader(PART_NAME, dslMetadataService.translate(locale.toLanguageTag(), PART_NAME));
table.setColumnHeader(BUNDLE_SYMBOLIC_NAME,
dslMetadataService.translate(locale.toLanguageTag(), BUNDLE_SYMBOLIC_NAME));
table.setColumnHeader(SEVERITY, dslMetadataService.translate(locale.toLanguageTag(), SEVERITY));
table.setColumnHeader(MESSAGE_PATH, dslMetadataService.translate(locale.toLanguageTag(), MESSAGE_PATH));
table.setColumnHeader(CREATOR_CLASS, dslMetadataService.translate(locale.toLanguageTag(), CREATOR_CLASS));
table.setColumnHeader(MESSAGE_CODE, dslMetadataService.translate(locale.toLanguageTag(), MESSAGE_CODE));
table.addItemClickListener(new ItemClickEvent.ItemClickListener() {
@Override
public void itemClick(ItemClickEvent event) {
focusStatus(event);
}
});
table.addValueChangeListener(e -> showDetailMessage((StatusBean) e.getProperty().getValue()));
detailLabel = new Label();
detailLabel.setPrimaryStyleName("detailmessage");
detailLabel.setContentMode(ContentMode.HTML);
detailLabel.setSizeFull();
parent.addComponent(detailLabel);
table.focus();
parent.setExpandRatio(table, 0.85f);
parent.setExpandRatio(detailLabel, 0.15f);
// handle changed validation scopes
//
changedScopeHandler = e -> refreshContent();
// handle changes in validation results
//
eventBroker.subscribe(IE4Topics.StatusManagerEvents.ACTIVE_SCOPE_CHANGED_TOPIC, changedScopeHandler);
changedValidationsHandler = e -> refreshContent();
eventBroker.subscribe(IE4Topics.StatusManagerEvents.VALIDATIONS_CHANGED_TOPIC, changedValidationsHandler);
return parent;
}
/**
* 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<>();
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() {
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() {
UI.getCurrent().accessSynchronously(() -> {
container.removeAllItems();
IStatusScope scope = statusManager.getActiveScope();
if (scope != null) {
container.addAll(mapStatus(scope));
}
detailLabel.setValue("");
LOGGER.debug("{}", "Table refreshed.");
resetTimer();
if (container.size() == 0) {
EventDispatcherEvent evt = new EventDispatcherEvent(perspective, EventDispatcherCommand.CLOSE, topic, sender);
eventDispatcher.sendEvent(evt);
} else {
table.select(container.getIdByIndex(0));
}
});
}
}, 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<>();
for (IStatus status : scope.getAllStatus()) {
result.add(StatusBean.create(status, dslMetadataService, locale));
}
return result;
}
/**
* Map status.
*
* @param manager
* the manager
* @return the list
*/
protected List<StatusBean> mapStatus(IStatusManager manager) {
List<StatusBean> result = new ArrayList<>();
for (IStatus status : manager.getAllScopeStatus()) {
result.add(StatusBean.create(status, dslMetadataService, locale));
}
return result;
}
/**
* Dispose.
*/
@PreDestroy
protected void dispose() {
eventBroker.unsubscribe(changedScopeHandler);
eventBroker.unsubscribe(changedValidationsHandler);
changedScopeHandler = null;
changedValidationsHandler = null;
table = null;
container = null;
}
/**
* 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;
/** The field value. */
private String fieldValue;
/**
* 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, IDSLMetadataService dslMetadataService, Locale locale) {
StatusBean bean = new StatusBean();
bean.severity = status.getSeverity();
bean.bundleSymbolicName = status.getBundleSymblicName();
bean.messageCode = status.getCode();
bean.fieldValue = (String) status.getProperty(IStatus.PROP_FIELD_VALUE);
String errorMessage = dslMetadataService.translate(locale.toLanguageTag(), status.getMessage());
if(bean.fieldValue != null) {
errorMessage = errorMessage.replace("{0}", bean.fieldValue);
}
bean.message = new Label(errorMessage,
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 = dslMetadataService.translate(locale.toLanguageTag(), bean.partId);
if (fieldI18nKey != null && !fieldI18nKey.equals("")) {
bean.fieldName = dslMetadataService.translate(locale.toLanguageTag(), fieldI18nKey);
} else {
bean.fieldName = dslMetadataService.translate(locale.toLanguageTag(), bean.fieldId);
}
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
*/
public Resource getSeverityImage() {
switch (severity) {
case OK:
case INFO:
return ResourceUtil.getResource(
"platform:/plugin/org.eclipse.osbp.utils.ui/images/info_tsk.png");
case WARNING:
return ResourceUtil.getResource(
"platform:/plugin/org.eclipse.osbp.utils.ui/images/warn_tsk.png");
case ERROR:
case CRITICAL:
case SYSTEMERROR:
return ResourceUtil.getResource(
"platform:/plugin/org.eclipse.osbp.utils.ui/images/error_tsk.png");
default:
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;
}
}
@Override
public void setLocale(Locale locale) {
this.locale = locale;
if (table != null) {
table.setColumnHeader(MESSAGE, dslMetadataService.translate(locale.toLanguageTag(), MESSAGE));
table.setColumnHeader(FIELD_NAME, dslMetadataService.translate(locale.toLanguageTag(), FIELD_NAME));
table.setColumnHeader(PART_NAME, dslMetadataService.translate(locale.toLanguageTag(), PART_NAME));
table.setColumnHeader(BUNDLE_SYMBOLIC_NAME,
dslMetadataService.translate(locale.toLanguageTag(), BUNDLE_SYMBOLIC_NAME));
table.setColumnHeader(SEVERITY, dslMetadataService.translate(locale.toLanguageTag(), SEVERITY));
table.setColumnHeader(MESSAGE_PATH, dslMetadataService.translate(locale.toLanguageTag(), MESSAGE_PATH));
table.setColumnHeader(CREATOR_CLASS, dslMetadataService.translate(locale.toLanguageTag(), CREATOR_CLASS));
table.setColumnHeader(MESSAGE_CODE, dslMetadataService.translate(locale.toLanguageTag(), MESSAGE_CODE));
refreshContent();
}
}
}