-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: HibTools - Custom Exporter newbie
PostPosted: Wed Jul 09, 2008 5:28 pm 
Regular
Regular

Joined: Fri Jul 30, 2004 4:02 pm
Posts: 50
Hey all,
hibernate 3.2.4.ga, hibtools 3.2.0.ga.

I would like to create a custom exporter.

1) is there any good documentation/guideline/wiki/blog that will help someone get started on writing a custom exporter. Google and searching this forum didn't produce anything useful that I could find.

The intent of the custom exporter I'm trying to create is to generate a util class for all known stored procedures (haven't found a way to do this normally, so if there is please show me).

Ideally, I would like to create the exporter class, but have the exporter class not actually do anything, but be used simply as user-defined 'functions' for the template. Looking through the existing exporters, they all define .ftl's within the class itself which is why I'm asking if this is a reasonable expectation to have the exporter just be a util/function class to be used in a manually defined template or not.
Code:

<!-- template is required, exporterclass by itself for my custom exporter doesn't do anything -->
    <hbmtemplate
     template="sproc.ftl" 
          exporterclass="SprocExporter"
    >



sample sproc.ftl trying to get too:

Code:
<#foreach singlesproc in sproc.getProcedures()>
           System.out.println( ${sproc.getCatalog(singlesproc)} );
           System.out.println( ${sproc.getSchema(singlesproc)} );
           System.out.println( ${sproc.getProcedureName(singlesproc)} );
           System.out.println( ${sproc.getProcedureRemark(singlesproc)} );

<#foreach sproccolumn in sprocdetail.getProcedureColumns(singlesproc)>
           System.out.println( ${sprocdetail.getProcedureName(singlesproc)} );
           System.out.println( ${sprocdetail.getColumnName(singlesproc)} );
           System.out.println( ${sprocdetail.getColumnTypeName(singlesproc)} );
           System.out.println( ${sprocdetail.getColumnNullable(singlesproc)} );

           System.out.println( ${sprocdetail.getColumnRemark(singlesproc)} );
</#foreach>


</#foreach>




Now, for the real meat -- how to I pull this off? I'm guessing I need to identify the freemarker user-defined function with just the getTemplateHelper().putInContext(), and the getName() is not used?

Also assuming you want to extend AbstractExporter instead of GenericExporter, or should I be using GenericExporter?

Code:
public class SprocExporter extends AbstractExporter {

   @Override
   protected void doStart() {
      // TODO Auto-generated method stub
      
   }
   
   public String getName() {
      return "sproc"; //is this really needed?
   }   
   
   /**
    * Setup the context variables used by the exporter. Subclasses should call super.setupContext() to ensure all needed variables are in the context.
    **/
   protected void setupContext() {
      super.setupContext();
      getTemplateHelper().putInContext("sproc", this);
      getTemplateHelper().putInContext("sprocdetail", this);
      if(!getProperties().containsKey("ejb3")) {
         getProperties().put("ejb3", "false");
      }
      if(!getProperties().containsKey("jdk5")) {
         getProperties().put("jdk5", "false");
      }   
   }
   

//how do I add this as a sub-method for freemarker template?
       private String[] getProcedures(){
               //impl
                return "to be implemented";
       }
   
//how do I add this as a sub-method for freemarker template, and
//what should the parameter look like.
       private String getProcedureName(String procedure){
               //impl
                return "to be implemented";
       }

//should sprocdetail equivalent be it's own class?
     private String getSprocDetailColumnName(String procedure){
             //impl
             return "to be implemented";
     }


//use existing hibernate database connection...?


}



Sorry for the long post a lot of questions, I'm kinda jumping in both feet into the dark here.....


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 12, 2008 8:01 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
The docs has an example of customizing code generation.

If you just want an instance of class which utility methods to call see http://docs.jboss.org/tools/2.1.0.Beta1 ... ml#d0e3308

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 14, 2008 8:43 am 
Regular
Regular

Joined: Fri Jul 30, 2004 4:02 pm
Posts: 50
The utility method approach is perfect.

Now, for moving forward:

1) is 'hibernate.sometool.toolclass' always consistent, as in I shouldn't replace 'sometool' with a special value.

2) does there exist an example that actually does this approach (with specifying the hibernate.sometool.toolclass). The documentation show a template already in place instead of an external util class.

3) Is there direction as to how to write the util class -- should it be through AbstractExporter/GenericExporter (since I would like to re-use the database connection if possible), or should it be as a pure Freemarker and extend TemplateModelDirective for example.

Thanks for taking a look at my question,
-D


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 15, 2008 8:11 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
dhartford wrote:
1) is 'hibernate.sometool.toolclass' always consistent, as in I shouldn't replace 'sometool' with a special value.


the "sometool" is whatever you want.

HTools looks after hibernate..*.toolclass and put whatever .* matches into the context.

Quote:
2) does there exist an example that actually does this approach (with specifying the hibernate.sometool.toolclass). The documentation show a template already in place instead of an external util class.


