blob: e70dbdcbaa16fe8f59c14429ebf3ead068848ba2 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>WrapperFactory :: Apache Isis</title>
<link rel="canonical" href="https://isis.apache.org/refguide/2.0.0-M3/applib-svc/WrapperFactory.html">
<meta name="generator" content="Antora 2.2.0">
<link rel="stylesheet" href="../../../_/css/site.css">
<link rel="stylesheet" href="../../../_/css/site-custom.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,700,700i|Raleway:300,400,500,700,800|Montserrat:300,400,700" rel="stylesheet">
<link rel="home" href="https://isis.apache.org" title="Apache Isis">
<link rel="next" href="XmlService.html" title="XmlService">
<link rel="prev" href="UserService.html" title="UserService">
</head>
<body class="article">
<header class="header">
<nav class="navbar">
<div class="navbar-brand">
<a class="navbar-item" href="https://isis.apache.org">
<span class="icon">
<img src="../../../_/img/isis-logo-48x48.png"></img>
</span>
<span>Apache Isis</span>
</a>
<button class="navbar-burger" data-target="topbar-nav">
<span></span>
<span></span>
<span></span>
</button>
</div>
<div id="topbar-nav" class="navbar-menu">
<a class="navbar-end">
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Quick Start</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Starter Apps</span>
<a class="navbar-item" href="../../../docs/latest/starters/helloworld.html">Hello World</a>
<a class="navbar-item" href="../../../docs/latest/starters/simpleapp.html">Simple App</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Demos &amp; Tutorials</span>
<a class="navbar-item" href="../../../docs/latest/demo/about.html">Demo App</a>
<a class="navbar-item" href="https://danhaywood.gitlab.io/isis-petclinic-tutorial-docs/petclinic/1.16.2/intro.html">Petclinic (tutorial)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Resources</span>
<a class="navbar-item" href="../../../docs/latest/resources/cheatsheet.html">Cheatsheet</a>
<a class="navbar-item" href="../../../docs/latest/resources/icons.html">Icons</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Guides</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Development</span>
<a class="navbar-item" href="../../../setupguide/latest/about.html">Setup Guide</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Core</span>
<a class="navbar-item" href="../../../userguide/latest/about.html">User Guide</a>
<a class="navbar-item" href="../../../refguide/latest/about.html">Reference Guide</a>
<a class="navbar-item" href="../../../testing/latest/about.html">Testing Guide</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Libraries</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">For Use in Apps</span>
<a class="navbar-item" href="../../../subdomains/latest/about.html">Subdomain Libraries</a>
<a class="navbar-item" href="../../../valuetypes/latest/about.html">Value Types</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Integrate between Apps</span>
<a class="navbar-item" href="../../../mappings/latest/about.html">Bounded Context Mapping Libraries</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Other</span>
<a class="navbar-item" href="../../../incubator/latest/about.html">Incubator</a>
<a class="navbar-item" href="../../../legacy/latest/about.html">Legacy</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Components</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Viewers</span>
<a class="navbar-item" href="../../../vw/latest/about.html">Wicket UI</a>
<a class="navbar-item" href="../../../vro/latest/about.html">Restful Objects (REST)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Security</span>
<a class="navbar-item" href="../../../security/latest/about.html">Security Guide</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Persistence</span>
<a class="navbar-item" href="../../../pjdo/latest/about.html">DataNucleus (JDO)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Extensions</span>
<a class="navbar-item" href="../../../extensions/latest/about.html">Extensions Catalog</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Support</a>
<div class="navbar-dropdown">
<span class="navbar-item navbar-heading">Contact</span>
<a class="navbar-item" href="../../../docs/latest/support/slack-channel.html">Slack</a>
<a class="navbar-item" href="../../../docs/latest/support/mailing-list.html">Mailing Lists</a>
<a class="navbar-item" href="https://issues.apache.org/jira/browse/ISIS">JIRA</a>
<a class="navbar-item" href="https://stackoverflow.com/questions/tagged/isis">Stack Overflow</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Releases</span>
<a class="navbar-item" href="../../../docs/latest/downloads/how-to.html">Downloads</a>
<a class="navbar-item" href="../../../relnotes/latest/about.html">Release Notes</a>
<a class="navbar-item" href="../../../docs/latest/archive/1-x.html">Archive (1.x)</a>
<hr class="navbar-divider"/>
<span class="navbar-item navbar-heading">Framework</span>
<a class="navbar-item" href="../../../conguide/latest/about.html">Contributors' Guide</a>
<a class="navbar-item" href="../../../comguide/latest/about.html">Committers' Guide</a>
<a class="navbar-item" href="../../../core/latest/about.html">Core Design</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">ASF</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="http://www.apache.org/">Apache Homepage</a>
<a class="navbar-item" href="https://www.apache.org/events/current-event">Events</a>
<a class="navbar-item" href="https://www.apache.org/licenses/">Licenses</a>
<a class="navbar-item" href="https://www.apache.org/security/">Security</a>
<a class="navbar-item" href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a>
<a class="navbar-item" href="https://www.apache.org/foundation/thanks.html">Thanks</a>
<hr class="navbar-divider"/>
<a class="navbar-item" href="https://whimsy.apache.org/board/minutes/Isis.html">PMC board minutes</a>
</div>
</div>
<a class="navbar-item" href="../../../docs/latest/about.html">
<span class="icon">
<img src="../../../_/img/home.png"></img>
</span>
</a>
</div>
</div>
</nav>
</header>
<div class="body ">
<div class="nav-container" data-component="refguide" data-version="2.0.0-M3">
<aside class="nav">
<div class="panels">
<div class="nav-panel-pagination">
<a class="page-previous" rel="prev" href="UserService.html" title="UserService"><span></span></a>
<a class="page-next" rel="next"
href="XmlService.html" title="XmlService"><span></span></a>
<!--
page.parent doesn't seem to be set...
<a class="page-parent" rel="prev" href="about.html" title="UserService"><span></span></a>
-->
</div>
<div class="nav-panel-menu is-active" data-panel="menu">
<nav class="nav-menu">
<h3 class="title"><a href="../about.html">Reference Guide</a></h3>
<ul class="nav-list">
<li class="nav-item" data-depth="0">
<ul class="nav-list">
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../applib-ant/about.html">Annotations</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Action.html">Action</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/ActionLayout.html">ActionLayout</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Collection.html">Collection</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/CollectionLayout.html">CollectionLayout</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Column.html">Column</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Digits.html">Digits</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Discriminator.html">Discriminator</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/DomainObject.html">DomainObject</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/DomainObjectLayout.html">DomainObjectLayout</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/DomainService.html">DomainService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/DomainServiceLayout.html">DomainServiceLayout</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Facets.html">Facets</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/HomePage.html">HomePage</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/MemberOrder.html">MemberOrder</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Mixin.html">Mixin</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/NotPersistent.html">NotPersistent.</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Nullable.html">Nullable</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/MinLength.html">MinLength</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Parameter.html">Parameter</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/ParameterLayout.html">ParameterLayout</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Pattern.html">Pattern</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/PersistenceCapable.html">PersistenceCapable</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/PrimaryKey.html">PrimaryKey</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Programmatic.html">Programmatic</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Property.html">Property</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/PropertyLayout.html">PropertyLayout</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/IsisSessionScope.html">RequestScoped</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/Title.html">Title</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/ViewModel.html">ViewModel</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/XmlJavaTypeAdapter.html">XmlJavaTypeAdapter</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-ant/XmlRootElement.html">XmlRootElement</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../applib-methods/about.html">Methods</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-methods/prefixes.html">Supporting Method Prefixes</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-methods/reserved.html">Reserved Methods</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-methods/lifecycle.html">Lifecycle Methods</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../applib-classes/about.html">Classes</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-classes/events.html">Events</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-classes/ViewModel.html"><code>ViewModel</code></a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-classes/value-types.html">Value Types</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-classes/spec.html">Specification pattern</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-classes/i18n.html">i18n support</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-classes/roles-mixins-contributees.html">Roles, Mixins and Contributees</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-classes/utility.html">Utility Classes</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../applib-classes/layout.html">Layout</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="about.html">Domain Services</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="AcceptHeaderService.html">AcceptHeaderService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="ApplicationFeatureRepository.html">ApplicationFeatureRepository</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="AuditerService.html">AuditerService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="BookmarkService.html">BookmarkService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="BookmarkUiService.html">BookmarkUiService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="ClockService.html">ClockService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="CommandContext.html">CommandContext</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="CommandDtoProcessorService.html">CommandDtoProcessorService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="CommandExecutorService.html">CommandExecutorService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="CommandService.html">CommandService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="ConfigurationMenu.html">ConfigurationMenu</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="ConfigurationViewService.html">ConfigurationViewService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="ContentMappingService.html">ContentMappingService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="DeepLinkService.html">DeepLinkService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="EmailNotificationService.html">EmailNotificationService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="EmailService.html">EmailService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="ErrorReportingService.html">ErrorReportingService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="EventBusService.html">EventBusService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="ExceptionRecognizerService.html">ExceptionRecognizerService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="FactoryService.html">FactoryService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="GridLoaderService.html">GridLoaderService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="GridService.html">GridService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="GridSystemService.html">GridSystemService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="HealthCheckService.html">HealthCheckService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="HintStore.html">HintStore</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="HomePageResolverService.html">HomePageResolverService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="InteractionContext.html">InteractionContext</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="JaxbService.html">JaxbService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="LayoutService.html">LayoutService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="LayoutServiceMenu.html">LayoutServiceMenu</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="LocaleProvider.html">LocaleProvider</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="MenuBarsLoaderService.html">MenuBarsLoaderService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="MenuBarsService.html">MenuBarsService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="MessageService.html">MessageService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="MetaModelService.html">MetamodelService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="MetaModelServiceMenu.html">MetamodelServiceMenu</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="MetricsService.html">MetricsService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="PublisherService.html">PublisherService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="QueryResultsCache.html">QueryResultsCache</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="RepositoryService.html">RepositoryService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="RoutingService.html">RoutingService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="Scratchpad.html">Scratchpad</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="ServiceInjector.html">ServiceInjector</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="ServiceRegistry.html">ServiceRegistry</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="SessionLoggingService.html">SessionLoggingService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="SudoService.html">SudoService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="SwaggerService.html">SwaggerService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="TableColumnOrderService.html">TableColumnOrderService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="TitleService.html">TitleService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="TranslationService.html">TranslationService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="TranslationsResolver.html">TranslationsResolver</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="TransactionService.html">TransactionService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="UrlEncodingService.html">UrlEncodingService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="UserProfileService.html">UserProfileService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="UserRegistrationService.html">UserRegistrationService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="UserService.html">UserService</a>
</li>
<li class="nav-item is-current-page" data-depth="2">
<a class="nav-link" href="WrapperFactory.html">WrapperFactory</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="XmlService.html">XmlService</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="XmlSnapshotService.html">XmlSnapshotService</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../config/about.html">Configuration</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.applib.html">Applib</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.core.meta-model.html">Core MetaModel</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.core.meta-model.introspector.html">Core MetaModel Introspection</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.core.meta-model.validator.html">MetaModel Validator</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.core.runtime.html">Core Runtime Services configurations</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.core.runtime-services.html">Core Runtime Services configurations</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.security.shiro.html">Shiro Security Implementation</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.persistence.jdo-datanucleus.html">JDO DataNucleus</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.persistence.jdo-datanucleus.impl.html">DataNucleus Configuration</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.viewer.restfulobjects.html">Restful Objects Viewer</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.viewer.wicket.html">Wicket Viewer</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.extensions.html">Extensions</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.value-types.html">Value types</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.testing.html">Testing</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/isis.legacy.html">Legacy</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/resteasy.html">RestEasy Configuration</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../config/sections/Other.html">Other</a>
</li>
</ul>
</li>
<li class="nav-item" data-depth="1">
<button class="nav-item-toggle"></button>
<a class="nav-link" href="../schema/about.html">Schema</a>
<ul class="nav-list">
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../schema/mml.html">MetaModel</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../schema/cmd.html">Command</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../schema/ixn.html">Interaction</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../schema/chg.html">Changes</a>
</li>
<li class="nav-item" data-depth="2">
<a class="nav-link" href="../schema/common.html">Common</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="nav-panel-explore" data-panel="explore">
<div class="context">
<span class="title">Reference Guide</span>
<span class="version">2.0.0-M3</span>
</div>
<ul class="components">
<li class="component">
<span class="title"> </span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../docs/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">BC Mappings Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../mappings/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Committers' Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../comguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Contributors' Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../conguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Design Docs</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../core/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Extensions Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../extensions/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Incubator Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../incubator/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">JDO/DataNucleus</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../pjdo/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Legacy Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../legacy/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component is-current">
<span class="title">Reference Guide</span>
<ul class="versions">
<li class="version is-current is-latest">
<a href="../about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Release Notes</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../relnotes/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Restful Objects Viewer</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../vro/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Security Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../security/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Setup Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../setupguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Subdomains Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../subdomains/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Testing Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../testing/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">User Guide</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../userguide/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Value Types Catalog</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../valuetypes/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
<li class="component">
<span class="title">Wicket Viewer</span>
<ul class="versions">
<li class="version is-latest">
<a href="../../../vw/2.0.0-M3/about.html">2.0.0-M3</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</aside>
</div>
<main role="main">
<div class="toolbar" role="navigation">
<button class="nav-toggle"></button>
<a href="../../../docs/2.0.0-M3/about.html" class="home-link"></a>
<nav class="breadcrumbs" aria-label="breadcrumbs">
<ul>
<li><a href="../about.html">Reference Guide</a></li>
<li><a href="about.html">Domain Services</a></li>
<li><a href="WrapperFactory.html">WrapperFactory</a></li>
</ul>
</nav>
<div class="edit-this-page"><a href="https://github.com/apache/isis/edit/2.0.0-M3/api/applib/src/main/adoc/modules/applib-svc/pages/WrapperFactory.adoc">Edit</a></div>
</div>
<article class="doc">
<a name="section-top"></a>
<h1 class="page"><code>WrapperFactory</code></h1>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>The <code>WrapperFactory</code> provides the ability to enforce business rules for programmatic interactions between domain objects.
If there is a (lack of) trust boundary between the caller and callee&#8201;&#8212;&#8201;eg if they reside in different modules&#8201;&#8212;&#8201;then the wrapper factory is one mechanism to ensure that any business constraints defined by the callee are honoured.</p>
</div>
<div class="paragraph">
<p>For example, if the calling object attempts to modify an unmodifiable property on the target object, then an exception will be thrown.</p>
</div>
<div class="paragraph">
<p>Said another way: interactions are performed "as if" they are through the viewer.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>For a discussion of the use of the <code>WrapperFactory</code> within integration tests (the primary or at least original use case for this service) can be found <a href="../../../testing/2.0.0-M3/integtestsupport/about.html#wrapper-factory" class="page">here</a>.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>This capability goes beyond enforcing the (imperative) constraints within the <code>hideXxx()</code>, <code>disableXxx()</code> and <code>validateXxx()</code> supporting methods; it also enforces (declarative) constraints such as those represented by annotations, eg <code>@Parameter(maxLength=&#8230;&#8203;)</code> or <code>@Property(mustSatisfy=&#8230;&#8203;)</code>.</p>
</div>
<div class="paragraph">
<p>This capability is frequently used within <a href="../../../testing/2.0.0-M3/integtestsupport/about.html" class="page">integration tests</a>, but can also be used in production code.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="api"><a class="anchor" href="#api"></a>API</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The API breaks into four parts, along with a number of supporting control classes.</p>
</div>
<div class="sect2">
<h3 id="synchronous-api"><a class="anchor" href="#synchronous-api"></a>Synchronous API</h3>
<div class="paragraph">
<p>The synchronous API provided by the service is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface WrapperFactory {
&lt;T&gt; T wrap(T domainObject, <i class="conum" data-value="1"></i><b>(1)</b>
SyncControl syncControl);
&lt;T&gt; T wrap(T domainObject); <i class="conum" data-value="2"></i><b>(2)</b>
&lt;T&gt; T wrapMixin(Class&lt;T&gt; mixinClass, Object mixedIn, <i class="conum" data-value="3"></i><b>(3)</b>
SyncControl syncControl);
&lt;T&gt; T wrapMixin(Class&lt;T&gt; mixinClass, Object mixedIn); <i class="conum" data-value="4"></i><b>(4)</b>
// ...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>wraps the underlying domain object so it can invoked (through its wrapper) synchronously in the same thread.
<div class="paragraph">
<p>The <code>SyncControl</code> modifies the way in which the wrapper interacts with the underlying domain object, discussed <a href="#synccontrol">below</a>.</p>
</div></td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>overload that wraps the underlying domain object with a wrapper that will validate all business rules and then execute if they pass.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>instantiates and wraps a mixin so that it can be invoked (through its wrapper) synchronously in the same thread.
Again <code>SyncControl</code> modifies the way in which the wrapper interacts with the underlying domain object, discussed <a href="#synccontrol">below</a>..</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>overload that instantiates and wraps a mixin with a wrapper that will validate all business rules and then execute the action if they pass.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The service works by returning a "wrapper" around a supplied domain object (using <a href="https://bytebuddy.net/">byte buddy</a>), and it is this wrapper that ensures that the hide/disable/validate rules implies by the Apache Isis programming model are enforced.</p>
</div>
<div class="sect3">
<h4 id="domain-objects"><a class="anchor" href="#domain-objects"></a>Domain Objects</h4>
<div class="paragraph">
<p>For domain objects (not mixins), the wrapper can be interacted with as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>a <code>get&#8230;&#8203;()</code> method for properties or collections</p>
</li>
<li>
<p>a <code>set&#8230;&#8203;()</code> method for properties</p>
</li>
<li>
<p>an <code>addTo&#8230;&#8203;()</code> or <code>removeFrom&#8230;&#8203;()</code> method for collections</p>
</li>
<li>
<p>any action</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Calling any of the above methods may result in a (subclass of) <code>InteractionException</code> if the object disallows it.
For example, if a property is annotated with <a href="../applib-ant/ActionLayout.html#hidden" class="page"><code>@ActionLayout#hidden</code></a> then a <code>HiddenException</code> will be thrown.
Similarly if an action has a <a href="../applib-methods/prefixes.html#validate" class="page"><code>validateXxx()</code></a> method and the supplied arguments are invalid then an <code>InvalidException</code> will be thrown.</p>
</div>
<div class="paragraph">
<p>In addition, the following methods may also be called:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the <a href="../applib-methods/reserved.html#title" class="page"><code>title()</code></a> and <code>toString()</code> methods</p>
</li>
<li>
<p>any <a href="../applib-methods/prefixes.html#default" class="page"><code>default&#8230;&#8203;()</code></a>, <a href="../applib-methods/prefixes.html#choices" class="page"><code>choices&#8230;&#8203;()</code></a> or <a href="../applib-methods/prefixes.html#autoComplete" class="page"><code>autoComplete&#8230;&#8203;()</code></a> methods</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>An exception will be thrown if any other methods are thrown.</p>
</div>
<div class="paragraph">
<p>If the interface is performed (action invoked or property set), then - irrespective of whether the business rules were checked or skipped - a <a href="../applib-ant/Action.html#command" class="page">command</a> will be created and pre- and post-execute <a href="../applib-ant/Action.html#domainEvent" class="page">domain event</a>s) will be fired.</p>
</div>
</div>
<div class="sect3">
<h4 id="mixins"><a class="anchor" href="#mixins"></a>Mixins</h4>
<div class="paragraph">
<p>For mixins, the behaviour of the wrapper is similar but simpler.
Mixin wrappers only apply to actions, and so the wrapper will enforce the hidden/disable/validate rules before executing.
In addition, any <a href="../applib-methods/prefixes.html#default" class="page"><code>default&#8230;&#8203;()</code></a>, <a href="../applib-methods/prefixes.html#choices" class="page"><code>choices&#8230;&#8203;()</code></a> or <a href="../applib-methods/prefixes.html#autoComplete" class="page"><code>autoComplete&#8230;&#8203;()</code></a> methods can be called.</p>
</div>
</div>
<div class="sect3">
<h4 id="synccontrol"><a class="anchor" href="#synccontrol"></a><code>SyncControl</code></h4>
<div class="paragraph">
<p>The <code>SyncControl</code> class controls the way that a (synchronous) wrapper works.
Its superclass <code>ControlAbstract</code> is:</p>
</div>
<div class="listingblock">
<div class="title">ControlAbstract.java</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class ControlAbstract&lt;T extends ControlAbstract&lt;T&gt;&gt; {
private boolean checkRules = true; <i class="conum" data-value="1"></i><b>(1)</b>
public T withCheckRules() {
// ...
}
public T withSkipRules() {
// ...
}
@Getter @NonNull
private ExceptionHandler exceptionHandler; <i class="conum" data-value="2"></i><b>(2)</b>
public T with(ExceptionHandler exceptionHandler) {
// ...
}
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>whether to check business rules (hide/disable/validate) before executing the underlying property or action</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>how to handle exceptions if they occur, using <code>ExceptionHandler</code>:
<div class="listingblock">
<div class="title">SyncControl.java</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@FunctionalInterface
public interface ExceptionHandler {
Object handle(Exception ex) throws Exception;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Exceptions can be rethrown or ignored.
If ignored, the handler can instead return a value; this must be compatible with the expected return value of the underlying action.</p>
</div></td>
</tr>
</table>
</div>
<div class="paragraph">
<p>... and the <code>SyncControl</code> class itself is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class SyncControl extends ControlAbstract&lt;SyncControl&gt; {
public static SyncControl control() {
return new SyncControl();
}
private SyncControl() {
with(exception -&gt; { <i class="conum" data-value="1"></i><b>(1)</b>
throw exception;
});
}
private boolean execute = true; <i class="conum" data-value="2"></i><b>(2)</b>
public SyncControl withExecute() {
// ...
}
public SyncControl withNoExecute() {
// ...
}
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Default exception handler is to rethrow the exception.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Don&#8217;t actually execute the action (for example, just check the rules as in a "dry-run").</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="asynchronous-api"><a class="anchor" href="#asynchronous-api"></a>Asynchronous API</h3>
<div class="paragraph">
<p>The <code>WrapperFactory</code> also allows domain objects to be interacted with in an asynchronous fashion, in other words executed in a separate thread:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface WrapperFactory {
&lt;T,R&gt; T asyncWrap(T domainObject, <i class="conum" data-value="1"></i><b>(1)</b>
AsyncControl&lt;R&gt; asyncControl);
&lt;T,R&gt; T asyncWrapMixin( <i class="conum" data-value="2"></i><b>(2)</b>
Class&lt;T&gt; mixinClass, Object mixedIn,
AsyncControl&lt;R&gt; asyncControl);
// ...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Wraps the underlying domain object so it can be invoked (through its wrapper) asynchronously in a separate thread.
The <code>AsyncControl</code> modifies the way in which the wrapper interacts with the underlying domain object, discussed <a href="#asynccontrol">below</a>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>instantiates and wraps a mixin so that it can be invoked (through its wrapper) asynchronously in a separate thread.
Again <code>AsyncControl</code> modifies the way this is done.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Executing in a separate thread means that the target and arguments are used in a new session.
If any of these are entities, they are retrieved from the database afresh; it isn&#8217;t possible to pass domain entity references from the foreground calling thread to the background threads.</p>
</div>
<div class="sect3">
<h4 id="asynccontrol"><a class="anchor" href="#asynccontrol"></a><code>AsyncControl</code></h4>
<div class="paragraph">
<p>The <code>AsyncControl</code> class controls the way that an asynchronous wrapper&#8201;&#8212;&#8201;as obtained by <code>asyncWrapXxx(&#8230;&#8203;)</code>&#8201;&#8212;&#8201;works.
The class inherits from <code>ControlAbstract</code> (see above), to allow the rules checking to be skipped and to configure the <code>ExceptionHandler</code>.
It extends with the following behaviour:</p>
</div>
<div class="listingblock">
<div class="title">AsyncControl.java</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Log4j2
public class AsyncControl&lt;R&gt; extends ControlAbstract&lt;AsyncControl&lt;R&gt;&gt; {
public static AsyncControl&lt;Void&gt; control() { <i class="conum" data-value="1"></i><b>(1)</b>
return new AsyncControl&lt;&gt;();
}
public static &lt;X&gt; AsyncControl&lt;X&gt; control(final Class&lt;X&gt; clazz) { <i class="conum" data-value="2"></i><b>(2)</b>
return new AsyncControl&lt;&gt;();
}
private AsyncControl() {
with(exception -&gt; { <i class="conum" data-value="3"></i><b>(3)</b>
log.error(logMessage(), exception);
return null;
});
}
@Getter @NonNull
private ExecutorService executorService = <i class="conum" data-value="4"></i><b>(4)</b>
ForkJoinPool.commonPool();
public AsyncControl&lt;R&gt; with(ExecutorService executorService) {
// ...
}
@Getter
private String user; <i class="conum" data-value="5"></i><b>(5)</b>
public AsyncControl&lt;R&gt; withUser(final String user) {
// ...
}
@Getter
private List&lt;String&gt; roles; <i class="conum" data-value="6"></i><b>(6)</b>
public AsyncControl&lt;R&gt; withRoles(final List&lt;String&gt; roles) {
// ...
}
public AsyncControl&lt;R&gt; withRoles(String... roles) {
// ...
}
@Getter
private Future&lt;R&gt; future; <i class="conum" data-value="7"></i><b>(7)</b>
// ...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>instantiate for a void action or property edit (where there is no need or intention to provide a return value through the <code>Future</code>, discussed below).</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>instantiate for an action returning a value of <code>&lt;R&gt;</code> (where this value will be returned through the <code>Future</code>, discussed below).</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Default exception handler is just to log the exception, though this can be overridden.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>Default executor service is the common pool.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b>5</b></td>
<td>Specify the user for the session used to execute the command asynchronously, in the background.
If not specified, then the user of the current foreground session is used.</td>
</tr>
<tr>
<td><i class="conum" data-value="6"></i><b>6</b></td>
<td>Specify the roles of the user for the session used to execute the command asynchronously, in the background.
If not specified, then the roles of the current user foreground user are used.</td>
</tr>
<tr>
<td><i class="conum" data-value="7"></i><b>7</b></td>
<td>Provides access to a <code>Future</code> representing the result of the background command.
This may or may not hold a value.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The <code>AsyncControl</code> can therefore be used to check business rules or to skip them.
If business rules are checked, note that they are performed in the context of the <em>foreground</em> session.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="unwrap-api"><a class="anchor" href="#unwrap-api"></a>Unwrap API</h3>
<div class="paragraph">
<p>The unwrap API provided by the service is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface WrapperFactory {
&lt;T&gt; T unwrap(T possibleWrappedDomainObject); <i class="conum" data-value="1"></i><b>(1)</b>
&lt;T&gt; boolean isWrapper(T possibleWrappedDomainObject); <i class="conum" data-value="2"></i><b>(2)</b>
// ...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Obtains the underlying domain object or mixin, if wrapped.
<div class="paragraph">
<p>If the object is not wrapped, returns back unchanged.</p>
</div></td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>whether the supplied object is a wrapper around a domain object or mixin.</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="listener-api"><a class="anchor" href="#listener-api"></a>Listener API</h3>
<div class="paragraph">
<p>The listener API allows the interactions between the wrapper and the underlying domain object to be observed:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface WrapperFactory {
// ...
List&lt;InteractionListener&gt; getListeners(); <i class="conum" data-value="1"></i><b>(1)</b>
boolean addInteractionListener(InteractionListener listener); <i class="conum" data-value="2"></i><b>(2)</b>
boolean removeInteractionListener( <i class="conum" data-value="3"></i><b>(3)</b>
InteractionListener listener);
void notifyListeners(InteractionEvent ev); <i class="conum" data-value="4"></i><b>(4)</b>
// ...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>all <code>InteractionListener</code>s that have been registered.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>registers an <code>InteractionListener</code>, to be notified of interactions on all wrappers.
The listener will be notified of interactions even on wrappers created before the listener was installed.
(From an implementation perspective this is because the wrappers delegate back to the container to fire the events).</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>remove an <code>InteractionListener</code>, to no longer be notified of interactions on wrappers.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>used by the framework itself</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>This API isn&#8217;t (currently) used by the framework itself.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>One possible use case would be to autogenerate documentation, for example a sequence diagram from tests.
Such a feature would probably also use <a href="InteractionContext.html" class="page"><code>InteractionContext</code></a>, which builds up an execution call graph of interactions between (wrapped) objects.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="typical-usage"><a class="anchor" href="#typical-usage"></a>Typical Usage</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The caller will typically obtain the target object (eg from some repository) and then use the injected <code>WrapperFactory</code> to wrap it before interacting with it.</p>
</div>
<div class="paragraph">
<p>For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class CustomerAgent {
@Action
public void refundOrder(final Order order) {
final Order wrappedOrder = wrapperFactory.wrap(order);
try {
wrappedOrder.refund();
} catch(InteractionException ex) { <i class="conum" data-value="1"></i><b>(1)</b>
messageService.raiseError(ex.getMessage()); <i class="conum" data-value="2"></i><b>(2)</b>
return;
}
}
...
@Inject
WrapperFactory wrapperFactory;
@Inject
MessageService messageService;
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>if any constraints on the <code>Order&#8217;s `refund()</code> action would be violated, then &#8230;&#8203;</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>&#8230;&#8203; these will be trapped and raised to the user as a warning.</td>
</tr>
</table>
</div>
</div>
</div>
</article>
<aside class="article-aside toc" role="navigation">
<p class="toc-title">On this page</p>
<div id="article-toc"></div>
</aside>
</main>
</div>
<footer class="footer">
<div class="content">
<div class="copyright">
<p>
Copyright © 2010~2020 The Apache Software Foundation, licensed under the Apache License, v2.0.
<br/>
Apache, the Apache feather logo, Apache Isis, and the Apache Isis project logo are all trademarks of The Apache Software Foundation.
</p>
</div>
<div class="revision">
<p>Revision: SNAPSHOT</p>
</div>
</div>
</footer>
<script src="../../../_/js/site.js"></script>
<script async src="../../../_/js/vendor/highlight.js"></script>
<script src="../../../_/js/vendor/jquery-3.4.1.min.js"></script>
<script src="../../../_/js/vendor/jquery-ui-1.12.1.custom.widget-only.min.js"></script>
<script src="../../../_/js/vendor/jquery.tocify.min.js"></script>
<script>
$(function() {
$("#article-toc").tocify( {
showEffect: "slideDown",
hashGenerator: "pretty",
hideEffect: "slideUp",
selectors: "h2, h3",
scrollTo: 120,
smoothScroll: true,
theme: "jqueryui",
highlightOnScroll: true
} );
});
</script>
</body>
</html>