What is a good usecase for Guice Mapbinder? - java

I've seen it used, but I'm not sure the usage were good usecase examples. Do you have examples of idiomatic usages of Guice Mapbinder? (Cases where Mapbinder is really the correct tool to solve a problem)

Offhand, it looks like a reasonable way to create a registry of runtime-named implementations of a common interface. Consider selecting one of many plugins/modes/whatever from a command line or configuration file: the desired injection can't be known at compile time. A MapBinder provides an easy runtime lookup without resorting to type-switching.

I extensively use it in Guts-GUI.
You can take a look, in particular, at the ResourceModule, where it is used to map the right ResourceConverter<T> for a given type T:
Map<TypeLiteral<?>>, ResourceConverter<?>>
The MapBinder is directly created in the Resources helper class.
This way, any module can add its own resource converters for its own types, e.g. MessageModule adds its own converters.
I also used it as Map<Integer, WindowProcessor>> in WindowsModule to define an ordered list of WindowProcessors to be applied, one after another, to a newly created window..
Once again, this allows various modules to insert their own processor to the list applied to every window: ResourceModule uses it to add the ability of automatic injection of i18n resources to windows.

Related

Can I use custom annotations to classify Java classes?

Is it possible that use self defined Annotation to classify java class into different product function ? (Following are my thoughts)
If not, are there any other method to achieve the same purpose in Android project?
Step1: use self defined annotation to make clear java class's function
#SelfDefinedAnnotation( "product-function-a" )
class MyClass {
void func() {
//do something
}
}
Step2: during building period, generate a mapping file like this
MyClass -> product-function-a
YourClass -> product-function-b
I'm not sure about android (never worked with it), but in pure java its possible for sure.
You should define an annotation with retention policy SOURCE and since you're talking about build time, define an annotation processor. This is something that is "hooked" into the compilation process and allows creating such a mapping (I assume you want to store it in some kind of file, maybe *.properties file, or even generate a java source code with these definitions.
The annotation processor is broad topic, there are many ways to register them, so it pretty much depends on how do you build your stuff exactly, but its a general direction.
Please check out this tutorial it talks about annotation processors, the ways to register them, to associate with your custom annotation and so forth.
One suggestion though, if you're about to generate Java Source class and not just a properties file, this tutorial goes "low level" and tries to prepare the syntax by itself, I suggest using a much nicer (IMO) Java Poet library that will help to generate a proper java code

Using an Annotation Processor to create a list of classes with a certain annotation

I have a custom annotation that I've implemented and I'd like to use an annotation processor to generate a list of all the classes in my app that use that particular annotation.
I've found this tutorial which describes how to generate a class file using an annotation processor, so it should be quite easy to generate a class for each class with my annotation.
What I can't figure out is how I can collect all of that information into a single class. There doesn't seem to be a way to modify a class, so I can't append new items to the list once the class has been generated the first time.
Is there a way to use an annotation processor to generate a method that will return the list of all classes in an app that are annotated with a particular annotation?
Generated classes do not necessarily have to correspond one-to-one to the input classes being processed. Plus, you can search for classes (Elements) that are annotated with a given annotation via the RoundEnvironment:
roundEnvironment.getElementsAnnotatedWith(MyAnnotation.class)
From this you can generate a single class with a method that returns a collection of the classes found.
A couple issues around this to highlight:
Annotation processors can run along with other annotation processors and thus have to deal with classes generated at compile time. To aid this, Java annotation processing is performed in rounds to allow processors to catch the outputs of others. To be compatible with other processors you need to gracefully handle the ErrorType.
Only classes in the current compilation pass are returned from the RoundEnvironmnet methods so classes in external libraries will not be included.
IDEs (cough cough Eclipse) implement the annotation processing facilities of Java differently which can be a problem for processors that require a full non-partial compilation like I've described.
Coincidentally, I created a similar project recently that does what you are looking for:
https://github.com/johncarl81/silver
Silver is very much a WIP and uses a lot of library code to accomplish the task, but it may give you an idea for what's possible.

Design pattern for parameter settings that is maintainable in decent size java project

