Creating new live-templates with import statements in IntelliJ IDEA - intellij-idea

Here is the Eclipse template that I want to port:
${:import(org.apache.log4j.Logger)}
private static final Logger LOG = Logger.getLogger(${enclosing_type}.class);
My current version in IDEA is as follows:
private static final Logger LOG = Logger.getLogger($CLASS_NAME$.class);$END$
where $CLASS_NAME$ is configured to use className() as its expression.
Unfortunately, I don't find any documentation on adding the import statement. Is there somehing equivalent to Eclipse ${:import(...)}?

According to this post, it is intended to use only full-qualified expressions. I tried it out and this worked for me:
private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger($CLASS_NAME$.class);$END$
IDEA automatically shortens it and adds the necessary import statements:
import org.apache.log4j.Logger;
// ...
private static final Logger LOG = Logger.getLogger(MyClass.class);
If you want to try yourself, note that you first have to define CLASS_NAME as className() via Edit variables. Also make sure that you allowed your Live Template for Java declarations via Change (at the bottom). Here is a screenshot with the final setup:

Just to save a little time for new visitors here: the accepted answer now needs some changes.
Go to Settings -> Editor -> Live Templates, select others, add a template:
private static final org.apache.logging.log4j.Logger logger = org.apache.logging.log4j.LogManager.getLogger($CLASS_NAME$.class);$END$
Then, press Edit Variables on the left and set expression for CLASS_NAME to className().
After all, set context on the bottom to Java -> Declaration (and Groovy -> Declaration if desired).
Imports will be magically generated on insert.

Now its possible to add live templates with static imports:
You have to check static import in Options
#org.junit.Test
public void should$EXPR$when$CONDITION$() {
org.junit.Assert.assertThat(null, org.hamcrest.CoreMatchers.is(org.hamcrest.CoreMatchers.nullValue()));
}

For apache commons logging use:
private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory.getLog($CLASS_NAME$.class);$END$

Related

Replacing Type with var for all 'Class class = new Class()' usages in Java project

I recently switched to Java 11 for a rather big project, and would like to switch to using var class = new Class() instead of Class class = new CLass().
I tried using Intellij Structural Search (and replace) for this, but its turning out to be more complex than expected.
My first attempt was $Type$ $Inst$ = new $Constructor$($Argument$);, which also matches global variables (which don't allow var).
My second attempt is:
class $Class$ {
$ReturnType$ $Method$ ($ParameterType$ $Parameter$) throws $ExceptionType$ {
$Statements$;
final $Type$ $Inst$ = new $Constructor$($Argument$);
$Statements2$;
}
}
Which misses all calls inside e.g. try blocks (since they get matched by the expressions)
Any help would be greatly appreciated!
Use your first template
$Type$ $Inst$ = new $Constructor$($Argument$);
But add a Script modifier on the $Inst$ variable with the following text:
Inst instanceof com.intellij.psi.PsiLocalVariable
Alternatively you may want to try the Local variable type can be omitted inspection that is available in IntelliJ IDEA.

Netflix Ribbon and Polling for Server List

I'm currently trying out the Netflix Ribbon library and I'm trying to dynamically update a list of available endpoints to load balance.
I've successfully created a httpResourceGroup that uses a configuration based server list, e.g.:
httpResourceGroup = Ribbon.createHttpResourceGroup("searchServiceClient",
ClientOptions.create()
.withMaxAutoRetriesNextServer(3)
.withLoadBalancerEnabled(true)
.withConfigurationBasedServerList(serverList))
However, I'd like to be able to use a DynamicServerList in the httpResourceGroup. I've managed to build a load balancer as follows:
LoadBalancerBuilder.<Server>newBuilder()
.withDynamicServerList(servicesList)
.buildDynamicServerListLoadBalancer();
but I can't find a way to swap out the load balancer configured by the httpResourceGroup ClientOptions.
Anyone know how I can do this?
The solution is to not specify withConfigurationBasedServerList() when constructing an HttpResourceGroup since this I believe this is meant for a fixed list though I am not sure. There are many ways to initialize a dynamic load balancer (typically you would never swap it out, but reuse the same load balancer and swap out new Servers as they become available or go away. The most straightforward way to do this might be via Archaius-based configuration.
Option 1
Create a config.properties file on the classpath containing the following
ribbon.NIWSServerListClassName=com.example.MyServerList
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule
Option 2
System.setProperty("ribbon.NIWSServerListClassName", "com.example.MyServerList");
System.setProperty("ribbon.NFLoadBalancerRuleClassName", "com.netflix.loadbalancer.RoundRobinRule");
Create a ServerList implementation
import java.util.Arrays;
import java.util.List;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerList;
public class MyServerList implements ServerList<Server> {
#Override
public final List<Server> getUpdatedListOfServers() {
// TODO do some fancy stuff here
return Arrays.asList(new Server("1.2.3.4", 8888), new Server("5.6.7.8", 9999));
}
#Override
public final List<Server> getInitialListOfServers() {
return Arrays.asList(new Server("1.2.3.4", 8888), new Server("5.6.7.8", 9999));
}
}
Run the code
HttpResourceGroup httpResourceGroup = Ribbon.createHttpResourceGroup("searchServiceClient",
ClientOptions.create()
.withMaxAutoRetriesNextServer(3);
HttpRequestTemplate<ByteBuf> recommendationsByUserIdTemplate = httpResourceGroup.newTemplateBuilder("recommendationsByUserId", ByteBuf.class)
.withMethod("GET")
.withUriTemplate("/users/{userId}/recommendations")
.withFallbackProvider(new RecommendationServiceFallbackHandler())
.withResponseValidator(new RecommendationServiceResponseValidator())
.build();
Observable<ByteBuf> result = recommendationsByUserIdTemplate.requestBuilder()
.withRequestProperty("userId", “user1")
.build()
.observe();
It sounds like you already have a ServerList implementation which is where you would do any event driven updates to your server list, but keep the load balancer the same.

Reference a class' static field of the same internal module but in a different file?

I'm using TypeScript and require.js to resolve dependencies in my files. I'm in a situation where I want to reference a static field of a class in an other file, but in the same internal module (same folder) and I am not able to access it, even if the Visual Studio pre-compiler does not show any error in my code.
I have the following situation :
Game.ts
class Game {
// ...
static width: number = 1920;
// ...
}
export = Game;
Launcher.ts
/// <reference path='lib/require.d.ts'/>
import Game = require("Game");
var width: number = Game.width;
console.log(width); // Hoping to see "1920"
And the TypeScript compiler is ok with all of this. However, I keep getting "undefined" at execution when running the compiled Launcher.ts.
It's the only reference problem I'm having in my project, so I guess the rest is configured correctly.
I hope I provided all necessary information, if you need more, please ask
Any help is appreciated, thanks !
Your code seems sound, so check the following...
You are referencing require.js in a script tag on your page, pointing at Launcher (assuming Launcher.ts is in the root directory - adjust as needed:
<script src="Scripts/require.js" data-main="Launcher"></script>
Remove the reference comment from Launcher.ts:
import Game = require("Game");
var width: number = Game.width;
console.log(width); // Hoping to see "1920"
Check that you are compiling using --module amd to ensure it generates the correct module-loading code (your JavaScript output will look like this...)
define(["require", "exports", "Game"], function (require, exports, Game) {
var width = Game.width;
console.log(width); // Hoping to see "1920"
});
If you are using Visual Studio, you can set this in Project > Properties > TypeScript Build > Module Kind (AMD)
If you are using require.js to load the (external) modules, the Game class must be exported:
export class Game {}
If you import Game in Launcher.ts like
import MyGame = require('Game')
the class can be referenced with MyGame.Game and the static variable with MyGame.Game.width
You should compile the ts files with tsc using option --module amd or the equivalent option in Visual Studio

Change application.conf runtime?

I want to set the database connection at run time for my Play project. I know that I can set a property run time with the following code:
#OnApplicationStart public class Bootstrap extends Job
{
#Override public void doJob()
{
// now set the values in the properties file
Play.configuration.setProperty("db.driver", dbDriver);
Play.configuration.setProperty("db.url", dbUrl);
Play.configuration.setProperty("db.user", dbUsername);
Play.configuration.setProperty("db.pass", dbPassword);
}
}
But when executing the code above the file is not actually changed, I think just in memory.
How can I set the database properties and force Play! to use this properties in order to connect to the right database onApplicationStart?
Thanks!
UPDATE 2012-01-29
Solution is possible via a plugin. In this plugin I have to override onConfigurationRead() and apply the properties to the configuration file at that moment. I will try to post some code as soon as I have time for this.
By the time you change the properties, the DB plugin is already initialized. You need to write a plugin and overwrite the onConfigurationRead() method, then put your new settings there. Paly's dbplugin will init later on.
I faced with the necessity of programmatically obtaining values from aws secret manager in runtime before using that values in play framework configuration. You can override initial default values from application.conf and add new.
Work for play framework v2.7.3
import com.typesafe.config.ConfigValueFactory;
import play.api.Configuration;
import play.api.inject.guice.GuiceApplicationBuilder;
import play.api.inject.guice.GuiceApplicationLoader;
public class ExtendedGuiceApplicationLoader extends GuiceApplicationLoader {
#Override
public GuiceApplicationBuilder builder(Context context) {
Configuration configuration = new Configuration(
context.initialConfiguration().underlying()
.withValue("db.default.username",
ConfigValueFactory.fromAnyRef("aws.secret.db.username"))
.withValue("db.default.password",
ConfigValueFactory.fromAnyRef("aws.secret.db.password"))
);
return super.builder(
new Context(context.environment(),
configuration,
context.lifecycle(),
context.devContext())
);
}
}
Don´t forget add this string to application.conf
play.application.loader="youpackage.ExtendedGuiceApplicationLoader"
Are you sure this is what you really intend to do?
Play offers the possibility to add different configurations in your application.conf
for example you could have:
db.url=mydefaulturl
%uat.db.url=uaturl
%prod.db.url=produrl
%prod1.db.url=prod1url
And then start the app with play start --%uat or play start --%prod

Eclipse: Within a plug-in, how to access another plug-ins preference store?

I have an Eclipse plug-in with a checkbox in the plug-in's preference page.
This checkbox is used for enabling and disabling an editor, which is being launched from this plug-in.
However, the problem is, I would also like to be able to enable and disable this 'editor-launch' from another plug-in, by having actions which change the value of the checkbox in the above mentioned preference page.
Here's the problem, how do I access that local preference store from another plug-in?
I've tried things like..
View myView = (View) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView("ViewID");
But this 'myView' always seems to be null.. And also, what would I do with the view since it's the Plug-in I want.
Platform.getBundle('bundleName')...
Same here, want the Plugin, not the bundle corresponding to is.
No matter what I try nothing seems to work.
Does anyone have any ideas?
There are two ways of doing this:
Please refer to http://www.vogella.com/tutorials/EclipsePreferences/article.html#preferences_pluginaccess
Using .getPluginPreferences(). For example, there is a plugin class "com.xxx.TestPlugin" which extends org.eclipse.ui.plugin.AbstractUIPlugin.Plugin, in order to get access to the preferences of TestPlugin. The plugin code could be below:
public class TestPlugin extends AbstractUIPlugin {
private static TestPlugin plugin;
public static final String PREF_TEST = "test_preference";
/**
* The constructor.
*/
public TestPlugin() {
plugin = this;
}
/**
* This method is called upon plug-in activation
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/**
* This method is called when the plug-in is stopped
*/
public void stop(BundleContext context) throws Exception {
super.stop(context);
plugin = null;
}
/**
* Returns the shared instance.
*/
public static TestPlugin getDefault() {
return plugin;
}
}
To access the preference of TestPlugin, the code could be:
TestPlugin.getDefault().getPluginPreferences().getDefaultBoolean(TestPlugin.PREF_TEST);
Or have a look at this answer: Writing Eclipse plugin to modify Editor Preferences
This thread recommend the use of a Service tracker:
ServiceTracker tracker = new ServiceTracker(ToolkitPlugin.getDefault().getBundle().getBundleContext(),
IProxyService.class.getName(), null);
tracker.open();
proxyService = (IProxyService) tracker.getService();
proxyService.addProxyChangeListener(this);
This may work.
Prefs stores are found per plugin. This is one way to get a prefs store for the plugin whose activator class is ActivatorA.
IPreferenceStore store = ActivatorA.getDefault().getPreferenceStore();
If you want another plugin to refer to the same store, perhaps you could expose some api on ActivatorA for it to get there, e.g.
public IPreferenceStore getSharedPrefs() {
return ActivatorA.getDefault().getPreferenceStore();
}
The second plugin would find the shared store by doing this
IPreferenceStore sharedPrefs = ActivatorA.getSharedPrefs();
Good luck.