How to pass the Patten and JsonFactoryDecorator programmatically in Logback in spring application - logback

This is my logback.spring.xml
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<arguments/>
<stackTrace/>
<mdc>
<excludeMdcKeyName>ClaimNo</excludeMdcKeyName>
<excludeMdcKeyName>ClaimId</excludeMdcKeyName>
</mdc>
<pattern>
<pattern>
{
"Claim": "[${logback.company}, ${logback.info}]", // YML file value
"Log level": "${logback.level}", // YML value
"Time": "%date",
"Thread ID": "%thread",
"claimId":"[%X{claimId}]", //MDC key
"Claim no": "[%X{CliamNo}]", // MDC Key
"Logger": "%logger",
"Message": "%msg"
}
</pattern>
</pattern>
</providers>
<jsonFactoryDecorator class="net.logstash.logback.decorate.CharacterEscapesJsonFactoryDecorator">
<escape>
<targetCharacterCode>9</targetCharacterCode> <!-- Tab-->
<escapeSequence></escapeSequence>
</escape>
<escape>
<targetCharacterCode>10</targetCharacterCode> <!-- New Line-->
<escapeSequence></escapeSequence>
</escape>
</jsonFactoryDecorator>
</encoder>
Since I am using different appender with same encode pattern and in order to reuse the pattern, I am trying to add programmatically as like below, but here I am not sure how to pass pattern, MDC value and CharacterEscapesJsonFactoryDecorator from class level. Please can you help me on this.
public class JsonEncoder extends LoggingEventCompositeJsonEncoder {
public JsonEncoder() {
}
#Override
public void start() {
List<String> mdcList = new ArrayList<String>();
mdcList.add("ClaimNo");
mdcList.add("CliamId");
MdcJsonProvider mdcJsonProvider= new MdcJsonProvider();
mdcJsonProvider.setExcludeMdcKeyNames(mdcList);
JsonProviders<ILoggingEvent> providers = getProviders();
providers.addProvider(mdcJsonProvider);
super.start();
}
}
Logback.spring.xml
<encoder class="com.solution.JsonEncoder"></encoder>

The xml element names match the setter/adder methods on the underlying configuration classes.
Also note that the pattern value should not contain comments.
public class JsonEncoder extends LoggingEventCompositeJsonEncoder {
#Override
public void start() {
/*
* <providers>
*/
JsonProviders<ILoggingEvent> providers = getProviders();
providers.setContext(getContext());
/*
* <arguments/>
*/
providers.addProvider(new ArgumentsJsonProvider());
/*
* <stackTrace/>
*/
providers.addProvider(new StackTraceJsonProvider());
/*
* <mdc>
* <excludeMdcKeyName>ClaimNo</excludeMdcKeyName>
* <excludeMdcKeyName>ClaimId</excludeMdcKeyName>
* </mdc>
*/
MdcJsonProvider mdcJsonProvider= new MdcJsonProvider();
List<String> mdcList = new ArrayList<String>();
mdcList.add("ClaimNo");
mdcList.add("ClaimId");
mdcJsonProvider.setExcludeMdcKeyNames(mdcList);
providers.addProvider(mdcJsonProvider);
/*
* <pattern>
* <pattern>...</pattern>
* </pattern>
*/
LoggingEventPatternJsonProvider patternJsonProvider = new LoggingEventPatternJsonProvider();
patternJsonProvider.setPattern("{\n" +
"\"Claim\": \"[${logback.company}, ${logback.info}]\",\n" +
"\"Log level\": \"${logback.level}\",\n" +
"\"Time\": \"%date\",\n" +
"\"Thread ID\": \"%thread\",\n" +
"\"claimId\":\"[%X{claimId}]\",\n" +
"\"Claim no\": \"[%X{CliamNo}]\",\n" +
"\"Logger\": \"%logger\",\n" +
"\"Message\": \"%msg\"\n" +
"}");
providers.addProvider(patternJsonProvider);
/*
* </providers>
*/
/*
* <jsonFactoryDecorator class="net.logstash.logback.decorate.CharacterEscapesJsonFactoryDecorator">
* <escape>
* <targetCharacterCode>9</targetCharacterCode> <!-- Tab-->
* <escapeSequence></escapeSequence>
* </escape>
* <escape>
* <targetCharacterCode>10</targetCharacterCode> <!-- New Line-->
* <escapeSequence></escapeSequence>
* </escape>
* </jsonFactoryDecorator>
*/
CharacterEscapesJsonFactoryDecorator jsonFactoryDecorator = new CharacterEscapesJsonFactoryDecorator();
CharacterEscapesJsonFactoryDecorator.Escape escape1 = new CharacterEscapesJsonFactoryDecorator.Escape();
escape1.setTargetCharacterCode(9);
escape1.setEscapeSequence("");
jsonFactoryDecorator.addEscape(escape1);
CharacterEscapesJsonFactoryDecorator.Escape escape2 = new CharacterEscapesJsonFactoryDecorator.Escape();
escape2.setTargetCharacterCode(10);
escape2.setEscapeSequence("");
jsonFactoryDecorator.addEscape(escape2);
setJsonFactoryDecorator(jsonFactoryDecorator);
super.start();
}
}

Related

java.lang.ClassCastException when maximize mpart

