blob: 5b5dc35b91e94d216219c1f87a5dff4caf3010b9 [file] [log] [blame]
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.1.2, mkdocs-material-7.1.5">
<title>Model Transformation (ETL) - Epsilon</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.bde7dde4.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.ef6f36e2.min.css">
<meta name="theme-color" content="#000000">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
<style>:root{--md-text-font-family:"Roboto";--md-code-font-family:"Roboto Mono"}</style>
<link rel="stylesheet" href="../../assets/stylesheets/mermaid.css">
<link rel="stylesheet" href="../../assets/javascript/google-code-prettify/prettify.css">
<link rel="stylesheet" href="https://unpkg.com/mermaid@8.5.1/dist/mermaid.css">
<link rel="stylesheet" href="../../assets/stylesheets/slick.css">
<link rel="stylesheet" href="../../assets/stylesheets/slick-theme.css">
<link rel="stylesheet" href="../../assets/stylesheets/extra.css">
<script>
window.ga = window.ga || function() {
(ga.q = ga.q || []).push(arguments)
}
ga.l = +new Date
/* Setup integration and send page view */
ga("create", "UA-184785655-1", "auto")
ga("set", "anonymizeIp", true)
ga("send", "pageview")
/* Register handler to log search on blur */
document.addEventListener("DOMContentLoaded", () => {
if (document.forms.search) {
var query = document.forms.search.query
query.addEventListener("blur", function() {
if (this.value) {
var path = document.location.pathname;
ga("send", "pageview", path + "?q=" + this.value)
}
})
}
})
</script>
<script async src="https://www.google-analytics.com/analytics.js"></script>
</head>
<body dir="ltr" data-md-color-scheme="" data-md-color-primary="black" data-md-color-accent="orange">
<script>function __prefix(e){return new URL("../..",location).pathname+"."+e}function __get(e,t=localStorage){return JSON.parse(t.getItem(__prefix(e)))}</script>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#the-epsilon-transformation-language-etl" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="Epsilon" class="md-header__button md-logo" aria-label="Epsilon" data-md-component="logo">
<img src="../../assets/images/epsilon-white-background.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Epsilon
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Model Transformation (ETL)
</span>
</div>
</div>
</div>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" data-md-state="active" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
</label>
<button type="reset" class="md-search__icon md-icon" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
Git repository @ Eclipse
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="Epsilon" class="md-nav__button md-logo" aria-label="Epsilon" data-md-component="logo">
<img src="../../assets/images/epsilon-white-background.png" alt="logo">
</a>
Epsilon
</label>
<div class="md-nav__source">
<a href="https://git.eclipse.org/c/epsilon/org.eclipse.epsilon.git/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
</div>
<div class="md-source__repository">
Git repository @ Eclipse
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
Home
</a>
</li>
<li class="md-nav__item">
<a href="../../download/" class="md-nav__link">
Download
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../live" class="md-nav__link">
Playground
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5" type="checkbox" id="__nav_5" checked>
<label class="md-nav__link" for="__nav_5">
Documentation
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Documentation" data-md-level="1">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
Documentation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../" class="md-nav__link">
Overview
</a>
</li>
<li class="md-nav__item">
<a href="../emc/" class="md-nav__link">
Model Connectivity
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_3" type="checkbox" id="__nav_5_3" checked>
<label class="md-nav__link" for="__nav_5_3">
Languages
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Languages" data-md-level="2">
<label class="md-nav__title" for="__nav_5_3">
<span class="md-nav__icon md-icon"></span>
Languages
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../eol/" class="md-nav__link">
Object Language (EOL)
</a>
</li>
<li class="md-nav__item">
<a href="../egl/" class="md-nav__link">
Code Generation (EGL)
</a>
</li>
<li class="md-nav__item">
<a href="../evl/" class="md-nav__link">
Model Validation (EVL)
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Model Transformation (ETL)
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
Model Transformation (ETL)
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#abstract-syntax" class="md-nav__link">
Abstract Syntax
</a>
</li>
<li class="md-nav__item">
<a href="#concrete-syntax" class="md-nav__link">
Concrete Syntax
</a>
</li>
<li class="md-nav__item">
<a href="#execution-semantics" class="md-nav__link">
Execution Semantics
</a>
<nav class="md-nav" aria-label="Execution Semantics">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#rule-and-block-overriding" class="md-nav__link">
Rule and Block Overriding
</a>
</li>
<li class="md-nav__item">
<a href="#rule-execution-scheduling" class="md-nav__link">
Rule Execution Scheduling
</a>
</li>
<li class="md-nav__item">
<a href="#source-elements-resolution" class="md-nav__link">
Source Elements Resolution
</a>
</li>
<li class="md-nav__item">
<a href="#overriding-the-semantics-of-the-eol-special-assignment-operator" class="md-nav__link">
Overriding the semantics of the EOL Special Assignment Operator
</a>
</li>
<li class="md-nav__item">
<a href="#interactive-transformations" class="md-nav__link">
Interactive Transformations
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#additional-resources" class="md-nav__link">
Additional Resources
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../ecl/" class="md-nav__link">
Model Comparison (ECL)
</a>
</li>
<li class="md-nav__item">
<a href="../eml/" class="md-nav__link">
Model Merging (EML)
</a>
</li>
<li class="md-nav__item">
<a href="../epl/" class="md-nav__link">
Pattern Matching (EPL)
</a>
</li>
<li class="md-nav__item">
<a href="../flock/" class="md-nav__link">
Model Migration (Flock)
</a>
</li>
<li class="md-nav__item">
<a href="../emg/" class="md-nav__link">
Model Generation (EMG)
</a>
</li>
<li class="md-nav__item">
<a href="../eunit/" class="md-nav__link">
Unit Testing (EUnit)
</a>
</li>
<li class="md-nav__item">
<a href="../pinset/" class="md-nav__link">
Dataset Extraction (Pinset)
</a>
</li>
<li class="md-nav__item">
<a href="../ewl/" class="md-nav__link">
Wizard Language (EWL)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_4" type="checkbox" id="__nav_5_4" >
<label class="md-nav__link" for="__nav_5_4">
Tools
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Tools" data-md-level="2">
<label class="md-nav__title" for="__nav_5_4">
<span class="md-nav__icon md-icon"></span>
Tools
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../picto/" class="md-nav__link">
Picto
</a>
</li>
<li class="md-nav__item">
<a href="../flexmi/" class="md-nav__link">
Flexmi
</a>
</li>
<li class="md-nav__item">
<a href="../eugenia/" class="md-nav__link">
Eugenia
</a>
</li>
<li class="md-nav__item">
<a href="../exeed/" class="md-nav__link">
Exeed
</a>
</li>
<li class="md-nav__item">
<a href="../modelink/" class="md-nav__link">
Modelink
</a>
</li>
<li class="md-nav__item">
<a href="../hutn/" class="md-nav__link">
HUTN
</a>
</li>
<li class="md-nav__item">
<a href="../workflow/" class="md-nav__link">
Workflow (Ant tasks)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../articles/" class="md-nav__link">
Articles
</a>
</li>
<li class="md-nav__item">
<a href="../../examples/" class="md-nav__link">
Examples
</a>
</li>
<li class="md-nav__item">
<a href="https://www.youtube.com/epsilondevs" class="md-nav__link">
Screencasts
</a>
</li>
<li class="md-nav__item">
<a href="https://www.youtube.com/playlist?list=PLRwHao6Ue0YUecg7vEUQTrtySIWwrd_mI" class="md-nav__link">
Lectures
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_9" type="checkbox" id="__nav_5_9" >
<label class="md-nav__link" for="__nav_5_9">
Javadoc
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Javadoc" data-md-level="2">
<label class="md-nav__title" for="__nav_5_9">
<span class="md-nav__icon md-icon"></span>
Javadoc
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://download.eclipse.org/epsilon/stable-javadoc/" class="md-nav__link">
Stable
</a>
</li>
<li class="md-nav__item">
<a href="https://download.eclipse.org/epsilon/interim-javadoc/" class="md-nav__link">
Interim
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6" type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6">
Issues
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Issues" data-md-level="1">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Issues
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/enter_bug.cgi?product=epsilon" class="md-nav__link">
Report a new issue
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=blocker&bug_severity=critical&bug_severity=major&bug_severity=normal&bug_severity=minor&bug_severity=trivial" class="md-nav__link">
View open bugs
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&bug_severity=enhancement" class="md-nav__link">
View enhancement requests
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?bug_status=RESOLVED&list_id=17694438&product=epsilon&query_format=advanced" class="md-nav__link">
View issues resolved since the last stable release
</a>
</li>
<li class="md-nav__item">
<a href="https://bugs.eclipse.org/bugs/buglist.cgi?product=epsilon&cmdtype=doit&order=Reuse+same+sort+as+last+time" class="md-nav__link">
View all issues
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7" type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7">
Community
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Community" data-md-level="1">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Community
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7_1" type="checkbox" id="__nav_7_1" >
<label class="md-nav__link" for="__nav_7_1">
Who is using Epsilon?
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Who is using Epsilon?" data-md-level="2">
<label class="md-nav__title" for="__nav_7_1">
<span class="md-nav__icon md-icon"></span>
Who is using Epsilon?
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../users/" class="md-nav__link">
Industry
</a>
</li>
<li class="md-nav__item">
<a href="../../users/education/" class="md-nav__link">
Education
</a>
</li>
<li class="md-nav__item">
<a href="../../users/open-source/" class="md-nav__link">
Open-source Projects
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="https://projects.eclipse.org/projects/modeling.epsilon/who" class="md-nav__link">
Who is developing Epsilon?
</a>
</li>
<li class="md-nav__item">
<a href="https://www.eclipse.org/forums/index.php/f/22/" class="md-nav__link">
Forum
</a>
</li>
<li class="md-nav__item">
<a href="../../professional-services" class="md-nav__link">
Professional Services
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7_5" type="checkbox" id="__nav_7_5" >
<label class="md-nav__link" for="__nav_7_5">
Social Media
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" aria-label="Social Media" data-md-level="2">
<label class="md-nav__title" for="__nav_7_5">
<span class="md-nav__icon md-icon"></span>
Social Media
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="https://twitter.com/eclipseepsilon" class="md-nav__link">
Twitter
</a>
</li>
<li class="md-nav__item">
<a href="https://youtube.com/epsilondevs" class="md-nav__link">
YouTube
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../labs/" class="md-nav__link">
Epsilon Labs
</a>
</li>
<li class="md-nav__item">
<a href="../../faq/" class="md-nav__link">
Frequently Asked Questions
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../../branding/" class="md-nav__link">
Branding
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#abstract-syntax" class="md-nav__link">
Abstract Syntax
</a>
</li>
<li class="md-nav__item">
<a href="#concrete-syntax" class="md-nav__link">
Concrete Syntax
</a>
</li>
<li class="md-nav__item">
<a href="#execution-semantics" class="md-nav__link">
Execution Semantics
</a>
<nav class="md-nav" aria-label="Execution Semantics">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#rule-and-block-overriding" class="md-nav__link">
Rule and Block Overriding
</a>
</li>
<li class="md-nav__item">
<a href="#rule-execution-scheduling" class="md-nav__link">
Rule Execution Scheduling
</a>
</li>
<li class="md-nav__item">
<a href="#source-elements-resolution" class="md-nav__link">
Source Elements Resolution
</a>
</li>
<li class="md-nav__item">
<a href="#overriding-the-semantics-of-the-eol-special-assignment-operator" class="md-nav__link">
Overriding the semantics of the EOL Special Assignment Operator
</a>
</li>
<li class="md-nav__item">
<a href="#interactive-transformations" class="md-nav__link">
Interactive Transformations
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#additional-resources" class="md-nav__link">
Additional Resources
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="the-epsilon-transformation-language-etl">The Epsilon Transformation Language (ETL)<a class="headerlink" href="#the-epsilon-transformation-language-etl" title="Permanent link">&para;</a></h1>
<p>The aim of ETL is to contribute model-to-model transformation capabilities to Epsilon. More specifically, ETL can be used to transform an arbitrary number of input models into an arbitrary number of output models of different modelling languages and technologies in a rule-based and modular manner.</p>
<div class="admonition tip">
<p class="admonition-title">Try ETL online</p>
<p>You can run and fiddle with an ETL transformation that transforms a tree model to a graph model in the <a href="../../live/?etl">online Epsilon Playground</a>.</p>
</div>
<h2 id="abstract-syntax">Abstract Syntax<a class="headerlink" href="#abstract-syntax" title="Permanent link">&para;</a></h2>
<p>As illustrated in the figure below, ETL transformations are organized in modules (<code>EtlModule</code>). A module can contain a number of transformation rules (<code>TransformRule</code>). Each rule has a unique name (in the context of the module) and also specifies one <code>source</code> and many <code>target</code> parameters. A transformation rule can also <code>extend</code> a number of other transformation rules and be declared as <code>abstract</code>, <code>primary</code> and/or <code>lazy</code><sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>. To limit its applicability to a subset of elements that conform to the type of the <code>source</code> parameter, a rule can optionally define a guard which is either an EOL expression or a block of EOL statements. Finally, each rule defines a block of EOL statements (<code>body</code>) where the logic for populating the property values of the target model elements is specified.</p>
<p>Besides transformation rules, an ETL module can also optionally contain a number of <code>pre</code> and <code>post</code> named blocks of EOL statements which, as discussed later, are executed before and after the transformation rules respectively. These should not be confused with the pre-/post-condition annotations available for EOL user-defined operations.</p>
<div class="mermaid mermaid-100">classDiagram
class TransformRule {
-name: String
-abstract: Boolean
-lazy: Boolean
-primary: Boolean
-greedy: Boolean
-type: EolModelElementType
-guard: ExecutableBlock&lt;Boolean&gt;
-body: ExecutableBlock&lt;Void&gt;
}
class Parameter {
-name: String
-type: EolType
}
class NamedStatementBlockRule {
-name: String
-body: StatementBlock
}
EolModule &lt;|-- ErlModule
EtlModule --|&gt; ErlModule
Pre --|&gt; NamedStatementBlockRule
Post --|&gt; NamedStatementBlockRule
ErlModule -- Pre: pre *
ErlModule -- Post: post *
EtlModule -- TransformRule: rules *
TransformRule -- Parameter: source
TransformRule -- Parameter: targets *
TransformRule -- TransformRule: extends *</div>
<h2 id="concrete-syntax">Concrete Syntax<a class="headerlink" href="#concrete-syntax" title="Permanent link">&para;</a></h2>
<p>The concrete syntax of a transformation rule is displayed in the listing below. The optional <code>abstract</code>, <code>lazy</code> and <code>primary</code> attributes of the rule are specified using respective annotations. The name of the rule follows the <code>rule</code> keyword and the <code>source</code> and <code>target</code> parameters are defined after the <code>transform</code> and <code>to</code> keywords. Also, the rule can define an optional comma-separated list of rules it extends after the <code>extends</code> keyword. Inside the curly braces ({}), the rule can optionally specify its <code>guard</code> either as an EOL expression following a colon (:) (for simple guards) or as a block of statements in curly braces (for more complex guards). Finally, the <code>body</code> of the rule is specified as a sequence of EOL statements.</p>
<div class="highlight"><pre><span></span><code>(@abstract)?
(@lazy)?
(@primary)?
rule &lt;name&gt;
transform &lt;sourceParameterName&gt;:&lt;sourceParameterType&gt;
to &lt;targetParameterName&gt;:&lt;targetParameterType&gt;
(,&lt;targetParameterName&gt;:&lt;targetParameterType&gt;)*
(extends &lt;ruleName&gt; (, &lt;ruleName&gt;*)? {
(guard (:expression)|({statementBlock}))?
statement+
}
</code></pre></div>
<p><code>Pre</code> and <code>post</code> blocks have a simple syntax that, as presented the listing below, consists of the identifier (<code>pre</code> or <code>post</code>), an optional name and the set of statements to be executed enclosed in curly braces.</p>
<div class="highlight"><pre><span></span><code>(pre|post) &lt;name&gt; {
statement+
}
</code></pre></div>
<h2 id="execution-semantics">Execution Semantics<a class="headerlink" href="#execution-semantics" title="Permanent link">&para;</a></h2>
<h3 id="rule-and-block-overriding">Rule and Block Overriding<a class="headerlink" href="#rule-and-block-overriding" title="Permanent link">&para;</a></h3>
<p>Similarly to EOL, an ETL module can import a number of other ETL modules. In this case, the importing ETL module inherits all the rules and pre/post blocks specified in the modules it imports (recursively). If the module specifies a rule or a pre/post block with the same name, the local rule/block overrides the imported one respectively.</p>
<h3 id="rule-execution-scheduling">Rule Execution Scheduling<a class="headerlink" href="#rule-execution-scheduling" title="Permanent link">&para;</a></h3>
<p>When an ETL module is executed, the <code>pre</code> blocks of the module are executed first in the order in which they have been specified.</p>
<p>Following that, each non-abstract and non-lazy rule is executed for all the elements on which it is applicable. To be applicable on a particular element, the element must have a type-of relationship with the type defined in the rule's <code>sourceParameter</code> (or a kind-of relationship if the rule is annotated as <code>@greedy</code>) and must also satisfy the <code>guard</code> of the rule (and all the rules it extends). When a rule is executed on an applicable element, the target elements are initially created by instantiating the <code>targetParameters</code> of the rules, and then their contents are populated using the EOL statements of the <code>body</code> of the rule.</p>
<p>Finally, when all rules have been executed, the <code>post</code> blocks of the module are executed in the order in which they have been declared.</p>
<h3 id="source-elements-resolution">Source Elements Resolution<a class="headerlink" href="#source-elements-resolution" title="Permanent link">&para;</a></h3>
<p>Resolving target elements that have been (or can be) transformed from source elements by other rules is a frequent task in the body of a transformation rule. To automate this task and reduce coupling between rules, ETL contributes the <code>equivalents()</code> and <code>equivalent()</code> built-in operations that automatically resolve source elements to their transformed counterparts in the target models.</p>
<p>When the <code>equivalents()</code> operation is applied on a single source element (as opposed to a collection of them), it inspects the established transformation trace (displayed in the figure below) and invokes the applicable rules (if necessary) to calculate the counterparts of the element in the target model. When applied to a collection it returns a <code>Bag</code> containing <code>Bag</code>s that in turn contain the counterparts of the source elements contained in the collection. The <code>equivalents()</code> operation can be also invoked with an arbitrary number of rule names as parameters to invoke and return only the equivalents created by specific rules. Unlike the main execution scheduling scheme discussed above, the <code>equivalents()</code> operation invokes both lazy and non-lazy rules. It is worth noting that lazy rules are computationally expensive and should be used with caution as they can significantly degrade the performance of the overall transformation.</p>
<p>With regard to the ordering of the results of the <code>equivalents()</code> operations, the returned elements appear in the respective order of the rules that have created them. An exception to this occurs when one of the rules is declared as <code>primary</code>, in which case its results precede the results of all other rules.</p>
<div class="mermaid mermaid-80">classDiagram
class Transformation {
-source: Object
-targets: Object[*]
}
class ITransformationStrategy {
+transformModels(context : EtlContext)
}
EolContext &lt;|-- EtlContext
EtlContext -- TransformationTrace
EtlContext -- ITransformationStrategy: strategy
TransformationTrace -- Transformation: transformations *
Transformation -- TransformRule: rule</div>
<p>ETL also provides the convenient <code>equivalent()</code> operation which, when applied to a single element, returns only the first element of the respective result that would have been returned by the <code>equivalents()</code> operation discussed above. Also, when applied to a collection the <code>equivalent()</code> operation returns a flattened collection (as opposed to the result of <code>equivalents()</code> which is a <code>Bag</code> of <code>Bag</code>s in this case). As with the <code>equivalents()</code> operation, the <code>equivalent()</code> operation can also be invoked with or without parameters.</p>
<p>The semantics of the <code>equivalent()</code> operation is further illustrated through a simple example. In this example, we need to transform a model that conforms to the Tree metamodel displayed below into a model that conforms to the Graph metamodel, also displayed below.</p>
<div class="mermaid mermaid-70">classDiagram
class Node {
+label: String
+incoming: Edge[*]
+outgoing: Edge[*]
}
class Edge {
+source: Node
+target: Node
}
class Tree {
+name: String
+parent: Tree
+children: Tree[*]
}
Tree -- Tree
Node -- Edge
Edge -- Node</div>
<p>More specifically, we need to transform each <code>Tree</code> element to a <code>Node</code>, and an <code>Edge</code> that connects it with the <code>Node</code> that is equivalent to the tree's <code>parent</code>. This is achieved using the rule below.</p>
<pre class="prettyprint lang-etl"><code>rule Tree2Node
transform t : Tree!Tree
to n : Graph!Node {
n.label = t.label;
if (t.parent.isDefined()) {
var edge = new Graph!Edge;
edge.source = n;
edge.target = t.parent.equivalent();
}
}</code></pre>
<p>In lines 1--3, the <code>Tree2Node</code> rule specifies that it can transform elements of the <code>Tree</code> type in the <code>Tree</code> model into elements of the <code>Node</code> type in the <code>Graph</code> model. In line 5 it specifies that the label of the created Node should be the same as the label of the source Tree. If the parent of the source <code>Tree</code> is defined (line 7), the rule creates a new <code>Edge</code> (line 8) and sets its <code>source</code> property to the created <code>Node</code> (line 9) and its <code>target</code> property to the <code>equivalent</code> <code>Node</code> of the source <code>Tree</code>'s <code>parent</code> (line 10).</p>
<h3 id="overriding-the-semantics-of-the-eol-special-assignment-operator">Overriding the semantics of the EOL Special Assignment Operator<a class="headerlink" href="#overriding-the-semantics-of-the-eol-special-assignment-operator" title="Permanent link">&para;</a></h3>
<p>As discussed above, resolving the equivalent(s) or source model elements in the target model is a recurring task in model transformation. Furthermore, in most cases resolving the equivalent of a model element is immediately followed by assigning/adding the obtained target model elements to the value(s) of a property of another target model element. For example, in line 10 of the listing above, the <code>equivalent</code> obtained is immediately assigned to the <code>target</code> property of the generated <code>Edge</code>. To make transformation specifications more readable, ETL overrides the semantics of the <code>SpecialAssignmentStatement</code> (<code>::=</code> in terms of concrete syntax), to set its left-hand side, not to the element its right-hand side evaluates to, but to its <code>equivalent</code> as calculated using the <code>equivalent()</code> operation discussed above. Using this feature, line 10 of the <code>Tree2Node</code> rule can be rewritten as shown below.</p>
<div class="highlight"><pre><span></span><code>edge.target ::= t.parent;
</code></pre></div>
<h3 id="interactive-transformations">Interactive Transformations<a class="headerlink" href="#interactive-transformations" title="Permanent link">&para;</a></h3>
<p>Using the user interaction facilities of EOL, an ETL transformation can become interactive by prompting the user for input during its execution. For example in the listing below, we modify the <code>Tree2Node</code> rule by adding a <code>guard</code> part that uses the user-input facilities of EOL (more specifically the <code>UserInput.confirm(String,Boolean)</code> operation) to enable the user select manually at runtime which of the Tree elements need to be transformed to respective Node elements in the target model and which not.</p>
<pre class="prettyprint lang-etl"><code>rule Tree2Node
transform t : Tree!Tree
to n : Graph!Node {
guard : UserInput.confirm
("Transform tree " + t.label + "?", true)
n.label = t.label;
var target : Graph!Node ::= t.parent;
if (target.isDefined()) {
var edge = new Graph!Edge;
edge.source = n;
edge.target = target;
}
}</code></pre>
<h2 id="additional-resources">Additional Resources<a class="headerlink" href="#additional-resources" title="Permanent link">&para;</a></h2>
<p>Additional resources about ETL are available <a href="../articles/#epsilon-transformation-language">here</a>.</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>The concept of lazy rules was first introduced in ATL&#160;<a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
</ol>
</div>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../evl/" title="Model Validation (EVL)" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Model Validation (EVL)
</span>
</div>
</a>
<a href="../ecl/" title="Model Comparison (ECL)" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Model Comparison (ECL)
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright © Eclipse Foundation, Inc. All Rights Reserved.
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">Material for MkDocs</a>
</div>
<div class="md-footer-copyright epsilon-eclipse-links">
<ul>
<li><a href="https://www.eclipse.org/legal/privacy.php">Privacy Policy</a></li>
<li><a href="https://www.eclipse.org/legal/termsofuse.php">Terms of Use</a></li>
<li><a href="https://www.eclipse.org/legal/copyright.php">Copyright Agent</a></li>
</ul>
</div>
<div class="md-footer-social">
<a href="https://twitter.com/eclipseepsilon" target="_blank" rel="noopener" title="twitter.com" class="md-footer-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
</a>
<a href="https://youtube.com/epsilondevs" target="_blank" rel="noopener" title="youtube.com" class="md-footer-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": [], "translations": {"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}, "search": "../../assets/javascripts/workers/search.d351de03.min.js", "version": null}</script>
<script src="../../assets/javascripts/bundle.a1609d9a.min.js"></script>
<script src="https://unpkg.com/mermaid@8.5.1/dist/mermaid.min.js"></script>
<script src="../../assets/javascript/mermaid.js"></script>
<script src="../../assets/javascript/jquery.js"></script>
<script src="../../assets/javascript/slick.min.js"></script>
<script src="../../assets/javascript/google-code-prettify/prettify.js"></script>
<script src="../../assets/javascript/google-code-prettify/lang-emfatic.js"></script>
<script src="../../assets/javascript/google-code-prettify/lang-epsilon.js"></script>
<script src="../../assets/javascript/google-code-prettify/prettyprint.js"></script>
<script src="../../assets/javascript/extra.js"></script>
<script src="https://w.appzi.io/w.js?token=jlv6W"></script>
</body>
</html>