1

I've been able to generate 99% of what I need with the CodeModel API, but I am stumped here...

Using the various "directXX" methods does not add import statements to the generated code, and I can work without the "directXXX" type of methods except for one place in a generated class.

Suppose I desire a generated method like:

/**
* Copies data from this Value-Obj instance, to the returned PERSON instance.
* 
* @return PERSON
* 
*/
public PERSON mapVOToPERSON() throws MappingException
{
   Mapper mapper = (com.blah.util.MapperSingleton.getMapperInstance());
   return mapper.map(this, PERSON.class);
}

You can see the right hand of the Mapper assignment in parens. Emitting the entire package+class was the only way I could find to just declare "SomeSingleton.someMethod()" on the right hand side and have the generated code compile. Without the MapperSingleton being added to the object model, there is no import generated...

Questions:

1) Is there a way to force an import to be generated?

2) How to declare an expression that gives me the right side of the Mapper assignment within the object model (so that an import of MapperSingleton gets generated.

Any help appreciated...

Luca Geretti
  • 10,206
  • 7
  • 48
  • 58
antarti
  • 11
  • 1
  • 2
  • Can you insert a dummy variable of type com.blah.util.MapperSingleton with JBlock.decl(). If you don't assign it, I think javac will omit it during compilation so there won't be any overhead – Peter Hull Jan 31 '11 at 15:02

2 Answers2

4

Maybe I don't understand the question fully but, is code like this OK?

JCodeModel model = new JCodeModel();
JClass mapper = model.directClass("com.another.Mapper");
JClass factory = model.directClass("com.another.MapperSingleton");
JDefinedClass dc = model._class("com.example.Something");
JMethod method = dc.method(JMod.PUBLIC | JMod.STATIC, mapper, "testMethod");
method.body()._return(factory.staticInvoke("getMapperInstance"));
model.build(destinationDirectory);

It will generate

package com.example;

import com.another.Mapper;
import com.another.MapperSingleton;

public class Something {


    public static Mapper testMethod() {
        return MapperSingleton.getMapperInstance();
    }

}

This is with CodeModel 2.4

EDIT! Second try

    JCodeModel model = new JCodeModel();
    JClass mapper = model.directClass("com.blah.util.Mapper");
    JClass factory = model.directClass("com.blah.util.MapperSingleton");
    JDefinedClass dc = model._class("com.example.Something");
    JDefinedClass person = model._class("com.example.PERSON");
    JMethod method = dc.method(JMod.PUBLIC, person, "mapVOToPERSON");
    JBlock block = method.body();
    JVar lhs = block.decl(mapper, "mapper", factory.staticInvoke("getMapperInstance"));
    JInvocation map = lhs.invoke("map");
    map.arg(JExpr._this()); 
    map.arg(person.dotclass());
    method.body()._return(map);
    model.build(destinationDirectory);

Generates

package com.example;

import com.blah.util.Mapper;
import com.blah.util.MapperSingleton;

public class Something {


    public PERSON mapVOToPERSON() {
        Mapper mapper = MapperSingleton.getMapperInstance();
        return mapper.map(this, PERSON.class);
    }

}
Peter Hull
  • 6,683
  • 4
  • 39
  • 48
  • What I am looking for is how I can use something other than the "_return" to just make it the right hand side of the assignment in my original example. I can't seem to just make the right hand side expression of the "Mapper mapper = MapperSingleton.getMapperInstance" correctly, so as to get an import. Thanks for the tip though, it might get me going in the right direction. – antarti Jan 31 '11 at 16:49
  • 1
    BTW I am using codemodel 2.4 also, and just to be clear I do not care for the parens around the "MapperSingleton.getMapperInstance()", but they are there when I generate with my current code. – antarti Jan 31 '11 at 17:47
  • You're welcome … but, how DO you add a 'this' with CodeModel. staticRef("this") isn't quite right... – Peter Hull Jan 31 '11 at 20:18
  • Does this solved your question antarti? Can you please accept this answer so that we can close this question? Also, you need to accept answers to previous questions if they fix your problem. – Zecas May 24 '12 at 17:20
1

Peter, I think what you're looking for is JVar#init(JExpression). This is the method you should use to create the RHS initialisation of a variable or field declaration.

So, when you declare mapper and get a JVar, call init on this JVar and pass in the JExpression that represents your call to com.blah.util.MapperSingleton.getMapperInstance().

In order to create the JExpression you need (one that represents a call to MapperSingleton), use myclass.owner().ref(MapperSingleton.class).staticInvoke("getMapperInstance").

joelittlejohn
  • 11,665
  • 2
  • 41
  • 54