I have a Eclipse E4 application with some different MParts. Now when I maximize the MPart by double clicking on its tab I got the ClassCastException. Also when I minimize it again, the same exception will be thrown. I looked at the error but could't find a place in my source where this exception can be thrown. Can someone help me with this? Below you can find the full stack trace of the error.
java.lang.ClassCastException: org.eclipse.swt.layout.GridData cannot be cast to org.eclipse.swt.layout.FillData
at org.eclipse.swt.layout.FillLayout.computeChildSize(FillLayout.java:145)
at org.eclipse.swt.layout.FillLayout.computeSize(FillLayout.java:123)
at org.eclipse.swt.widgets.Composite.computeSizeInPixels(Composite.java:238)
at org.eclipse.swt.widgets.Control.computeSize(Control.java:663)
at org.eclipse.ui.forms.widgets.LayoutComposite.computeSize(LayoutComposite.java:37)
at org.eclipse.ui.forms.widgets.SizeCache.controlComputeSize(SizeCache.java:391)
at org.eclipse.ui.forms.widgets.SizeCache.computeMinimumWidth(SizeCache.java:430)
at org.eclipse.ui.forms.widgets.SizeCache.computeSize(SizeCache.java:189)
at org.eclipse.ui.forms.widgets.ExpandableComposite$ExpandableLayout.computeSize(ExpandableComposite.java:476)
at org.eclipse.ui.forms.widgets.ExpandableComposite.computeSize(ExpandableComposite.java:964)
at org.eclipse.swt.layout.FillData.computeSize(FillData.java:26)
at org.eclipse.swt.layout.FillLayout.computeChildSize(FillLayout.java:152)
at org.eclipse.swt.layout.FillLayout.computeSize(FillLayout.java:123)
at org.eclipse.swt.widgets.Composite.computeSizeInPixels(Composite.java:238)
at org.eclipse.swt.widgets.Control.computeSize(Control.java:663)
at org.eclipse.swt.layout.FillData.computeSize(FillData.java:26)
at org.eclipse.swt.layout.FillLayout.computeChildSize(FillLayout.java:152)
at org.eclipse.swt.layout.FillLayout.computeSize(FillLayout.java:123)
at org.eclipse.swt.widgets.Composite.computeSizeInPixels(Composite.java:238)
at org.eclipse.swt.widgets.Control.computeSize(Control.java:663)
at org.eclipse.ui.forms.widgets.LayoutComposite.computeSize(LayoutComposite.java:37)
at org.eclipse.ui.forms.widgets.SizeCache.controlComputeSize(SizeCache.java:391)
at org.eclipse.ui.forms.widgets.SizeCache.computeMinimumWidth(SizeCache.java:430)
at org.eclipse.ui.forms.widgets.SizeCache.computeSize(SizeCache.java:189)
at org.eclipse.ui.forms.widgets.Form$FormLayout.computeSize(Form.java:143)
at org.eclipse.ui.forms.widgets.Form.computeSize(Form.java:200)
at org.eclipse.ui.forms.widgets.SizeCache.controlComputeSize(SizeCache.java:391)
at org.eclipse.ui.forms.widgets.SizeCache.computeSize(SizeCache.java:270)
at org.eclipse.ui.forms.widgets.SharedScrolledComposite.reflow(SharedScrolledComposite.java:188)
at org.eclipse.ui.forms.widgets.SharedScrolledComposite.scheduleReflow(SharedScrolledComposite.java:237)
at org.eclipse.ui.forms.widgets.SharedScrolledComposite.access$1(SharedScrolledComposite.java:221)
at org.eclipse.ui.forms.widgets.SharedScrolledComposite$1.handleEvent(SharedScrolledComposite.java:68)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4410)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1079)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1103)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1084)
at org.eclipse.swt.widgets.Control.WM_SIZE(Control.java:5459)
at org.eclipse.swt.widgets.Scrollable.WM_SIZE(Scrollable.java:367)
at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1783)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4866)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5102)
at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method)
at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547)
at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88)
at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5691)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4879)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5102)
at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method)
at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482)
at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3251)
at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1099)
at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3212)
at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3208)
at org.eclipse.swt.widgets.Control.setBounds(Control.java:3203)
at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:219)
at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1383)
at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1794)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4866)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5102)
at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method)
at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547)
at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88)
at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5691)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4879)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5115)
at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method)
at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482)
at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3251)
at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1099)
at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3212)
at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3208)
at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3284)
at org.eclipse.swt.widgets.Control.setBounds(Control.java:3280)
at org.eclipse.swt.custom.CTabFolderLayout.layout(CTabFolderLayout.java:116)
at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1383)
at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1794)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4866)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5102)
at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method)
at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547)
at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88)
at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5691)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4879)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5115)
at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method)
at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1027)
at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:993)
at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1207)
at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1798)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4866)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5102)
at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method)
at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547)
at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88)
at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5691)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4879)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5102)
at org.eclipse.swt.internal.win32.OS.SetWindowPos(Native Method)
at org.eclipse.swt.widgets.Widget.SetWindowPos(Widget.java:1482)
at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3251)
at org.eclipse.swt.widgets.Composite.setBoundsInPixels(Composite.java:1099)
at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3212)
at org.eclipse.swt.widgets.Control.setBoundsInPixels(Control.java:3208)
at org.eclipse.swt.widgets.Control.setBounds(Control.java:3203)
at org.eclipse.swt.layout.FillLayout.layout(FillLayout.java:204)
at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1383)
at org.eclipse.swt.widgets.Composite.WM_SIZE(Composite.java:1794)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4866)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5102)
at org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method)
at org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2547)
at org.eclipse.swt.widgets.Scrollable.callWindowProc(Scrollable.java:88)
at org.eclipse.swt.widgets.Control.WM_WINDOWPOSCHANGED(Control.java:5691)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:4879)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:5115)
at org.eclipse.swt.internal.win32.OS.EndDeferWindowPos(Native Method)
at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:1027)
at org.eclipse.swt.widgets.Composite.resizeChildren(Composite.java:993)
at org.eclipse.swt.widgets.Composite.setResizeChildren(Composite.java:1207)
at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1384)
at org.eclipse.swt.widgets.Composite.updateLayout(Composite.java:1368)
at org.eclipse.swt.widgets.Composite.setLayoutDeferred(Composite.java:1167)
at org.eclipse.swt.widgets.Display.runDeferredLayouts(Display.java:4252)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3809)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1121)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:336)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1022)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:150)
at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:161)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:388)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:243)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:673)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:610)
at org.eclipse.equinox.launcher.Main.run(Main.java:1519)
at org.eclipse.equinox.launcher.Main.main(Main.java:1492)
My class that will render the screen:
public class UsersScreen extends MainPart {
/**
* Table with all the users
*/
private CustomNatTable<PlatformUser> userTable;
/**
* Table with all the different roles
*/
private CustomNatTable<RoleCompanyViewModel> roleTable;
/**
* #see org.eclipse.e4.ui.workbench.modeling.EPartService
*/
private EPartService partService;
/**
* Part of this part
*/
private MPart part;
/**
* List of all the roleCompany view models
*/
private ArrayList<RoleCompanyViewModel> roleData = new ArrayList<>();
/**
* List of all the userroles
*/
private ArrayList<UserRole> allUserRoles;
/**
* UserPermissionRepository repository to search for the user permissions
*/
private UserPermissionRepository userPermissionrepo;
/**
* Parent composite of the userTable
*/
private Composite userComposite;
/**
* Parent composite of the roleTable
*/
private Composite roleComposite;
private IEclipseContext context;
/**
* Creates the components and place it on the screen
*
* #param parent
* Parent composite where the components need to be write on
* #param application
* #see org.eclipse.e4.ui.model.application.MApplication
* #param service
* #see org.eclipse.e4.ui.workbench.modeling.EModelService
* #param partService
* #see org.eclipse.e4.ui.workbench.modeling.EPartService
* #param context
* #see org.eclipse.e4.core.contexts.IEclipseContext
* #param currentPart
* MPart of the UserScreen
*/
#PostConstruct
public void createComposite(Composite parent, MApplication application, EModelService service,
EPartService partService, final IEclipseContext context, MPart currentPart) {
this.userPermissionrepo = new RepositoryManager<UserPermissionRepository>()
.getRepository(UserPermissionRepository.class.getSimpleName());
this.application = application;
this.service = service;
this.partService = partService;
this.part = currentPart;
this.context = context;
FormToolkit toolkit = new FormToolkit(parent.getDisplay());
ScrolledForm form = toolkit.createScrolledForm(parent);
form.setText("User Management");
Composite body = form.getBody();
toolkit.decorateFormHeading(form.getForm());
toolkit.paintBordersFor(body);
form.getBody().setLayout(new FillLayout(SWT.HORIZONTAL));
Composite container = new Composite(body, SWT.NONE);
container.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
container.setLayout(new FillLayout());
Section userSection = toolkit.createSection(container, Section.TITLE_BAR);
//userSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1));
toolkit.paintBordersFor(userSection);
userSection.setText("Users");
Section roleSection = toolkit.createSection(container, Section.TITLE_BAR);
//roleSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 1, 2));
toolkit.paintBordersFor(roleSection);
roleSection.setText("Roles");
userComposite = toolkit.createComposite(userSection);
roleComposite = toolkit.createComposite(roleSection);
userComposite.setLayout(new FillLayout());
roleComposite.setLayout(new FillLayout());
userSection.setClient(userComposite);
roleSection.setClient(roleComposite);
showToolItems();
createUserTable(userComposite, context);
createRoleTable(roleComposite, context);
}
/**
* Creates the role table on the parent composite
*
* #param roleTableComposite
* Composite where the table must be on
* #param context
* #see org.eclipse.e4.core.contexts.IEclipseContext
*/
private void createRoleTable(Composite roleTableComposite, final IEclipseContext context) {
ArrayList<NATColumnDefinition> roleDefinitions = new ArrayList<>();
NATColumnDefinition assigned = new NATColumnDefinition("on");
assigned.setLabel("Assigned");
assigned.setAligment(Alignment.COLUMN_CENTER_LABEL);
assigned.setColumnWidth(60);
assigned.setData(NATColumnDefinition.DataType.BOOLEAN_COLUMN_LABEL);
if (!connectionClosed && userPermissionrepo.containsPermission("AssignRole")) {
assigned.setEditor(NATColumnDefinition.EditorType.BOOLEAN_EDITOR_COLUMN_LABEL);
}
NATColumnDefinition roleName = new NATColumnDefinition("name");
roleName.setLabel("Name");
roleName.setAligment(Alignment.COLUMN_CENTER_LABEL);
roleName.setColumnWidth(120);
NATColumnDefinition description = new NATColumnDefinition("description");
description.setLabel("Description");
description.setAligment(Alignment.COLUMN_CENTER_LABEL);
description.setColumnWidth(240);
roleDefinitions.add(assigned);
roleDefinitions.add(roleName);
roleDefinitions.add(description);
roleTable = new CustomNatTable<>(roleDefinitions, roleTableComposite);
roleTableComposite.setLayout(new FillLayout(SWT.HORIZONTAL));
roleTable.showFilterRow(true);
roleTable.setSortEnabled(true);
roleTable.showHeaderGroups(false);
roleTable.showHeaderGroupGroups(false);
roleTable.expandTree(true);
roleTable.treeFormat(new TreeFormat<RoleCompanyViewModel>(new Comparator<RoleCompanyViewModel>() {
#Override
public int compare(RoleCompanyViewModel obj1, RoleCompanyViewModel obj2) {
if (obj1.getCompanyId() != null && obj2.getCompanyId() != null) {
return obj1.getCompanyId().compareTo(obj2.getCompanyId());
}
return 0;
}
}));
roleTable.generate();
roleTable.addMoficationListener(new IModificationListener<RoleCompanyViewModel>() {
#Override
public void objectModified(RoleCompanyViewModel changedObject, RoleCompanyViewModel originalObject) {
PlatformUser user = userTable.getSelectedItem();
if (changedObject.getChildren().size() > 0) {
ArrayList<RoleCompanyViewModel> userRoles = (ArrayList<RoleCompanyViewModel>) changedObject
.getChildren();
for (RoleCompanyViewModel viewModel : userRoles) {
UserRole role = new UserRole();
role.setPlatformUser(user);
role.setCompany(viewModel.getCompanyObject());
role.setRole(viewModel.getRoleObject());
if (viewModel.isOn()) {
SendInsertHandler<UserRole> handler = new SendInsertHandler<>();
handler.execute(role, context, UserRole.class.getSimpleName(), "UserManagement", part);
} else {
SendRemoveHandle<UserRole> handler = new SendRemoveHandle<>();
handler.execute(role, context, UserRole.class.getSimpleName(), "UserManagement", part);
}
}
} else {
UserRole role = new UserRole();
role.setPlatformUser(user);
role.setCompany(changedObject.getCompanyObject());
role.setRole(changedObject.getRoleObject());
if (changedObject.isOn()) {
SendInsertHandler<UserRole> handler = new SendInsertHandler<>();
handler.execute(role, context, UserRole.class.getSimpleName(), "UserManagement", part);
} else {
SendRemoveHandle<UserRole> handler = new SendRemoveHandle<>();
handler.execute(role, context, UserRole.class.getSimpleName(), "UserManagement", part);
}
}
}
});
updateRoleTable(null, null);
}
/**
* Creates the user table on the parent composite
*
* #param userTableComposite
* Composite where the table must be on
* #param context
* #see org.eclipse.e4.core.contexts.IEclipseContext
*/
private void createUserTable(Composite userTableComposite, final IEclipseContext context) {
ArrayList<NATColumnDefinition> userColumnDefinitions = new ArrayList<>();
NATColumnDefinition userName = new NATColumnDefinition("userName");
userName.setLabel("User name");
userName.setAligment(Alignment.COLUMN_CENTER_LABEL);
userName.setColumnWidth(120);
NATColumnDefinition firstName = new NATColumnDefinition("firstName");
firstName.setLabel("First name");
firstName.setAligment(Alignment.COLUMN_CENTER_LABEL);
firstName.setColumnWidth(120);
NATColumnDefinition lastName = new NATColumnDefinition("lastName");
lastName.setLabel("Last name");
lastName.setAligment(Alignment.COLUMN_CENTER_LABEL);
lastName.setColumnWidth(120);
NATColumnDefinition domain = new NATColumnDefinition("domain");
domain.setLabel("Domain");
domain.setAligment(Alignment.COLUMN_CENTER_LABEL);
domain.setColumnWidth(60);
NATColumnDefinition active = new NATColumnDefinition("active");
active.setLabel("Active");
active.setAligment(Alignment.COLUMN_CENTER_LABEL);
active.setColumnWidth(60);
active.setDataType(NATColumnDefinition.DataType.BOOLEAN_COLUMN_LABEL);
if (!connectionClosed && userPermissionrepo.containsPermission("DeactivateUser")) {
active.setEditor(NATColumnDefinition.EditorType.BOOLEAN_EDITOR_COLUMN_LABEL);
}
if (!connectionClosed && userPermissionrepo.containsPermission("EditUser")) {
firstName.setEditor(NATColumnDefinition.EditorType.TEXT_EDITOR_COLUMN_LABEL);
lastName.setEditor(NATColumnDefinition.EditorType.TEXT_EDITOR_COLUMN_LABEL);
}
userColumnDefinitions.add(userName);
userColumnDefinitions.add(firstName);
userColumnDefinitions.add(lastName);
userColumnDefinitions.add(domain);
userColumnDefinitions.add(active);
userTable = new CustomNatTable<>(userColumnDefinitions, userTableComposite);
// userTableComposite.setLayout(new FillLayout(SWT.HORIZONTAL));
userTable.showFilterRow(true);
userTable.setSortEnabled(true);
userTable.showHeaderGroups(false);
userTable.showHeaderGroupGroups(false);
userTable.generate();
userTable.addSelectionListener(new SelectionListener<PlatformUser>() {
#Override
public void itemSelected(PlatformUser item) {
checkSelection(item);
roleTable.refresh(false);
}
#Override
public void gridSelectionChanged(GridSelection selection) {
}
});
userTable.addMoficationListener(new IModificationListener<PlatformUser>() {
#Override
public void objectModified(PlatformUser changedObject, PlatformUser originalObject) {
SendUpdateHandler<PlatformUser> handler = new SendUpdateHandler<>();
handler.execute(changedObject, originalObject, context, changedObject.getClass().getSimpleName(),
"UserManagement", partService.getActivePart());
}
});
userDataChanged(null);
}
/**
* Handles the close action from the window
*/
#PreDestroy
public void windowClose() {
CloseScreenHandler handler = new CloseScreenHandler();
handler.execute("UserManagement", part);
MDirectToolItem addUser = getToolItem(application, service, "addUserToolItem");
addUser.setToBeRendered(false);
addUser.setVisible(false);
}
/**
* Will be called when some data has been changed in the RoleRepository
*
* #param repo
* Platform user repository
*/
#Inject
#Optional
public void roleDataChanged(#UIEventTopic("RoleRepository") RoleRepository repo) {
updateRoleTable(repo, null);
}
/**
* Will be called when some data has been changed in the
* PlatformUserRepository
*
* #param data
* Platform user repository
*/
#Inject
#Optional
public void userDataChanged(#UIEventTopic("PlatformUserRepository") PlatformUserRepository data) {
if(data == null)
{
RepositoryManager<PlatformUserRepository> manager = new RepositoryManager<PlatformUserRepository>();
data = manager.getRepository(PlatformUserRepository.class.getSimpleName());
}
userTable.setItems(data.getAllData());
userTable.refresh(true);
}
/**
* Will be called when some data has been changed in the CompanyRepository.
*
* #param repo
* Company repository
*/
#Inject
#Optional
public void companyDataChanged(#UIEventTopic("CompanyRepository") CompanyRepository repo) {
updateRoleTable(null, repo);
}
/**
* Handles the change of UserRoleRepository object
*
* #param repo
* UserRoleRepository object that has been changed
*/
#Inject
#Optional
public void userRolDataChanged(#UIEventTopic("UserRoleRepository") UserRoleRepository repo) {
allUserRoles = repo.getAllData();
PlatformUser selectedUser = userTable.getSelectedItem();
if(selectedUser != null)
{
checkSelection(selectedUser);
roleTable.refresh(false);
}
}
}
I found the issue. Some old code was still in my class to draw the a Nattable.
The code was a GridFactory that places the table on a grid. Removed this line fixed my problem.

