Activity node get executed in a template that accepts only Class type - acceleo

I have an uml diagram made with Topcased 5.2. The uml contains Class diagram and Activity Diagram.
I wrote a template that accepts as parameter Class type in order to generate java classes.
The java classes were generated but in addition my method get executed for Activity node. How can I prevent execution of Activity node?
Following my template:
[template public generateEntity(c : Class)]
[comment #main /]
[file (c.getEntityFullPathFile().trim(), false)]
[c.generateEntity()/]
[/file]
[/template]
Thanks for your help

Please have a look at the UML metamodel (File > import > select "plugins and fragments", click 'next' then search for 'org.eclipse.uml2.uml', select it and 'Finish' the wizard). In there, you will see that an Activity is a Class (Activity inherits from Behavior which inherits from Class). That's all Acceleo 'sees'.
If you wish to generate your code for all Classes save for Activities, you can use a guard :
[template public generateEntity(c : Class) ? (not c.oclIsKindOf(Activity))]
...

Related

Can we use UmlStateMachineModelFactory inside a StateMachineBuilder

I am using StateMachineBuilder to create state machine , coz I needed to use it programatically to configure states and transitions.
But due to some requirement change my configuration is almost constant and now I wanted to use eclipse uml modelling since I no longer need to build state machine dynamically or programatically.
To avoid big code rework I thought of using UmlStateMachineModelFactory inside builder like below.
Builder<String, String> builder = StateMachineBuilder
.<String, String> builder();
builder.configureConfiguration()
.withConfiguration()
.autoStartup(false)
.listener(listener())
.beanFactory(
this.applicationContext.getAutowireCapableBeanFactory());
builder.configureModel().withModel().factory(new UmlStateMachineModelFactory("classpath:model2.uml"));
1) Is it legal in state machine, if so how can I attach entry actions for each state?
Currently using the builder I am using the below code for attaching entry actions for each state
stateConfigurer.state("State1", this.state1EntryAction, null);
// State1EntryAction is #Autowired inside my controller class and
// State1EntryAction implements Action<String, String> and
// annotated with #Component (org.springframework.stereotype.Component)
2) Can i give the name of entry action class inside the uml model, order to attach entry actions for each stage? if so how can i do that in eclipse papyrus.
Thanks in Advance!
Docs are probably a little unclear of this(especially if user is not familiar with papyrus and uml concepts). I'd start by studying uml test sources in uml xml test files how actions/guards are referenced from uml into a runtime resolving. Things become more clear when you see those using real papyrus uml modeler.
On default guard/action will resolve as equivalent bean name from an application context, but there is a way to hook additional instances manually(i.e. if guard/action is not defined as a bean).
This test testSimpleFlat2() will register additional actions/guards. These are resolved via StateMachineComponentResolver interface and internally instance of DefaultStateMachineComponentResolver will resolve from BeanFactory if it's known but user can add secondary DefaultStateMachineComponentResolver as demonstrated in that test.

Add attributes to Entity Framework database first generated classes

I am using Entity Framework 4.1 and generating my classes using the database first approach. I have a an EDMX file in my solution.
I am trying to add attributes to my classes using the MetadataTypeAttribute approach which seems to be the recommended way of doing this outside of editing the T4 template, however, I cannot seem to get it to work because I keep getting this compile error:
'Patient' is an ambiguous reference between 'PatientManagementSystem.Patient' and 'PatientManagementSystem.Models.Patient'
Here is the code I am using:
[MetadataTypeAttribute(typeof(PatientMetadata))]
public partial class Patient
{
}
public class PatientMetadata
{
[Required]
public string LastName {get; set;}
}
Is this error happening because I don't actually have classes for this because I am doing Database first and everything in the EDMX?
Thanks!
Flea
Make sure both are in the same namespace. Since it's a partial class, the class you are modifying must also be in the same namespace or it isn't the same class.

Cannot Create Controller with EF Generated DBContext Classes using Partial Classes

