Get codechanges in Eclipse (live) - java

I am trying to listen on codechanges in eclipse using a plugin. In the Eclipse help-files I have found this listener:
IResourceChangeListener
But it seems to update when the file is saved, not when writing to it. Is there a posibility, to get these changes "live"?
EDIT: By code changes I mean, that you edit the content of a file in the eclipse editor. Basicly, waht I need is a Event caling, when you type something ;)
EDIT2: My code looks like this:
plugin.xml:
<extension
point="org.eclipse.core.resources.fileModificationValidator">
<fileModificationValidator
class="packages.in.project.MyFileModificationValidator">
</fileModificationValidator>
MyFileModificationValidator:
package packages.in.project;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.team.FileModificationValidationContext;
import org.eclipse.core.resources.team.FileModificationValidator;
import org.eclipse.core.runtime.IStatus;
public class MyFileModificationValidator extends FileModificationValidator {
#Override
public IStatus validateEdit(IFile[] files, FileModificationValidationContext context) {
System.out.println("Modified!");
return null;
}
#Override
public IStatus validateSave(IFile file) {
return null;
}
}

What is a "code change"?... because your use case is not very clear, providing you are not interested in the change of the physical resource (when it´s saved)
Is a "code change" any change in memory of the content of a source file? If so, the answer is NO. I could write a program to read a file do something with the content in memory and you wouldn´t notice if I don´t provide a mechanism to do so.
In resume, all depends of who is accessing and if they provide a mechanism to notify that they are a doing a "code change", whatever that means for you. For physical resource changes, you were right that Eclipse notifies it for you and the IResourceChangeListener interface is the correct one to use in order to be aware of those changes.

IResourceChangeListener is a good start. You can use this to detect changes to workspace resources.
You should also look into implementing FileModificationValidator. The file modification validator is a Team-related hook for pre-checking operations that modify the contents of files. You can implement both validateEdit and validateSave.

Got the Answer ;)
I used the IDocumentListener to
get changes in the Editor.
#Override
public void documentChanged(DocumentEvent event) {
//...
}

Related

Android Am I using multiple ClassLoader/PathClassLoaders?

I am having issues with ClassLoaders in Android. At least I think it has to do with ClassLoaders. So here is the issue... I have a project that utilizes a custom widget library, lets call it CustomDialogView. It is a subclass of an android View object. I have a dialog that I created that extends CustomDialogView... So its important to mention the structure of how views are created and setup within this process (and eventually the activity).
My project is an Android service that registers Views to another process via a ContentResolver. The other process then pulls this data and will create the views based off of the classes sent. So, the view is eventually created and inflated in this other process (in an activity). I know, that is confusing but that is the method that is used for our application. So, in the view code eventually I may need to show a dialog. They give me a standard Object and it uses reflection to call the show dialog method. So here is the code snippet:
private static void showTheDialog(Object mainActivity, CustomDialogView view, boolean isModal) {
try {
mainActivity.getClass().getMethod("showDialog", View.class, Boolean.TYPE).invoke(mainActivity, view, isModal);
} catch (Exception var4) {
Log.w(TAG, var4.getClass().getName(), var4);
}
}
So on their end, they have this method within that object of interest:
public void showDialog(View dialogView, boolean isModal)
So here is where the issue comes in. In the method mentioned above (showDialog). They try to cast the dialogView, into a CustomDialogView so:
CustomDialogView dialogContent = (CustomDialogView)dialogView;
I get a ClassCastException as a result. I confirmed that I am using the same version of library that implements the CustomDialogView between both projects. I print the class loaders when I call showTheDialog and I get:
dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.this.is.project.myproject-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.this.is.project.myproject-1, /vendor/lib, /system/lib]]]
I print out the class loader in the showDialog (in thier project) and I get:
dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.this.is.thier.project.thierproject-1.apk", zip file "/data/data/com.this.is.thier.project/code_cache/secondary-dexes/com.this.is.thier.project.thierproject-1.apk.classes2.zip", zip file "/data/data/com.this.is.thier.project/code_cache/secondary-dexes/com.this.is.thier.project.thierproject-1.apk.classes3.zip", zip file "/data/data/com.this.is.thier.project/code_cache/secondary-dexes/com.this.is.thier.project.thierproject-1.apk.classes4.zip", zip file "/data/data/com.this.is.thier.project/code_cache/secondary-dexes/com.this.is.thier.project.thierproject-1.apk.classes5.zip", zip file "/data/data/com.this.is.thier.project/code_cache/secondary-dexes/com.this.is.thier.project.thierproject-1.apk.classes6.zip"],nativeLibraryDirectories=[/data/app-lib/com.this.is.thier.project.thierproject-1, /vendor/lib, /system/lib]]]
So, we are using two different class loaders right? I have a hard time understanding this concept. Please let me know if you have any other questions if needed.
So, it appears that I am using multiple class loaders. As you may know, this can cause the class cast exception to occur. To solve, I can use reflection on the passed object. So here is a small snippit:
obj.getClass().getMethod("getterMethod").invoke(obj);
Above is the example of taking in the passed object (obj), using reflection to obtain its class then calling the method that I need. I hope this helps others. No class loader issues now. Thanks.