Can I convert JSON object to JAXB object?

I have been working with JAXB objects. Now my requirement is using JSON instead of XML. Can someone help me out with the logic?
I can't read replace entire code base with json objects. Is there any way to convert these json to jaxb objects?
Thanks in advance.
xml:
<skins>
<skin id="lineNormal" type="style" displayname="Skin">
<attributes datatype="string" value="one" name="bg_type" platform="general"/>
<attributes datatype="string" value="5c5c5c00" name="background_color" platform="general"/>
<attributes datatype="boolean" value="false" name="customcss" platform="general"/>
<attributes datatype="string" value="00000000" name="border_color" platform="general"/>
<attributes datatype="number" value="0" name="border_width" platform="general"/>
<attributes datatype="string" value="plain" name="border_style" platform="general"/>
<attributes datatype="number" value="0" name="border_radius" platform="general"/>
<attributes datatype="string" value="Line" name="wtype" platform="general"/>
</skin>
JSON:
{
"lineNormal": {
"wType": "Button",
"bg_type": "one",
"border_color": "00000000",
"border_radius": 0,
"border_style": "plain",
"border_width": 0,
"border_type": 0,
"font_color": "00000000",
"font_size": 100,
"font_weight": "normal",
"background_color : "xxx"
}
}
My class file for fetching application graph from the above xml is:
`
#XmlRootElement(name = "application")
public class Application implements Serializable
{
private ArrayList <Container> containers;
private Skins skins = new Skins();
private String name;
private String id;
#XmlElement(name = "container")
public ArrayList <Container> getContainers() {
return containers;
}
/**
* Sets teh containers collection
* #param containers
*/
public void setContainers(ArrayList <Container> containers) {
this.containers = containers;
}
/**
*
* #return
*/
#XmlElement(name = "skins")
public Skins getSkins()
{
return skins;
}
/**
*
* #param skins
*/
public void setSkins(Skins skins)
{
this.skins = skins;
}
#XmlElement(name = "globals")
public Global getGlobal() {
return global;
}
public void setGlobal(Global global) {
this.global = global;
}
#XmlAttribute(name="id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#XmlElement(name = "attributes")
public ArrayList<Attributes> getAttributes() {
return attributes;
}`
//skin class is ::
`
public class Skins implements Serializable{
private ArrayList <Skin> skins = new ArrayList();
#XmlElement(name = "skin")
public ArrayList<Skin> getSkinList()
{
return skins;
}
/**
*
* #param skins
*/
public void setSkinList(ArrayList<Skin> skins)
{
this.skins = skins;
}
}
`
"Can I convert JSON object to JAXB object?"
The jackson-module-jaxb-annotations for Jackson will allow you to do this.
This Jackson extension module provides support for using JAXB (javax.xml.bind) annotations as an alternative to native Jackson annotations. It is most often used to make it easier to reuse existing data beans that used with JAXB framework to read and write XML.
With Maven, you just need this dependency (it will pull in a couple other Jackson core dependencies):
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>2.4.0</version>
</dependency>
Having this dependency, you simply need to register the JAXB module with the ObjectMapper
JaxbAnnotationModule module = new JaxbAnnotationModule();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(module);
Then you can read the JSON into your JAXB objects.
RootObject root = objectMapper.readValue(json, RootObject.class);
This is not a sure-fire solution for all use cases, as the module does not support all JAXB annotations. See here for supported annotations
You may also want to check out MOXy support for this, as seen here

