How to hook into the internal Eclipse browser? - java

For my eclipse plugin I want to track every URL that is opened with the internal (and if possible also external) Eclipse browser.
So far I use
org.eclipse.swt.browser.Browser;
and
addLocationListener(...)
But I would prefer that it works also for the internal Eclipse browser. How can I achieve that?

One possible solution for the Eclipse Internal Browser would be to create an eclipse plugin that registers an IStartup extension. In your earlyStartup() method you would register an IPartListener on the workbenchPage. Then when the internal browser part is created, you will receive a callback with a reference to the WebBrowserEditor (or WebBrowserView). Since there is no direct API you will have to hack a bit and use reflection to grab the internal SWT Browser instance. Once you have that, you can add your location listener.
Sometimes during early startup there is no active Workbench window yet so you have to loop through all existing workbench windows (usually just one) and each of their workbench pages to add part listeners also.
Here is the snippet of code for the earlyStartup() routine. Note that I have omitted any cleanup of listeners during dispose for windows/pages so that still needs to be done.
//Add this code to an IStartup.earlyStartup() method
final IPartListener partListener = new IPartListener() {
#Override
public void partOpened(IWorkbenchPart part) {
if (part instanceof WebBrowserEditor)
{
WebBrowserEditor editor = (WebBrowserEditor) part;
try {
Field webBrowser = editor.getClass().getDeclaredField("webBrowser");
webBrowser.setAccessible(true);
BrowserViewer viewer = (BrowserViewer)webBrowser.get(editor);
Field browser = viewer.getClass().getDeclaredField("browser");
browser.setAccessible(true);
Browser swtBrowser = (Browser) browser.get(viewer);
swtBrowser.addLocationListener(new LocationListener() {
#Override
public void changed(LocationEvent event) {
System.out.println(event.location);
}
});
} catch (Exception e) {
}
}
else if (part instanceof WebBrowserView)
{
WebBrowserView view = (WebBrowserView) part;
try {
Field webBrowser = editor.getClass().getDeclaredField("viewer");
webBrowser.setAccessible(true);
BrowserViewer viewer = (BrowserViewer)webBrowser.get(view);
Field browser = viewer.getClass().getDeclaredField("browser");
browser.setAccessible(true);
Browser swtBrowser = (Browser) browser.get(viewer);
swtBrowser.addLocationListener(new LocationListener() {
#Override
public void changed(LocationEvent event) {
System.out.println(event.location);
}
});
} catch (Exception e) {
}
}
}
...
};
final IPageListener pageListener = new IPageListener() {
#Override
public void pageOpened(IWorkbenchPage page) {
page.addPartListener(partListener);
}
...
};
final IWindowListener windowListener = new IWindowListener() {
#Override
public void windowOpened(IWorkbenchWindow window) {
window.addPageListener(pageListener);
}
...
};
IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (activeWindow != null)
{
IWorkbenchPage activePage = activeWindow.getActivePage();
if (activePage != null)
{
activePage.addPartListener(partListener);
}
else
{
activeWindow.addPageListener(pageListener);
}
}
else
{
for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows())
{
for (IWorkbenchPage page : window.getPages()) {
page.addPartListener(partListener);
}
window.addPageListener(pageListener);
}
PlatformUI.getWorkbench().addWindowListener(windowListener);
}
One last detail about this code snippet is that it requires a dependency on the org.eclipse.ui.browser plugin to have access to the WebBrowserEditor class.

Related

How to programatically (java) prevent specific errors messages to be sent to Sentry

How to programatically (java) prevent specific errors messages to be sent to Sentry? I want, for example, do not send to Sentry errors with the word "any_example_word". It's important to know that filtering by error message is not enabled in the User Interface.
I'm using Sentry 1.7.23, but all examples I can find use latest version (4.*), which are tottaly different. They use classes and methods that do not exist in this old version.
I don't know if this is relevant, but my application runs over thorntail and it uses jdk 8.
Edit:
I'm trying to do this:
#WebListener
public class MyContextListener implements ServletContextListener {
private static SentryClient sentryClient = SentryClientFactory.sentryClient();
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
Sentry.init();
String testStrings = "ipsis litteris;some_error_message";
String[] messagesToIgnore = StringUtils.split(testStrings, ';');
sentryClient.addShouldSendEventCallback(new ShouldSendEventCallback() {
#Override
public boolean shouldSend(Event event) {
for (Map.Entry<String, SentryInterface> interfaceEntry : event.getSentryInterfaces().entrySet()) {
if (interfaceEntry.getValue() instanceof ExceptionInterface) {
ExceptionInterface i = (ExceptionInterface) interfaceEntry.getValue();
for (SentryException sentryException : i.getExceptions()) {
for (String msgToIgnore : messagesToIgnore) {
if (StringUtils.contains(sentryException.getExceptionMessage(), msgToIgnore)) {
return false;
}
}
}
}
}
return true;
}
});
Sentry.setStoredClient(sentryClient);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Question 1) Is this the correct place to initialize Sentry?
Question 2) Why ShouldSendEventCallback is lost? Looking at
io.sentry.SentryClient:
public void sendEvent(Event event) {
for (ShouldSendEventCallback shouldSendEventCallback : shouldSendEventCallbacks) {
if (!shouldSendEventCallback.shouldSend(event)) {
logger.trace("Not sending Event because of ShouldSendEventCallback: {}", shouldSendEventCallback);
return;
}
}
try {
connection.send(event);
} catch (LockedDownException | TooManyRequestsException e) {
logger.debug("Dropping an Event due to lockdown: " + event);
} catch (Exception e) {
logger.error("An exception occurred while sending the event to Sentry.", e);
} finally {
getContext().setLastEventId(event.getId());
}
}
In some point during app execution, sentryClient is reinitialized and shouldSendEventCallbacks becomes empty, what causes my messages not being filtered.
So I get back to question 1, since apparently sentry configuration is not being persistent.

Wicket, modify HTML <body> element

I want to modify the HTML body tag when I open a Wicket-Bootstrap Modal. What I'm trying to achieve is <body class="modal-open"> instead of <body>
Using Wicket 8 M8 , I have this code:
owsImportDialog = new MyModalBootstrapDialog("owsImportDialog"
, new CompoundPropertyModel<>(new BopOwsTO())) {
#Override
void importOws(AjaxRequestTarget target, IModel<BopOwsTO> owsModel) {
appendCloseDialogJavaScript(target);
BopOwsTO owsTo = owsModel.getObject();
try {
importOwsCapabilities(owsTo);
owsViewDialog.header(Model.of("OWS anzeigen"))
.setModel(Model.of(owsTo.getServiceId()));
owsViewDialog.appendShowDialogJavaScript(target);
}
catch (OwsCapsImportException e) {
String localizedMessage = e.getLocalizedMessage();
importAlert.setModelObject(localizedMessage);
importAlert.appendShowDialogJavaScript(target);
error(localizedMessage);
}
finally {
target.appendJavaScript("document.getElementsByTagName('body')[0]" +
".setAttribute('class', 'modal-open');");
// target.appendJavaScript("document.body.setAttribute('class', 'modal-open');");
// target.prependJavaScript("document.body.setAttribute('class', 'modal-open');");
// target.appendJavaScript("alert('Hallo');");
// owsViewDialog is a child of owsView WebMarkupContainer
target.add(owsView, feedback);
}
}
#Override
void saveOws(AjaxRequestTarget target, IModel<BopOwsTO> owsModel)
{ }
#Override
void cancel(AjaxRequestTarget target)
{ }
};
If the line target.appendJavaScript("alert('Hallo');"); is active I actually see the alert window.
I also tried this code in the page class:
#Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
PackageResourceReference resourceReference = new PackageResourceReference(
getClass(), "../css/BuiOwsPage.css");
CssReferenceHeaderItem cssRef = CssReferenceHeaderItem.forReference(resourceReference);
response.render(cssRef);
response.render(OnLoadHeaderItem
.forScript("document.body.setAttribute('class', 'modal-open');"));
}
But none of my attempts was succesful.
Update
The answer of #martin-g didn't solve the issue.
I'm quite sure that the problem is caused by the sequence of these statements:
{
appendCloseDialogJavaScript(target);
...
try {
owsViewDialog.appendShowDialogJavaScript(target);
....
}
catch { ... }
finally {
target.add(owsView, feedback);
}
}
When this modal is closed because of appendCloseDialogJavaScript() ,
the class modal-open is erased from the class attribute of the <body> .
Then owsViewDialog opens, but modal-open isn't inserted in class, no matter if I append the snippet jQuery(document.body).addClass('modal-open') or not. The missing modal-open means that the page can't be scrolled.
Since Wicket and Bootstrap are used then jQuery is also available. I would recommend you to use jQuery(document.body).addClass('modal-open').
There must be a reason why jQuery has both addClass() and attr()!

Update Eclipse E4 application using p2

I'm adding an update feature in my Eclipse E4 application. Herefor I used the source code and tutorial from Lars Vogel. When I test my application the provisioningJob is always null. It should only be null when it run into Eclipse. But when I try to update my exported application the provisioningJob is still null. What I'm doing wrong?
public class UpdateHandler {
private static final String REPOSITORY_LOC = System.getProperty("UpdateHandler.Repo",
"file:////updateServer/repository");
#Execute
public void execute(final IProvisioningAgent agent, final Shell shell, final UISynchronize sync,
final IWorkbench workbench) {
Job updateJob = new Job("Update Job") {
#Override
protected IStatus run(final IProgressMonitor monitor) {
return checkForUpdates(agent, shell, sync, workbench, monitor);
}
};
updateJob.schedule();
}
private IStatus checkForUpdates(final IProvisioningAgent agent, final Shell shell, final UISynchronize sync,
final IWorkbench workbench, IProgressMonitor monitor) {
// configure update operation
final ProvisioningSession session = new ProvisioningSession(agent);
final UpdateOperation operation = new UpdateOperation(session);
configureUpdate(operation);
// check for updates, this causes I/O
final IStatus status = operation.resolveModal(monitor);
// failed to find updates (inform user and exit)
if (status.getCode() == UpdateOperation.STATUS_NOTHING_TO_UPDATE) {
LogModule.log(LogLevel.INFO, "No updated has been found");
showMessage(shell, sync);
return Status.CANCEL_STATUS;
}
else
{
LogModule.log(LogLevel.INFO, "Updates are found");
}
// run installation
final ProvisioningJob provisioningJob = operation.getProvisioningJob(monitor);
// updates cannot run from within Eclipse IDE!!!
if (provisioningJob == null) {
System.err.println("Trying to update from the Eclipse IDE? This won't work!");
LogModule.log(LogLevel.WARNING, "Trying to update from the Eclipse IDE? This won't work!");
return Status.CANCEL_STATUS;
}
configureProvisioningJob(provisioningJob, shell, sync, workbench);
//provisioningJob.schedule();
provisioningJob.run(monitor);
return Status.OK_STATUS;
}
private void configureProvisioningJob(ProvisioningJob provisioningJob, final Shell shell, final UISynchronize sync,
final IWorkbench workbench) {
// register a job change listener to track
// installation progress and notify user upon success
provisioningJob.addJobChangeListener(new JobChangeAdapter() {
#Override
public void done(IJobChangeEvent event) {
//if (event.getResult().isOK()) {
sync.syncExec(new Runnable() {
#Override
public void run() {
LogModule.log(LogLevel.INFO, "Update ready to install");
boolean restart = MessageDialog.openQuestion(shell, "Updates installed, restart?",
"Updates have been installed. Do you want to restart?");
if (restart) {
workbench.restart();
}
}
});
// }
super.done(event);
}
});
}
private void showMessage(final Shell parent, final UISynchronize sync) {
sync.syncExec(new Runnable() {
#Override
public void run() {
MessageDialog.openWarning(parent, "No update",
"No updates for the current installation have been found.");
}
});
}
private UpdateOperation configureUpdate(final UpdateOperation operation) {
// create uri and check for validity
URI uri = null;
try {
uri = new URI(REPOSITORY_LOC);
} catch (final URISyntaxException e) {
System.err.println(e.getMessage());
LogModule.log(LogLevel.ERROR, e.getMessage());
return null;
}
// set location of artifact and metadata repo
operation.getProvisioningContext().setArtifactRepositories(new URI[] { uri });
operation.getProvisioningContext().setMetadataRepositories(new URI[] { uri });
return operation;
}
}
P2 uses internally a lot of services and those are not explicitly referenced as bundle dependencies. So you might miss those additional required services. Adding them via the "Add required ..." inside PDE launches is not working.
Make sure that your Launch or Product is really including all requirements.I would start with the content of org.eclipse.equinox.p2.sdk. This should definitely work. Afterwards you can try to strip the requirements down to org.eclipse.equinox.p2.core.feature or even less.

TimeoutException on telegram java client