I have an interface defined as:
public interface ICMDBContext
{
DBSet<Building> {get;}
DBSet<Room> {get;}
more DBSet methods...
string Save()
}
I have the DBContext generated class named CMDB_DataModelContainer.
I have a partial class CMDB_DataModelContainer which implements ICMDBContext which looks like this (And yes, both are in the same namespace):
public partial class CMDB_DataModelContainer : ICMDBContext
{
string Save() { implemenation... }
}
Everything compiles all fine and dandy, but when I try to create a controller and use CMDB_ModelConatiner as the context class (creating a Strongly-typed controller) I get the error
There was an error generating 'CMDB.Domain.Models.CMDB_DataModelContainer'. Try rebuilding your project.
I removed the partial class and was able to create the controller. Any ideas why this would happen?
To add, the DBContext classes are in a separate project.
The fact it is in a separate project doesn't matter. I created a test project with DBcontext class and the MVC3 app in same project and still a no go.
I suppose a question to ask is if anyone has actually setup a repository when using Model first approach. I am finding myself running into problem after problem trying to apply this pattern when using model first.
If you want to recreate the issue, just make an MVC 3 (or 4, I used 3). This is what I did for a test to recreate it myself.
Add a new ADO.Net Entity Data Model.
Create two entities: Taco and Filling
Add a "name" scalar property to each.
Add association m <---> m
Create a new folder named "Partial" in the models folder.
Add a new class - the class should be named the same as the Context class (if you left default names it should be Model1Container) and in the same namespace.
e.g.
public partial class Model1Container
{
}
- Add a new controller "TacoController" as strongly typed against, you guessed it, Taco, and using the Model1Container as the context class. Voila, reproduced. Yes, I like tacos.
As you have probably discovered, removing(/renaming) the partial class, creating the controller and then reinstating your partial class seems to be an adequate workaround. As for why:
One of the times I tried I noticed something strange: a new declaration had appeared in the partial class file I'd created:
public DbSet<Taco> Taco { get; set; }
I can only speculate that VS is getting confused by the partial class files - it finds the partial class file you created, doesn't see the DBSet declared, tries to add it and then gets in a tizzy because that's too many tacos.
Chris

Validate attributes through edmx

I'm working on an MVC3 project I have created my database on SQL server 2008 then I add it using entity data model, now I have the .edmx I don't want to generate the code of the classes because till now it's not stable and I don't feel the need to do that except to make the validations
I'm wondering if there is a way to make validation directly using the .edmx without generating the code of classes
Need server and client side validation
Cheers
You can't do it from edmx. You can however have classes that add the metadata to the edmx generated classes.
This adds a metadata containing class to the class that was generated by the edmx:
[MetadataTypeAttribute(typeof(CustomerMetadata))]
public partial class Customer
{
}
and then you have the metadata class which has the metadata attributes:
internal sealed class CustomerMetadata
{
public int ID;
[Required]
[StringLength(60)]
public string Name;
}
Edit:
EF generates all it's classes as partial. That means you can add functionality in a different file to the same class. We use this feature to add an attribute telling .net that there's a class that has the metadata information. In this case the class with the metadata for the Customer class is CustomerMetadata.
It has all the properties that you want decorated with metadata. In this case ID is not actually required to be there.
(I would have added this as a comment but I don't have enough reputation points yet)
Be sure that the namespace in your partial class exactly matches the EF-generated class's namespace, including the correct case.

Defining data annotation using DbContext versus Objectcontext in the database first approach

I am using the database first approach with entity framework, when i used to work on the default template the database tables were mapped using the ObjectContext, so i used to create #partial classes & [MetadataType(typeof ) to apply the data annotation ,, but when i start using the Dbcontext code generation template to map the database tables i found that it will create .tt folder in my Model area were i find that i can apply the data annotation directly to the .cs classes themselves without the need to create partial classes as in objectcontext case.
Currently the data annotations are working fine,, but would my approach cause me problems i am not aware of and i should create partial classes as i used to do with the Objectcontext ?
BR
In general, you shouldn't edit generated code because changes you make will be overwritten on re-generation. This is why most generators emit partial classes.
The best practice for your situation would be to create a new file in your solution with another partial class declaration. In that file, add the MetadataType attribute to the class, and add your property-level validation attributes to the "buddy" class (the one referenced in the attribute). This allows you to use validation attributes on the generated properties and, should your model/database change, you can still re-generate your model classes without losing them.
For example, your new file might look something like:
[MetadataType(typeof(PersonMetadata))]
partial class Person
{
// Add logic to the generated class in here.
public string FullName
{
get { return FirstName + " " + LastName; }
}
}
class PersonMetadata
{
// Add attributes to the generated properties in here.
[Required]
public string FirstName { get; set; }
}
Create the same partial classes to define your metadata OR you can simply reverse engineer your existing database using the Entity Framework Power Tools so you have POCO classes. Then you can use the fluent API (you'll see the validations it adds for you) instead of data annotations to give you server side validation.
If you want client side, then you can still apply them to your models, as they wont be regenerated every time you compile .
however - I would recommend you create ViewModels and use AutoMapper to map between your EF objects and viewmodels. Then you can apply your annotations directly to your ViewModels.
My understanding of your situation is that you reverse-engineered your Database-First style to a Code-First style. If your context class inherits from DbContext, you are in Code-First style now (unless there is some strange hybrid possible, which I don't know about!).
In code-first, there is really no point of creating partial classes for data annotations, IMO.

Resources