I am looking for concrete ideas of how to manage a lot of different parameter settings for my java program. I know this question is a bit diffuse but I need some ideas about the big picture so that my code becomes more maintainable.
What my project does is to perform many processing steps on data, mostly text. These processing steps are algorithms of varying complexity that often have many settings. I would also like to change which processing steps are used by e.g. configuration files.
The reason for my program is to do repeatable experiments, and because of this I need to be able to get a complete view of all the parameters used in the different parts of the code, preferably in a nice format.
At this (prototype) stage I have the settings in source code like:
public static final param1=0.35;
and each class that is responsible for some processing step has its own hard coded settings. It is actually quite scary because there is no simple way to change things or to even see what is done and with what parameters/settings.
My idea is to have a central key/value store for all settings that also supports a dump of all settings. Example:
k:"classA_parameter1",v:"0.35"
k:"classC_parameter5",v:"false"
However, I would not really like to just store the parameters as strings but have them associated to an actual java class or object.
Is it smarter to have a singleton "SettingsManager" that manages everything. Or to have a SettingsManager object in each class that main has access to? I don't really like storing string descriptions of the settings but I cant see any other way (Lets say one setting is a SAXparser implementation that is used and another parameter is a double, e.g. percentage) since I really don't want to store them as Objects and cast them.
Experience and links to pages about relevant design patterns is greatly appreciated.
To clarify, my experiments could be viewed as a series of algorithms that are working on data from files/databases. These algorithms are grouped into different classes depending on their task in the whole process, e.g.
Experiment //main
InternetLookup //class that controls e.g. web scraping
ThreadedWebScraper
LanguageDetection //from "text analysis" package
Statistics //Calculate and store statistics
DatabaseAccess
DecisionMaking //using the data that we have processed earlier, make decisions (machine learning)
BuildModel
Evaluate
Each of the lowest level classes have parameters and are different but I still want a to get a view of everything that is going on.
You have the following options, starting with the simplest one:
A Properties file
Apache Commons Configuration
Spring Framework
The latter allows creation of any Java object from an XML config file but note that it's a framework, not a library: this means that it affects the design of the whole application (it promotes the Inversion of Control pattern).
This wheel has been invented multiple times already.
From the most basic java.util.Properties to the more advanced frameworks like Spring, which offers advanced features like value injection and type conversion.
Building it yourself is probably the worst approach.
Maybe not a complete answer to your question, but some points to consider:
Storing values as strings (and parsing the strings into other types via your SettingsManager) is the usual approach. If your configuration value is too complex to do this then it's probably not really a configuration value, but part of your implementation.
Consider injecting the individual configuration values required by each class via constructor arguments, rather than just passing in the whole SettingsManager object (see Law of Demeter)
Avoid creating a Singleton SettingsManager if possible, singletons harm testability and damage the design of your application in various ways.
If the number of parameters is big I would split them to several config files. Apache Commons Configuration, as mentioned by #Pino is really a nice library to handle them.
On the Java-side I would probably create one config-class per file and wrap Commons Configuration config to load settings, eg:
class StatisticsConfig {
private Configuration config = ... ;
public double getParameter1() {
return config.getDouble("classA_parameter1");
}
}
This may need quite a lot of boilerplate code if the number of parameters is big but I think it is quite clean solution (and easy to refactor).

Dependency Injection With Annotations

