Book a Demo

Author Topic: Some trouble creating a code template  (Read 7694 times)

casper

  • EA Novice
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Some trouble creating a code template
« on: October 24, 2005, 06:21:03 am »
I want to create a custom code template. The target implementation is nHibernate. As you may know this is a XML type file. It maps the objects to their equal (relational) entities.

I have figured out quit a bit, but still I'm stuck with some parts.

1) Is it possible to add the childs of a class to the base class contents (this is how nHibernate handels inheritance). Which value holds the child classes of a class?

2) Adding custom properties to a class for nHibernate.
Like lazy-loading or discriminator-value.
(I know this isn't very elegant, it sure does break down the UML standard)

3) Is it possible to export Code Templates so other may use it as well. Instead of using the EAP which contains the Code Template.

If all goes well and my company let me, I will make the nHibernate template free to use to anyone.

p.s I couldn't store the EAP any where, at work we don't have the lesuire of FTP or any other public storage. So please don't ask for the file.

Eve

  • EA Administrator
  • EA Guru
  • *****
  • Posts: 8110
  • Karma: +119/-20
    • View Profile
Re: Some trouble creating a code template
« Reply #1 on: October 24, 2005, 04:50:42 pm »
Hi Casper,

1) Currently the only way to do list over base class contents is to use an addin call witin the template.  I'd recommend adding a list over all generalization connectors and making a call using the opposite end to your current class.

The following may help.

Code: [Select]
%if classGUID==connectorSourceElemGUID%$guid=%connectorDestElemGUID%
%else%
$guid=%connectorSourceElemGUID%
%endIf%

2) a. Tagged values on the class accessed with %classTag:"tagName"%
b. Stereotyped attributes/operations, then add stereotype override template.  Lists can then have a condition on the stereotype.

3) Tools | Export Referenece Data.  Select nHibernate_Code_Template

If you are allowed to share them, you could upload them onto http://www.eausergroup.org/.

casper

  • EA Novice
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: Some trouble creating a code template
« Reply #2 on: October 24, 2005, 11:54:22 pm »
Hi Simon,

First of all, thanks for the quick reply. Your information was most helpful, still I'm left with some questions.

1) How do I manualy set the type of extention for my generated sourcecode? since when I use nHibernate I want my files to have the hbm.xml extention, not .h

2) How to access tag values of a connector. I tried %connectorTag:"name"% still it didn't work.

3) why doesn't  classBaseName return the name of the base class (or doesn't it because I have a link/Generalization to it?)


Well I hope you could provide me with an awnser. My Code template file looks like this.

Code: [Select]

 <?xml version="1.0"  encoding="windows-1252"?>
<RefData version="1.0" exporter="EA.25">
     <DataSet name="nHibernate_Code_Template" table="t_template" filter="TemplateType='#TemplateType#' and TemplateName='#TemplateName#' and Style='#Style#'">
           <DataRow>
                 <Column name="TemplateID" value="{466B9884-DC98-41da-8789-2944EADCBEA4}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="File"/>
                 <Column name="Template" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;\n
%list=&quot;Namespace&quot; @separator=&quot;\n&quot;%

"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{2A51372E-C775-4b7b-B75B-3593611123E8}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Namespace"/>
                 <Column name="Template" value="%list=&quot;Namespace&quot; @separator=&quot;\n&quot;%
%NamespaceBody%
"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{D17B044C-47B4-41a0-84C8-170BF67CCCE5}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Class"/>
                 <Column name="Template" value="%ClassBody%
"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{65DB8043-8B24-44ad-ACBB-46D4431F65D2}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Attribute"/>
                 <Column name="Template" value="%if classTag:&quot;discriminatorValue&quot; != attName%
&lt;property access=&quot;property&quot; name=&quot;%attName%&quot; column=&quot;%attName%&quot; type=&quot;%attType%&quot;/&gt;
%endIf%"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{B9BDEE8C-FC92-4b22-9D34-B1B8B3394241}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Linked Attribute"/>
                 <Column name="Template" value="&lt;many-to-one access=&quot;field&quot; name=&quot;%linkAttName%&quot; class=&quot;%linkParentName%&quot; /&gt;
"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{9F48B0D3-0CEF-475b-A662-1B57553BC747}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Linked Class Base"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{167473FC-038B-402c-A209-41D2C354E807}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Class Inherits"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{B345563B-E761-43f5-B35F-4CABCB6F6913}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Namespace Body"/>
                 <Column name="Template" value="$classes = %list=&quot;Class&quot; @separator=&quot;\n&quot;%
%if $classes != &quot;&quot;%
&lt;hibernate-mapping xmlns=&quot;urn:nhibernate-mapping-2.0&quot; namespace=&quot;%packagePath%&quot; assembly=&quot;%packageName%&quot;&gt;\n
$classes
&lt;/hibernate-mapping&gt;
%endIf%"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{DCFA47A6-2203-4f5f-B679-E18414F7D37C}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Class Impl"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{0D8B728F-303A-4e98-A1AA-06E561D05A6B}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Class Base"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{49E53475-BBBF-4b65-8598-7B9AAAD7DD76}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Class Body"/>
                 <Column name="Template" value="$tablename = %className%+&quot;s&quot;
$tablename = %REPLACE($tablename , &quot;ys&quot;, &quot;ies&quot;)%

%if classHasParent != &quot;T&quot;%
&lt;class name=&quot;%className%&quot; table=&quot;$tablename&quot;&gt;
%list=&quot;Attribute&quot; @separator=&quot;\n&quot;%
%list=&quot;LinkedAttribute&quot; @separator=&quot;\n&quot;%
&lt;/class&gt;
%else%
$connectors = %list=&quot;Connector__All&quot; @separator=&quot;\n&quot;%
%if $connectors != &quot;&quot;%
$connectors
%endIf%
%endIf%
"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{14E2958A-824F-4f31-9EDD-4EA3849EEFCC}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Namespace Impl"/>
           </DataRow>
           <DataRow>
                 <Column name="TemplateID" value="{3EE7EE9F-BA93-4224-A4AA-0778AE6CC9FE}"/>
                 <Column name="TemplateType" value="nHibernate_Code_Template"/>
                 <Column name="TemplateName" value="Connector__All"/>
                 <Column name="Template" value="$tablename = %className%+&quot;s&quot;
$tablename = %REPLACE($tablename , &quot;ys&quot;, &quot;ies&quot;)%

$proxy = &quot;proxy=&quot;+%qt%+%classTag:&quot;proxy&quot;%+%qt%
$dUpdate = &quot;dynamic-update=&quot;+%qt%+%classTag:&quot;dynamicUpdate&quot;%+%qt%
$dInsert = &quot;dynamic-insert=&quot;+%qt%+%classTag:&quot;dynamicInsert&quot;%+%qt%

%if connectorType == &quot;Generalization&quot; %
&lt;joined-subclass name=&quot;%className%&quot; $dUpdate $dInsert $proxy extends=&quot;%connectorDestElemName%&quot; table=&quot;$tablename&quot;&gt;
&lt;key /&gt;
%list=&quot;Attribute&quot; @separator=&quot;\n&quot;%
%list=&quot;LinkedAttribute&quot; @separator=&quot;\n&quot;%
&lt;/joined-subclass&gt;
%endIf%"/>
           </DataRow>
     </DataSet>
</RefData>
« Last Edit: October 25, 2005, 07:13:12 am by Casper »

Eve

  • EA Administrator
  • EA Guru
  • *****
  • Posts: 8110
  • Karma: +119/-20
    • View Profile
Re: Some trouble creating a code template
« Reply #3 on: October 25, 2005, 04:39:59 pm »
1) Not really any supported way at the moment.  You can work around the issue by setting the default extension for C++ (because that appears to be your default language) to .xml instead of .h.

2) Unfortunately there isn't currently any support for getting tagged values from connectors.  So again you would need to make an addin call using EXEC_ADD_IN to get them.

3) classBaseName won't be defined outside of a ClassBase template.  So you'll need to add a %list="ClassBase" @separator=", "% and %list="ClassInterface" @separator=", "% if you need interfaces too.  Then you'll need to define a template for Class Base, Class Interface, Linked Class Base and Linked Class Interface.  If you actually have the link/Generalization then you'll need to use %linkParentName% in the LinkedClassBase template.

casper

  • EA Novice
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: Some trouble creating a code template
« Reply #4 on: October 27, 2005, 02:27:13 am »
Sory to bother you again with a Code Generation Template question. I just couldn't figure it out myself.

What I want to do is get the list of attributes of the connector's destination. Since the class which holds the attributes doesn't exist in the database I want to add them to the entity the class belongs to. This only happends when a connection is made of the aggregation type composite (and the connection has a multiplicity of 1 or 0..1).

For now I got this:

Code: [Select]

%if connectorDestAggregation == 2%
           <component name="%connectorDestRole%" class="%connectorDestElemName%">
                      %list="connectorDestElemAttribute" @separator="\n"
           </component>
%else%
      <one-to-one access="field" name="%connectorDestRole%" column="%connectorDestRole%" class="%connectorDestElemName%" />
%endIf%

Eve

  • EA Administrator
  • EA Guru
  • *****
  • Posts: 8110
  • Karma: +119/-20
    • View Profile
Re: Some trouble creating a code template
« Reply #5 on: October 27, 2005, 04:05:51 pm »
As I said previously, there isn't any direct access to the attributes at the other end of a connector.  The closest that you can come to that is the following.

Code: [Select]

%if connectorDestElemMultiplicity=="1" or connectorDestElemMultiplicity=="0..1" or connectorDestAggregation == 2%
           <component name="%connectorDestRole%" class="%connectorDestElemName%">
                      %EXEC_ADD_IN("nHibernateTemplateHelper","ListClassAttributes",connectorDestElemGUID)%
           </component>
%else%
      <one-to-one access="field" name="%connectorDestRole%" column="%connectorDestRole%" class="%connectorDestElemName%" />
%endIf%

Note that I also modified your if condition to handle your multiplicity constraint.  The ordering of the expression is important because and/or precedence isn't handled.

casper

  • EA Novice
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: Some trouble creating a code template
« Reply #6 on: October 28, 2005, 03:32:34 am »
Well, it's me again ;D

I followed up your advice about creating a add-in. The fact is, it wont work.

I looked at your examples and I consructed my own add-in. When I load it up, everything works like a charm. The EA_Connect function works and I'm also able to create a menu item. But when I use my Add-in in the code template, it wont result anything. I guess I'm doing something wrong, but I couldn't figure it out.

An excerpt of my C# Add-in
Code: [Select]

namespace nHibernateTemplateHelper
{
   public class Main
   {
 
       public String EA_Connect(Repository repository)
       {
           System.Windows.Forms.MessageBox.Show("Howdy!"); // This works
           return "";
       }

       public String ListClassAttributes(Repository repository, String connectorDestElemGUID)
       {
           return "anything";
       }
}
}


As template code I use the same Simon made except the connectorDestElemGUID has no space between.

I registrated my plugin as:

[HKEY_CURRENT_USER\Software\Sparx Systems\EAAddins\Test]
@="nHibernateTemplateHelper.Main"

Also I tried some minor alterations like lowcaps or string instead of String. Well again thanks for the support!

* added an extra }
« Last Edit: November 01, 2005, 04:47:43 am by Casper »

casper

  • EA Novice
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: Some trouble creating a code template
« Reply #7 on: November 01, 2005, 01:18:11 am »
Well I'm almost there. I figured out my registry settings weren't right. The 'Test' in [HKEY_CURRENT_USER\Software\Sparx Systems\EAAddins\Test]  should have been 'nHibernateTemplateHelper'. Otherwise EA isn't able to call it when using
Code: [Select]
%EXEC_ADD_IN("nHibernateTemplateHelper","ListClassAttributes",connectorD estElemGUID)%

But still it doesn't work. When I execute the code generation template the plugin is found but EA show's an error window which states;
An error has occured while attempting to communicate whit an Addin: nHibernateTemplateHelper(nHibernateTemplateHelper.Main)"ListClassAttributes: Invalid Parameter(s)" Please contact the add-in provider for assistance."

It's prety straight foreward but still I can't fix it my self. I Added several different variations of the ListClassAttributes method to my Add-in. But none of them worked.

casper

  • EA Novice
  • *
  • Posts: 2
  • Karma: +0/-0
    • View Profile
Re: Some trouble creating a code template
« Reply #8 on: November 01, 2005, 04:47:05 am »
Sorry, I forgot to put an extra brace in the code example. I didn't copy paste it entirely, I only pasted the important parts. There's no need for a bloated example when only a few functions are important.

Btw. I have found what I did wrong. My C# function shouldn't been like that. It should be like:

Code: [Select]

     public object ListClassAttributes(Repository repository, object connectorDestElemGUID)
       {
             // Function content
       }
« Last Edit: November 01, 2005, 06:23:18 am by Casper »