ReferenceContributor don't works for existing languages

I am trying to implements a new reference from an existing language, in case, PHP, but it even is catched from debugger. Seems that it just is not initialized.
My problem is the following: the Laravel Frameworks implements a concept called query scopes. With that, when I do a method call like $user->filterAge() it, on reality, calls from a definition declared as User::scopeFilterAge() (briefly).
What I want to do: I like that PhpStorm understand that the "filterAge" points to scopeFilterAge declaration (ctrl+click). Like it does when I do at $user, for instance:
What I tried: I tried to follow the plugin development doc about reference contribuitor. Then I updated my plugin.xml with a new extension. Note: my inspections or completion contribuitors on this same file works fine. My problem is justly with this reference contribuitor over an existing language.
My plugin.xml:
<extensions defaultExtensionNs="com.intellij">
<psi.referenceContributor language="PHP"
implementation="[...].ScopeReferenceContribuitor"/>
</extensions>
And the implementation of ScopeReferenceContribuitor.java:
public class ScopeReferenceContribuitor extends PsiReferenceContributor {
#Override
public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
// Breakpoint:
[...]
}
}
This breakpoint just don't works, never is called, nothing. Even if I force an error (like an NPE) it just don't works.
What I am forgiving?
This topic seems solve my problem, but I already tested, and for some reason it just don't call the debugger on breakpoint.
I too commited my code example.

Suppress console output of player commands

I'm making a bukkit plugin that allows players to lock chests with a password. To protect the players I would like to keep the password from the prying eyes of even the server operator.
I would like to hide the console text that is printed when a player uses a command. For instance, when a player types, /gamemode 1, the console prints out the command and who used it. Is there any way to stop this? Maybe intercept it and wipe it, or garble it?
So I looked around at those plugins, and they're much more complicated than what I need to do this simple thing, so I thought I would post my solution for anybody who stumbles upon this.
What you want to do is create a filter with the java.util.logging.Filter interface. In that you override the isLoggable() function. For my case, this is my exact object that I made.
import java.util.logging.Filter;
import java.util.logging.LogRecord;
public class CustomFilter implements Filter {
#Override
public boolean isLoggable(LogRecord record) {
if(record.getMessage().contains("issued server command: /login")) {
return false;
}
else {
return true;
}
}
}
Then the only other thing you have to do is add this filter to the server logger. The exact line I used is:
CustomFilter filter = new CustomFilter();
plugin.getServer().getLogger().setFilter(filter);
Where plugin is the instance of the plugin in the main class.
Hope this helps anybody who finds this.
There seems to be a couple plug-ins designed for doing this, but neither one is still maintained.
ConsoleFilter
BlockConsoleMessages
One of them may work for you, or you may be able to find the code in them that does what you want.

Cannot call method in red5 server from AS3 Flash CS6

Okay, this had been making me very mad. I've followed almost 8 tutorials all over the Internet and in the end, I got my Red5 server instance working. Good for me! But when I'm calling my Java methods in my Red5 apps from my AS3 apps, in the 'Console' window in Eclipse, I got this error :
[ERROR] [NioProcessor-1] org.red5.server.service.ServiceInvoker - Method getTheName with parameters [] not found in org.red5.core.Application#17e5fde
Here's my Application.java file.
package org.red5.core;
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.IScope;
import org.red5.server.api.service.ServiceUtils;
/**
* Sample application that uses the client manager.
*
* #author The Red5 Project (red5#osflash.org)
*/
public class Application extends ApplicationAdapter {
/** {#inheritDoc} */
#Override
public boolean connect(IConnection conn, IScope scope, Object[] params) {
return true;
}
/** {#inheritDoc} */
#Override
public void disconnect(IConnection conn, IScope scope) {
super.disconnect(conn, scope);
}
public String getTheName() { return "MyName!"; }
}
And here's my AS3 code. I just put this on the Timeline.
var nc:NetConnection = new NetConnection();
nc.connect("http://localhost/Mintium/RoomHere", "SomeUsernameHere");
nc.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
nc.objectEncoding = ObjectEncoding.AMF0;
function onNetStatus(e:NetStatusEvent):void
{
switch (e.info.code)
{
case "NetConnection.Connect.Success" :
trace("connected");
nc.call("getTheName", new Responder(getName_result, getName_error));
break;
}
}
function getName_result(res:Object):void { append("Name : " + res.toString()); }
function getName_error(res:Object):void { append(res.toString()); }
Its been a week I've been trying to figure it out and my dateline is next month. If this stuff is not solved, I'm gonna fail my assessment. Please help me with my problems. Thank you very much.
Sorry I did not see this 2 months ago, I could have helped you pass your assessment. Nevertheless, I think I can answer this question, having had a similar problem calling Red5 services.
The key to solving this problem is in those parts of Red5 that utilize the Spring Framework. In your project, there should be a file called red5-web.xml that resides in the Server project's WEB-INF folder. This file contains some Bean dependencies used by Red5's Spring components. This is not mentioned in the tutorials that I read, or even in most of the (rather sparse and distributed) red5 programming documentation.
What you have to do is add a bean entry for your method in that file. In your case, the entry should look like this:
<bean id="getTheName.service" class="org.red5.core.Application" />
Note my use of the name of your function, with ".service" appended. I do not understand why, but you need the ".service" appended in order for Red5 to find your function. You need to add a similar entry for every class whose functions you want to use as services.
Of course, I based everything I said above on the fact that you put the service into the Application class -- something which I never do. if you read the red5-web.xml file, you will see that there is already an entry for that class, because it is already injected through Spring as the class that acts as an "endpoint" for processing requests over the web. I do not know if using the Application class as an endpoint and a provider of services is a good idea (it violates "separation of concerns" in OOP and may cause problems with Spring).
What I usually do is add a separate class in the org.red5.core package (or any other package you might want) that acts to deliver the desired service, then put an entry into red5-web.xml that injects the class and its method. So, for your project, lets assume you have a class called NameProvider in the org.red5.core package:
public class NameProvider
{
public NameProvider() {}
public String getTheName() { return("MyName!"); }
}
then you add the following entry to your red5-web.xml file:
<bean id="getTheName.service" class="org.red5.core.NameProvider" />
That should make everything work.
I hope this helps you in the future, or anyone else having this problem. I just wish I'd seen this question sooner.

GWT app UI wont display

