How to compare files programmatically in eclipse? - eclipse

I am developing an eclipse plugin that runs code violation checker on the difference of two versions of a file. Right now I am using diff.exe to get the difference between the two files. But as diff.exe is an extrenal app, I realized that its better to use eclipse built-in compare tool to get the file difference.
So I used org.eclipse.compare and reached up to this point:
public static List<Patch> compare(String old, String recent) {
try{
IRangeComparator left = new TokenComparator(old); //what exactly to be passed in this constructor, a file path, a literal value or something else?
IRangeComparator right = new TokenComparator(recent);
RangeDifference[] diffs = RangeDifferencer.findDifferences(left, right); // This line is throwing NPE
//..
// Process RangeDifferences into Collection of Patch collection
//..
}catch(Exception e){}
//Returns a collection of file differences.
return null;
}
Now the problem is I am not sure what exactly to be passed in the constructor TokenComparator(String). The document says this constructor Creates a TokenComparator for the given string. But it is not written what exactly to be passed in this constructor, a file path, a literal value or something else? When I'm passing a file path or a string literal I am getting NullPointerException on the next line of finding differences.
java.lang.NullPointerException
at org.eclipse.compare.internal.core.LCS.isCappingDisabled(LCS.java:98)
at org.eclipse.compare.internal.core.LCS.longestCommonSubsequence(LCS.java:55)
at org.eclipse.compare.rangedifferencer.RangeComparatorLCS.longestCommonSubsequence(RangeComparatorLCS.java:186)
at org.eclipse.compare.rangedifferencer.RangeComparatorLCS.findDifferences(RangeComparatorLCS.java:31)
at org.eclipse.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java:98)
at org.eclipse.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java:82)
at org.eclipse.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java:67)
at com.dassault_systemes.eclipseplugin.codemonview.util.CodeMonDiff.compare(CodeMonDiff.java:48)
at com.dassault_systemes.eclipseplugin.codemonview.util.CodeMonDiff.main(CodeMonDiff.java:56)
Someone please tell what is right way to proceed.

If the question is What value the token comparators constructor takes then the answer is it takes the input string to compare. Specified in javadoc here http://help.eclipse.org/indigo/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fcompare%2Fcontentmergeviewer%2FTokenComparator.html
TokenComparator(String text)
Creates a TokenComparator for the given string.
And the null pointer yo are getting is because in function isCappingDisabled it tries to open the compare plugin which seems to be null. You seem to be missing a direct dependency to the plugin "org.eclipse.compare.core"

The org.eclipse.compare plugin was never meant to be used in standalone : many of its functionalities require a running instance of Eclipse. Furthermore, it mixes core and UI code within the same plugin, which will lead to unexpected behavior if you are not very careful about what you use and what dependencies are actually available in your environment.
You mentionned that you were developping an Eclipse plugin. However, the NPE you get indicates that you are not running your code as an Eclipse plugin, but rather as a standard Java program. In an Eclipse environment, ComparePlugin.getDefault() cannot return null : the plugin needs to be started for that call to return anything but null.... and the mere loading of the ComparePlugin class within Eclipse is enough to start it.
The answer will be a choice :
You need your code to run as a standalone Java program out of Eclipse. In such an event, you cannot use org.eclipse.compare and diff.exe is probably your best choice (or you could switch to an implementation of diff that was implemented in Java in order to be independent of the platform).
You do not need your program to work in a standalone environment, only as an Eclipse plugin. In this case, you can keep the code you're using. However, when you run your code, you have to launch it as a new "Eclipse application" instead of "Java Application". You might want to look at a tutorial on how to develop Eclipse plugins for this, This simple tutorial from Lars Vogel shows how to run a new Eclipse Application to test an Hello World plugin. You will need a similar code, with a menu entry to launch your plugin somewhere (right-click on a file then select "check violations" in your case?).

Related

How can I use JDT compiler programmatically?