Mask sensitive data in logs with logback

I need to be able to search an event for any one of a number of patterns and replace the text in the pattern with a masked value. This is a feature in our application intended to prevent sensitive information falling into the logs. As the information can be from a large variety of sources, it is not practical to apply filters on all the inputs. Besides there are uses for toString() beyond logging and I don't want toString() to uniformly mask for all calls (only logging).
I have tried using the %replace method in logback.xml:
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %replace(%msg){'f k\="pin">(.*?)</f','f k\="pin">**********</f'}%n</pattern>
This was successful (after replacing the angle brackets with character entities), but it can only replace a single pattern. I would also like to perform the equivalent of
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %replace(%msg){'pin=(.*?),','pin=**********,'}%n</pattern>
at the same time, but cannot. There is no way to mask two patterns in the one %replace.
The other way that has been loosely discussed on the interblags is extending something on the appender/encoder/layout hierarchy, but every attempt to intercept the ILoggingEvent has resulted in a collapse of the whole system, usually through instantiation errors or UnsupportedOperationException.
For example, I tried extending PatternLayout:
#Component("maskingPatternLayout")
public class MaskingPatternLayout extends PatternLayout {
#Autowired
private Environment env;
#Override
public String doLayout(ILoggingEvent event) {
String message=super.doLayout(event);
String patternsProperty = env.getProperty("bowdleriser.patterns");
if( patternsProperty != null ) {
String[] patterns = patternsProperty.split("|");
for (int i = 0; i < patterns.length; i++ ) {
Pattern pattern = Pattern.compile(patterns[i]);
Matcher matcher = pattern.matcher(event.getMessage());
matcher.replaceAll("*");
}
} else {
System.out.println("Bowdleriser not cleaning! Naughty strings are getting through!");
}
return message;
}
}
and then adjusting the logback.xml
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<layout class="com.touchcorp.touchpoint.utils.MaskingPatternLayout">
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</layout>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/touchpoint.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>logs/touchpoint.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>10MB</maxFileSize>
</triggeringPolicy>
<encoder>
<layout class="com.touchcorp.touchpoint.utils.MaskingPatternLayout">
<pattern>%date{YYYY-MM-dd HH:mm:ss} %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</layout>
</encoder>
</appender>
<logger name="com.touchcorp.touchpoint" level="DEBUG" />
<logger name="org.springframework.web.servlet.mvc" level="TRACE" />
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
I have tried many other insertions, so I was wondering if anyone has actually achieved what I am attempting and if they could provide any clues or a solution.
You need to wrap layout using LayoutWrappingEncoder. And also I believe you cannot use spring here as logback is not managed by spring.
Here is the updated class.
public class MaskingPatternLayout extends PatternLayout {
private String patternsProperty;
public String getPatternsProperty() {
return patternsProperty;
}
public void setPatternsProperty(String patternsProperty) {
this.patternsProperty = patternsProperty;
}
#Override
public String doLayout(ILoggingEvent event) {
String message = super.doLayout(event);
if (patternsProperty != null) {
String[] patterns = patternsProperty.split("\\|");
for (int i = 0; i < patterns.length; i++) {
Pattern pattern = Pattern.compile(patterns[i]);
Matcher matcher = pattern.matcher(event.getMessage());
if (matcher.find()) {
message = matcher.replaceAll("*");
}
}
} else {
}
return message;
}
}
And sample logback.xml
<appender name="fileAppender1" class="ch.qos.logback.core.FileAppender">
<file>c:/logs/kp-ws.log</file>
<append>true</append>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="com.kp.MaskingPatternLayout">
<patternsProperty>.*password.*|.*karthik.*</patternsProperty>
<pattern>%d [%thread] %-5level %logger{35} - %msg%n</pattern>
</layout>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="fileAppender1" />
</root>
UPDATE
Here its better approach, set Pattern during init itself. such that we can avoid recreating Pattern again and again and this implementation is close to realistic usecase.
public class MaskingPatternLayout extends PatternLayout {
private String patternsProperty;
private Optional<Pattern> pattern;
public String getPatternsProperty() {
return patternsProperty;
}
public void setPatternsProperty(String patternsProperty) {
this.patternsProperty = patternsProperty;
if (this.patternsProperty != null) {
this.pattern = Optional.of(Pattern.compile(patternsProperty, Pattern.MULTILINE));
} else {
this.pattern = Optional.empty();
}
}
#Override
public String doLayout(ILoggingEvent event) {
final StringBuilder message = new StringBuilder(super.doLayout(event));
if (pattern.isPresent()) {
Matcher matcher = pattern.get().matcher(message);
while (matcher.find()) {
int group = 1;
while (group <= matcher.groupCount()) {
if (matcher.group(group) != null) {
for (int i = matcher.start(group); i < matcher.end(group); i++) {
message.setCharAt(i, '*');
}
}
group++;
}
}
}
return message.toString();
}
}
And the updated Configuration file.
<appender name="fileAppender1" class="ch.qos.logback.core.FileAppender">
<file>c:/logs/kp-ws.log</file>
<append>true</append>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="com.kp.MaskingPatternLayout">
<patternsProperty>(password)|(karthik)</patternsProperty>
<pattern>%d [%thread] %-5level %logger{35} - %msg%n</pattern>
</layout>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="fileAppender1" />
</root>
Output
My username=test and password=*******
From the documentation:
replace(p){r, t}
The pattern p can be arbitrarily complex and in particular can contain multiple conversion keywords.
Facing same problem having to replace 2 patterns in a message, I just tried to chain so p is just an invocation of replace, in my case:
%replace( %replace(%msg){'regex1', 'replacement1'} ){'regex2', 'replacement2'}
Worked great, though I wonder if I'm pushing it a bit and p can be indeed that arbitrarily complex.
A very similar but slightly different approach evolves around customizing CompositeConverter and defining a <conversionRule ...> within the logback that references the custom converter.
In one of my tech-demo projects I defined a MaskingConverter class that defines a series of patterns the logging event is analyzed with and on a match updated which is used inside my logback configuration.
As link-only answers are not that beloved here at SO I'll post the important parts of the code here and explain what it does and why it is set up like that. Starting with the Java-based custom converter class:
public class MaskingConverter<E extends ILoggingEvent> extends CompositeConverter<E> {
public static final String CONFIDENTIAL = "CONFIDENTIAL";
public static final Marker CONFIDENTIAL_MARKER = MarkerFactory.getMarker(CONFIDENTIAL);
private Pattern keyValPattern;
private Pattern basicAuthPattern;
private Pattern urlAuthorizationPattern;
#Override
public void start() {
keyValPattern = Pattern.compile("(pw|pwd|password)=.*?(&|$)");
basicAuthPattern = Pattern.compile("(B|b)asic ([a-zA-Z0-9+/=]{3})[a-zA-Z0-9+/=]*([a-zA-Z0-9+/=]{3})");
urlAuthorizationPattern = Pattern.compile("//(.*?):.*?#");
super.start();
}
#Override
protected String transform(E event, String in) {
if (!started) {
return in;
}
Marker marker = event.getMarker();
if (null != marker && CONFIDENTIAL.equals(marker.getName())) {
// key=value[&...] matching
Matcher keyValMatcher = keyValPattern.matcher(in);
// Authorization: Basic dXNlcjpwYXNzd29yZA==
Matcher basicAuthMatcher = basicAuthPattern.matcher(in);
// sftp://user:password#host:port/path/to/resource
Matcher urlAuthMatcher = urlAuthorizationPattern.matcher(in);
if (keyValMatcher.find()) {
String replacement = "$1=XXX$2";
return keyValMatcher.replaceAll(replacement);
} else if (basicAuthMatcher.find()) {
return basicAuthMatcher.replaceAll("$1asic $2XXX$3");
} else if (urlAuthMatcher.find()) {
return urlAuthMatcher.replaceAll("//$1:XXX#");
}
}
return in;
}
}
This class defines a number of RegEx patterns the respective log-line should be compared against and on a match lead to an update of the event by masking the passwords.
Note that this code sample assumes that a log line only contains one kind of password. You are of course free to adapt the bahvior to your needs in case you want to probe each line for multiple pattern matches.
To apply this converter one simply has to add the following line to the logback configuration:
<conversionRule conversionWord="mask" converterClass="at.rovo.awsxray.utils.MaskingConverter"/>
which defines a new function mask which can be used in a pattern in order to mask any log events matching any of the patterns defined in the custom converter. This function can now be used inside a pattern to tell Logback to perform the logic on each log event. The respective pattern might be something along the lines below:
<property name="patternValue"
value="%date{yyyy-MM-dd HH:mm:ss} [%-5level] - %X{FILE_ID} - %mask(%msg) [%thread] [%logger{5}] %n"/>
<!-- Appender definitions-->
<appender class="ch.qos.logback.core.ConsoleAppender" name="console">
<encoder>
<pattern>${patternValue}</pattern>
</encoder>
</appender>
where %mask(%msg) will take the original log-line as input and perform the password masking on each of the lines passed to that function.
As probing each line for one or multiple pattern matches might be costly, the Java code above includes Markers that can be used in log statements to send certain meta information on the log statement itself to Logback/SLF4J. Based on such markers different behaviors might be achievable. In the scenario presented a marker interface can be used to tell Logback that the respective log line contains confidential information and thus requires masking if it matches. Any log line that isn't marked as confidential will be ignored by this converter which helps in pumping out the lines faster as no pattern matching needs to be performed on those lines.
In Java such a marker can be added to a log statement like this:
LOG.debug(MaskingConverter.CONFIDENTIAL_MARKER, "Received basic auth header: {}",
connection.getBasicAuthentication());
which might produce a log line similar to Received basic auth header: Basic QlRXXXlQ= for the above mentioned custom converter, which leaves the first and last couple of characters in tact but obfuscates the middle bits with XXX.
Here is my approach, maybe it can help somebody
Try this one.
1. First of all, we should create a class for handling our logs (each row)
public class PatternMaskingLayout extends PatternLayout {
private Pattern multilinePattern;
private List<String> maskPatterns = new ArrayList<>();
public void addMaskPattern(String maskPattern) { // invoked for every single entry in the xml
maskPatterns.add(maskPattern);
multilinePattern = Pattern.compile(
String.join("|", maskPatterns), // build pattern using logical OR
Pattern.MULTILINE
);
}
#Override
public String doLayout(ILoggingEvent event) {
return maskMessage(super.doLayout(event)); // calling superclass method is required
}
private String maskMessage(String message) {
if (multilinePattern == null) {
return message;
}
StringBuilder sb = new StringBuilder(message);
Matcher matcher = multilinePattern.matcher(sb);
while (matcher.find()) {
if (matcher.group().contains("creditCard")) {
maskCreditCard(sb, matcher);
} else if (matcher.group().contains("email")) {
// your logic for this case
}
}
return sb.toString();
}
private void maskCreditCard(StringBuilder sb, Matcher matcher) {
//here is our main logic for masking sensitive data
String targetExpression = matcher.group();
String[] split = targetExpression.split("=");
String pan = split[1];
String maskedPan = Utils.getMaskedPan(pan);
int start = matcher.start() + split[0].length() + 1;
int end = matcher.end();
sb.replace(start, end, maskedPan);
}
}
The second step is we should create appender for logback into logback.xml
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="com.bpcbt.micro.utils.PatternMaskingLayout">
<maskPattern>creditCard=\d+</maskPattern> <!-- SourcePan pattern -->
<pattern>%d{dd/MM/yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%ex</pattern>-->
</layout>
</encoder>
Now we can use logger into our code
log.info("card context set for creditCard={}", creditCard);
As a result, we will see
one row from logs
card context set for creditCard=11111******111
without these options, our logs would be like this row
card context set for creditCard=1111111111111
I've used censor based on RegexCensor from library https://github.com/tersesystems/terse-logback.
In logback.xml
<!--censoring information-->
<newRule pattern="*/censor" actionClass="com.tersesystems.logback.censor.CensorAction"/>
<conversionRule conversionWord="censor" converterClass="com.tersesystems.logback.censor.CensorConverter" />
<!--impl inspired by com.tersesystems.logback.censor.RegexCensor -->
<censor name="censor-sensitive" class="com.mycompaqny.config.logging.SensitiveDataCensor"></censor>
where i put list regex replacements.
#Getter#Setter
public class SensitiveDataCensor extends ContextAwareBase implements Censor, LifeCycle {
protected volatile boolean started = false;
protected String name;
private List<Pair<Pattern, String>> replacementPhrases = new ArrayList<>();
public void start() {
String ssnJsonPattern = "\"(ssn|socialSecurityNumber)(\"\\W*:\\W*\".*?)-(.*?)\"";
replacementPhrases.add(Pair.of(Pattern.compile(ssnJsonPattern), "\"$1$2-****\""));
String ssnXmlPattern = "<(ssn|socialSecurityNumber)>(\\W*.*?)-(.*?)</";
replacementPhrases.add(Pair.of(Pattern.compile(ssnXmlPattern), "<$1>$2-****</"));
started = true;
}
public void stop() {
replacementPhrases.clear();
started = false;
}
public CharSequence censorText(CharSequence original) {
CharSequence outcome = original;
for (Pair<Pattern, String> replacementPhrase : replacementPhrases) {
outcome = replacementPhrase.getLeft().matcher(outcome).replaceAll(replacementPhrase.getRight());
}
return outcome;
}
}
and used it in logback.xml like this
<message>[ignore]</message> <---- IMPORTANT to disable original message field so you get only censored message
...
<pattern>
{"message": "%censor(%msg){censor-sensitive}"}
</pattern>
I was trying to mask some sensitive data in my demo project logs. I tried with but it didn't worked for me because of Java Reflections as I took variable name as pattern. I am adding the solution which worked for me incase if it helps anyone else also.
I added below code in logback.xml(inside encoder tag) file for masking field1 and field2 information in the logs.
<encoder class="com.demo.config.CustomJsonMaskLogEncoder">
<patterns>
<pattern>\"field1\"\s*:\s*\"(.*?)\"</pattern>
<pattern>\"field2\"\s*:\s*\"(.*?)\"</pattern>
<pattern>%-5p [%d{ISO8601,UTC}] [%thread] %c: %m%n%rootException</pattern>
</patterns>
</encoder>
I have written a CustomJsonMaskLogEncoder which does the job of masking the field data as per regex.
package com.demo.config;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import java.util.ArrayList;
import net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder;
import org.slf4j.LoggerFactory;
public class CustomJsonMaskLogEncoder extends LoggingEventCompositeJsonEncoder {
private final CustomPatternMaskingLayout customPatternMaskingLayout;
private boolean maskEnabled;
public JsonMaskLogEncoder() {
super();
customPatternMaskingLayout = new CustomPatternMaskingLayout();
maskEnabled = true;
}
#Override
public byte[] encode(ILoggingEvent event) {
return maskEnabled ? getMaskedJson(event) : super.encode(event);
}
private byte[] getMaskedJson(ILoggingEvent event) {
final Logger logger =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(event.getLoggerName());
final String message = customPatternMaskingLayout.maskMessage(event.getFormattedMessage());
final LoggingEvent loggingEvent =
new LoggingEvent(
"", logger, event.getLevel(), message, getThrowable(event), event.getArgumentArray());
return super.encode(loggingEvent);
}
private Throwable getThrowable(ILoggingEvent event) {
return event.getThrowableProxy() == null ? null : new Throwable(getStackTrace(event));
}
private String getStackTrace(ILoggingEvent event) {
final ExtendedThrowableProxyConverter throwableConverter =
new ExtendedThrowableProxyConverter();
throwableConverter.start();
final String errorMessageWithStackTrace = throwableConverter.convert(event);
throwableConverter.stop();
return errorMessageWithStackTrace;
}
#SuppressWarnings("unused")
public void setEnableMasking(boolean enabled) {
this.maskEnabled = enabled;
}
#SuppressWarnings("unused")
public void setPatterns(Patterns patterns) {
customPatternMaskingLayout.addMaskPatterns(patterns);
}
public static class Patterns extends ArrayList<String> {
#SuppressWarnings("unused")
public void addPattern(String pattern) {
add(pattern);
}
}
}
And below is the code for actual CustomPatternMaskingLayout:
package com.demo.config;
import static java.lang.String.format;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class CustomPatternMaskingLayout {
private Pattern multilinePattern;
private final List<String> maskPatterns = new ArrayList<>();
public CustomPatternMaskingLayout() {
compilePattern();
}
void addMaskPatterns(CustomJsonMaskLogEncoder.Patterns patterns) {
maskPatterns.addAll(patterns);
compilePattern();
}
private void compilePattern() {
multilinePattern = Pattern.compile(String.join("|", maskPatterns),Pattern.MULTILINE);
}
String maskMessage(String message) {
if (multilinePattern == null) {
return message;
}
StringBuilder sb = new StringBuilder(message);
Matcher matcher = multilinePattern.matcher(sb);
while (matcher.find()) {
IntStream.rangeClosed(1, matcher.groupCount()).forEach(group -> {
if (matcher.group(group) != null) {
IntStream.range(matcher.start(group), matcher.end(group)).forEach(i -> sb.setCharAt(i, '*'));
}
});
}
return sb.toString();
}
}
Hope this helps!!!

How to set EnumDecoder in Smooks

I'm facing some issues when trying to set an enum decoder in Smooks, in order to decode values from a CSV file.
I need an EnumDecoder and although I saw that you can instantiate it and set the configuration, I could not find where to set it in order to make it active.
So far I managed to write something like this:
EnumDecoder decoder = (EnumDecoder)DataDecoder.Factory.create(SomeEnumTypeClass.class);
Properties properties = new Properties();
properties.put("enumType", SomeEnumTypeClass.class.getName());
properties.put("John", SomeEnumTypeClass.JOHN);
decoder.setConfiguration(properties);
One other issue with setting the decoder I had from the configuration file.
smooks-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.2.xsd"
xmlns:csv="http://www.milyn.org/xsd/smooks/csv-1.2.xsd">
<csv:reader fields="field1,field2EnumType" separator=";">
<csv:listBinding beanId="beanList" class="com.myApp.TestingBean"/>
</csv:reader>
<jb:bean beanId="beanMockUp"
class="com.myApp.TestingBean">
<jb:value property="field1" data="header/field1" />
<jb:value property="field2EnumType"
data="header/field2EnumType"
decoder="Enum">
<jb:decodeParam name="enumType">com.myApp.SomeEnumTypeClass</jb:decodeParam>
<jb:decodeParam name="John">JOHN</jb:decodeParam>
<jb:decodeParam name="Jack">JACK</jb:decodeParam>
</jb:value>
</jb:bean>
</smooks-resource-list>
Main.java:
Smooks smooks = null;
try {
smooks = new Smooks("smooks-config.xml");
} catch (IOException | SAXException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
try {
ExecutionContext executionContext = smooks.createExecutionContext();
JavaResult result = new JavaResult();
smooks.filterSource(executionContext, new StringSource(messageIn), result);
return (List) result.getBean("beanList");
} finally {
smooks.close();
}
TestingBean.java:
public class TestingBean {
private String field1;
private SomeEnumTypeClass field2EnumType;
/**
* Get the value of field2EnumType
*
* #return the value of field2EnumType
*/
public SomeEnumTypeClass getField2EnumType() {
return field2EnumType;
}
/**
* Set the value of field2EnumType
*
* #param field2EnumType new value of field2EnumType
*/
public void setField2EnumType(SomeEnumTypeClass field2EnumType) {
this.field2EnumType = field2EnumType;
}
/**
* Get the value of field1
*
* #return the value of field1
*/
public String getField1() {
return field1;
}
/**
* Set the value of field1
*
* #param field1 new value of field1
*/
public void setField1(String field1) {
this.field1= field1;
}
}
CSV file:
abc;john
I always end up with the error:
Exception in thread "main" org.milyn.SmooksException: Failed to filter source.
at org.milyn.delivery.sax.SmooksSAXFilter.doFilter(SmooksSAXFilter.java:97)
at org.milyn.delivery.sax.SmooksSAXFilter.doFilter(SmooksSAXFilter.java:64)
at org.milyn.Smooks._filter(Smooks.java:526)
at org.milyn.Smooks.filterSource(Smooks.java:482)
..........
Caused by: org.milyn.javabean.DataDecodeException: Failed to decode binding value 'John' for property 'field2EnumType' on bean 'fewijf-3243-fijewoi'
at org.milyn.javabean.BeanInstancePopulator.decodeDataString(BeanInstancePopulator.java:624)
at org.milyn.javabean.BeanInstancePopulator.decodeAndSetPropertyValue(BeanInstancePopulator.java:513)
at org.milyn.javabean.BeanInstancePopulator.bindSaxDataValue(BeanInstancePopulator.java:449)
at org.milyn.javabean.BeanInstancePopulator.visitAfter(BeanInstancePopulator.java:379)
at org.milyn.delivery.sax.SAXHandler.visitAfter(SAXHandler.java:389)
at org.milyn.delivery.sax.SAXHandler.endElement(SAXHandler.java:204)
at org.milyn.delivery.SmooksContentHandler.endElement(SmooksContentHandler.java:96)
at org.milyn.flatfile.FlatFileReader.parse(FlatFileReader.java:165)
at org.milyn.delivery.sax.SAXParser.parse(SAXParser.java:76)
at org.milyn.delivery.sax.SmooksSAXFilter.doFilter(SmooksSAXFilter.java:86)
... 5 more
Thanks!
In your csv data "john" is lowercase, but your smooks config decodeParam for "JOHN" is tied to "John" capitalized.
Your smocks-config for the Enum should be something like this:
<jb:value property="field2EnumType"
data="header/field2EnumType"
decoder="Enum">
<jb:decodeParam name="enumType">com.myApp.SomeEnumTypeClass</jb:decodeParam>
<jb:decodeParam name="john">JOHN</jb:decodeParam>
<jb:decodeParam name="jack">JACK</jb:decodeParam>
</jb:value>
Notice the name attribute of the decodeParam. It needs to exactly match the data you are decoding (case sensitive).

Handling checked exceptions for eclipse plugin

I am working on an Eclipse plugin and am faced with checked exceptions thrown from the API that I am using in my plugin. What is the practice around handling such exceptions in the context of a plugin? I could not find an appropriate Exception subclass from the Plugin development API.
Thanks in advance.
I use logging classes that I found in a book titled "Eclipse Plug-ins", by Eric Clayberg and Dan Rubel.
Here's the main logging class.
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
public class EclipseLogging {
public static void logInfo(Plugin plugin, String pluginID, String message,
boolean display) {
log(plugin, pluginID, IStatus.INFO, IStatus.OK, message, null, display);
}
public static void logInfo(Plugin plugin, String pluginID,
Throwable exception) {
log(plugin, createStatus(pluginID, IStatus.ERROR, IStatus.OK,
"Unexpected Exception", exception));
}
public static void logInfo(Plugin plugin, String pluginID, String message,
Throwable exception) {
log(plugin, createStatus(pluginID, IStatus.ERROR, IStatus.OK, message,
exception));
}
public static void logError(Plugin plugin, String pluginID,
Throwable exception) {
logError(plugin, pluginID, "Unexpected Exception", exception);
}
public static void logError(Plugin plugin, String pluginID, String message,
Throwable exception) {
log(plugin, pluginID, IStatus.ERROR, IStatus.OK, message, exception,
true);
}
public static void log(Plugin plugin, String pluginID, int severity,
int code, String message, Throwable exception, boolean display) {
if (display) {
ExceptionAction action = new ExceptionAction(plugin, message,
exception);
action.run();
}
log(plugin, createStatus(pluginID, severity, code, message, exception));
}
public static IStatus createStatus(String pluginID, int severity, int code,
String message, Throwable exception) {
return new Status(severity, pluginID, code, message, exception);
}
public static void log(Plugin plugin, IStatus status) {
plugin.getLog().log(status);
}
}
And here's the exception action class.
import org.eclipse.core.runtime.Plugin;
import org.eclipse.jface.action.Action;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
public class ExceptionAction extends Action {
private Plugin plugin;
private String message;
private Throwable exception;
public ExceptionAction(Plugin plugin, String message, Throwable exception) {
this.plugin = plugin;
this.message = message;
this.exception = exception;
}
public void run() {
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
if (window != null) {
Shell parentShell = window.getShell();
parentShell.forceActive();
try {
ExceptionDetailsDialog dialog = new ExceptionDetailsDialog(
parentShell, null, null, message, exception, plugin);
dialog.open();
} catch (SWTException e) {
}
}
}
}
And finally, the classes to display the exception.
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.SameShellProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
/**
* An abstract dialog with a details section that can be shown or hidden by the
* user. Subclasses are responsible for providing the content of the details
* section.
*/
public abstract class AbstractDetailsDialog extends Dialog {
private final String title;
private final String message;
private final Image image;
private Button detailsButton;
private Control detailsArea;
private Point cachedWindowSize;
/**
* Construct a new instance with the specified elements. Note that the
* window will have no visual representation (no widgets) until it is told
* to open. By default, <code>open</code> blocks for dialogs.
*
* #param parentShell
* the parent shell, or <code>null</code> to create a top-level
* shell
* #param title
* the title for the dialog or <code>null</code> for none
* #param image
* the image to be displayed
* #param message
* the message to be displayed
*/
public AbstractDetailsDialog(Shell parentShell, String title, Image image,
String message) {
this(new SameShellProvider(parentShell), title, image, message);
}
/**
* Construct a new instance with the specified elements. Note that the
* window will have no visual representation (no widgets) until it is told
* to open. By default, <code>open</code> blocks for dialogs.
*
* #param parentShell
* the parent shell provider (not <code>null</code>)
* #param title
* the title for the dialog or <code>null</code> for none
* #param image
* the image to be displayed
* #param message
* the message to be displayed
*/
public AbstractDetailsDialog(IShellProvider parentShell, String title,
Image image, String message) {
super(parentShell);
this.title = title;
this.image = image;
this.message = message;
setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL);
}
/**
* Configures the given shell in preparation for opening this window in it.
* In our case, we set the title if one was provided.
*/
protected void configureShell(Shell shell) {
super.configureShell(shell);
if (title != null)
shell.setText(title);
}
/**
* Creates and returns the contents of the upper part of this dialog (above
* the button bar). This includes an image, if specified, and a message.
*
* #param parent
* the parent composite to contain the dialog area
* #return the dialog area control
*/
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
if (image != null) {
((GridLayout) composite.getLayout()).numColumns = 2;
Label label = new Label(composite, 0);
image.setBackground(label.getBackground());
label.setImage(image);
label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER
| GridData.VERTICAL_ALIGN_BEGINNING));
}
Label label = new Label(composite, SWT.WRAP);
if (message != null)
label.setText(message);
GridData data = new GridData(GridData.FILL_HORIZONTAL
| GridData.VERTICAL_ALIGN_CENTER);
data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
label.setLayoutData(data);
label.setFont(parent.getFont());
return composite;
}
/**
* Adds OK and Details buttons to this dialog's button bar.
*
* #param parent
* the button bar composite
*/
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
false);
detailsButton = createButton(parent, IDialogConstants.DETAILS_ID,
IDialogConstants.SHOW_DETAILS_LABEL, false);
}
/**
* The buttonPressed() method is called when either the OK or Details
* buttons is pressed. We override this method to alternately show or hide
* the details area if the Details button is pressed.
*/
protected void buttonPressed(int id) {
if (id == IDialogConstants.DETAILS_ID)
toggleDetailsArea();
else
super.buttonPressed(id);
}
/**
* Toggles the unfolding of the details area. This is triggered by the user
* pressing the Details button.
*/
protected void toggleDetailsArea() {
Point oldWindowSize = getShell().getSize();
Point newWindowSize = cachedWindowSize;
cachedWindowSize = oldWindowSize;
// Show the details area.
if (detailsArea == null) {
detailsArea = createDetailsArea((Composite) getContents());
detailsButton.setText(IDialogConstants.HIDE_DETAILS_LABEL);
}
// Hide the details area.
else {
detailsArea.dispose();
detailsArea = null;
detailsButton.setText(IDialogConstants.SHOW_DETAILS_LABEL);
}
/*
* Must be sure to call getContents().computeSize(SWT.DEFAULT,
* SWT.DEFAULT) before calling getShell().setSize(newWindowSize) since
* controls have been added or removed.
*/
// Compute the new window size.
Point oldSize = getContents().getSize();
Point newSize = getContents().computeSize(SWT.DEFAULT, SWT.DEFAULT);
if (newWindowSize == null)
newWindowSize = new Point(oldWindowSize.x, oldWindowSize.y
+ (newSize.y - oldSize.y));
// Crop new window size to screen.
Point windowLoc = getShell().getLocation();
Rectangle screenArea = getContents().getDisplay().getClientArea();
final int pos = screenArea.height - (windowLoc.y - screenArea.y);
if (newWindowSize.y > pos)
newWindowSize.y = pos;
getShell().setSize(newWindowSize);
((Composite) getContents()).layout();
}
/**
* subclasses must implement createDetailsArea to provide content for the
* area of the dialog made visible when the Details button is clicked.
*
* #param parent
* the details area parent
* #return the details area
*/
protected abstract Control createDetailsArea(Composite parent);
}
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.text.MessageFormat;
import java.util.Dictionary;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.SameShellProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
/**
* A dialog to display one or more errors to the user, as contained in an
* <code>IStatus</code> object along with the plug-in identifier, name, version
* and provider. If an error contains additional detailed information then a
* Details button is automatically supplied, which shows or hides an error
* details viewer when pressed by the user.
*
* #see org.eclipse.core.runtime.IStatus
*/
public class ExceptionDetailsDialog extends AbstractDetailsDialog {
/**
* The details to be shown ({#link Exception}, {#link IStatus}, or
* <code>null</code> if no details).
*/
private final Object details;
/**
* The plugin triggering this details dialog and whose information is to be
* shown in the details area or <code>null</code> if no plugin details
* should be shown.
*/
private final Plugin plugin;
/**
* Construct a new instance with the specified elements. Note that the
* window will have no visual representation (no widgets) until it is told
* to open. By default, <code>open</code> blocks for dialogs.
*
* #param parentShell
* the parent shell, or <code>null</code> to create a top-level
* shell
* #param title
* the title for the dialog or <code>null</code> for none
* #param image
* the image to be displayed
* #param message
* the message to be displayed
* #param details
* an object whose content is to be displayed in the details
* area, or <code>null</code> for none
* #param plugin
* The plugin triggering this deatils dialog and whose
* information is to be shown in the details area or
* <code>null</code> if no plugin details should be shown.
*/
public ExceptionDetailsDialog(Shell parentShell, String title, Image image,
String message, Object details, Plugin plugin) {
this(new SameShellProvider(parentShell), title, image, message,
details, plugin);
}
/**
* Construct a new instance with the specified elements. Note that the
* window will have no visual representation (no widgets) until it is told
* to open. By default, <code>open</code> blocks for dialogs.
*
* #param parentShell
* the parent shell provider (not <code>null</code>)
* #param title
* the title for the dialog or <code>null</code> for none
* #param image
* the image to be displayed
* #param message
* the message to be displayed
* #param details
* an object whose content is to be displayed in the details
* area, or <code>null</code> for none
* #param plugin
* The plugin triggering this deatils dialog and whose
* information is to be shown in the details area or
* <code>null</code> if no plugin details should be shown.
*/
public ExceptionDetailsDialog(IShellProvider parentShell, String title,
Image image, String message, Object details, Plugin plugin) {
super(parentShell, getTitle(title, details), getImage(image, details),
getMessage(message, details));
this.details = details;
this.plugin = plugin;
}
/**
* Build content for the area of the dialog made visible when the Details
* button is clicked.
*
* #param parent
* the details area parent
* #return the details area
*/
protected Control createDetailsArea(Composite parent) {
// Create the details area.
Composite panel = new Composite(parent, SWT.NONE);
panel.setLayoutData(new GridData(GridData.FILL_BOTH));
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
panel.setLayout(layout);
// Create the details content.
createProductInfoArea(panel);
createDetailsViewer(panel);
return panel;
}
/**
* Create fields displaying the plugin information such as name, identifer,
* version and vendor. Do nothing if the plugin is not specified.
*
* #param parent
* the details area in which the fields are created
* #return the product info composite or <code>null</code> if no plugin
* specified.
*/
protected Composite createProductInfoArea(Composite parent) {
// If no plugin specified, then nothing to display here
if (plugin == null)
return null;
Composite composite = new Composite(parent, SWT.NULL);
composite.setLayoutData(new GridData());
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
composite.setLayout(layout);
Dictionary<?, ?> bundleHeaders = plugin.getBundle().getHeaders();
String pluginId = plugin.getBundle().getSymbolicName();
String pluginVendor = (String) bundleHeaders.get("Bundle-Vendor");
String pluginName = (String) bundleHeaders.get("Bundle-Name");
String pluginVersion = (String) bundleHeaders.get("Bundle-Version");
new Label(composite, SWT.NONE).setText("Provider:");
new Label(composite, SWT.NONE).setText(pluginVendor);
new Label(composite, SWT.NONE).setText("Plug-in Name:");
new Label(composite, SWT.NONE).setText(pluginName);
new Label(composite, SWT.NONE).setText("Plug-in ID:");
new Label(composite, SWT.NONE).setText(pluginId);
new Label(composite, SWT.NONE).setText("Version:");
new Label(composite, SWT.NONE).setText(pluginVersion);
return composite;
}
/**
* Create the details field based upon the details object. Do nothing if the
* details object is not specified.
*
* #param parent
* the details area in which the fields are created
* #return the details field
*/
protected Control createDetailsViewer(Composite parent) {
if (details == null)
return null;
Text text = new Text(parent, SWT.MULTI | SWT.READ_ONLY | SWT.BORDER
| SWT.H_SCROLL | SWT.V_SCROLL);
text.setLayoutData(new GridData(GridData.FILL_BOTH));
// Create the content.
StringWriter writer = new StringWriter(1000);
if (details instanceof Throwable)
appendException(new PrintWriter(writer), (Throwable) details);
else if (details instanceof IStatus)
appendStatus(new PrintWriter(writer), (IStatus) details, 0);
text.setText(writer.toString());
return text;
}
// /////////////////////////////////////////////////////////////////
//
// Utility methods for building content
//
// /////////////////////////////////////////////////////////////////
/**
* Answer the title based on the provided title and details object.
*/
public static String getTitle(String title, Object details) {
if (title != null)
return title;
if (details instanceof Throwable) {
Throwable e = (Throwable) details;
while (e instanceof InvocationTargetException)
e = ((InvocationTargetException) e).getTargetException();
String name = e.getClass().getName();
return name.substring(name.lastIndexOf('.') + 1);
}
return "Exception";
}
/**
* Answer the image based on the provided image and details object.
*/
public static Image getImage(Image image, Object details) {
if (image != null)
return image;
Display display = Display.getCurrent();
if (details instanceof IStatus) {
switch (((IStatus) details).getSeverity()) {
case IStatus.ERROR:
return display.getSystemImage(SWT.ICON_ERROR);
case IStatus.WARNING:
return display.getSystemImage(SWT.ICON_WARNING);
case IStatus.INFO:
return display.getSystemImage(SWT.ICON_INFORMATION);
case IStatus.OK:
return null;
}
}
return display.getSystemImage(SWT.ICON_ERROR);
}
/**
* Answer the message based on the provided message and details object.
*/
public static String getMessage(String message, Object details) {
if (details instanceof Throwable) {
Throwable e = (Throwable) details;
while (e instanceof InvocationTargetException)
e = ((InvocationTargetException) e).getTargetException();
if (message == null)
return e.toString();
return MessageFormat.format(message, new Object[] { e.toString() });
}
if (details instanceof IStatus) {
String statusMessage = ((IStatus) details).getMessage();
if (message == null)
return statusMessage;
return MessageFormat
.format(message, new Object[] { statusMessage });
}
if (message != null)
return message;
return "An Exception occurred.";
}
public static void appendException(PrintWriter writer, Throwable ex) {
if (ex instanceof CoreException) {
appendStatus(writer, ((CoreException) ex).getStatus(), 0);
writer.println();
}
appendStackTrace(writer, ex);
if (ex instanceof InvocationTargetException)
appendException(writer, ((InvocationTargetException) ex)
.getTargetException());
}
public static void appendStatus(PrintWriter writer, IStatus status,
int nesting) {
for (int i = 0; i < nesting; i++)
writer.print(" ");
writer.println(status.getMessage());
IStatus[] children = status.getChildren();
for (int i = 0; i < children.length; i++)
appendStatus(writer, children[i], nesting + 1);
}
public static void appendStackTrace(PrintWriter writer, Throwable ex) {
ex.printStackTrace(writer);
}
}