Get the current source code of an Eclipse editor? - java

I am working with Eclipse IDE. I want to develop a plug-in first of all, this plug-in allows me to get the whole source code as a simple string.
I made a simple "hello the world" plug-in using the template "hello world command". Now I am searching to get the source code from the editor of Eclipse and display it with System.out.println(); statement instead of showing HELLO THE WORLD.
I tried this but it shows me only the hierarchical sequence of my project, packageName/src/nameOfClass.
System.out.println(
Workbench.getInstance().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getEditorInput()
);
My goal is to get the source code of the class itself (public class nameOfClass{ *** }).

First do not use Workbench this is an internal class and must not be used. Use PlatformUI to get the workbench.
IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
if (editor instanceof ITextEditor)
{
ITextEditor textEditor = (ITextEditor)editor;
IDocumentProvider provider = textEditor.getDocumentProvider();
IEditorInput input = editor.getEditorInput();
IDocument document = provider.getDocument(input);
String text = document.get();
...
}
Note: Not all editors are text editors so this needs to be checked (the ITextEditor instance check above).

Related

Get a list of all PsiFiles/VirtualFiles in opened project in IntelliJ

I am developing a plugin in IntelliJ in which I am trying to find all the comments throughout the whole project source code.
I am currently able to get only the comments in an opened or selected file, not in all the project files. This is done by the following code:
public void actionPerformed(AnActionEvent e) {
Editor editor = e.getData(PlatformDataKeys.EDITOR);
PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);
PsiElement element = psiFile.getFirstChild(); WORKS
for(PsiElement el : element.getParent().getChildren()){
for(PsiElement el2 : el.getChildren()){
if(el2 instanceof PsiComment){
This obviously only gives me the PsiFile corresponding to the opened file in the editor.
I found out that I could find a list of VirtualFiles from which I would be able to extract PsiElements, however, using:
VirtualFile[] vFiles = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
also gives me only the selected files and not all the project files.
I am new to PsiElements and VirtualFiles and therefore might even be misunderstanding their usage. If however, my previously listed code is close, is there a way I could get all the PsiFiles/VirtualFiles of the project?
Thanks to Peter's comment I have tried the following block of code:
ProjectFileIndex.SERVICE.getInstance(e.getProject()).iterateContent(new ContentIterator() {
#Override
public boolean processFile(VirtualFile fileInProject) {
System.out.println(fileInProject.getFileType());
PsiFile psiFile1 = PsiManager.getInstance(e.getProject()).findFile(fileInProject);
if (psiFile1 == null)
System.out.println("IT'S NULL!");
System.out.println(psiFile1.getText());
return true;
}
});
Which as an output gives me:
com.intellij.openapi.fileTypes.UnknownFileType#18cf8e97
IT'S NULL!
Meaning it's finding only one VirtualFile with unknown type.
You can use ProjectFileIndex.SERVICE.getInstance(project).iterateContent to iterate over all VirtualFiles. Then you can use PsiManager#findFile to get a PsiFile.

Eclipse - how to create on-class-created template

I watched the question about Eclipse -> Java -> Templates and how to create template to decrease code time development but I couldn't find how to:
generate template on Java class created
generate the template for some special Java classes which extend javax.swing.JPanel
for example how to generate code like :
public class AClass extends JPanel {
public AClass(){this.aMethod();}
private void aMethod(){}
}
...on Java class created?
EDIT :
I try to invoke template code generation on new java source file created (see image)
I tried to edit the preferences -> Java -> code templates constructor body (see image) but I am not sure how to insert method invoke into constructor body :(
I tried to input this.aMethod(); into the edit text area but this doesn't generate constructor body as : public AClass(){this.aMethod();}
for question A :
You can edit template through eclipse preferences :
Java code style > Code template
For question B :
You would have to create a custom new file wizard (a little overkill maybe...)
you can find a simple tutorial on vogella :
http://www.vogella.com/tutorials/EclipseWizards/article.html

Creating a new Java project

I am able to create a default project in PDE just like mentioned here.
However I want to know how to create a Java project. How can I do that?
As a minimum you need to add the Java project nature to the project you create. Use something like:
private void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException
{
IProjectDescription description = proj.getDescription();
String[] prevNatures = description.getNatureIds();
String[] newNatures = new String[prevNatures.length + 1];
System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
newNatures[prevNatures.length] = natureId;
description.setNatureIds(newNatures);
proj.setDescription(description, monitor);
}
The nature id for a Java project is 'org.eclipse.jdt.core.javanature' (also in the JavaCore.NATURE_ID constant).
Note that this does not add the various builders that are normally used in a Java project. The IProjectDescription.setBuildSpec method adds those in a similar way. Create a command for the build spec with:
ICommand command = description.newCommand();
command.setBuilderName(builderID);
where 'builderId' is 'org.eclipse.jdt.core.javabuilder' for the main Java builder (JavaCore.BUILDER_ID constant).
All this information is stored in the '.project' file in the project root folder. This is an XML file which you can look at to see the set up of existing projects.
Window->Open Perspective->Java
then
File->New->Java Project (you may have to go via "Project..." to get to the "Java Project" option)
Please refer to New Project Creation Wizards
On the Plug-in Project page, use com.example.helloworld as the name
for your project and check the box for Create a Java project (this
should be the default). Leave the other settings on the page with
their default settings and then click Next to accept the default
plug-in project structure.

How do I programmatically change the Eclipse CDT tool settings for a file?

I want to programmatically (from a plugin) change the "Other flags" field in the Miscellaneous settings in the Tool Settings tab for an individual file in a CDT managed build project. (See this Eclipse documentation page for a screenshot and brief description of how this change would be made using the UI.)
Note: I've updated this twice now as I approach a solution. But instead of adding an update onto the end (as I do for shorter questions), I'm revising the entire question. If it helps to see the breadcrumbs leading to where I am now, you can read the history.
The following code will result in settings written to the .cproject file (I'll go into detail on that below), but when I open the Properties dialog for the file, and click on C/C++ Build->Settings and then Miscellaneous, the changes do not appear in the "Other flags" field (as they do when I make changes using the dialog).
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow workbenchwindow = workbench.getActiveWorkbenchWindow();
IWorkbenchPage workbenchpage = workbenchwindow.getActivePage();
IEditorPart editorpart = workbenchpage.getActiveEditor();
IEditorInput editorinput = editorpart.getEditorInput();
IResource file = ((IFileEditorInput)editorinput).getFile();
IProject project = file.getProject();
IManagedBuildInfo buildInfo = ManagedBuildManager.getBuildInfo(project);
IConfiguration[] configurations = buildInfo.getManagedProject().getConfigurations();
IConfiguration conf = configurations[0];
IFileInfo fileInfo = conf.createFileInfo(file.getFullPath());
ITool[] tools = fileInfo.getTools();
ITool tool = tools[0];
IOption option = tool.getOptionById("my.gnu.compiler.misc.other");
String oldOptionValue = option.getDefaultValue().toString();
String newOptionValue = oldOptionValue + " -eg";
ManagedBuildManager.setOption(fileInfo, tool, option, newOptionValue);
ManagedBuildManager.saveBuildInfo(project, true);
I looked at the differences between the .cproject file where I changed the tool settings manually, and in a different .cproject file after running the above code. Below are the pertinent bits from each.
Here is the XML from the .cproject file where the tool settings were changed manually:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.company.product.toolchain.configuration.changed.1964078554">
...
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" cleanCommand="rm -f" description="" id="com.company.product.toolchain.configuration.changed.1964078554" name="changed" parent="com.company.product.toolchain.configuration.changed">
...
<fileInfo id="com.company.product.toolchain.configuration.changed.1964078554.915152327" name="code.cpp" rcbsApplicability="disable" resourcePath="src/code.cpp" toolsToInvoke="com.company.product.toolchain.compiler.1643348654.1411455203">
<tool id="com.company.product.toolchain.compiler.1643348654.1411455203" name="Company GNU compilers" superClass="com.company.product.toolchain.compiler.1643348654">
<option id="company.gnu.compiler.misc.other.789167779" name="Other flags" superClass="company.gnu.compiler.misc.other" value="-c -fmessage-length=0 -eg" valueType="string"/>
<inputType id="com.company.product.toolchain.cxxinputtype.877052163" name="C++ Input" superClass="com.company.product.toolchain.cxxinputtype"/>
<inputType id="com.company.product.toolchain.cinputtype.1390394900" name="C input" superClass="com.company.product.toolchain.cinputtype"/>
</tool>
</fileInfo>
...
And here is the XML from the .cproject file where they were changed programmatically:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.company.product.toolchain.configuration.changed.2057644715">
...
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" cleanCommand="rm -f" description="" id="com.company.product.toolchain.configuration.changed.2057644715" name="changed" parent="com.company.product.toolchain.configuration.changed">
...
<fileInfo id="com.company.product.toolchain.configuration.changed.2057644715./test3/src/code.cpp" name="code.cpp" rcbsApplicability="disable" resourcePath="test3/src/code.cpp" toolsToInvoke="com.company.product.toolchain.compiler.1482360042.1005761865">
<tool id="com.company.product.toolchain.compiler.1482360042.1005761865" name="Company GNU compilers" superClass="com.company.product.toolchain.compiler.1482360042">
<option id="company.gnu.compiler.misc.other.999025984" superClass="company.gnu.compiler.misc.other" value="-c -fmessage-length=0 -eg" valueType="string"/>
<inputType id="com.company.product.toolchain.cxxinputtype.1253686787" name="C++ Input" superClass="com.company.product.toolchain.cxxinputtype"/>
<inputType id="com.company.product.toolchain.cinputtype.1141524787" name="C input" superClass="com.company.product.toolchain.cinputtype"/>
</tool>
</fileInfo>
...
Aside from the numbers, which I assume are some kind of GUIDs, there are three differences:
For some reason, the id attribute of the fileInfo element in the programmatic changes contains the path to the file, including the project name: id="com.company.product.toolchain.configuration.changed.2057644715./test3/src/code.cpp"
The resourcePath attribute value of the fileInfo element contains the project name, only in the programmatic changes: resourcePath="test3/src/code.cpp".
The option element in the fileInfo element as a name attribute (name="Other flags") that matches the field in the dialog, only in the manual changes.
I'm guessing that one or all of these differences are preventing my programmatic changes from being "compatible" with the manual ones (so they show up in the dialog). I'm trying to figure out how to create the IFileInfo, IOption (and ITool?) objects without causing these differences. I'm trying to find how these objects are created for the dialog, but haven't yet.
Any suggestions appreciated.
Update: I got an answer from Doug Schaefer to my question on the cdt-dev mailing list. He suggested I "stick breakpoints in places and see how the UI does it." I wrote back:
I have been doing that. I set a breakpoint in org.eclipse.cdt.managedbuilder.core.ManagedBuildManager.setOption(IResourceInfo, IHoldsOptions, IOption, String) and it triggers when I open the Properties dialog for a file, expand "C/C++ Build", select "Settings", and then "Miscellaneous" in the Tool Settings tab. I can see the arguments, and presumably if I can call setOption with the same arguments I'll get the same results in the .cproject file. But I haven't been able to figure out how to do that. Do you have any suggestions for how I figure out where those objects are created so I can set breakpoints there?
Update #2: Vladimir's answer solved my problem. While I was more concerned with difference number 3 in the two .cproject file fragments above, the key was difference 2 and the inclusion of the project name in difference 1.
I changed the code to create the IFileInfo object to:
IFileInfo fileInfo = conf.createFileInfo(file.getProjectRelativePath());
...which resulted in the fileInfo element not having the project name:
<fileInfo id="com.company.product.toolchain.configuration.changed.838214286.src/code.cpp" name="code.cpp" rcbsApplicability="disable" resourcePath="src/code.cpp" toolsToInvoke="com.company.product.toolchain.compiler.2027651356.1970239371">
...and most importantly, resulted in the programmatic changes showing up in the "Other flags" field in the Miscellaneous settings in the Tool Settings tab for the individual file. (I guess the other differences in the .cproject files are not important.)
I suspect there might be problem in you IFileInfo creation. Here's the code that we use to obtain IResourceInfo for a translation unit to set per-file options:
protected IResourceInfo getResourceInfo(ITranslationUnit translationUnit, ICProjectDescription prjDescription) {
ICProject cProject = translationUnit.getCProject();
if (cProject != null) {
ICConfigurationDescription cfgDescription = prjDescription.getActiveConfiguration();
IConfiguration configuration = ManagedBuildManager.getConfigurationForDescription(cfgDescription);
IPath projectPath = translationUnit.getResource().getProjectRelativePath();
IResourceInfo ri = configuration.getResourceInfo(projectPath, true);
if (ri == null) {
ri = configuration.createFileInfo(projectPath);
}
return ri;
}
return null;
}
Note this line, in particular:
IPath projectPath = translationUnit.getResource().getProjectRelativePath();
Maybe, all you need is to use getProjectRelativePath() in your code?
Generally you can set an option to different objects, i.e. a configuration (if you want the option to apply to all files of a given type in a configuration) or a resource (if you want the option to apply only to the files in a folder or to a single file).
setOption() has multiple prototypes; it looks like you used the one that applies to a file resource.
In my GNU ARM Eclipse Plug-in I successfully used another version:
setOption(IConfiguration config, IHoldsOptions holder, IOption option, String value)
You can see an example in this file, line 583.
I guess this will work in your case too.

gettext-common example doesn't work

I need to translate my app, so i want to use gettext-common from http://code.google.com/p/gettext-commons
I checked out the svn and tried to compile the example:
javac -classpath ../java I18nExample.java
java -classpath ../../target/gettext-commons-0.9.6.jar:. I18nExample
The program does not give me the targeted output; I have absolutely no idea whats going on!
It seems that the de.properties is completly ignored. If I set the Properties file to "de" in the Factory's constructor, I get partly the output I want to see.
Is there anywhere in the internet a working example of gettext for java?
this is the output from the example script:
First run
This text is marked for translation and is translated
This text is marked for translation but not translated
This text is marked for translation but not translated
Four: 4
chat
chat
1 file is open
2 files are open
Second run
This text is marked for translation and is translated
This text is marked for translation but not translated
This text is marked for translation but not translated
Four: 4
chat
chat
1 file is open
2 files are open
There are a couple of issues, perhaps due to the build process.
First, for the message lookup to work, I needed to move the en and de resources into Messages_en.properties and Messages_de.properties in order to make a real resource bundle.
Second, the example code tries to use messages with no translations available, like the "file is open" stuff. Here's an updated version of what I tried; this all appears to work with the above modification:
public static void main(String[] args) {
I18n i18n = I18nFactory.getI18n(I18nExample.class, "Messages");
for (int i = 0; i < 2; i++) {
if (i == 0) {
print("First run");
} else {
print("Second run");
i18n.setLocale(Locale.GERMAN);
}
print("Current locale: " + i18n.getLocale());
print(i18n.tr("This text is marked for translation and is translated"));
String mark = i18n.marktr("This text is marked for translation but not translated");
print(mark);
print(i18n.tr(mark));
mark = i18n.tr("This is the {0}. text to be translated", "chat (noun)");
print(mark);
mark = i18n.tr("This is the {0}. text to be translated", "chat (verb)");
print(mark);
print(i18n.tr("chat (noun)"));
print(i18n.tr("chat (verb)"));
print("");
}
}
Note also that to insert translated words, you need something like this:
print(i18n.tr("This is the {0}. text to be translated", i18n.tr("chat (noun)")));
print(i18n.tr("This is the {0}. text to be translated", i18n.tr("chat (verb)")));
However, without un-banging (removing the ! and providing an English translation in Messages_en.properties, it shows up as chat (noun), which... strikes me as being almost useless.
The documentation is lacking on this aspect.

Categories