I use JDT to compile my java classes. BatchCompiler returns a string but I need an array of problems/errors with their column and row information. compiler.compile(units); prints the error to its printwriter, compiler.resolve(unit) does exactly what I want but it can compile only one java file.
I created a compiler object in this way:
Compiler compiler = new Compiler(env, DefaultErrorHandlingPolicies.exitAfterAllProblems(), new CompilerOptions(), requestor, new DefaultProblemFactory());
And create CompilationUnits that contains filenames and file contents to the compiler.
CompilationUnit[] units = project.toCompilationUnit();
AFAIK, there are 2 ways to compile, one of them is compile(units) method that returns void and prints errors and problems to its PrintWriter, because it doesn't return column information it's not useful for me. The other way is resolve(unit) method but it can work with only one CompilationUnit.
compiler.resolve(units[index], true, true, true);
Does anyone know how I can use JDT compiler programmatically to compile multiple files?
org.eclipse.jdt.internal.compiler.Compiler is internal API. According to the JavaDoc of its resolve method: Internal API used to resolve a given compilation unit. Can run a subset of the compilation process.
Instead, the official way of compiling Java files and determining the compilation problems is described here. Basically, you create a Java project and invoke Eclipse's builder on it, then query the project's Java problem markers.

Eclipse is not showing method parameters properly

In my eclipse, when i check for method help with ctrl+space i see the method parameters are showing like strings, int as arguments. Not showing like, string name/int id .
getAttribute(String arg0)
How can i make the eclipse to show the method as getAttribute(String name)
This is really difficult to me identify which param i should pass fro a method.
Any idea, where should i set the settings?
This problem happens when eclipse can't find the source or attached Javadoc, since java argument names are usually not present in the .class files (it would only be present in debug, and not for the interfaces).
You can check if a source or a documentation is attached using the helper F3.
You can increase the timeout eclipse uses for fetching a parameter name from attached Javadoc in the settings.
You can also attach the corresponding documentation jar or source jar as a dependency in order to allow eclipse to look-up the corresponding source.

Gwt i18n > generating properties files

I'm using GWT in my stuff, and I would like to make it,
international, so I use GWT constants method.
I have a java file with defaults, and I now need to make properties files.
In a remember, there is a special thing to do (or done automagically) to generate
a kind of template where all constants are generated with empty labels for other langages.
Did I dream this ?
(using eclipse indigo to develop webapp with gwt but not gae)
[edit:]
this was not a dream, it's i18ncreator:
http://code.google.com/intl/fr-FR/webtoolkit/doc/latest/RefCommandLineTools.html#i18nCreator
but I can't make it working on windows :-(
[edit again ]
due to this issue : http://code.google.com/p/google-web-toolkit/issues/detail?id=5113
recommended solution is use i18ncreator in gwt 1.7 (!)
you should see the page on locales in GWT
I had the same issue. I was looking all over the place for the answer but could not find an answer; either in the docs or on stackoverflow.
So I asked in the GWT gitter channel and was told to use the compiler argument
-extra <destination-folder-name>
to generate the .properties files from the Interface files.
Steps in eclipse:
Select project you want to compile
[right click] -> Google -> GWT Compile
In the window that opens, open the Advanded options.
Add the following additional compiler argument -extra <destination-folder-name>
Compile
This should generate the *.properties files in the /destination-folder-name.
NOTE: This only generates the .properties files. It does not actually compile the application with all the locales for deploy.
Move the MyInterfaceExtension_*.properties to be right beside the MyInterfaceExtension.java file.
Make copies for each locale i.e. MyInterfaceExtension_fr_CA.properties, MyInterfaceExtension_fr_FR.properties, etc..
Translate them
Then run the compilation process again with out the -extra <destination-folder-name> option. Because it is not needed anymore.
This will compile with all the locales you enabled. You can now deploy the app the usual way.
Quick Tips:
When compiling for the first time in order to generate the .properties file, I commented out the locales in the module definition file so that the compiler will not sit there and compile again and again for every browser and every locale
i.e. supported_browser_count x enabled_locale_count = 5 browsers x 3 locales = 15 compilation Permutations, which is going to increase your compilation time.
Because, all I needed was that one *_en.properties file.
For the second compilation, after you copied and translated the properties files for each locale, you have to enable all the locales you want to support and compile.
Credits:
github #niloc132 : Colin Alworth
github #ibaca : Ignacio Baca Moreno-Torres
For helping me with this.
For my project, I used the i18n-Creator
http://code.google.com/webtoolkit/doc/latest/DevGuideI18n.html#DevGuidePropertiesFiles
It kind of does the opposite of what you are asking for. With the i18n-creator, you create the properties files for the various locales and run the script that is generated with the i18n-creator, and it will generate the constants interface.
I haven't heard yet of this feature in Eclipse but IntelliJ IDEA has this feature, you just create the Constants Interface class and the properties file. If you add a method in the class file it will warn you to add the property or the other way around. HTH.

