I was doing some research into PolymerDart and the various annotations which can be applied to the dart files. Be it: #Property, #property, #observe, #reflectable, #PolymerRegister, OR #HtmlImport.
So, I started to look into the concept of Dart and how to make annotations for them. I saw on stackoverflow that you can do something like this.
class Datatable {
final String name;
const DataTable(this.name);
}
which can easily do some additional information inside the constructor optionally.
class Datatable {
final String name;
const DataTable(this.name) {
console.log("$name was referenced.");
}
}
So, I can create and implement a variety of Annotations we could leverage, but this is where it starts to get fishy.
I was curious if there was a way to create annotations for polymerdart? is that mostly locked down, or can is there a way to create ones which do simple functions, maybe even for example: creating an Annotation which executes the #Property(computed:"") functionality.
I was wanted to create some sort of customization for our team to use.
For the record, I know that i can do something like
const myCustomAnnotation = const Property();
which would allow me to do:
#myCustomAnnotation
I was thinking I could then do something like like:
class myCustomComputed extends Property {
final String functionName;
const myCustomComputed() : Property(computed: this.functionName);
}
to allow me to do something like:
#myCustomComputed("testFunction(varA)")
This is a big topic, but the brief answer is, yes, what you describe is technically possible but not trivial.
Dart annotations are available at runtime via reflection, but are most often used by pub transformers during the build process. The purpose of a transformer is to modify assets (e.g. dart code) to some new form before runtime.
The Polymer annotations you mentioned above are handled by the Polymer transformer. This transformer handles identifying the annotations you mentioned above and automatically rewriting annotated code to include all the necessary implementations and wiring such that everything behaves as we expect as Polymer elements.
So there's nothing stopping you from defining your own annotations and transformers, including those that build upon the existing Polymer transformers, and packaging it up for your own or others' use.
I will note though that it is somewhat complex topic (ref the Polymer transformer) and there seem to be few simple code-rewriting transformer examples from which to build on.
I have the following situation. There are two combos on my UI form, one shows the list of vegetables and another one shows a list of fruits.
In my supporting view class I'd like to declare such methods:
#UiFactory
SimpleComboBox<Vegetable> createVegetablesCombo() {
return vegetables;
}
#UiFactory
SimpleComboBox<Fruit> createFruitsCombo() {
return fruits;
}
But it seems that GWT does not recognize parameterized returned types... Every time I get an error:
ERROR: Duplicate factory in class VegetablesAndFruitsView for type SimpleComboBox.
Is it possible to handle this case? Is there a good example of multiple comboboxes on one UI form?
From the perspective of Java (not GWT, not UiBinder, but the Java language itself) at runtime there isn't a difference between SimpleComboBox<Vegetable> and SimpleComboBox<Fruit>. That said, this error is coming from UiBinder's code generation, which is looking for all #UiConstructor methods, and using them to build things.
So what does UiBinder have to work with? From the UiBinder XML, there is no generics. The only way UiBinder could get this right is if you happen to have included a #UiField entry in your class with the proper generics. This then would require #UiField annotations any time there might be ambiguity like this, something GWT doesn't presently do.
What are you trying to achieve in this? You are returning a field (either vegetables or fruits) - why isn't that field just tagged as #UiField(provided=true)? Then, whatever wiring you are doing to assign those fields can be used from UiBinder without the need for the #UiConstructor methods at all.
#UiField(provided=true)
SimpleComboBox<Fruit> fruits;
//...
public MyWidget() {
fruits = new SimpleComboBox<Fruit>(...);
binder.createAndBind(this);
}
...
<form:SimpleComboBox ui:field="fruits" />
If this is just an over-simplification, and you actually plan on creating new objects in those methods, then consider passing an argument in, something like String type, and returning a different SimpleComboBox<?> based on the value. From your UiBinder xml, you could create the right thing like this:
<field:SimpleComboBox type="fruit" />
I am using Xtext do define a new language. I wish to generate code from this language, however I do not want to use the automatically suggested doGenerate function. Instead, I need to use a java code (not Xtend), that I can call from the build process.
Of course in that java code I want to be able to use the 'resource' that is passed to the original suggested function, so I can access all the information from the DSL's code.
I Believe by default the generator is implementation is an xtend file but there is nothing stopping you from changing this to a java file, you just need to override the binding in your [LanguageName]RuntimeModule class as follows:-
public class ExampleRuntimeModule extends com.example.AbstractExampleRuntimeModule {
#Override
public Class<? extends IGenerator> bindIGenerator() {
return YourOwnGenerator.class;
}
}
Where YourOwnGenerator should implement IGenerator.
I'd like to generate method-chaining setters (setters that return the object being set), like so:
public MyObject setField (Object value) {
this.field = value;
return this;
}
This makes it easier to do one-liner instantiations, which I find easier to read:
myMethod (new MyObject ().setField (someValue).setOtherField (someOtherValue));
Can Eclipse's templates be modified to do this? I've changed the content to include return this; but the signature is not changed.
I confirm eclipse (up to 3.5RC1) does not support "method chaining" setter generation.
It only allows for comment and body customization, not API modification of a setter (meaning a generated setter still return 'void').
May be the plugin Builder Pattern can help here... (not tested though)
Classic way (not "goof" since it will always generate a "void" as return type for setter):
(source: eclipse.org)
Vs. new way (Builder Pattern, potentially used as an Eclipse plugin)
alt text http://www.javadesign.info/media/blogs/JDesign/DesignConcepts/DesignPatterns/GOF/Creational-BuilderPatternStructure.jpeg
Don't use eclipse myself, but you'll have to change one of the standard templates if you can't find a feature.
It's called method chaining by the way (which might help with a Google search or two).
GWT.create() is the reflection equivalent in GWT,
But it take only class literals, not fully qualified String for the Class name.
How do i dynamically create classes with Strings using GWT.create()?
Its not possible according to many GWT forum posts but how is it being done in frameworks like Rocket-GWT (http://code.google.com/p/rocket-gwt/wiki/Ioc) and Gwittir (http://code.google.com/p/gwittir/wiki/Introspection)
It is possible, albeit tricky. Here are the gory details:
If you only think as GWT as a straight Java to JS, it would not work. However, if you consider Generators - Special classes with your GWT compiler Compiles and Executes during compilation, it is possible. Thus, you can generate java source while even compiling.
I had this need today - Our system deals with Dynamic resources off a Service, ending into a String and a need for a class. Here is the solutuion I've came up with - btw, it works under hosted, IE and Firefox.
Create a GWT Module declaring:
A source path
A Generator (which should be kept OUTSIDE the package of the GWT Module source path)
An interface replacement (it will inject the Generated class instead of the interface)
Inside that package, create a Marker interface (i call that Constructable). The Generator will lookup for that Marker
Create a base abstract class to hold that factory. I do this in order to ease on the generated source code
Declare that module inheriting on your Application.gwt.xml
Some notes:
Key to understanding is around the concept of generators;
In order to ease, the Abstract base class came in handy.
Also, understand that there is name mandling into the generated .js source and even the generated Java source
Remember the Generator outputs java files
GWT.create needs some reference to the .class file. Your generator output might do that, as long as it is referenced somehow from your application (check Application.gwt.xml inherits your module, which also replaces an interface with the generator your Application.gwt.xml declares)
Wrap the GWT.create call inside a factory method/singleton, and also under GWT.isClient()
It is a very good idea to also wrap your code-class-loading-calls around a GWT.runAsync, as it might need to trigger a module load. This is VERY important.
I hope to post the source code soon. Cross your fingers. :)
Brian,
The problem is GWT.create doen't know how to pick up the right implementation for your abstract class
I had the similar problem with the new GWT MVP coding style
( see GWT MVP documentation )
When I called:
ClientFactory clientFactory = GWT.create(ClientFactory.class);
I was getting the same error:
Deferred binding result type 'com.test.mywebapp.client.ClientFactory' should not be abstract
All I had to do was to go add the following lines to my MyWebapp.gwt.xml file:
<!-- Use ClientFactoryImpl by default -->
<replace-with class="com.test.mywebapp.client.ClientFactoryImpl">
<when-type-is class="com.test.mywebapp.client.ClientFactory"/>
</replace-with>
Then it works like a charm
I ran into this today and figured out a solution. The questioner is essentially wanting to write a method such as:
public <T extends MyInterface> T create(Class<T> clz) {
return (T)GWT.create(clz);
}
Here MyInterface is simply a marker interface to define the range of classes I want to be able to dynamically generate. If you try to code the above, you will get an error. The trick is to define an "instantiator" such as:
public interface Instantiator {
public <T extends MyInterface> T create(Class<T> clz);
}
Now define a GWT deferred binding generator that returns an instance of the above. In the generator, query the TypeOracle to get all types of MyInterface and generate implementations for them just as you would for any other type:
e.g:
public class InstantiatorGenerator extends Generator {
public String generate(...) {
TypeOracle typeOracle = context.getTypeOracle();
JClassType myTYpe= typeOracle.findType(MyInterface.class.getName());
JClassType[] types = typeOracle.getTypes();
List<JClassType> myInterfaceTypes = Collections.createArrayList();
// Collect all my interface types.
for (JClassType type : types) {
if (type.isInterface() != null && type.isAssignableTo(myType)
&& type.equals(myType) == false) {
myInterfaceTypes.add(type);
}
for (JClassType nestedType : type.getNestedTypes()) {
if (nestedType.isInterface() != null && nestedType.isAssignableTo(myType)
&& nestedType.equals(myTYpe) == false) {
myInterfaceTypes.add(nestedType);
}
}
}
for (JClassType jClassType : myInterfaceTypes) {
MyInterfaceGenerator generator = new MyInterfaceGenerator();
generator.generate(logger, context, jClassType.getQualifiedSourceName());
}
}
// Other instantiator generation code for if () else if () .. constructs as
// explained below.
}
The MyIntefaceGenerator class is just like any other deferred binding generator. Except you call it directly within the above generator instead of via GWT.create. Once the generation of all known sub-types of MyInterface is done (when generating sub-types of MyInterface in the generator, make sure to make the classname have a unique pattern, such as MyInterface.class.getName() + "_MySpecialImpl"), simply create the Instantiator by again iterating through all known subtypes of MyInterface and creating a bunch of
if (clz.getName().equals(MySpecialDerivativeOfMyInterface)) { return (T) new MySpecialDerivativeOfMyInterface_MySpecialImpl();}
style of code. Lastly throw an exception so you can return a value in all cases.
Now where you'd call GWT.create(clz); instead do the following:
private static final Instantiator instantiator = GWT.create(Instantiator.class);
...
return instantiator.create(clz);
Also note that in your GWT module xml, you'll only define a generator for Instantiator, not for MyInterface generators:
<generate-with class="package.rebind.InstantiatorGenerator">
<when-type-assignable class="package.impl.Instantiator" />
</generate-with>
Bingo!
What exactly is the question - i am guessing you wish to pass parameters in addition to the class literal to a generator.
As you probably already know the class literal passed to GWT.create() is mostly a selector so that GWT can pick and execute a generator which in the end spits out a class. The easist way to pass a parameter to the generator is to use annotations in an interface and pass the interface.class to GWT.create(). Note of course the interface/class must extend the class literal passed into GWT.create().
class Selector{
}
#Annotation("string parameter...")
class WithParameter extends Selector{}
Selector instance = GWT.create( WithParameter.class )
Everything is possible..although may be difficult or even useless. As Jan has mentioned you should use a generator to do that. Basically you can create your interface the generator code which takes that interface and compile at creation time and gives you back the instance. An example could be:
//A marker interface
public interface Instantiable {
}
//What you will put in GWT.create
public interface ReflectionService {
public Instantiable newInstance(String className);
}
//gwt.xml, basically when GWT.create finds reflectionservice, use reflection generator
<generate-with class="...ReflectionGenerator" >
<when-type-assignable class="...ReflectionService" />
</generate-with>
//In not a client package
public class ReflectionGenerator extends Generator{
...
}
//A class you may instantiate
public class foo implements Instantiable{
}
//And in this way
ReflectionService service = GWT.create(ReflectionService.class);
service.newInstance("foo");
All you need to know is how to do the generator. I may tell you that at the end what you do in the generator is to create Java code in this fashion:
if ("clase1".equals(className)) return new clase1();
else if ("clase2".equals(className)) return new clase2();
...
At the final I thought, common I can do that by hand in a kind of InstanceFactory...
Best Regards
I was able to do what I think you're trying to do which is load a class and bind it to an event dynamically; I used a Generator to dynamically link the class to the event. I don't recommend it but here's an example if it helps:
http://francisshanahan.com/index.php/2010/a-simple-gwt-generator-example/
Not having looked through the code of rocket/gwittir (which you ought to do if you want to find out how they did it, it is opensource after all), i can only guess that they employ deferred binding in such a way that during compile time, they work out all calls to reflection, and statically generate all the code required to implement those call. So during run-time, you cant do different ones.
What you're trying to do is not possible in GWT.
While GWT does a good job of emulating Java at compile time the runtime is of course completely different. Most reflection is unsupported and it is not possible to generate or dynamically load classes at runtime.
I had a brief look into code for Gwittir and I think they are doing their "reflection stuff" at compile time. Here: http://code.google.com/p/gwittir/source/browse/trunk/gwittir-core/src/main/java/com/totsp/gwittir/rebind/beans/IntrospectorGenerator.java
You might be able to avoid the whole issue by doing it on the server side. Say with a service
witch takes String and returns some sort of a serializable super type.
On the server side you can do
return (MySerializableType)Class.forName("className").newInstance();
Depending on your circumstances it might not be a big performance bottleneck.