450 likes | 718 Views
SCE - 7 יצירת קוד מקור Code Generation (Velocity) דר’ יעקב אקסמן תשס"ו. הנדסת מרכיבי תוכנה. דרישות תוכנה. דגם הייררכי. דגם פיזיקלי. מרכיבים. קוד להרצה = exe. מדידות. Code-Generators תפיסה. יצירת קוד מקור מתוך תבניות תמליל בעזרת מנוע הצבה. Code-Generators תפיסה. נתונים.
E N D
SCE-7 יצירת קוד מקור Code Generation (Velocity) דר’ יעקב אקסמן תשס"ו
הנדסת מרכיבי תוכנה דרישות תוכנה דגםהייררכי דגםפיזיקלי מרכיבים קוד להרצה = exe מדידות
Code-Generators תפיסה יצירת קוד מקור מתוך תבניות תמליל בעזרת מנוע הצבה
Code-Generators תפיסה נתונים מנוע הצבה יעד תבניות
Velocity אתרים [Apache] www.apache.org = open source software projects [Jakarta] jakarta.apache.org = open source JAVA sub-projects [Velocity] jakarta.apache.org/velocity = JAVA-based template engine
Velocity ספרות [Naccar2004] Naccarato, G. “Template-Based Code Generation with Apache Velocity” [Parts 1 and 2.] http://www.onjava.com/pub/a/onjava/2004/05/05/cg-vel1.html http://www.onjava.com/pub/a/onjava/2004/06/02/cg-vel-2.html
תבניות תמליל דוגמה 1 תבנית 1 נתונים #person.txt $name = John $surname = Smith #person.template Hello, my name is $name and my surname is $surname
תבניות תמליל דוגמה 1 הצבה יעד > transformperson.txt person.template Hello my name is John and my surname is Smith
תבניות תמליל דוגמה 1 תבנית 2 #person2.template *********************** Name = $name Surname = $surname ***********************
תבניות תמליל דוגמה 1 הצבה 2 יעד2 > transformperson.txt person2.template *********************** Name = John Surname = Smith ***********************
Template Engine הפרדת מנוע שינוי תבנית או נתונים בלבד גורר שינוי יעד בלי לגעת במנוע הצבה
Code-Generators דוגמה 2 תבנית 1 נתונים יעד #student.txt $name = Student $base = Person #javaclass.template public class $name extends $base { } public class Student extends Person { } מחלקה ב-JAVA
Code-Generators דוגמה 2 תבנית 2 יעד #javainterface.template public interface $name implements $base { } public interface Student implements Person { } ממשק ב-JAVA
Code Generator שפות שונות אותם נתונים תבניות שונות כדי להפיק תוכניות בשפות שונות
Code-Generators דוגמה 2- שפה אחרת תבנית 3 יעד #cpp.template class $name : public $base { } class Student : public Person { } מחלקה ב-C++
Code Generator דוגמת שימוש Velocity נתונים = XML יעד = תוכנית ב-JAVA תבניות = VTL(Velocity Template Language) מנוע הצבה = Velocity תוכנית יצירה = ב-JAVA
Code Generator Velocity נתונים XML Code Generator ClassDescriptorImporter XML parser (SAX) Class Descriptors יעד: תוכנית JAVA Velocity תבניות VTL
Velocity דוגמה נתונים ב-XML <?xml version="1.0" encoding="UTF-8"?> <!-- order.xml --!> <Content> <Class name="Customer"> <Attribute name="code" type="int"/> <Attribute name="description" type="String"/> </Class> <Class name="Order"> <Attribute name="number" type="int"/> <Attribute name="date" type="Date"/> <Attribute name="customer" type="Customer"/> </Class> </Content> שתי מחלקות ב-JAVA
Velocity דוגמה יעד ב-JAVA import java.util.*; public class Customer { // code private int code; public int getCode() { return this.code; } public void setCode(int code) { this.code = code; } // description private String description; public String getDescription() { return this.description; } public void setDescription(String description) { this.description = description; } } מחלקה Customer
Velocity דוגמה יעד ב-JAVA import java.util.*; public class Order { // number private int number; public int getNumber( ) { return this.number; } public void setNumber(int number) { this.number = number; } // date private Date date; public Date getDate( ) { return this.date; } public void setDate(Date date) { this.date = date; } // customer private Customer customer; public Customer getCustomer( ) { return this.customer; } public void setCustomer(Customer customer) { this.customer = customer; } } מחלקה Order
Code Generator מימוש תוכנית עיקרית public static void start(String modelFile, String templateFile) throws Exception { // Imports XML FileInputStream input = new FileInputStream(modelFile); xmlReader.parse(new InputSource(input)); input.close(); classes = cdImporter.getClasses(); // ClassDescriptor Array // Generates Java classes source code // by using Apache Velocity GeneratorUtility utility = new GeneratorUtility(); for (int i = 0; i < classes.size(); i++) { VelocityContext context = new VelocityContext(); ClassDescriptor cl = (ClassDescriptor) classes.get(i); context.put("class", cl); context.put("utility", utility); Template template = Velocity.getTemplate(templateFile); BufferedWriter writer = new BufferedWriter(new FileWriter(cl.getName()+".java")); template.merge(context, writer); writer.flush(); writer.close(); System.out.println("Class " + cl.getName() + " generated!"); } }
Code Generator מימוש מבנה נתונים כדי לקלוט נתוני XML // ClassDescriptor.java package com.codegenerator.example1; import java.util.*; public class ClassDescriptor { private String name; private ArrayList attributes = new ArrayList( ); public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void addAttribute(AttributeDescriptor attribute) { attributes.add(attribute); } public ArrayList getAttributes( ) { return attributes; } }
Code Generator מימוש מבנה נתונים שני כדי לקלוט נתוני XML // AttributeDescriptor.java package com.codegenerator.example1; import java.util.*; public class AttributeDescriptor { private String name; private String type; public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setType(String type) { this.type = type; } public String getType() { return this.type; } }
SAX parser כדי לייבא נתונים מ- XML Code Generator מימוש package com.codegenerator.example1; import java.util.*; import javax.xml.parsers.*; import org.xml.sax.*; import org.xml.sax.helpers.*; public class ClassDescriptorImporter extends DefaultHandler { private ArrayList classes = new ArrayList(); public ArrayList getClasses() { return classes; } public void startElement(String uri, String name, String qName, Attributes attr) throws SAXException { // Imports <Class> if (name.equals("Class")) { ClassDescriptor cl = new ClassDescriptor(); cl.setName(attr.getValue("name")); classes.add(cl); } // Imports <Attribute> else if (name.equals("Attribute")) { AttributeDescriptor at = new AttributeDescriptor(); at.setName(attr.getValue("name")); at.setType(attr.getValue("type")); ClassDescriptor parent = (ClassDescriptor) classes.get(classes.size()-1); parent.addAttribute(at); } else if (name.equals("Content")) { } else throw new SAXException("Element " + name + " not valid"); } }
Code Generator מימוש תבנית VTL=Velocity Template Lang. יוצרת מחלקת JAVA עם נתונים ושיטות get, set ## class.vm import java.util.*; public class $class.Name { #foreach($att in $class.Attributes) // $att.Name private $att.Type $att.Name; public $att.Type get$utility.firstToUpperCase($att.Name)( ) { return this.$att.Name; } public void set$utility.firstToUpperCase($att.Name)($att.Type $att.Name) { this.$att.Name = $att.Name; } #end }
Code Generators Platform Independence חוסר תלות ב…
Code Generator ארכיטקטורה
Code Generator ארכיטקטורה יבואן = מייבא נתונים IOM = Internal Object Model אוסף מחלקות ייצוג פנימי של נתונים בלתי-תלוי בשפת היעד (PIM= (Platform Independent Model יצואן = על סמך תבניות יוצר יעד בשפה נתונה
Code Generator ארכיטקטורה דגם של הדגם meta-model דגם = model עצם = object דגם שלUML UML JAVA, C++
Code Generator מחלקות ב-IOM דגם של הדגם
Code Generator ארכיטקטורה של יצואן יצואן IOM יעד Navigator Generator תבניות
Code Generator ממשק היצואן public interface Exporter { public void initialize( ) throws Exception; public void startClass(IOMClass cl) throws Exception; public void endClass(IOMClass cl) throws Exception; public void startAssociation(IOMAssociation association, IOMClass currentClass) throws Exception; public void endAssociation(IOMAssociation association, IOMClass currentClass) throws Exception; public void startOperation(IOMOperation operation) throws Exception; public void endOperation(IOMOperation operation) throws Exception; public void startAttribute(IOMAttribute attribute) throws Exception; public void endAttribute(IOMAttribute attribute) throws Exception; public void startParameter(IOMParameter parameter) throws Exception; public void endParameter(IOMParameter parameter) throws Exception; public void finalize() throws Exception; } start… end…
Code Generator תרשים זרימה פונקציית Start של מחלקת IOMNavigator Start Class navigation Attribute navigation Association navigation Operation navigation Parameter navigation
Code Generator מחלקת IOMNavigator package com.codegenerator; import java.util.*; public class IOMNavigator { private Exporter exporter = null; public IOMNavigator(Exporter exporter) { this.exporter = exporter; } public void start( ) throws Exception { exporter.initialize(); // Class navigation { // Attribute navigation // Association navigation // Operation navigation { // Parameter navigation exporter.endOperation(operation); } exporter.endClass(cl); } exporter.finalize(); } }
Code Generator Attibute navigation // Attribute navigation for (int j = 0; j < cl.getAttributes( ).size( ); j++) { IOMAttribute attribute = (IOMAttribute) cl.getAttributes( ).get(j); exporter.startAttribute(attribute); exporter.endAttribute(attribute); }
Code Generator מימוש יצואן ע"י Velocity public class IOMVelocityExporter implements Exporter { private final static String TEMPLATE = "IOMTemplate.vm"; private GeneratorUtility utility = null; public void initialize( ) throws Exception { Velocity.init(); utility = new GeneratorUtility(); } public void startClass(IOMClass cl) throws Exception { VelocityContext context = new VelocityContext(); context.put("class", cl); context.put("utility", utility); Template template = Velocity.getTemplate(TEMPLATE); BufferedWriter writer = new BufferedWriter(new FileWriter(cl.getName()+".java")); template.merge(context, writer); writer.flush(); writer.close(); System.out.println("Class " + cl.getName() + " generated!"); } …
Code Generator דוגמת מסקנה מ- association דו-כיווני חד-כיווני
Code Generator דוגמת מסקנה מ- association • מסתמכת על: • multiplicity • isNavigable
Code Generator תרגיל ליצור את קוד המקור עבור תרשים המחלקות בדגם הבא:
Code Generator יחס בין IOM לבין תבנית • הגיון הגישה לדגם IOM • נמצא רק בתבנית • בעייה • שפת כתיבת התבנית • חלשה יותר משפת תכנות JAVA • הפשטה לעומת יעילות
Code Generator הפרדת IOM, PSM
Code Generator מחלקות ב-PSM • מידע ייחודי לשפה • חוסך חישובי הכנה • מן התבנית: • UpperCase • Multiplicity
Code Generator תרגום IOM ל-PSM • היצואן מכיל תוכנה ב-JAVA • לתרגום IOM ל-PSM • מפשט את התבנית.
Code Generator תרגיל ArgoUML – Code Generator מקורות ליצירת קוד ב-JAVA: www.tigris.org Sources argouml / src_new / org / argouml / language / java / generator להשוות את הגישה של המקורות הנ"ל לנלמד כאן.