i used the java telegram api to communicate with telegram core api in windows intellij idea
https://github.com/ex3ndr/telegram-api
But the app is facing Timeout error in line TLConfig config = api.doRpcCall(new TLRequestHelpGetConfig());Full source code:
AppInfo appinfo=new AppInfo(45687, "Myapp", "154", "587","en");
TLRequestAuthCheckPhone checkRequest = new TLRequestAuthCheckPhone("96521452365");
MyApiStorage state=new MyApiStorage();
TelegramApi api = new TelegramApi(state, appinfo, new ApiCallback()
{
public void onApiDies(TelegramApi api) {
// When auth key or user authorization dies
}
#Override
public void onUpdatesInvalidated(TelegramApi api) {
System.out.print("############################### onUpdatesInvalidated");
// When api engine expects that update sequence might be broken
}
#Override
public void onAuthCancelled(TelegramApi ta) {
System.out.print("############################### onAuthCancelled");
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void onUpdate(TLAbsUpdates updates) {
System.out.print("############################### onUpdate");
System.out.println("user Id ::::"+((TLUpdateShortMessage) updates).getFromId());
}
});
api.switchToDc(1);
TLConfig config = api.doRpcCall(new TLRequestHelpGetConfig());
System.out.print("############################### config" + config.getTestMode());
state.updateSettings(config);
api.doRpcCall(checkRequest, new RpcCallbackEx<TLCheckedPhone>() {
public void onConfirmed() {
System.out.print("############################### onConfirmed");
}
public void onResult(TLCheckedPhone result) {
boolean invited = result.getPhoneInvited();
boolean registered = result.getPhoneRegistered();
System.out.print("############################### onResult" + registered);
// TODO process response further
}
public void onError(int errorCode, String message) {
System.out.print("############################### onError" + message);
}
});
can someone help me
Your timeout might happen for several reasons:
1. You are using
api.doRpcCall(new TLRequestHelpGetConfig());
In the TelegramApi class this translates into
return this.doRpcCall(method, timeout, 0);
0 there stands for DC. If your DC is different you will timeout
2. There were suggestions in other places to use doRpcCallSide instead and it worked for some and not for others. The reason is it translates into
return this.doRpcCall(method, 15000, this.primaryDc, true);
where true stands authRequired.
3. If you want to do this without authorization then use api.doRpcCallNonAuth

How to send custom graph data to MCStats every hour?

I have been working on a plugin and have gotten some really interesting data with it, I am trying to add a custom graph and have succeeded on getting the graph to appear with the name I set in code on MCStats.
My plugin is here and recreates the Dense Ores Mod.
I would like to send block mined data on an hourly basis. This is what I have in my onEnable so far:
try {
Metrics metrics = new Metrics(this);
Graph blocksMinedGraph = metrics.createGraph("Extra items from blocks");
blocksMinedGraph.addPlotter(new Metrics.Plotter("Coal Ore") {
#Override
public int getValue() {
return coalMined;
}
});
blocksMinedGraph.addPlotter(new Metrics.Plotter("Iron Ore") {
#Override
public int getValue() {
return ironMined;
}
});
metrics.start();
} catch (IOException e) {
getLogger().info(ANSI_RED + "Metrics have been unable to load for: DenseOres" + ANSI_RESET);
}
This has successfully created a new graph on my MCStats page called 'Extra items from blocks' although I have been unable to populate it thus far. I have tried but cannot work out how to send the data.
Connected to this question, when sending the data, will I have to keep a count of the values in a file somewhere so they persist between reloads and server restarts?
I appear to have solved it by placing the blocksMinedGraph.addPlotter(...) parts in an async repeating task.
Here is the code with the repeating task in place, the graphs on MCStats take forever to update though.
try {
Metrics metrics = new Metrics(this);
if (!metrics.isOptOut()) {
final Graph blocksMinedGraph = metrics.createGraph("Extra items from blocks (Since v2.3)");
Bukkit.getScheduler().runTaskTimerAsynchronously(this, new Runnable() {
public void run() {
getLogger().info("Graph data sent");
blocksMinedGraph.addPlotter(new Metrics.Plotter("Coal Ore") {
#Override
public int getValue() {
return coalMined;
}
});
blocksMinedGraph.addPlotter(new Metrics.Plotter("Iron Ore") {
#Override
public int getValue() {
return ironMined;
}
});
}
}, DELAY, INCREMENT);
getLogger().info("Metrics started");
metrics.start();
}
} catch (IOException e) {
getLogger().info(ANSI_RED + "Metrics have been unable to load for: DenseOres" + ANSI_RESET);
}

Categories