I have implemented a simple GWT app that uses 1 Place and 1 Activity (which I have implemented as a Presenter which extends an AbstractActivity and which contains a Composite "view" subclass). The 1 and only UI object in the view is a GWT-Bootstrap NavBar that I want presented at the very top of my "home page".
I'm running the app locally from inside Eclipse and am not getting any compiler or runtime errors. When I go to the URL that the Development Mode console points me to, I get a slight pause in the browser (I assume this is the browser "downloading" the JavaScript) and then I see a blank white screen (instead of my NavBar). The window title is correct (I set this in the module's HTML page) and when I view source I see the same HTML source, so I know that the app's JavaScript is getting to the browser properly. It's just not rendering the NavBar.
I have sprinkled System.out.println() statements throughout onModuleLoad(), my default ActivityManager, ActivityMapper, PlaceHistoryMapper, presenter and view Composite, and all these sysout statements print in the dev console; telling me that I have wired everything together correctly, and that at runtime when the PlaceHistoryHandler#handleCurrentHistory method is called (from inside onModuleLoad), I should be seeing my NavBar.
The only possibilities I can think of are:
I have configured gwt-bootstrap incorrectly; or
I'm not using UiBinder correctly
Something else is wrong with how I am using Activities and Places, or perhaps how I am attaching the UI to RootLayoutPanel inside onModuleLoad().
As for gwt-bootstrap:
I placed the JAR on my project's classpath (I know this because when I include a new UiField of type NavBar inside my widget/view, I don't get any compiler errors)
I added <inherits name="com.github.gwtbootstrap.Bootstrap"/> to my GWT module XML
So if there's anything else I have to configure, please let me know!
As for the UiBinder stuff, here's my widget/view:
public class WebRootDisplay extends BaseDisplay {
private static WebRootDisplayUiBinder uiBinder = GWT
.create(WebRootDisplayUiBinder.class);
interface WebRootDisplayUiBinder extends UiBinder<Widget, WebRootDisplay> {
}
#UiField
Navbar navBar;
public WebRootDisplay(EventBus eventBus) {
super(eventBus);
System.out.println("I get this printing to the console at runtime.");
initWidget(uiBinder.createAndBindUi(this));
System.out.println("...and this too!");
}
}
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:b="urn:import:com.github.gwtbootstrap.client.ui">
<g:HTMLPanel>
<b:Navbar ui:field="navBar">
<b:Nav>
<b:NavLink href="http://www.google.com">
Home
</b:NavLink>
</b:Nav>
</b:Navbar>
</g:HTMLPanel>
</ui:UiBinder>
One thing I noticed is that I've got my NavBar inside an HTMLPanel in the UiBinder XML. I did this because I used the Google-Eclipse plugin to generate a new UiBinder for me (which autogenerated both the Composite (which I then modified to extend BaseDisplay, which itself extends Composite) as well as the UiBinder snippet. I figured GWT wants me to put all the UI fields inside this HTMLPanel...(?)
If I'm missing anything here please let me know. I'm not instantiating the NavBar field because I believe that's what createAndBindUi does for me.
If both my gwt-bootstrap config and my use of UiBinder looks correct, then something else is obviously wrong and I will have to post more code. I just wanted to hold off on that initially before these first two items were ruled out. Thanks in advance!
Update
Here is onModuleLoad:
public void onModuleLoad() {
// Some homegrown DI stuff. I have verified that the injector works properly.
ApplicationScope appScope = new ApplicationScope();
setInjector(new ApplicationInjector(appScope,
InjectorProvider.newMasterProvider()));
// Add the sole composite child to the RootLayoutPanel.
// I have verified that injectWebRootDisplay returns a fully configured
// WebRootDisplay instance.
RootLayoutPanel.get().add(injector.injectWebRootDisplay());
historyHandler.register(placeController, eventBus, defaultPlace);
historyHandler.handleCurrentHistory();
}
Could you paste the onModuleLoad() part of your code please?
If you don't got any Exception and error message, I think you should check that you add the view properly to the RootPanel, or when you run the app you should check that the view is there in a div in the HTML and just unvisible or something similar.
The UiBinder part looks fine in a first look.
EDIT:
This onModuleLoad() doesn't said too much to me, but you could try something.
I always use the RootLayoutPanel.get() method in the following way:
RootLayoutPanel.get("someDivId").add(injector.injectWebRootDisplay());
So I always add a div or table to the placeholder HTML with a id, so you can refer to that div when you get the RootPanel. I'm not confident about this is necessary, but I saw this at the first time, and it's working properly.
If you have question or problem, please let me know. :)
Well, I've tried a local example looking exactly like yours code, and I think that problem is not in UI binder. The code you provided so far, is correct, so it most likely that the error is somewhere else.
The biggest suspect is the BaseDisplay class. As far as I can see, this class is not from GWT or gwt-bootstrap. You can really quickly check it, by changing WebRootDisplay class, so it extends classic GWT Composite class instead of BaseDisplay (and disabling all mvp stuff for while). If it works, you have a proof that the problem is caused by 'BaseDisplay'
Since I don't have the full code, I can only assume that WebRootDisplay is used also for displaying the views, and most likely the error is that when view is added to that class, previously added widget (in your case it is a NavBar which you add in constructor of WebRootDisplay) is removed. Most likely the problem should be in methods setWidget and initWidget
In my experience with GWT Activities and Places, a common culprit of a blank white page is failing to register the Place's Tokenizer with the PlaceHistoryMapper as so:
/**
* PlaceHistoryMapper interface is used to attach all places which the
* PlaceHistoryHandler should be aware of. This is done via the #WithTokenizers
* annotation or by extending PlaceHistoryMapperWithFactory and creating a
* separate TokenizerFactory.
*/
#WithTokenizers({
MyPlace.Tokenizer.class,
SomeOtherPlace.Tokenizer.class})
public interface AppPlaceHistoryMapper extends PlaceHistoryMapper {}
See https://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces#PlaceHistoryMapper
Another cause for a white page (particularly when using RootLayoutPanel.get() with a single place is failing to map the place correctly in the ActivityMapper:
/**
* AppActivityMapper associates each Place with its corresponding
* {#link Activity}
*
* #param clientFactory
* Factory to be passed to activities
*/
public class AppActivityMapper implements ActivityMapper {
private ClientFactory clientFactory;
public AppActivityMapper(ClientFactory clientFactory) {
super();
this.clientFactory = clientFactory;
}
#Override
public Activity getActivity(Place place) {
if (place instanceof MyPlace)
return new MyActivity((MyPlace) place, clientFactory);
else if (place instanceof SomeOtherPlace)
return new SomeOtherActivity((SomeOtherPlace) place, clientFactory);
return null; // If your return null with single place bound to RootLayoutPanel
// you may get a blank white page
}
}
See https://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces#ActivityMapper
Without a more complete code sample it is impossible to determine exactly what is happening, but the two causes outlined above are common oversights which may help anyone who comes across this thread.
Instead of System.println use GWT.log messages. Then open the Javascript console (of Firebug or Chrome) and see where your code ends up. GWT.log will print out in the browser console, so you can see what the compiled JS code does.
Also, if you compile with the Pretty mode, you'll see the generated Javascript code in the browser and be able to step through and see what is being called (or not).

Categories