Why am I getting NullPointerException in the CompilationUnit instances returned from ASTParser.createASTs()

I am working on an Eclipse JDT plugin that requires parsing large numbers of source files,
so I am hoping to use the batch method ASTParser.createASTs(). The parsing executes without errors, but within the CompilationUnit instances it produces, many of the org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding instances have had their scope field set to null. This setting to null is occurring in the CompilationUnitDeclaration.cleanUp() methods, which are invoked on a worker thread that is unrelated to my plugin's code (i.e., my plugin's classes do not appear on the cleanUp() method call stack).
My parsing code looks like this (all rawSources are within the same project):
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setResolveBindings(true);
parser.setStatementsRecovery(true);
parser.setBindingsRecovery(true);
parser.setIgnoreMethodBodies(false);
parser.setProject(project);
parser.createASTs(rawSources.values().toArray(new ICompilationUnit[0]), new String[0], this, deltaAnalyzer.progressMonitor);
Alternatively, I can execute the parsing this way, and no such problems occur:
for (ICompilationUnit source : rawSources.values())
{
parser.setResolveBindings(true);
parser.setStatementsRecovery(true);
parser.setBindingsRecovery(true);
parser.setIgnoreMethodBodies(false);
parser.setProject(project);
parser.setSource(source);
CompilationUnit ast = (CompilationUnit)parser.createAST(deltaAnalyzer.progressMonitor);
parsedSources.add(deltaAnalyzer.createParsedSource(source, ast));
}
This issue occurs in both Helios and Indigo (the very latest release build). I filed a bug in Eclipse Bugzilla, but if anyone knows of a way to work around this--or if I am using the API wrong--I would greatly appreciate your help.
Byron
Without knowing exactly what your exception is, I can still offer 2 suggestions:
Have a look at org.eclipse.jdt.ui.SharedASTProvider. If you are not making any changes to ASTs, this class may provide a more robust way of getting the ASTs.
Play around with some of the settings that you are using. Do you really need bindingsRecovery set to true? What about statementRecovery? Setting these to false may help you.

Why eclipse is generating argument names as arg0,arg1,arg2.... for methods?

When I try to access some class's method; eclipse gets that method but arguments inside that method are replaced by arg0, arg1, arg2...
Example:-
Suppose I have this method in some class named ReadFile.java
#Override
public int readXXX(int start, int end, String xxx) throws IOException {
return 0;
}
When I try to access that method from an instance of class it shows me as follows:
readFile.readXXX(arg0, arg1, arg2);
It becomes hard to identify what I should pass in argument. The same thing also happens for java methods. i.e. when I implement interface all method under that will be generated but arguments in that methods are arg0, arg1.....
Is there any setting I can do prevent this?
I'm using Eclipse Galelio.
Eclipse can't work out the arguments because it can't find the source or javadoc attachments.
Make sure your source is attached.
To check, click on the method call readXXX and press F3 which should open the method declaration. If the source is not attached, Eclipse will say "Source not found" and will allow you to "Attach Source...".
Anyone having the same issue, try performing a Project > Clean, this will delete the old class files, and Eclipse will recompile them in debug mode this time. Worked for me in Indigo 3.7.2
The problem is that your class files lacks debug information embedded in them. JDT doesn't reparse the source files or the javadoc for dependencies, when building the AST for your project, so it doesn't have idea what the name of the parameter is, even when you are able to open the class and clearly see what are the method names.
In order to correct this, you need to recompile your class files with debug information enabled, which makes the class file considerably larger, but unless you are developing for memory-constraint devices, you should be fine.
for those like me who tried to apply one of our colleagues suggestions and unfortunately hasn't worked, please, give a try to check the option "Add variable attributes to generated class files (used by the debugger)" within Window -> Preferences -> Java + Compiler.
Once you've done that, try to build the project again.
Cheers.
I solved this by going to preferences
Java / Content Assist
On this page under "Sorting and Filtering" I unchecked "Hide proposals not visible in the invocation context" now instead of seeing (arg0, arg1, arg2) etc in autocomplete I see (catalog, schemaPattern, tableNamePattern...)
I am using Spring Tools Suite 3.7.2 which runs on the Eclipse Mars 4.5.1 platform.
This link helped me to solve this problem.
1) Right click on your android.jar and select Properties.
2) Select Java Source Attachment. Enter the source directory location (you can also use External Folder… to browse to the directory) and click on “Apply“.
The code names match the following version numbers, along with API levels and NDK releases provided for convenience: