eclipse jdt automatic method stub generation - eclipse

i am creating java source files using eclipse JDT & AST. There are cases that generated source files are implementing or extending something.
is it possible to add method stubs automatically before actually creating them? like invoking this "Add unimplemented methods" quick fix via JDT.
i know i can add them myself via those API's, but i want to tweak.

i found solution after a couple of hours; code is roughly like this. there are also many good code manipulation classes in this package "org.eclipse.jdt.internal.corext.codemanipulation.*"
ICompilationUnit createCompilationUnit = getItSomeHow();
RefactoringASTParser parser1 = new RefactoringASTParser(AST.JLS3);
CompilationUnit unit = parser1.parse(createCompilationUnit, true);
AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) ASTNodes.getParent(
NodeFinder.perform(unit, createCompilationUnit.getTypes()[0].getNameRange()),
AbstractTypeDeclaration.class);
ITypeBinding binding = declaration.resolveBinding();
IMethodBinding[] overridableMethods = StubUtility2.getOverridableMethods(unit.getAST(), binding, false);
AddUnimplementedMethodsOperation op = new AddUnimplementedMethodsOperation(unit, binding,
null/* overridableMethods */, -1, true, true, true);

Related

Changing jasper report parameters in runtime

I know, but we really need it.
We have a clear division of labor.
They create templates, I fill them in runtime according to some rules.
Can't teach my business to insert something like this and be sure they really did it ok(so can't move any logic to templates):
$P{risk_types}.get($F{risk_type}) ?: "UNDEFINED"
Also can not fill from files hardcoded in some adapter hadwritten by god-knows-who and unchangeable in runtime. It's a web app. Best option is to find a way to replace that file source from adapter to a ByteArrayStream.
SO:
Need to substitute contents of parameters(also default ones) at runtime.
example:
need to set JSON_INPUT_STREAM
Like this unsolved thread.
https://community.jaspersoft.com/questions/516611/changing-parameter-scriptlet
Really hope not to work on xml level, but xml also can't solve my problem as far as I tried.
Thank you!
The easiest and cleanest way we did this(bypassing usage of tons of deprecated documentation and unfinished bugged undocumented static antipatterned new features):
Create context with repository extension
SimpleJasperReportsContext jasperReportsContext = new SimpleJasperReportsContext();
jasperReportsContext.setExtensions(RepositoryService.class, Collections.singletonList(new MyRepositoryService(jasperReportsContext, yourOptionalParams)));
Fill this way(after compile and other usual actions)
JasperPrint print = JasperFillManager.getInstance(jasperReportsContext).fill(compiled, new HashMap<>());
Now your repository must extend default one to be hack-injected(cause of hodgie coded "isAssignableFrom") successfully
public class PrintFormsRepositoryService extends DefaultRepositoryService {
#Override
public InputStream getInputStream(RepositoryContext context, String uri) {
// return here your own good simple poj inputStream even from memory if you found source
// or pass to another repository service(default one probably)
return null;
}
}

Disable logging on FileConfigurationSourceChanged - LogEnabledFilter

I want Administrators to enable/disable logging at runtime by changing the enabled property of the LogEnabledFilter in the config.
There are several threads on SO that explain workarounds, but I want it this way.
I tried to change the Logging Enabled Filter like this:
private static void FileConfigurationSourceChanged(object sender, ConfigurationSourceChangedEventArgs e)
{
var fcs = sender as FileConfigurationSource;
System.Diagnostics.Debug.WriteLine("----------- FileConfigurationSourceChanged called --------");
LoggingSettings currentLogSettings = e.ConfigurationSource.GetSection("loggingConfiguration") as LoggingSettings;
var fdtl = currentLogSettings.TraceListeners.Where(tld => tld is FormattedDatabaseTraceListenerData).FirstOrDefault();
var currentLogFileFilter = currentLogSettings.LogFilters.Where(lfd => { return lfd.Name == "Logging Enabled Filter"; }).FirstOrDefault();
var filterNewValue = (bool)currentLogFileFilter.ElementInformation.Properties["enabled"].Value;
var runtimeFilter = Logger.Writer.GetFilter<LogEnabledFilter>("Logging Enabled Filter");
runtimeFilter.Enabled = filterNewValue;
var test = Logger.Writer.IsLoggingEnabled();
}
But test reveals always the initially loaded config value, it does not change.
I thought, that when changing the value in the config the changes will be propagated automatically to the runtime configuration. But this isn't the case!
Setting it programmatically as shown in the code above, doesn't work either.
It's time to rebuild Enterprise Library or shut it down.
You are right that the code you posted does not work. That code is using a config file (FileConfigurationSource) as the method to configure Enterprise Library.
Let's dig a bit deeper and see if programmatic configuration will work.
We will use the Fluent API since it is the preferred method for programmatic configuration:
var builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging()
.WithOptions
.DoNotRevertImpersonation()
.FilterEnableOrDisable("EnableOrDisable").Enable()
.LogToCategoryNamed("General")
.WithOptions.SetAsDefaultCategory()
.SendTo.FlatFile("FlatFile")
.ToFile(#"fluent.log");
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
var defaultWriter = new LogWriterFactory(configSource).Create();
defaultWriter.Write("Test1", "General");
var filter = defaultWriter.GetFilter<LogEnabledFilter>();
filter.Enabled = false;
defaultWriter.Write("Test2", "General");
If you try this code the filter will not be updated -- so another failure.
Let's try to use the "old school" programmatic configuration by using the classes directly:
var flatFileTraceListener = new FlatFileTraceListener(
#"program.log",
"----------------------------------------",
"----------------------------------------"
);
LogEnabledFilter enabledFilter = new LogEnabledFilter("Logging Enabled Filter", true);
// Build Configuration
var config = new LoggingConfiguration();
config.AddLogSource("General", SourceLevels.All, true)
.AddTraceListener(flatFileTraceListener);
config.Filters.Add(enabledFilter);
LogWriter defaultWriter = new LogWriter(config);
defaultWriter.Write("Test1", "General");
var filter = defaultWriter.GetFilter<LogEnabledFilter>();
filter.Enabled = false;
defaultWriter.Write("Test2", "General");
Success! The second ("Test2") message was not logged.
So, what is going on here? If we instantiate the filter ourselves and add it to the configuration it works but when relying on the Enterprise Library configuration the filter value is not updated.
This leads to a hypothesis: when using Enterprise Library configuration new filter instances are being returned each time which is why changing the value has no effect on the internal instance being used by Enterprise Library.
If we dig into the Enterprise Library code we (eventually) hit on LoggingSettings class and the BuildLogWriter method. This is used to create the LogWriter. Here's where the filters are created:
var filters = this.LogFilters.Select(tfd => tfd.BuildFilter());
So this line is using the configured LogFilterData and calling the BuildFilter method to instantiate the applicable filter. In this case the BuildFilter method of the configuration class LogEnabledFilterData BuildFilter method returns an instance of the LogEnabledFilter:
return new LogEnabledFilter(this.Name, this.Enabled);
The issue with this code is that this.LogFilters.Select returns a lazy evaluated enumeration that creates LogFilters and this enumeration is passed into the LogWriter to be used for all filter manipulation. Every time the filters are referenced the enumeration is evaluated and a new Filter instance is created! This confirms the original hypothesis.
To make it explicit: every time LogWriter.Write() is called a new LogEnabledFilter is created based on the original configuration. When the filters are queried by calling GetFilter() a new LogEnabledFilter is created based on the original configuration. Any changes to the object returned by GetFilter() have no affect on the internal configuration since it's a new object instance and, anyway, internally Enterprise Library will create another new instance on the next Write() call anyway.
Firstly, this is just plain wrong but it is also inefficient to create new objects on every call to Write() which could be invoked many times..
An easy fix for this issue is to evaluate the LogFilters enumeration by calling ToList():
var filters = this.LogFilters.Select(tfd => tfd.BuildFilter()).ToList();
This evaluates the enumeration only once ensuring that only one filter instance is created. Then the GetFilter() and update filter value approach posted in the question will work.
Update:
Randy Levy provided a fix in his answer above.
Implement the fix and recompile the enterprise library.
Here is the answer from Randy Levy:
Yes, you can disable logging by setting the LogEnabledFiter. The main
way to do this would be to manually edit the configuration file --
this is the main intention of that functionality (developers guide
references administrators tweaking this setting). Other similar
approaches to setting the filter are to programmatically modify the
original file-based configuration (which is essentially a
reconfiguration of the block), or reconfigure the block
programmatically (e.g. using the fluent interface). None of the
programmatic approaches are what I would call simple – Randy Levy 39
mins ago
If you try to get the filter and disable it I don't think it has any
affect without a reconfiguration. So the following code still ends up
logging: var enabledFilter = logWriter.GetFilter();
enabledFilter.Enabled = false; logWriter.Write("TEST"); One non-EntLib
approach would just to manage the enable/disable yourself with a bool
property and a helper class. But I think the priority approach is a
pretty straight forward alternative.
Conclusion:
In your custom Logger class implement a IsLoggenabled property and change/check this one at runtime.
This won't work:
var runtimeFilter = Logger.Writer.GetFilter<LogEnabledFilter>("Logging Enabled Filter");
runtimeFilter.Enabled = false/true;

Trigger formatter in a custom plug-in in Eclipse

I writing my own text editor plugin for eclipse. I am now working on my own formatter. Actually, following that link http://wiki.eclipse.org/FAQ_How_do_I_support_formatting_in_my_editor%3F.
I have written my Strategy, I have overridden getContentFormatter in my SourceViewerConfiguration..
As I run my plugin and press Ctrl+Shift+F - and nothing happens.
I think that I'm missing a step here. Should I create a handler or something?
Thanks
Might it be you skipped the last part of the linked page?
Finally, you will need to create an action that invokes the formatter. No generic formatting action is defined by the text infrastructure, but it is quite easy to create one of your own. The action’s run method can simply call the following on the source viewer to invoke the formatter:
sourceViewer.doOperation(ISourceViewer.FORMAT);
What helped me. I have created a handler with the following executors body:
//get the editorPart
if (editorPart != null) {
ITextOperationTarget target = (ITextOperationTarget) editorPart
.getAdapter(ITextOperationTarget.class);
if (target instanceof ISourceViewer) {
ISourceViewer textViewer = (ISourceViewer) target;
((ITextOperationTarget) textViewer)
.doOperation(ISourceViewer.FORMAT);
}
}
Then just create menu items and bind them to the handler.

How can I create a custom project layout based on another eclipse plugin?

My ultimate goal is to create an eclipse plugin that sets up a PDT project, but with some added builders (and custom build scripts) as well as a specific folder layout (and different folders should be treated as source and some as regular folders).
I've looked at / followed eclipse plugin development tutorials, and ok. I get the gist of creating a wizard that creates a file, but I'm having trouble trying to figure out how to create a project, and more importantly, make that project associated with the PDT (PHP Development Tools) feature.
Answer:
I did stumble upon a solution myself before the answer was given, but it's quite similar.
First, WizardNewProjectCreationPage was used as the first page of my wizard.
Second, on performFinish() I ran the following code:
IProgressMonitor m = new NullProgressMonitor();
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IProject project = root.getProject(_pageOne.getProjectName());
if (!project.exists())
{
IProjectDescription desc = project.getWorkspace().newProjectDescription(project.getName());
URI projectLocation = _pageOne.getLocationURI();
// desc.setLocationURI(projectLocation);
String[] natures = desc.getNatureIds();
String[] newNatures = new String[natures.length + 1];
System.arraycopy(natures, 0, newNatures, 0, natures.length);
newNatures[natures.length] = PHPNature.ID;
desc.setNatureIds(newNatures);
project.create(desc, m);
project.open(m);
}
how to create a project
Take a look at BasicNewProjectResourceWizard.createNewProject() method.
make that project associated with the PDT (PHP Development Tools) feature
You need to add "org.eclipse.php.core.PHPNature" to the project (that's what Add PHP Support... action does). Use IProjectDescription.setNatureIds().

When writing Eclipse plugins, what is the correct way for checking if an IEditorPart is a Java editor?

I am writing Eclipse plugins for Java, and have the following problem:
Given an IEditorPart, I need to check if it is a java editor.
I could do (IEditor instanceof JavaEditor),
but JavaEditor is an org.eclipse.jdt.internal.ui.javaeditor.JavaEditor,
which falls under the JDT's "internal" classes.
Is there a smarter and safer way to do this? I'm not sure why there is no non-internal interface for this.
You should test the id of the IEditorPart:
private boolean isJavaEditor(IWorkbenchPartReference ref) {
if (ref == null) {
return false; }
String JavaDoc id= ref.getId();
return JavaUI.ID_CF_EDITOR.equals(id) || JavaUI.ID_CU_EDITOR.equals(id);
}
Testing the instance was only needed in eclipse3.1.
alt text http://blogs.zdnet.com/images/Burnette_DSCN0599.JPG
JavaUI is the main access point to the Java user interface components. It allows you to programmatically open editors on Java elements, open a Java or Java Browsing perspective, and open package and type prompter dialogs.
JavaUI is the central access point for the Java UI plug-in (id "org.eclipse.jdt.ui")
You can see that kind of utility function ("isJavaEditor()") used for instance in ASTProvider.
The mechanism of identification here is indeed simple String comparison.
Anyway, you are wise to avoid cast comparison with internal class: it has been listed as one of the 10 common errors in plugins development ;) .
One strategy might be to use JavaUI.getEditorInputJavaElement(IEditorPart):
// given IEditorPart editor
IJavaElement elt = JavaUI.getEditorInputJavaElement(editor.getEditorInput());
if (elt != null) {
// editor is a Java editor
}
The method returns null if the editor input is not in fact a Java element.