The example is <property key="hibernatetool.sometool.toolclass" value="x.y.z.NameOfToolClass"/>, you just insert the property line in your existing <configuration> tag and replace "sometool" with whatever name you want and the value with whatever classname you have.

Quote:
3) Is there direction as to how to write the util class -- should it be through AbstractExporter/GenericExporter (since I would like to re-use the database connection if possible), or should it be as a pure Freemarker and extend TemplateModelDirective for example.


It is just a java class, if you want to pass in specific things then you just pass it in.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 15, 2008 11:09 am 
Regular
Regular

Joined: Fri Jul 30, 2004 4:02 pm
Posts: 50
If there does not exist an example that is an external util class, I'll try to step through this.


I've implemented so far:


Code:
   
<!-- filepattern must have {class-name}, otherwise doesnt export (?) -->
<hbmtemplate
     filepattern="{package-name}/model/{class-name}Sproc.java"
     templatepath="./template"
     template="sproc.ftl" 
    >

<!-- hibernatetool.%value%.toolclass, the %value% is what is used in the ftl to call the class and it's methods -->
       <property key="hibernatetool.checksproc.toolclass" value="com.mydomain.CheckSproc"/>
       <property key="ejb3" value="true"/>
       <property key="jdk5" value="true"/>
       <property key="mycustomkey" value="mycustomvalue"/>
</hbmtemplate>   



CheckSproc:
Code:
public class CheckSprocs extends AbstractExporter{

   public CheckSprocs(){
        super();
        System.out.println("Constructor called");
      
      Session session = null;
      SessionFactory sessionFactory = null;
      try {      
         sessionFactory = getConfiguration().buildSessionFactory(); //nullpointerexception
         session = sessionFactory.openSession();      
         if (session == null){
            System.out.println("Session is null!");
         }
         
      }catch(Exception e){
         System.out.println(e);
      }
      
      Set<Object> keySet = getProperties().keySet();
      System.out.println("List of properties:");
      for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
         Object object = (Object) iterator.next();
         System.out.println(object);
      }      
      
   }


     public String hello(){
            return "hello, it is working!";
}

}




sample.ftl (checksproc.hello is working):
Code:
This is a test.

Should be saying hello: ${checksproc.hello()}



Now, specifically, how would this get access to

*Hibernate Session (the already setup database connection)
*the template Properties (mycustomkey/mycustomvalue)

The constructor does not seem to have access to anything, and according to the AbstractExporter, the toolclass is instantiated with no-param constructor.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 21, 2008 1:11 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
dhartford wrote:
If there does not exist an example that is an external util class, I'll try to step through this.


a patch t the docs would be appreciated when you get it working ;)

Quote:
Code:
   
<!-- filepattern must have {class-name}, otherwise doesnt export (?) -->
<hbmtemplate
     filepattern="{package-name}/model/{class-name}Sproc.java"
     templatepath="./template"
     template="sproc.ftl" 
    >

<!-- hibernatetool.%value%.toolclass, the %value% is what is used in the ftl to call the class and it's methods -->
       <property key="hibernatetool.checksproc.toolclass" value="com.mydomain.CheckSproc"/>
       <property key="ejb3" value="true"/>
       <property key="jdk5" value="true"/>
       <property key="mycustomkey" value="mycustomvalue"/>
</hbmtemplate>   


filepattern looks for {class-name} to detect if it should iterate over classes or just the Configuration.

You can control that with the foreach attribute. foreach="entity, component" will do the same - but you would have to use *something* to distinguish the generated files and for that {class-name} is the best thing we got for now.

Quote:
CheckSproc:
Code:
public class CheckSprocs extends AbstractExporter{

   public CheckSprocs(){
        super();
        System.out.println("Constructor called");
      
      Session session = null;
      SessionFactory sessionFactory = null;
      try {      
         sessionFactory = getConfiguration().buildSessionFactory(); //nullpointerexception
         session = sessionFactory.openSession();      
         if (session == null){
            System.out.println("Session is null!");
         }
         
      }catch(Exception e){
         System.out.println(e);
      }
      
      Set<Object> keySet = getProperties().keySet();
      System.out.println("List of properties:");
      for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
         Object object = (Object) iterator.next();
         System.out.println(object);
      }      
      
   }


     public String hello(){
            return "hello, it is working!";
}

}



No need to extend AbstractExporter here; it is just a plain utility class.

Quote:
Now, specifically, how would this get access to

*Hibernate Session (the already setup database connection)


$cfg gives you access to the Configuration which you can use to get all the info you want...but noone asked for the db connection within the templates before - what is your usecase ?

ReverseEngineeringStrategy gets access to it because it more likely needs it - maybe that is what you need instead or ?

Quote:
*the template Properties (mycustomkey/mycustomvalue)


They are directly available as $mycustomkey.

_________________
Max
Don't forget to rate


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.