DF14900 Component Based Software Peter Bunus Department of Computer and Information Science Linköping University, Sweden peter.bunus@liu.se Copyright © Peter Bunus 2008 MetaProgramming and MetaModeling Overview of the Lecture ! ! ! ! Introduction to Metalevels Different Levels of MetaProgramming UML MetaModel and MOF Component Markup 2 Metadata! ! Meta: means describing ! ! Metadata: describing data (sometimes: self-describing data). ! • The language (esp., type system) for specifying metadata is called metamodel.! ! Metalevel: the elements of the meta-level (the meta-objects) describe the objects on the base level! ! Metamodeling: description of the model elements/concepts in the metamodel! ! Metadata Data, Code, Information Meta level Concepts level Base level Meta-Meta-Modeling MetaModel = Set of (formal/less formal) rules or concepts of a specific modeling language The meta- metamodel layer Meta- Modeling Language Meta-Meta- Model Finite- State Machine Meta-Model 1 The metamodel layer State Machine Meta- Modeling Language trans from Meta-Model State Transition * trans to The model layer resistor1 Domain Modeling Language A inductor1 C emf1 signalVoltage1 Model step 1 start B inertia1 stop ground1 The user object Computer Based layer System Finite- State Machine Model A Direct Current Motor Model Modeled in Modelica Metalevels in Programming Languages! Level 3 - Meta-Concepts in the ! metameta model, the metalanguage! (language description)! Level 2 - Language concepts! (Metaclasses in the metamodel)! Level 1 - Software Classes! (meta-objects)! (Model)! Level 0 - Software Objects! Real World Entities! Class! Car! car 1! car! Programming Language Concept! Method! Attribute! int color! void drive() {}! car1.drive()! car1.color! driving! car color! Classes and Metaclasses! Classes in a software system class WorkPiece { Object belongsTo; } class RotaryTable { WorkPiece place1, place2; } class Robot { WorkPiece piece1, piece2; } class ConveyorBelt { WorkPiece pieces[]; } Metaclasses Concepts of a metalevel can be represented at the base level. This is called reification. Examples: • Java Reflection API [Szyperski 14.4.1] • UML metamodel (MOF) public class Class { Attribute[] fields; Method[] methods; Class ( Attribute[] f, Method[] m) { fields = f; methods = m; } } public class Attribute {..} public class Method {..} Reflection (Self-Modification, Metaprogramming)! ! Reflection is computation about the metamodel in the base model. ! ! The application can look at its own skeleton (metadata) and may even change it! • Allocating new classes, methods, fields! • Removing classes, methods, fields ! ! Enabled by reification of meta-objects at base level (e.g., as API)! Remark: In the literature, reflection was originally introduced to denote computation about the own program [Maes'87] but has also been used in the sense of computing about other programs (e.g., components). Metadata Meta level Data, Code, Information Base level What is Reflection ! When you look in the mirror • You can see your reflection • You can act on what you see, for example, straighten your tie. ! In computer programming: • Reflection is infrastructure enabling a program can see and manipulate itself • It consists of metadata plus operation to manipulate the metadata. ! Meta means self-referential • So metadata is data (information) about oneself 8 Introduction to Java Reflection Accessing metadata ! Java stores metadata in classes • • • • Metadata for a class: Metadata for a constructor: Metadata for a field: Metadata for a method: java.lang.Class java.lang.reflect.Constructor java.lang.reflect.Field java.lang.reflect.Method ! Two ways to access a Class object for a class: Class c1 = Class.forName(“java.util.Properties”); Object obj = ...; Class c2 = obj.getClass(); ! Reflection classes are inter-dependent • Examples are shown on the next slide Examples of inter-relatedness of reflection classes class Class { Constructor[] Field Field[] Method[] ... } getConstructors(); getDeclaredField(String name); getDeclaredFields(); getDeclaredMethods(); class Field { Class getType(); ... } class Method { Class[] getParameterTypes(); Class getReturnType(); ... } Metadata for primitive types and arrays ! Java associates a Class instance with each primitive type: Class c1 = int.class; Might be returned by Class c2 = boolean.class; Method.getReturnType() Class c3 = void.class; ! Use Class.forName() to access the Class object for an array Class Class Class Class c4 c5 c6 c7 = = = = byte.class; // byte Class.forName(“[B”); // byte[] Class.forName(“[[B”); // byte[][] Class.forName(“[Ljava.util.Properties”); ! Encoding scheme used by Class.forName() • B à byte; C à char; D à double; F à float; I à int; J à long; Lclass-name à class-name[]; S à short; Z à boolean • Use as many “[”s as there are dimensions in the array Miscellaneous Class methods ! Here are some useful methods defined in Class class Class { public String getName(); // fully-qualified name public boolean isArray(); public boolean isInterface(); public boolean isPrimitive(); public Class getComponentType(); // only for arrays ... } Calling constructors Invoking a default constructor ! Use Class.newInstance() to call the default constructor Example: abstract class Foo { public static Foo create() throws Exception { String className = System.getProperty( “foo.implementation.class”, “com.example.myproject.FooImpl”); Class c = Class.forName(className); return (Foo)c.newInstance(); } abstract void op1(...); abstract void op2(...); } ... Foo obj = Foo.create(); obj.op1(...); Invoking a default constructor (cont’) ! This technique is used in CORBA: • • • • CORBA is an RPC (remote procedure call) standard There are many competing implementations of CORBA Factory operation is called ORB.init() A system property specifies which implementation of CORBA is used ! A CORBA application can be written in a portable way • Specify the implementation you want to use via a system property (pass –D<name>=<value> command-line option to the Java interpreter) ! Same technique is used for J2EE: • J2EE is a collection of specifications • There are many competing implementations • Use a system property to specify which implementation you are using A plug-in architecture ! Use a properties file to store a mapping for plugin name à class name • Many tools support plugins: Ant, Maven, Eclipse, … abstract class Plugin { abstract void op1(...); abstract void op1(...); } abstract class PluginManager { public static Plugin load(String name) throws Exception { String className = props.getProperty(name); Class c = Class.forName(className); return (Plugin)c.newInstance(); } } ... Plugin obj = PluginManager.load(“...”); Invoking a non-default constructor ! Slightly more complex than invoking the default constructor: • Use Class.getConstructor(Class[] parameterTypes) • Then call Constructor.newInstance(Object[] parameters) abstract class PluginManager { public static Plugin load(String name) throws Exception { String className = props.getProperty(name); Class c = Class.forName(className); Constructor cons = c.getConstructor( new Class[]{String.class, String.class}); return (Plugin)cons.newInstance( new Object[]{“x”, “y”}); } } ... Plugin obj = PluginManager.load(“...”); Methods Invoking a method ! Broadly similar to invoking a non-default constructor: • Use Class.getMethod(String name, Class[]parameterTypes) • Then call Method.invoke(Object target, Object[] parameters) Object obj = ... Class c = obj.getClass(); Method m = c.getMethod(“doWork”, new Class[]{String.class, String.class}); Object result= m.invoke(obj, new Object[]{“x”,“y”}); Looking up methods ! The API for looking up methods is fragmented: • You can lookup a public method in a class or its ancestor classes • Or, lookup a public or non-public method declared in the specified class A better name would have been getPublicMethod() class Class { public Method getMethod(String name, Class[] parameterTypes); public Method[] getMethods(); public Method getDeclaredMethod(String name, Class[] parameterTypes); public Method[] getDeclaredMethods(); ... } Finding an inherited method ! This code searches up a class hierarchy for a method • Works for both public and non-public methods Method findMethod(Class cls, String methodName, Class[] paramTypes) { Method method = null; while (cls != null) { try { method = cls.getDeclaredMethod(methodName, paramTypes); break; } catch (NoSuchMethodException ex) { cls = cls.getSuperclass(); } } return method; } ! 5. Fields Accessing a field ! There are two ways to access a field: • By invoking get- and set-style methods (if the class defines them) • By using the code shown below Object obj = ... Class c = obj.getClass(); Field f = c.getField(“firstName”); f.set(obj, “John”); Object value = f.get(obj); Looking up fields ! The API for looking up fields is fragmented: • You can lookup a public field in a class or its ancestor classes • Or, lookup a public or non-public field declared in the specified class class Class { public Field public Field[] public Field public Field[] ... } A better name would have been getPublicField() getField(String name); getFields(); getDeclaredField(String name); getDeclaredFields(); Finding an inherited field ! This code searches up a class hierarchy for a field • Works for both public and non-public fields Field findField(Class cls, String fieldName) { Field field = null; while (cls != null) { try { field = cls.getDeclaredField(fieldName); break; } catch (NoSuchFieldException ex) { cls = cls.getSuperclass(); } } return field; } Modifiers Java modifiers ! Java defines 11 modifiers: • abstract, final, native, private, protected, public, static, strictfp, synchronized, transient and volatile ! Some of the modifiers can be applied to a class, method or field: • Set of modifiers is represented as bit-fields in an integer • Access set of modifiers by calling int getModifiers() ! Useful static methods on java.lang.reflect.Modifier: static static static static ... boolean boolean boolean boolean isAbstract(int modifier); isFinal(int modifier); isNative(int modifier); isPrivate(int modifier); Introspection! ! Read-only reflection is called introspection! • The component can look up the metadata of itself or another component and learn from it (but not change it!) ! ! Typical application: find out features of components! • Classes, methods, attributes, types! • Very important for late (run-time) binding! ! Metadata Data, Code, Information Data, Code, Information Reflection Example! Reading Reflection ! (Introspection):! for all c in self.classes do generate_class_start(c); for all a in c.attributes do generate_attribute(a); done; generate_class_end(c); done; Full Reflection (Introcession): for all c in self.classes do helpClass = makeClass( c.name + "help ); for all a in c.attributes do helpClass.addAttribute(copyAttribute(a)); done; self.addClass(helpClass); done; A reflective system is a system that uses this information about itself in its normal course of execution. Use of Metamodels and Metaprogramming! To model, describe, introspect, and manipulate! ! Programming languages, such as Java Reflection API! ! Modeling languages, such as UML or Modelica! ! XML! ! Compilers! ! Debuggers! ! Component systems, such as JavaBeans or CORBA DII! ! Composition systems, such as Invasive Software Composition! ! Databases! ! ... many other systems ...! 2. Different Ways of Metaprogramming - meta-level vs. base level - static vs. dynamic! ! Metaprograms are programs that compute about programs Metaprogram Program Program’ run-time input run-time output Metaprograms can run at base level or at meta level! Metaprogram execution at the metalevel:! ! Metaprogram is separate from base-level program! ! Direct control of the metadata as metaprogram data structures! ! Expression operators are defined directly on the metaobjects! ! Example: Compiler, program analyzer, program transformer ! • Program metadata = the internal program representation ! – has classes to create objects describing base program clas- ses, functions, statements, variables, constants, types etc.! Metaprogram execution at the base level:! ! Metaprogram/-code embedded into the base-level program! ! All expressions etc. evaluated at base level! ! Access to metadata only via special API, e.g. Java Reflection! Base-Level Metaprogram! Metaobjects Repository with Concepts/ Types/Descriptions as Artefacts Metalevel Reflection Base-level program data memory: Repository with Objects as Artefacts Metaprogram Class someclass = foo.getClass(); Base Level Meta-level Metaprogram! Metaobjects Metalevel Metaprogram for each class c add a new method int bar() {...} Base Level Static vs. Dynamic Metaprogramming! Recall: Metaprograms are programs that compute about programs. ! ! Static metaprograms! • Execute before runtime! • Metainformation removed before execution – no runtime overhead! • Examples: Program generators, compilers, static analyzers ! ! ! Dynamic metaprograms! • Execute at runtime! • Metadata stored and accessible during runtime! • Examples: ! – Programs using reflection (Introspection, Introcession); ! – Interpreters, debuggers! Static Metaprogramming! Static Time Metaprogram Metaobjects Run Time Metalevel Base Level Metaprogram and metaobjects exist only at compile time. No run-time overhead. Example: Static Metaprogramming (1)! Static Time Metalevel Metaobjects Metaprogram Compiler Run Time Integer! 4! myType! 8! type table ...malloc( N * sizeof(myType)); Metaprogram and metaobjects exist only at compile time. No run-time overhead. ...malloc( N * 8 ); Base Level Example: Static Metaprogramming (2)! C++ templates! ! Example: generic type definition! • (Meta)Information about generic type removed after compiling!! template <class E> class Vector { E *pelem; int size; E get( int index ) {...} ... } ... Vector<int> v1; Vector<float> v2; expanded at compile time to equivalent of: class Vector_int { int *pelem; int size; int get( int index ) {...} ... } class Vector_float { float *pelem; int size; float get( int index ) {...} ... } ... Vector_int v1; Vector_float v2; Compilers Are Static Metaprograms! Metaclasses: The compiler’s own data types to represent IR structures Programs in Source Form Metaprogram (Level 2) Programs in Target Form IR Parsing, Analysing IR Analysis, Transformations Code Generation / Pretty Printing Classes etc. represented by IR objects = metaobjects = instances of IR classes (metaclasses) Run time objects (Level 0) Dynamic Metaprogramming! Repository with Concepts/ Types/Descriptions as Artefacts Metaobjects Metalevel Reflection Base-level program data memory: Repository with Objects Metaas Artefactsprogram Class someclass = foo.getClass(); Base Level Summary: Ways of Metaprogramming! Metaprogram runs at:! Base level! Compile/Deployment time (static metaprogramming)! C++ template programs Compiler C sizeof(...) operator transformations;! C preprocessor! Run time Java Reflection! (dynamic metaprogramming)! JavaBeans introspection! Reflection Meta level! Debugger! UML METAMODEL AND MOF! UML Metamodel and MOF! UML metamodel! ! specifies UML semantics! ! in the form of a (UML) class model (= reification)! ! specified in UML Superstructure document (OMG 2006) using only elements provided in MOF ! UML metametamodel: MOF (”Meta-Object Facility”)! ! self-describing! ! subset of UML (= reification)! ! for bootstrapping the UML specification! ! UML Extension possibility 1: Stereotypes! ! e.g., <<metaclass>> is a stereotype (specialization) of a class! • by subclassing metaclass ”Class” of the UML metamodel! ! UML Extension possibility 2: Extend the metamodel ! ! by subclassing elements of the Metametamodel (MOF)! UML metamodel hierarchy! Metametalevel (L3) UML metametamodel: MOF Metalevel (L2) UML metamodel ModelElement : ModelElement name: Name is instance of Class : ModelElement isActive: Boolean is instance of Base level (L1) UML base-level class diagrams Cat : Class name: String color: Color age: Integer is instance of Object level (L0) tom : Cat name: ”Tom” color: White age: 7 UML vs. programming language metamodel hierarchies! Metametalevel (L3) UML metametamodel: MOF Metalevel (L2) UML metamodel ModelElement : ModelElement name: Name is instance of Class : ModelElement models isActive: Boolean UML base-level class diagrams Cat : Class models name: String color: Color age: Integer is instance of Object level (L0) tom : Cat name: ”Tom” color: White age: 7 java.lang.Class is instance of is instance of Base level (L1) -- class Cat { String name; Color color; Integer age; ... } is instance of models Cat tom = new Cat(”Tom”, White, 7); UML Metamodel (Simplified Excerpt)! ModelElement name: Name Generalizable Element isRoot: Boolean isLeaf: Boolean isAbstract: Boolean 1 1 * subtype Generalization * discriminator: Name supertype 1 type * Class isActive: Boolean ownerScope: ScopeKind visibility: VisibilityKind BehavioralFeature multiplicity: Multiplicity changeable: ChangeableKind targetScope: ScopeKind isQuery: Boolean Attribute <<metaclass>> * StructuralFeature owner Classifier Feature initialValue: Expression Interface Datatype Operation isAbstract: Boolean concurrency: CallConcurKind Simple Metamodel Example Modeling and MetaModeling So, what’s the idea, here? Uses System designer Metamodeling environment Produces Domain specific modeling Program(s) environment System user(s) Produces Executable models PARC | 49 Runs Plant!!! Model Integrated Computing Metaprogramming Interface Environment Evolution Application Domain Application Evolution App. 1 Formal Specifications App. 2 DSDE Model Builder Model Interpretation Meta-Level Translation Models Model Interpreters [Sztipanovitch and Karsai 2000] App. 3 Metamodeling – Heavy Weight Approach PARC | 51 Metamodeling – Light Weight Approach PARC | 52 Example: Reading the UML Metamodel! Some semantics rules expressed in the UML metamodel above: ! ! Each model element must have a name. ! ! A class can be a root, leaf, or abstract ! • (inherited from GenerizableElement) ! ! A class can have many subclasses and many superclasses! • (1:N relations to class ”Generalization”) ! ! A class can have many features, e.g. attributes, operations! • (via Classifier) ! ! Each attribute has a type ! • (1:N relation to Classifier),! e.g. classes, interfaces, datatypes! Caution! ! A metamodel is not a model of a model but a model of a modeling language of models.! ! A model (e.g. in UML) describes a language-specific software item at the same level of the metalevel hierarchy.! • In contrast, metadata describes it from the next higher level, from which it can be instantiated.! ! MOF is a subset of UML able to describe itself – no higher metalevels required for UML.! Master Thesis Proposal ! MOFLON: the standard-compliant, fully integrated, graph-based meta-CASE tool for rapid development of Java CASE tools and tool adapters. 55