| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <meta name="generator" content="Asciidoctor 2.0.15"> |
| <link rel="icon" type="image/png" href="/favicon.png"> |
| <title>Eclipse CommaSuite</title> |
| <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"> |
| <style> |
| /* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */ |
| /* Uncomment @import statement to use as custom stylesheet */ |
| /*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/ |
| article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section{display:block} |
| audio,video{display:inline-block} |
| audio:not([controls]){display:none;height:0} |
| html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} |
| a{background:none} |
| a:focus{outline:thin dotted} |
| a:active,a:hover{outline:0} |
| h1{font-size:2em;margin:.67em 0} |
| abbr[title]{border-bottom:1px dotted} |
| b,strong{font-weight:bold} |
| dfn{font-style:italic} |
| hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0} |
| mark{background:#ff0;color:#000} |
| code,kbd,pre,samp{font-family:monospace;font-size:1em} |
| pre{white-space:pre-wrap} |
| q{quotes:"\201C" "\201D" "\2018" "\2019"} |
| small{font-size:80%} |
| sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} |
| sup{top:-.5em} |
| sub{bottom:-.25em} |
| img{border:0} |
| svg:not(:root){overflow:hidden} |
| figure{margin:0} |
| fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em} |
| legend{border:0;padding:0} |
| button,input,select,textarea{font-family:inherit;font-size:100%;margin:0} |
| button,input{line-height:normal} |
| button,select{text-transform:none} |
| button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} |
| button[disabled],html input[disabled]{cursor:default} |
| input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0} |
| button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} |
| textarea{overflow:auto;vertical-align:top} |
| table{border-collapse:collapse;border-spacing:0} |
| *,*::before,*::after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box} |
| html,body{font-size:100%} |
| body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased} |
| a:hover{cursor:pointer} |
| img,object,embed{max-width:100%;height:auto} |
| object,embed{height:100%} |
| img{-ms-interpolation-mode:bicubic} |
| .left{float:left!important} |
| .right{float:right!important} |
| .text-left{text-align:left!important} |
| .text-right{text-align:right!important} |
| .text-center{text-align:center!important} |
| .text-justify{text-align:justify!important} |
| .hide{display:none} |
| img,object,svg{display:inline-block;vertical-align:middle} |
| textarea{height:auto;min-height:50px} |
| select{width:100%} |
| .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em} |
| div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0} |
| a{color:#2156a5;text-decoration:underline;line-height:inherit} |
| a:hover,a:focus{color:#1d4b8f} |
| a img{border:0} |
| p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility} |
| p aside{font-size:.875em;line-height:1.35;font-style:italic} |
| h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em} |
| h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0} |
| h1{font-size:2.125em} |
| h2{font-size:1.6875em} |
| h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em} |
| h4,h5{font-size:1.125em} |
| h6{font-size:1em} |
| hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0} |
| em,i{font-style:italic;line-height:inherit} |
| strong,b{font-weight:bold;line-height:inherit} |
| small{font-size:60%;line-height:inherit} |
| code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} |
| ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} |
| ul,ol{margin-left:1.5em} |
| ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em} |
| ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit} |
| ul.square{list-style-type:square} |
| ul.circle{list-style-type:circle} |
| ul.disc{list-style-type:disc} |
| ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} |
| dl dt{margin-bottom:.3125em;font-weight:bold} |
| dl dd{margin-bottom:1.25em} |
| abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help} |
| abbr{text-transform:none} |
| blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd} |
| blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)} |
| @media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2} |
| h1{font-size:2.75em} |
| h2{font-size:2.3125em} |
| h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em} |
| h4{font-size:1.4375em}} |
| table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede;word-wrap:normal} |
| table thead,table tfoot{background:#f7f8f7} |
| table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} |
| table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)} |
| table tr.even,table tr.alt{background:#f8f8f7} |
| table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6} |
| h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em} |
| h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400} |
| .center{margin-left:auto;margin-right:auto} |
| .stretch{width:100%} |
| .clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table} |
| .clearfix::after,.float-group::after{clear:both} |
| :not(pre).nobreak{word-wrap:normal} |
| :not(pre).nowrap{white-space:nowrap} |
| :not(pre).pre-wrap{white-space:pre-wrap} |
| :not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed} |
| pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed} |
| pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit} |
| pre>code{display:block} |
| pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal} |
| em em{font-style:normal} |
| strong strong{font-weight:400} |
| .keyseq{color:rgba(51,51,51,.8)} |
| kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap} |
| .keyseq kbd:first-child{margin-left:0} |
| .keyseq kbd:last-child{margin-right:0} |
| .menuseq,.menuref{color:#000} |
| .menuseq b:not(.caret),.menuref{font-weight:inherit} |
| .menuseq{word-spacing:-.02em} |
| .menuseq b.caret{font-size:1.25em;line-height:.8} |
| .menuseq i.caret{font-weight:bold;text-align:center;width:.45em} |
| b.button::before,b.button::after{position:relative;top:-1px;font-weight:400} |
| b.button::before{content:"[";padding:0 3px 0 2px} |
| b.button::after{content:"]";padding:0 2px 0 3px} |
| p a>code:hover{color:rgba(0,0,0,.9)} |
| #header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em} |
| #header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table} |
| #header::after,#content::after,#footnotes::after,#footer::after{clear:both} |
| #content{margin-top:1.25em} |
| #content::before{content:none} |
| #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} |
| #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf} |
| #header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px} |
| #header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap} |
| #header .details span:first-child{margin-left:-.125em} |
| #header .details span.email a{color:rgba(0,0,0,.85)} |
| #header .details br{display:none} |
| #header .details br+span::before{content:"\00a0\2013\00a0"} |
| #header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)} |
| #header .details br+span#revremark::before{content:"\00a0|\00a0"} |
| #header #revnumber{text-transform:capitalize} |
| #header #revnumber::after{content:"\00a0"} |
| #content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem} |
| #toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em} |
| #toc>ul{margin-left:.125em} |
| #toc ul.sectlevel0>li>a{font-style:italic} |
| #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0} |
| #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none} |
| #toc li{line-height:1.3334;margin-top:.3334em} |
| #toc a{text-decoration:none} |
| #toc a:active{text-decoration:underline} |
| #toctitle{color:#7a2518;font-size:1.2em} |
| @media screen and (min-width:768px){#toctitle{font-size:1.375em} |
| body.toc2{padding-left:15em;padding-right:0} |
| #toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} |
| #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em} |
| #toc.toc2>ul{font-size:.9em;margin-bottom:0} |
| #toc.toc2 ul ul{margin-left:0;padding-left:1em} |
| #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em} |
| body.toc2.toc-right{padding-left:0;padding-right:15em} |
| body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}} |
| @media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0} |
| #toc.toc2{width:20em} |
| #toc.toc2 #toctitle{font-size:1.375em} |
| #toc.toc2>ul{font-size:.95em} |
| #toc.toc2 ul ul{padding-left:1.25em} |
| body.toc2.toc-right{padding-left:0;padding-right:20em}} |
| #content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} |
| #content #toc>:first-child{margin-top:0} |
| #content #toc>:last-child{margin-bottom:0} |
| #footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em} |
| #footer-text{color:rgba(255,255,255,.8);line-height:1.44} |
| #content{margin-bottom:.625em} |
| .sect1{padding-bottom:.625em} |
| @media screen and (min-width:768px){#content{margin-bottom:1.25em} |
| .sect1{padding-bottom:1.25em}} |
| .sect1:last-child{padding-bottom:0} |
| .sect1+.sect1{border-top:1px solid #e7e7e9} |
| #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400} |
| #content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em} |
| #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible} |
| #content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none} |
| #content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221} |
| details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em} |
| details>summary:first-of-type{cursor:pointer;display:list-item;outline:none;margin-bottom:.75em} |
| .admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic} |
| table.tableblock.fit-content>caption.title{white-space:nowrap;width:0} |
| .paragraph.lead>p,#preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)} |
| table.tableblock #preamble>.sectionbody>[class="paragraph"]:first-of-type p{font-size:inherit} |
| .admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%} |
| .admonitionblock>table td.icon{text-align:center;width:80px} |
| .admonitionblock>table td.icon img{max-width:none} |
| .admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase} |
| .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere} |
| .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} |
| .exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px} |
| .exampleblock>.content>:first-child{margin-top:0} |
| .exampleblock>.content>:last-child{margin-bottom:0} |
| .sidebarblock{border-style:solid;border-width:1px;border-color:#dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;-webkit-border-radius:4px;border-radius:4px} |
| .sidebarblock>:first-child{margin-top:0} |
| .sidebarblock>:last-child{margin-bottom:0} |
| .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} |
| .exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} |
| .literalblock pre,.listingblock>.content>pre{-webkit-border-radius:4px;border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em} |
| @media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}} |
| @media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}} |
| .literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class="highlight"],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8} |
| .literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)} |
| .listingblock>.content{position:relative} |
| .listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5} |
| .listingblock:hover code[data-lang]::before{display:block} |
| .listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5} |
| .listingblock.terminal pre .command:not([data-prompt])::before{content:"$"} |
| .listingblock pre.highlightjs{padding:0} |
| .listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px} |
| .listingblock pre.prettyprint{border-width:0} |
| .prettyprint{background:#f7f7f8} |
| pre.prettyprint .linenums{line-height:1.45;margin-left:2em} |
| pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0} |
| pre.prettyprint li code[data-lang]::before{opacity:1} |
| pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none} |
| table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none} |
| table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal} |
| table.linenotable td.code{padding-left:.75em} |
| table.linenotable td.linenos{border-right:1px solid currentColor;opacity:.35;padding-right:.5em} |
| pre.pygments .lineno{border-right:1px solid currentColor;opacity:.35;display:inline-block;margin-right:.75em} |
| pre.pygments .lineno::before{content:"";margin-right:-.125em} |
| .quoteblock{margin:0 1em 1.25em 1.5em;display:table} |
| .quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em} |
| .quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify} |
| .quoteblock blockquote{margin:0;padding:0;border:0} |
| .quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)} |
| .quoteblock blockquote>.paragraph:last-child p{margin-bottom:0} |
| .quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right} |
| .verseblock{margin:0 1em 1.25em} |
| .verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} |
| .verseblock pre strong{font-weight:400} |
| .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex} |
| .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic} |
| .quoteblock .attribution br,.verseblock .attribution br{display:none} |
| .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)} |
| .quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none} |
| .quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0} |
| .quoteblock.abstract{margin:0 1em 1.25em;display:block} |
| .quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center} |
| .quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf} |
| .quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0} |
| .quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem} |
| .quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0} |
| p.tableblock:last-child{margin-bottom:0} |
| td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere} |
| td.tableblock>.content>:last-child{margin-bottom:-1.25em} |
| table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} |
| table.grid-all>*>tr>*{border-width:1px} |
| table.grid-cols>*>tr>*{border-width:0 1px} |
| table.grid-rows>*>tr>*{border-width:1px 0} |
| table.frame-all{border-width:1px} |
| table.frame-ends{border-width:1px 0} |
| table.frame-sides{border-width:0 1px} |
| table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0} |
| table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0} |
| table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0} |
| table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0} |
| table.stripes-all tr,table.stripes-odd tr:nth-of-type(odd),table.stripes-even tr:nth-of-type(even),table.stripes-hover tr:hover{background:#f8f8f7} |
| th.halign-left,td.halign-left{text-align:left} |
| th.halign-right,td.halign-right{text-align:right} |
| th.halign-center,td.halign-center{text-align:center} |
| th.valign-top,td.valign-top{vertical-align:top} |
| th.valign-bottom,td.valign-bottom{vertical-align:bottom} |
| th.valign-middle,td.valign-middle{vertical-align:middle} |
| table thead th,table tfoot th{font-weight:bold} |
| tbody tr th{background:#f7f8f7} |
| tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold} |
| p.tableblock>code:only-child{background:none;padding:0} |
| p.tableblock{font-size:1em} |
| ol{margin-left:1.75em} |
| ul li ol{margin-left:1.5em} |
| dl dd{margin-left:1.125em} |
| dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0} |
| ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em} |
| ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none} |
| ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em} |
| ul.unstyled,ol.unstyled{margin-left:0} |
| ul.checklist{margin-left:.625em} |
| ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em} |
| ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em} |
| ul.inline{display:-ms-flexbox;display:-webkit-box;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em} |
| ul.inline>li{margin-left:1.25em} |
| .unstyled dl dt{font-weight:400;font-style:normal} |
| ol.arabic{list-style-type:decimal} |
| ol.decimal{list-style-type:decimal-leading-zero} |
| ol.loweralpha{list-style-type:lower-alpha} |
| ol.upperalpha{list-style-type:upper-alpha} |
| ol.lowerroman{list-style-type:lower-roman} |
| ol.upperroman{list-style-type:upper-roman} |
| ol.lowergreek{list-style-type:lower-greek} |
| .hdlist>table,.colist>table{border:0;background:none} |
| .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none} |
| td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em} |
| td.hdlist1{font-weight:bold;padding-bottom:1.25em} |
| td.hdlist2{word-wrap:anywhere} |
| .literalblock+.colist,.listingblock+.colist{margin-top:-.5em} |
| .colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top} |
| .colist td:not([class]):first-child img{max-width:none} |
| .colist td:not([class]):last-child{padding:.25em 0} |
| .thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd} |
| .imageblock.left{margin:.25em .625em 1.25em 0} |
| .imageblock.right{margin:.25em 0 1.25em .625em} |
| .imageblock>.title{margin-bottom:0} |
| .imageblock.thumb,.imageblock.th{border-width:6px} |
| .imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em} |
| .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0} |
| .image.left{margin-right:.625em} |
| .image.right{margin-left:.625em} |
| a.image{text-decoration:none;display:inline-block} |
| a.image object{pointer-events:none} |
| sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super} |
| sup.footnote a,sup.footnoteref a{text-decoration:none} |
| sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline} |
| #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} |
| #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0} |
| #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em} |
| #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em} |
| #footnotes .footnote:last-of-type{margin-bottom:0} |
| #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0} |
| .gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0} |
| .gist .file-data>table td.line-data{width:99%} |
| div.unbreakable{page-break-inside:avoid} |
| .big{font-size:larger} |
| .small{font-size:smaller} |
| .underline{text-decoration:underline} |
| .overline{text-decoration:overline} |
| .line-through{text-decoration:line-through} |
| .aqua{color:#00bfbf} |
| .aqua-background{background:#00fafa} |
| .black{color:#000} |
| .black-background{background:#000} |
| .blue{color:#0000bf} |
| .blue-background{background:#0000fa} |
| .fuchsia{color:#bf00bf} |
| .fuchsia-background{background:#fa00fa} |
| .gray{color:#606060} |
| .gray-background{background:#7d7d7d} |
| .green{color:#006000} |
| .green-background{background:#007d00} |
| .lime{color:#00bf00} |
| .lime-background{background:#00fa00} |
| .maroon{color:#600000} |
| .maroon-background{background:#7d0000} |
| .navy{color:#000060} |
| .navy-background{background:#00007d} |
| .olive{color:#606000} |
| .olive-background{background:#7d7d00} |
| .purple{color:#600060} |
| .purple-background{background:#7d007d} |
| .red{color:#bf0000} |
| .red-background{background:#fa0000} |
| .silver{color:#909090} |
| .silver-background{background:#bcbcbc} |
| .teal{color:#006060} |
| .teal-background{background:#007d7d} |
| .white{color:#bfbfbf} |
| .white-background{background:#fafafa} |
| .yellow{color:#bfbf00} |
| .yellow-background{background:#fafa00} |
| span.icon>.fa{cursor:default} |
| a span.icon>.fa{cursor:inherit} |
| .admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default} |
| .admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c} |
| .admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111} |
| .admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900} |
| .admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400} |
| .admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000} |
| .conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);-webkit-border-radius:50%;border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold} |
| .conum[data-value] *{color:#fff!important} |
| .conum[data-value]+b{display:none} |
| .conum[data-value]::after{content:attr(data-value)} |
| pre .conum[data-value]{position:relative;top:-.125em} |
| b.conum *{color:inherit!important} |
| .conum:not([data-value]):empty{display:none} |
| dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility} |
| h1,h2,p,td.content,span.alt{letter-spacing:-.01em} |
| p strong,td.content strong,div.footnote strong{letter-spacing:-.005em} |
| p,blockquote,dt,td.content,span.alt{font-size:1.0625rem} |
| p{margin-bottom:1.25rem} |
| .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} |
| .exampleblock>.content{background:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc} |
| .print-only{display:none!important} |
| @page{margin:1.25cm .75cm} |
| @media print{*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important} |
| html{font-size:80%} |
| a{color:inherit!important;text-decoration:underline!important} |
| a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important} |
| a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em} |
| abbr[title]::after{content:" (" attr(title) ")"} |
| pre,blockquote,tr,img,object,svg{page-break-inside:avoid} |
| thead{display:table-header-group} |
| svg{max-width:100%} |
| p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3} |
| h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid} |
| #header,#content,#footnotes,#footer{max-width:none} |
| #toc,.sidebarblock,.exampleblock>.content{background:none!important} |
| #toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important} |
| body.book #header{text-align:center} |
| body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em} |
| body.book #header .details{border:0!important;display:block;padding:0!important} |
| body.book #header .details span:first-child{margin-left:0!important} |
| body.book #header .details br{display:block} |
| body.book #header .details br+span::before{content:none!important} |
| body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important} |
| body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always} |
| .listingblock code[data-lang]::before{display:block} |
| #footer{padding:0 .9375em} |
| .hide-on-print{display:none!important} |
| .print-only{display:block!important} |
| .hide-for-print{display:none!important} |
| .show-for-print{display:inherit!important}} |
| @media print,amzn-kf8{#header>h1:first-child{margin-top:1.25rem} |
| .sect1{padding:0!important} |
| .sect1+.sect1{border:0} |
| #footer{background:none} |
| #footer-text{color:rgba(0,0,0,.6);font-size:.9em}} |
| @media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}} |
| </style> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> |
| <!-- |
| |
| Copyright (c) 2021 Contributors to the Eclipse Foundation |
| |
| This program and the accompanying materials are made |
| available under the terms of the Eclipse Public License 2.0 |
| which is available at https://www.eclipse.org/legal/epl-2.0/ |
| |
| SPDX-License-Identifier: EPL-2.0 |
| |
| --> |
| <style> |
| html { |
| height: 100%; |
| } |
| body { |
| min-height: 100%; |
| display: flex; |
| flex-direction: column; |
| align-content: space-between; |
| } |
| #content { |
| flex: 1; |
| } |
| #footer-text, #footer-text a { |
| color: rgba(255,255,255,.8); |
| } |
| </style> |
| </head> |
| <body class="article toc2 toc-left"> |
| <div id="header"> |
| <div id="toc" class="toc2"> |
| <div id="toctitle">Eclipse CommaSuite</div> |
| <ul class="sectlevel1"><li><a style="" href="javascript:navigatePage('../index.html')">Home</a></li><li><a style="" href="javascript:navigatePage('../site/download.html')">Download</a></li><li><a style="" href="javascript:navigatePage('../site/developers.html')">Developers</a></li><li><a style="" href="javascript:navigatePage('../site/publications.html')">Publications</a></li><li><a style="" href="javascript:navigatePage('../user_guide.html')">User guide</a><ul class="sectlevel2"><li><a style="" href="javascript:navigatePage('../overview/intro.html')">Language overview</a><ul class="sectlevel3"><li><a style="" href="javascript:navigatePage('../overview/gettingstarted.html')">Getting started</a><ul class="sectlevel4"></ul></li><li><a style="" href="javascript:navigatePage('language.html')">Language</a><ul class="sectlevel4"><li><a style="" href="javascript:navigatePage('types.html')">Types</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('interfaces.html')">Interface signatures</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('statemachines.html')">Interfaces</a><ul class="sectlevel5"><li><a style="" href="javascript:navigatePage('states.html')">States</a><ul class="sectlevel6"></ul></li><li><a style="" href="javascript:navigatePage('transitions.html')">Transitions</a><ul class="sectlevel6"></ul></li><li><a style="" href="javascript:navigatePage('timing_constraints.html')">Timing constraints</a><ul class="sectlevel6"></ul></li><li><a style="" href="javascript:navigatePage('data_constraints.html')">Data constraints</a><ul class="sectlevel6"></ul></li><li><a style="" href="javascript:navigatePage('generic_constraints.html')">Generic constraints</a><ul class="sectlevel6"></ul></li></ul></li><li><a style="font-weight: bold" href="javascript:navigatePage('components.html')">Components</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('expressions.html')">Statements and expressions</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('comments.html')">Documenting models</a><ul class="sectlevel5"></ul></li></ul></li></ul></li><li><a style="" href="javascript:navigatePage('../generators/generators.html')">Generator tasks</a><ul class="sectlevel3"><li><a style="" href="javascript:navigatePage('../generators/umlgeneration.html')">Generation of UML diagrams</a><ul class="sectlevel4"></ul></li><li><a style="" href="javascript:navigatePage('../generators/docgeneration.html')">Document generation</a><ul class="sectlevel4"></ul></li><li><a style="" href="javascript:navigatePage('../generators/monitoring.html')">Monitoring</a><ul class="sectlevel4"></ul></li><li><a style="" href="javascript:navigatePage('../generators/reachabilitygraph.html')">Reachability graph</a><ul class="sectlevel4"></ul></li><li><a style="" href="javascript:navigatePage('../generators/testgeneration.html')">Test generation</a><ul class="sectlevel4"></ul></li></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/intro.html')">Tutorial</a><ul class="sectlevel3"><li><a style="" href="javascript:navigatePage('../tutorial/preparation.html')">Preparation</a><ul class="sectlevel4"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/serviceinterface.html')">Service interface</a><ul class="sectlevel4"><li><a style="" href="javascript:navigatePage('../tutorial/activity1.html')">Activity 1: Get familiar with the Vending Machine</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/activity2.html')">Activity 2: Make an initial specification of the service interface</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/activity3.html')">Activity 3: Check an execution trace against the state machine</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/activity4.html')">Activity 4: Extend the specification of the service interface</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/activity5.html')">Activity 5: Add a time constraint</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/activity6.html')">Activity 6: Documentation generation</a><ul class="sectlevel5"></ul></li></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/coincheckinterface.html')">Coin checker interface</a><ul class="sectlevel4"><li><a style="" href="javascript:navigatePage('../tutorial/activity7.html')">Activity 7: State machine of the coin checker</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/activity8.html')">Activity 8: Check the specified interfaces by monitoring</a><ul class="sectlevel5"></ul></li></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/userinterface.html')">User interface</a><ul class="sectlevel4"><li><a style="" href="javascript:navigatePage('../tutorial/activity9.html')">Activity 9: State machine of the user interface</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/activity10.html')">Activity 10: Check the specified interfaces by monitoring</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/activity11.html')">Activity 11: Define time constraints</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/activity12.html')">Activity 12: Define a data constraint</a><ul class="sectlevel5"></ul></li></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/componentmodel.html')">Component model</a><ul class="sectlevel4"><li><a style="" href="javascript:navigatePage('../tutorial/activity13.html')">Activity 13: Define component and add functional constraint</a><ul class="sectlevel5"></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/activity14.html')">Activity 14: Define additional component constraints</a><ul class="sectlevel5"></ul></li></ul></li><li><a style="" href="javascript:navigatePage('../tutorial/concludingremarks.html')">Concluding remarks</a><ul class="sectlevel4"></ul></li></ul></li><li><a style="" href="javascript:navigatePage('../commandline/commandline.html')">Command line tool</a><ul class="sectlevel3"></ul></li><li><a style="" href="javascript:navigatePage('../eventfiles/eventfiles.html')">Event files</a><ul class="sectlevel3"></ul></li><li><a style="" href="javascript:navigatePage('../shortcuts/shortcuts.html')">Shortcuts</a><ul class="sectlevel3"></ul></li><li><a style="" href="javascript:navigatePage('../problems/problemsolving.html')">Problem solving</a><ul class="sectlevel3"></ul></li></ul></li></ul> |
| </div> |
| </div> |
| <div id="content"> |
| <div class="sect1"> |
| <h2 id="_components"><a class="anchor" href="#_components"></a>Components</h2> |
| <div class="sectionbody"> |
| <div class="paragraph normal"> |
| <p>Several interfaces are typically used together in the scope of a software sub-system where some of them are exposed to clients and the sub-system itself is a client for other sub-systems via their interfaces. In such a scope, interfaces may have interdependencies manifested as constraints on the allowed order of their events. |
| As a trivial example consider a car that first has to be started (by pressing the 'start' button) and only after that the driver can operate the car entertainment touch screen. |
| The actions of starting the car and starting the MP3 player may logically belong to different interfaces still obeying some cross-interface rules. |
| The rules for using several interfaces together need to be explicitly given similarly to the rules for a single interface.</p> |
| </div> |
| <div class="paragraph"> |
| <p>In the CommaSuite framework, this need is addressed in component models. |
| A component is an abstraction where several interfaces are used together and specifies how these interfaces interact with each other. |
| Furthermore, a component may impose restrictions on the interaction among possibly multiple clients of the same interface. |
| The name 'component' may clash with the same name used to denote a unit in a software/system logical or physical architecture. |
| In this respect, a CommaSuite component does not necessarily correspond to an architectural or implementation construct that might also be named 'component'.</p> |
| </div> |
| <div class="sect2"> |
| <h3 id="_syntax_of_component_models"><a class="anchor" href="#_syntax_of_component_models"></a>Syntax of Component Models</h3> |
| <div class="paragraph"> |
| <p>Component models are stored in files with extension 'component'. A component has number of <em>ports</em>, each port associated to a CommaSuite interface. Ports are connection points of the component and are classified as <em>provided</em> or <em>required</em>. A provided port is used by the clients of the component to communicate with it following the port’s interface protocol. A required port is used by the component to communicate with its environment (in the role of a client), again following the corresponding interface protocol. All ports are named. It is possible to have two ports associated to the same interface. In the general case, we assume that multiple clients can connect to a provided port and a component instance can connect to multiple servers via a required port.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The dependencies among the interfaces of the ports in the component are defined in component <em>functional constraints</em>. Furthermore, components may have <em>time and data constraints</em> expressed in the same syntax as the ones for interfaces. The general syntax of component models is given below:</p> |
| </div> |
| <div class="literalblock"> |
| <div class="content"> |
| <pre>import "interface1.interface" |
| import "interface2.interface" |
| //... other imports |
| |
| component componentName |
| |
| provided port IInterface1 port1 //port interface and port name |
| required port IInterface2 port2 |
| //... other ports</pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p><span class="maroon"><strong>functional constraints</strong></span></p> |
| </div> |
| <div class="paragraph"> |
| <p>Optional <a href="#fconstraint">functional constraints</a></p> |
| </div> |
| <div class="paragraph"> |
| <p><span class="maroon"><strong>timing constraints</strong></span></p> |
| </div> |
| <div class="paragraph"> |
| <p>Optional <a href="#tdconstraints">timing constraints</a></p> |
| </div> |
| <div class="paragraph"> |
| <p><span class="maroon"><strong>data constraints</strong></span></p> |
| </div> |
| <div class="paragraph"> |
| <p>Optional <a href="#tdconstraints">data constraints</a></p> |
| </div> |
| <div class="paragraph"> |
| <p>The important new construct here is <em>functional constraint</em>. It will be explained on the basis of a simple example.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_example"><a class="anchor" href="#_example"></a>Example</h3> |
| <div class="paragraph"> |
| <p>The example uses a hypothetical component that is capturing micro images of materials in a controlled environment with required temperature and presence of vacuum. Each of the three aspects of image capturing, setting the temperature and the vacuum is controlled via a separate interface: IImaging, ITemperature and IVacuum respectively.</p> |
| </div> |
| <div class="paragraph"> |
| <p>IImaging defines commands for preparing and creating images. IVacuum defines commands for enabling/disabling vacuum (vacuum On and Off). ITemperature defines commands for setting the temperature at certain level and resetting the temperature level. All interfaces send notifications as an indication of successful execution.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The following table gives the state machines of these interfaces:</p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 33.3333%;"> |
| <col style="width: 33.3333%;"> |
| <col style="width: 33.3334%;"> |
| </colgroup> |
| <thead> |
| <tr> |
| <th class="tableblock halign-left valign-top">ITemperature</th> |
| <th class="tableblock halign-left valign-top">IVacuum</th> |
| <th class="tableblock halign-left valign-top">IImaging</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="image"><img src="../img/ITemperature.png" alt="image"></span></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="image"><img src="../img/IVacuum.png" alt="image"></span></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><span class="image"><img src="../img/IImaging.png" alt="image"></span></p></td> |
| </tr> |
| </tbody> |
| </table> |
| <div class="paragraph"> |
| <p>The component satisfies the following requirements regarding the interaction among the three interfaces:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>Creating an image is possible only if the vacuum is present and the requested temperature is reached</p> |
| </li> |
| <li> |
| <p>Setting the temperature is possible only if the vacuum is present</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>These two requirements will be expressed as component functional constraints. The goal of a functional constraint is to capture only an aspect of the total behavior of the component. Component models are not expected to define the complete component behavior in terms of reactions to all possible commands in different states. In other words, component models are not design specifications that are used to derive an implementation. An implementation of a component is expected to satisfy all the functional constraints defined in a component model along with the time and data constraints.</p> |
| </div> |
| <div class="literalblock"> |
| <div class="content"> |
| <pre>import "IImaging.interface" |
| import "ITemperature.interface" |
| import "IVacuum.interface" |
| |
| component Imaging |
| |
| provided port IImaging iImagPort |
| provided port ITemperature iTempPort |
| provided port IVacuum iVacPort |
| |
| functional constraints |
| ...</pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>One example functional constraint is explained in the next section.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_functional_constraints"><a class="anchor" href="#_functional_constraints"></a><span id="fconstraint">Functional</span> Constraints</h3> |
| <div class="paragraph"> |
| <p>We distinguish between <em>state-based</em> and <em>predicate</em> functional constraints. The first kind is a state-based specification of behavior using a subset of the union of all events that can be observed on all the component ports. The second kind is a Boolean expression that has to be true every time the component receives or sends a message.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Component monitoring process checks if all functional constraints hold for a set of traces. The process of checking a functional constraint is done in parallel with interface monitoring, that is, a check if the given trace satisfies all the interfaces at the component ports. This means that the information about the port state is available during the check of a functional constraint (which syntax construct is used for this is explained shortly). The monitoring of component ports follows the principles of <a href="../monitoring/monitoring.html#singleton_multiton_monitoring">interface monitoring</a>. In particular, a port associated to multiton interface is monitored by creating a monitor for each connection. A port of singleton interface uses a single monitor for all the connections.</p> |
| </div> |
| <div class="sect3"> |
| <h4 id="_state_based_functional_constraints"><a class="anchor" href="#_state_based_functional_constraints"></a>State-based Functional Constraints</h4> |
| <div class="paragraph"> |
| <p>The example below is a state-based functional constraint that implements the first requirement: imaging is possible only if the vacuum is present and a target temperature is set. We also temporarily assume that the ports have a single client.</p> |
| </div> |
| <div class="literalblock"> |
| <div class="content"> |
| <pre>ImagingConstraint { |
| use events |
| command iImagPort::CreateImage |
| iImagPort::reply to command CreateImage |
| |
| initial state Status { |
| command iImagPort::CreateImage where iVacPort in Vacuum and iTempPort in TemperatureSet |
| iImagPort::reply(Result::Ok) to command CreateImage |
| next state: Status |
| |
| command iImagPort::CreateImage where not iVacPort in Vacuum or not iTempPort in TemperatureSet |
| iImagPort::reply(Result::NotAvailable) to command CreateImage |
| next state: Status |
| } |
| }</pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The constraint named 'ImagingConstraint' first declares which events will be used (clause 'use events'). In the example we are interested in two events only: command CreateImage and its reply. As can be seen all events are prefixed with the ports at which they are observed. This is needed for name disambiguation because an interface can be associated to more than one port. Events that are not declared in this clause cannot be used in the constraint.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Generally a state-based constraint is given as a state machine with exactly one initial state. Transitions are sequences of actions where the first action is an <em>event reception</em>: an indication that an event is expected to be observed. In the example we have only one state with two transitions. The intention behind the specification is that if the command CreateImage is received under the correct conditions the reply gives the value OK (the first transition). Otherwise the reply returns value NotAvailable (second transition).</p> |
| </div> |
| <div class="paragraph"> |
| <p>An event reception may have an optional boolean expression as a condition after the keyword <em>where</em>. The reception is successful if the event is observed in the trace and the condition is true. The example condition shows how functional constraints use information about the state of the interface at a given port. The general syntax is <em>portName in stateName</em>. State <em>Vacuum</em> indicates that the vacuum is properly set, state <em>TemperatureSet</em> indicates the desired temperature is established. This access to interface state information is extremely handy. Without it, the functional constraint should trace the sequence of the events in the other two interfaces, a task that is often performed by the interface specs and the interface monitor. This way, code duplication is avoided and the size of the constraint is reduced.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Informally, the semantics of a state-based functional constraint is as follows. For a given trace, first a projection is made by eliminating all the events not listed in the 'use events'. Then starting from the initial state and the first event in the trace, a transition traversal path is searched that accepts the trace. Each transition accepts a fragment of the trace by executing the actions in its body. Recall that a transition always starts with an event reception. Transitions are tried in the order of their appearance in the state. When an event reception action is executed it has to match the current observed event and the condition must be true (if present) in case of match. If the head event reception of a transition matches the event, then the transition is taken. Otherwise the next one is tried. If no transition is taken, a functional constraint monitoring error is generated. If a transition is taken then all the executed event reception actions in its body must succeed on the subsequently observed events until the move to the next state is done. Please note that if an event reception fails after the transition is selected then the whole transition fails, the next one is not tried and a monitoring error is given.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The full details on the syntax of <em>use events</em> clause, event receptions, and the allowed actions in the transition bodies are given in the subsequent appendix.</p> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_predicate_functional_constraints"><a class="anchor" href="#_predicate_functional_constraints"></a>Predicate Functional Constraints</h4> |
| <div class="paragraph"> |
| <p>As an example of predicate functional constraint we will give a different interpretation and implementation of the same requirement as before. We will require that if port iImagPort is in state Imaging then iTempPort is in state TemperatureSet and iVacPort is in state Vacuum.</p> |
| </div> |
| <div class="literalblock"> |
| <div class="content"> |
| <pre>ImagingConstraint_Predicate |
| always |
| not iImagPort in Imaging or |
| (iTempPort in TemperatureSet and iVacPort in Vacuum)</pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The meaning of this functional constraint is that whenever an event is observed at any component port, the boolean expression after 'always' must evaluate to true.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Please note that the two example constraints are not equivalent in terms of the set of traces that satisfy them. The first constraint strictly requires reply(OK) to command CreateImage if the temperature and vacuum ports are in the required states whereas the second constraint allows reply(NotAvailable) to be sent under the same conditions. If however, iImagPort enters state Imaging (which is only possible if reply(OK) is observed) then the temperature and vacuum ports must be in the required states.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Another important subtlety is how the state of a port is determined. In this example we assumed a single client per port meaning that a single interface monitor will be created per port thus the port states are uniquely determined. However, the general case is multiple connections per port leading to possibly different states per connection on the same port. Next section explains the language constructs that give fine grained access to port connection states.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_identification_and_quantification_over_port_connections"><a class="anchor" href="#_identification_and_quantification_over_port_connections"></a>Identification and Quantification over Port Connections</h3> |
| <div class="paragraph"> |
| <p>As already mentioned, we generally assume that multiple communication parties can be connected to a port. For a provided port these are the clients of the component. For a required port these are the servers used by the component. A given event observed at a given port is always associated to a communication party. It is possible to capture the identity of this party in a variable and to use it in expressions. Furthermore, during component monitoring, an instance of the port’s interface is created for every connection to or from the port. This gives the possibility to obtain the current interface state at a given port for a given connection. Based on this information, the CommaSuite component language provides a number of expressions that quantify over the connections at a given port stating, for example, that all or some connections are in a given interface state. We will illustrate these expressions on the basis of an example.</p> |
| </div> |
| <div class="paragraph"> |
| <p>As an example, consider a component that provides a hypothetical resource to its clients via an interface IResource. Multiple clients can request control over the resource. The component is responsible for implementing a policy for sharing the resource among multiple clients. In our example, the component will allow at most one client at a time to be in control of the resource. The following is the definition of the IResource interface:</p> |
| </div> |
| <div class="literalblock"> |
| <div class="content"> |
| <pre>interface IResource |
| |
| machine Main { |
| initial state Idle { |
| transition trigger: getControl |
| do: reply(true) |
| next state: InControl |
| OR |
| do: reply(false) |
| next state: Idle |
| } |
| |
| state InControl { |
| //... do something with the resource |
| transition do: controlLost |
| next state: Idle |
| } |
| }</pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Here is a snippet of the component definition with two functional constraints that use constructs for identification and quantification of connections.</p> |
| </div> |
| <div class="literalblock"> |
| <div class="content"> |
| <pre>component ResourceControl |
| |
| provided port IResource resPort |
| //other ports |
| //... |
| |
| functional constraints |
| |
| FC1 { |
| use events |
| resPort::reply to command getControl |
| notification resPort::controlLost |
| |
| variables |
| id c |
| id c1 |
| |
| initial state ResourceFree { |
| <c> resPort::reply(true) to command getControl |
| next state: ResourceTaken |
| |
| resPort::reply(false) to command getControl |
| next state: ResourceFree |
| } |
| |
| state ResourceTaken { |
| notification <c1>resPort::controlLost where c == c1 |
| next state: ResourceFree |
| |
| resPort::reply(false) to command getControl |
| next state: ResourceTaken |
| } |
| } |
| |
| FC2 |
| always [0-1] connections at portRes in InControl</pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Functional constraint FC1 is state-based. If in the initial state ResourceFree a reply to command getControl with argument true is observed then the identifier of the client who receives the reply is bound to the variable <em>c</em>. Note the type of the variable: <em>id</em>. This is a predefined primitive type used only in component definitions. It allows only identity comparison operations.</p> |
| </div> |
| <div class="paragraph"> |
| <p>If a client receives a positive reply to the getControl request the state ResourceTaken becomes the current state of the FC1 machine. In this state no more positive replies to control requests are allowed. The control over the resource can be released only if the component decides to sent notification controlLost to the client which currently has the control. Observe the usage of the variable c1 that captures the identity of the receiver of the notification. It is used in the condition that ensures that the client which is currently in control receives the notification.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The logic in FC1 can be expressed more compactly as a predicate constraint. During component monitoring, the state information of each client of port resPort is available. The requirement is that at most one client is in the interface state InControl. Constraint FC2 shows the corresponding expression. It uses a quantifier over the port connections (zero or one connection satisfies a condition). The syntax of the possible quantifiers is given in the appendix.</p> |
| </div> |
| <div class="paragraph"> |
| <p>It should be noted that this example shows how component functional constraints can restrict the order of events over the connections of a single port. In contrast, the first example (about imaging, vacuum and temperature) involves multiple ports and interfaces.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_time_and_data_constraints"><a class="anchor" href="#_time_and_data_constraints"></a><span id="tdconstraints">Time and Data Constraints</span></h3> |
| <div class="paragraph"> |
| <p>Similarly to interface specifications, component models may have time and data constraints. The main difference is that events belonging to different interfaces or observed at different ports can be used. For example, a time constraint may specify that receiving a request at a provided port is followed within a certain interval by an outgoing request at a required port.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The syntax of the constraints remains the same as in interface specifications with two exceptions:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>all events must be prefixed with their ports</p> |
| </li> |
| <li> |
| <p>events cannot be assigned with states in which they are expected to occur. <em>Note:</em> in case of interface specification, states refer to interface states. In component models, there are no component states. The possibility to refer to the port states is under investigation and may be included in a future version of the CommaSuite framework.</p> |
| </li> |
| </ul> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_appendix_functional_constraints_syntax"><a class="anchor" href="#_appendix_functional_constraints_syntax"></a>Appendix: Functional Constraints Syntax</h3> |
| <div class="paragraph"> |
| <p>The syntax of state-based functional constraints has the following general structure:</p> |
| </div> |
| <div class="literalblock"> |
| <div class="content"> |
| <pre>constraintName { |
| use events |
| one or more event patterns |
| |
| variables |
| optionally, declaration of variables |
| |
| init |
| optionally, initialization of variables |
| |
| initial state S{ |
| //transition |
| eventReception //first action |
| ...other actions |
| next state: stateName |
| |
| //... other transitions |
| } |
| |
| //other states (optional) |
| state P{ |
| //... transitions |
| }</pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The syntax of predicate functional constraint is:</p> |
| </div> |
| <div class="literalblock"> |
| <div class="content"> |
| <pre>constraintName |
| always boolean_expression</pre> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_use_events_patterns"><a class="anchor" href="#_use_events_patterns"></a><span id="useevents">Use</span> Events Patterns</h4> |
| <div class="paragraph"> |
| <p>List of event patterns. Every pattern denotes a non-empty set of events. Patterns are one of:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>Single event: (<strong>command</strong> | <strong>signal</strong> | <strong>notification</strong>) portName::eventName</p> |
| </li> |
| <li> |
| <p>Reply on a given port. Can denote replies to multiple commands: portName::<strong>reply</strong></p> |
| </li> |
| <li> |
| <p>Reply to a concrete command: portName::<strong>reply to command</strong> commandName</p> |
| </li> |
| <li> |
| <p>Wildcard for events per kind: <strong>any</strong> portName::(<strong>command</strong> | <strong>signal</strong> | <strong>notification</strong>)</p> |
| </li> |
| <li> |
| <p>Wildcard that denotes all events: <strong>any</strong> portName::<strong>event</strong></p> |
| </li> |
| </ul> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_event_receptions_and_actions"><a class="anchor" href="#_event_receptions_and_actions"></a><span id="actions">Event Receptions and Actions</span></h4> |
| <div class="paragraph"> |
| <p>Event receptions indicate that an event is expected to be observed subject of an optional condition. The syntax is:</p> |
| </div> |
| <div class="paragraph"> |
| <p><em>EventPattern</em> (<strong>where</strong> <em>booleanExpression</em>)?</p> |
| </div> |
| <div class="paragraph"> |
| <p>Event pattern is one of:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>(<strong>command</strong> | <strong>signal</strong> | <strong>notification</strong>) (<<em>var</em>>)? portName::eventName(<em>expr1</em>, <em>expr2</em>, …​). The number and type of expressions must match the parameters in the event definition given in the interface signature. If an expression is a variable and the observed event matches the pattern then the actual observed parameter value is assigned to the variable and can be used later, for example, in the condition. If the expression is not a variable, it is evaluated and the value must match the observed value ('*' is allowed as a value like in interface specifications).</p> |
| </li> |
| <li> |
| <p>(<<em>var</em>>)? portName::<strong>reply</strong>(expr1, expr2, …​) (<strong>to command</strong> commandName)?</p> |
| </li> |
| <li> |
| <p><strong>any</strong> (<<em>var</em>>)? portName::(<strong>command</strong> | <strong>signal</strong> | <strong>notification</strong>)</p> |
| </li> |
| <li> |
| <p><strong>any</strong> (<<em>var</em>>)? portName::<strong>event</strong></p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>The check if an observed event matches the pattern is similar to the matching in time and data constraints. The port, event kind and name have to be the same. Parameter values must match with the exception of variables (explained earlier). In case of successful match the variables in the pattern are assigned with the observed value. The optional condition is evaluated after a successful match.</p> |
| </div> |
| <div class="paragraph"> |
| <p>The allowed actions in transitions are a subset of the ones used in interface specifications plus event reception:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>event reception (explained above)</p> |
| </li> |
| <li> |
| <p>assignment, including assignment of record fields</p> |
| </li> |
| <li> |
| <p><strong>if-then-else</strong> with the limitation that event receptions cannot be used inside it</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>Note that the <strong>any order</strong> construct is not allowed in functional constraints. It can possibly be included in a future version of the CommaSuite framework.</p> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="_quantifiers_over_port_connections"><a class="anchor" href="#_quantifiers_over_port_connections"></a><span id="actions">Quantifiers over Port Connections</span></h4> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><em>var</em> <strong>at</strong> <em>port</em> <strong>in</strong> (<em>state</em> | {<em>states, …​</em>}). Evaluates to true if the value of <em>var</em> denotes an existing communication party that is connected to the given port and this connection is in the given state (or in one of the given states). Remark: if the port is provided port of singleton interface then the result is the same for all existing communication parties since all connections share the monitor.</p> |
| </li> |
| <li> |
| <p><strong>all</strong> <strong>at</strong> <em>port</em> <strong>in</strong> (<em>state</em> | {<em>states, …​</em>}). Evaluates to true if all the connections at the given port are in one of the given states. Note that if no connections exist at the time of evaluation the value is vacuously true.</p> |
| </li> |
| <li> |
| <p><strong>some</strong> <strong>at</strong> <em>port</em> <strong>in</strong> (<em>state</em> | {<em>states, …​</em>}). Evaluates to true if at least one connection at the given port is in one of the given states.</p> |
| </li> |
| <li> |
| <p><strong>one</strong> <strong>at</strong> <em>port</em> <strong>in</strong> (<em>state</em> | {<em>states, …​</em>}). Evaluates to true if exactly one connection at the given port is in one of the given states.</p> |
| </li> |
| <li> |
| <p>[m-n] <strong>connections</strong> <strong>at</strong> <em>port</em> <strong>in</strong> (<em>state</em> | {<em>states, …​</em>}). Evaluates to true if between m and n connections at the given port are in one of the given states.</p> |
| </li> |
| <li> |
| <p><em>port</em> <strong>in</strong> <em>state</em>. Evaluates as follows:</p> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>if there is already at least one connection established over the port, the expression is an abbreviation of <strong>all</strong> <strong>at</strong> <em>port</em> <strong>in</strong> <em>state</em></p> |
| </li> |
| <li> |
| <p>if no connections are present yet on the port, the expression evaluates to true if the state is an initial state of a machine in the port’s interface</p> |
| </li> |
| </ul> |
| </div> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| <!-- |
| |
| Copyright (c) 2021 Contributors to the Eclipse Foundation |
| |
| This program and the accompanying materials are made |
| available under the terms of the Eclipse Public License 2.0 |
| which is available at https://www.eclipse.org/legal/epl-2.0/ |
| |
| SPDX-License-Identifier: EPL-2.0 |
| |
| --> |
| <div id="footer"> |
| <div id="footer-text"> |
| <a href="https://www.eclipse.org">Eclipse Home</a> |
| | |
| <a href="https://www.eclipse.org/legal/privacy.php">Privacy Policy</a> |
| | |
| <a href="https://www.eclipse.org/legal/termsofuse.php">Terms of Use</a> |
| | |
| <a href="https://www.eclipse.org/legal/copyright.php">Copyright Agent</a> |
| | |
| <a href="https://www.eclipse.org/legal">Eclipse Legal</a> |
| </div> |
| </div> |
| |
| <!-- Maintains the toc (menu) scroll position when navigating between pages --> |
| <script type="text/javascript"> |
| var toc = document.querySelector('#toc'); |
| |
| function navigatePage(page) { |
| if (toc && localStorage) { |
| localStorage.setItem('tocScrollTop', toc.scrollTop); |
| } |
| |
| document.location.href = page; |
| } |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| if (toc && localStorage && localStorage.getItem('tocScrollTop') != null) { |
| toc.scrollTop = localStorage.getItem('tocScrollTop'); |
| localStorage.setItem('tocScrollTop', null); |
| } |
| }); |
| </script> |
| </body> |
| </html> |