I would like to build my own custom DI framework based on Java annotations and I need a little direction to get started. I know it would be much easier to use one of the many wonderful frameworks out there such as guice or spring, but for the sake of my own curiosity, i'd like to build my own.
I'm not very familiar with annotations, so i'm having a bit of trouble finding resources and would really appreciate someone just sort of spelling out a few of the steps i'll need to take to get started.
As fore mentioned, id like to take a factory approach and somehow label my getters with an #Resource or #Injectable type annotation, and then in my business classes be able to set my variable dependencies with an #Inject annotation and have the resource automatically available.
Does anyone have any sort of resource they can pass along to help me understand the process of tagging methods based on annotations and then retrieving values from a separate class based on an annotation. A little direction is all I need, something to get me started. And of course i'll be happy to post a little code sample here once I get going, for the sake of others future reading of course.
EDIT
The resources I am using to put this together:
Java Reflection: Annotations
How to find annotations in a given package: Stack Overflow ?
Scanning Annotations at Runtime
I have not actually finished writing this yet, but the basic task list is going to be as follows (for anyone who might be interested in doing something similar in the future)
At class runtime scan for all #Inject fields and get object type.
Scan all classes (or just a specific package of classes (I haven't
decided yet)) for annotated methods #InjectableResource.
Loop all annotated methods and find the method that returns the
object type I am looking for.
Run the method and get the dependency.
It will also be helpful to note that when scanning all the classes I will be using a library called Javassist. Basically what this does is allows me to read the bytecode information of each class without actually loading the class. So I can read the annotation strings without creating serious memory problems.
Interesting that you want to build your own. I love Google Guice - it makes code so elegant and simple.
I've used this guide before which I found pretty useful for learning about annotations and how you can pull them out of classes and methods.
You will have to define your own Annotations which is done using #interface. Then you will have to define some kind of class for doing bindings e.g. where you see an interface bind in this concrete class. Finally, you will need some logic to pull it altogether e.g. go through each class, find each annotation, and then find a suitable binding.
Give consideration to things like lazy instantiation through Reflections and singletons. Guice, for example, allows you to use a singleton so your only using one instance of the concrete class, or you can bind a new version each time.
Good luck!
Have a look at the following methods:
java/lang/Class.html#getAnnotation(java.lang.Class)
java/lang/Class.html#getAnnotations()
java/lang/Class.html#getDeclaredAnnotations()
Methods of the same name also exist for the java/lang/reflect/Method, java/lang/reflect/Field and java/lang/reflect/Constructor classes.
So in order to use these sorts of methods, you need to know a bit about Java reflection.

Explanation about Annotations

Can anyone please explain what the following two paragraphs mean, in simple english? (Taken from http://www.ibm.com/developerworks/java/library/j-cwt08025.html)
"Annotations are more flexible in
terms of how you use them, with
options for whether the annotation
information is to be included in class
files output by the compiler and made
available to the application at run
time"
Not sure what these means. Can Annotations be configured to optionally change the bytecode?
While annotations are ideal for
metadata that relates to a particular
component, they are not well suited to
metadata with cross-component
application.
IMHO most web applications would be cross-component ones. What is the author trying to say here?
Annotations are more flexible in terms
of how you use them, with options for
whether the annotation information is
to be included in class files output
by the compiler and made available to
the application at run time
This, I think, refers to the fact that Java5 annotations can be dropped by the compiler, whereas some can be retained in the bytecode. This is controlled by the #Retention annotation that is placed on your annotation type, e.g
#Documented
#Retention(value=RUNTIME)
public #interface Deprecated
This indicates that the #Deprecated annotation will be present in the bytecode, and will also be visible to reflection. java.lang.annotation.RetentionPolicy defines the different options.
"Annotations are more flexible in terms of how you use them, with options for whether the annotation information is to be included in class files output by the compiler and made available to the application at run time"
It is more flexible than XDoclet because:
it can be used from the source code (like XDoclet)
it can be used at runtime, when you only have the byte-code and not the source code (unlike XDoclet)
While annotations are ideal for metadata that relates to a particular component, they are not well suited to metadata with cross-component application.
Annotations (like XDoclet) have one interesting feature, as opposed to an external Xml for example :
Annotations live in the code, so it is natural for them to be applied to the code they are defined on. You don't have to specify (using some complex syntax) to what piece of code they apply. Examples:
if an annotation is defined on a method, it applies naturally to that method
if an annotation is defined on a field, it applies naturally to that field
if an annotation is defined on a class, it applies naturally to that class
if an annotation is defined on a package, it applies naturally to that package
If you want to have the same in an external Xml file, you have to use a complex syntax to identify the piece of code you refer to. So that makes them very easy to apply.
Also, in case of a code refactoring (like renaming), annotations continue to work just fine, while an external xml would have to be changed to point to the new class or method name.
I don't believe that in a web application, most things are cross-component.
If you defined Persistance (to a database) of an Entity, like what is the table where this class should be persisted, it is not something global to all Entities, it only affects the current Entity.
same for many other examples...

Categories