Hey all,
I created a simple bean data control that supports CRUD operations. I get a NPE when I attempt to change any of the values of the model, provided by the bean data control, on my JSF page. Below is the data control code and the stacktrace. Also, what are the expected return values of the methods that are automatically added when you chose to create a CRUD data control (setAttributeValue, registerDataProvider, etc)? I've looked at the Oracle documentation but couldn't find any mention on what should be returned.
Thanks in advance, I'm on Jdeveloper 12.2.1.4.
Here's my data control...
package my.model;
import java.util.ArrayList;
import java.util.List;
import oracle.binding.AttributeContext;
import oracle.binding.RowContext;
public class AsRunDataControl {
private AsRun asrun;
private List<Object> dirtyEntities = new ArrayList<>();
public void loadAsRun(Long asrunId) throws ModelException {
asrun = HttpUtils.get(AsRun.class, Resources.getAsRunUrl(asrunId));
}
public AsRun getAsRun() {
return asrun;
}
public boolean isTransactionDirty() {
return !dirtyEntities.isEmpty();
}
public void rollbackTransaction() {
// TODO
}
public void commitTransaction() throws ModelException {
// TODO
}
public boolean setAttributeValue(AttributeContext ctx, Object newValue) {
dirtyEntities.add(ctx.getRowDataContainer());
return true;
}
public Object createRowData(RowContext p0) {
throw new UnsupportedOperationException();
}
public Object registerDataProvider(RowContext p0) {
return this;
}
public boolean removeRowData(RowContext p0) {
throw new UnsupportedOperationException();
}
public void validate() {
}
}
Here is the stacktrace...
java.lang.NullPointerException
at oracle.jbo.common.JboBeanUtils.getPropertyDescriptor(JboBeanUtils.java:28)
at oracle.jbo.common.JboBeanUtils.getProperty(JboBeanUtils.java:85)
at oracle.jbo.common.JboBeanUtils.getPropertyInMapOrBean(JboBeanUtils.java:270)
at oracle.adf.model.bean.DCDataRow.getDataProviderProperty(DCDataRow.java:300)
at oracle.jbo.script.ExprDef$SourceHintProperty.evaluate(ExprDef.java:155)
at oracle.jbo.ExprEval.doEvaluate(ExprEval.java:835)
at oracle.jbo.ExprEval.evaluateForRow(ExprEval.java:725)
at oracle.jbo.ExprEval.evaluateForRow(ExprEval.java:712)
at oracle.jbo.server.AttributeDefImpl.evaluateTransientExpression(AttributeDefImpl.java:2920)
at oracle.jbo.server.ViewRowStorage.getAttributeInternal(ViewRowStorage.java:2134)
at oracle.jbo.server.ViewRowImpl.getAttributeValue(ViewRowImpl.java:2353)
at oracle.jbo.server.ViewRowImpl.getAttributeInternal(ViewRowImpl.java:1026)
at oracle.jbo.server.ProgrammaticViewRowImpl.getAttributeInternalDelegation(ProgrammaticViewRowImpl.java:435)
at oracle.adf.model.bean.DCDataRow.getAttributeInternal(DCDataRow.java:291)
at oracle.jbo.server.ViewRowImpl.getAttrInvokeAccessor(ViewRowImpl.java:1116)
at oracle.jbo.server.ViewRowImpl.getAttribute(ViewRowImpl.java:1064)
at oracle.jbo.uicli.binding.JUCtrlValueBinding.internalGetAttributeValueFromRow(JUCtrlValueBinding.java:1329)
at oracle.jbo.uicli.binding.JUCtrlValueBinding.getAttributeFromRow(JUCtrlValueBinding.java:815)
at oracle.jbo.uicli.binding.JUCtrlValueBinding.getInputValueInRow(JUCtrlValueBinding.java:3221)
at oracle.jbo.uicli.binding.JUCtrlValueBinding.getInputValue(JUCtrlValueBinding.java:3067)
at oracle.jbo.uicli.binding.JUCtrlValueBinding.getInputValue(JUCtrlValueBinding.java:3057)
at oracle.adfinternal.view.faces.model.binding.FacesCtrlAttrsBinding.getInputValue(FacesCtrlAttrsBinding.java:214)
at oracle.jbo.uicli.binding.JUCtrlValueBinding.put(JUCtrlValueBinding.java:2723)
at javax.el.MapELResolver.setValue(MapELResolver.java:226)
at com.sun.faces.el.DemuxCompositeELResolver._setValue(DemuxCompositeELResolver.java:255)
at com.sun.faces.el.DemuxCompositeELResolver.setValue(DemuxCompositeELResolver.java:281)
at com.sun.el.parser.AstValue.setValue(AstValue.java:254)
at com.sun.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:294)
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:131)
at org.apache.myfaces.trinidad.component.UIXEditableValue.updateModel(UIXEditableValue.java:395)
at org.apache.myfaces.trinidad.component.UIXEditableValue.processUpdates(UIXEditableValue.java:326)
at org.apache.myfaces.trinidad.component.UIXComponentBase.updateChildrenImpl(UIXComponentBase.java:1636)
at org.apache.myfaces.trinidad.component.UIXComponentBase.updateChildren(UIXComponentBase.java:1626)
at org.apache.myfaces.trinidad.component.UIXComponentBase.processUpdates(UIXComponentBase.java:1373)
at org.apache.myfaces.trinidad.component.UIXComponentBase.updateChildrenImpl(UIXComponentBase.java:1636)
at oracle.adf.view.rich.component.fragment.UIXRegion.updateChildrenImpl(UIXRegion.java:547)
at org.apache.myfaces.trinidad.component.UIXComponentBase.updateChildren(UIXComponentBase.java:1626)
at org.apache.myfaces.trinidad.component.UIXComponentBase.processUpdates(UIXComponentBase.java:1373)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl$UpdateModelValuesCallback.invokeContextCallback(LifecycleImpl.java:2146)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnNamingContainerComponent(UIXComponentBase.java:2155)
at oracle.adf.view.rich.component.fragment.UIXRegion.invokeOnComponent(UIXRegion.java:452)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:2110)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:2240)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:2110)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:2240)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:2110)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:2240)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:2110)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent.invokeOnComponent(ContextSwitchingComponent.java:263)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:2110)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:2240)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:2110)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:2240)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:2110)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:2240)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:2110)
at oracle.adf.view.rich.component.fragment.UIXInclude.invokeOnComponent(UIXInclude.java:166)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:2110)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:2240)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnChildrenComponents(UIXComponentBase.java:2110)
at org.apache.myfaces.trinidad.component.UIXComponentBase.invokeOnComponent(UIXComponentBase.java:2240)
at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1503)
at javax.faces.component.UIComponentBase.invokeOnComponent(UIComponentBase.java:714)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executeApplyValidateOrUpdate(LifecycleImpl.java:660)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl._executePhase(LifecycleImpl.java:386)
at oracle.adfinternal.view.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:237)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:650)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:295)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:353)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.adf.model.servlet.ADFBindingFilter.doFilter(ADFBindingFilter.java:207)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.adfinternal.view.faces.webapp.rich.RegistrationFilter.doFilter(RegistrationFilter.java:105)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain$1.call(TrinidadFilterImpl.java:591)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain$1.call(TrinidadFilterImpl.java:587)
at org.apache.myfaces.trinidad.context.ExternalContextPropagator.processInScope(ExternalContextPropagator.java:216)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:596)
at oracle.adfinternal.view.faces.activedata.AdsFilter.doFilter(AdsFilter.java:91)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain$1.call(TrinidadFilterImpl.java:591)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain$1.call(TrinidadFilterImpl.java:587)
at org.apache.myfaces.trinidad.context.ExternalContextPropagator.processInScope(ExternalContextPropagator.java:216)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$FilterListChain.doFilter(TrinidadFilterImpl.java:596)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$1.call(TrinidadFilterImpl.java:372)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl$1.call(TrinidadFilterImpl.java:368)
at org.apache.myfaces.trinidad.context.ExternalContextPropagator.processInScope(ExternalContextPropagator.java:216)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:383)
at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:241)
at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:101)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.adf.library.webapp.LibraryFilter.doFilter(LibraryFilter.java:169)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.security.jps.ee.http.JpsAbsFilter$3.run(JpsAbsFilter.java:175)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:315)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:650)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:112)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilterInternal(JpsAbsFilter.java:293)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:150)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:94)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:248)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.jrf.servlet.ExtensibleGlobalFilter.doFilter(ExtensibleGlobalFilter.java:92)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:32)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3797)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3763)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:344)
at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2451)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2299)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2277)
at weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1720)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1680)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:272)
at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:352)
at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:337)
at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:57)
at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)
at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:655)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:420)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:360)
Here is the code for the As Run model:
package my.model;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
public class AsRun {
private Long asRunId;
private Long procedureId;
private Integer runNumber;
private String title;
private String description;
private Integer projectId;
private Integer createdBy;
private Timestamp creationDate;
private Integer lastUpdatedBy;
private Timestamp lastUpdateDate;
private String self;
public void setAsRunId(Long asRunId) {
this.asRunId = asRunId;
}
public Long getAsRunId() {
return asRunId;
}
public void setProcedureId(Long procedureId) {
this.procedureId = procedureId;
}
public Long getProcedureId() {
return procedureId;
}
public void setRunNumber(Integer runNumber) {
this.runNumber = runNumber;
}
public Integer getRunNumber() {
return runNumber;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
public void setDescription(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setProjectId(Integer projectId) {
this.projectId = projectId;
}
public Integer getProjectId() {
return projectId;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreationDate(Timestamp creationDate) {
this.creationDate = creationDate;
}
public Timestamp getCreationDate() {
return creationDate;
}
public void setLastUpdatedBy(Integer lastUpdatedBy) {
this.lastUpdatedBy = lastUpdatedBy;
}
public Integer getLastUpdatedBy() {
return lastUpdatedBy;
}
public void setLastUpdateDate(Timestamp lastUpdateDate) {
this.lastUpdateDate = lastUpdateDate;
}
public Timestamp getLastUpdateDate() {
return lastUpdateDate;
}
public void setSelf(String self) {
this.self = self;
}
public String getSelf() {
return self;
}
}
Here's the code for the HttpUtils:
package my.model;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.Closeable;
import java.io.IOException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class HttpUtils {
private HttpUtils() {
throw new AssertionError("Cannot instaniate a utility class.");
}
public static <T> T get(Class<T> clazz, String url) throws ModelException {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.createDefault();
HttpGet request = new HttpGet(url);
response = httpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode == 400) {
Gson gson = new GsonBuilder().create();
ErrorResponse errorResponse = gson.fromJson(EntityUtils.toString(response.getEntity()), ErrorResponse.class);
throw new ModelException(errorResponse.getReason());
} else if(statusCode != 200) {
throw new ModelException("An unexpected exception has occurred.");
}
Gson gson = new GsonBuilder().create();
return gson.fromJson(EntityUtils.toString(response.getEntity()), clazz);
} catch (IOException ex) {
throw new RuntimeException(ex);
} finally {
close(response);
close(httpClient);
}
}
public static <T> String post(T entity, String url) throws ModelException {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
Gson gson = new GsonBuilder().create();
String entityString = (entity instanceof String ? (String) entity : gson.toJson(entity));
httpClient = HttpClients.createDefault();
HttpPost request = new HttpPost(url);
request.setEntity(new StringEntity(entityString));
response = httpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode == 400) {
ErrorResponse errorResponse = gson.fromJson(EntityUtils.toString(response.getEntity()), ErrorResponse.class);
throw new ModelException(errorResponse.getReason());
} else if(statusCode != 201) {
throw new ModelException("An unexpected exception has occurred.");
}
CreatedResponse createdResponse = gson.fromJson(EntityUtils.toString(response.getEntity()), CreatedResponse.class);
return createdResponse.getLocation();
} catch (IOException ex) {
throw new RuntimeException(ex);
} finally {
close(response);
close(httpClient);
}
}
public static <T> void put(T entity, String url) throws ModelException {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
try {
Gson gson = new GsonBuilder().create();
httpClient = HttpClients.createDefault();
HttpPut request = new HttpPut(url);
request.setEntity(new StringEntity(gson.toJson(entity)));
response = httpClient.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode == 400) {
ErrorResponse errorResponse = gson.fromJson(EntityUtils.toString(response.getEntity()), ErrorResponse.class);
throw new ModelException(errorResponse.getReason());
} else if (statusCode != 200 && statusCode != 201) {
throw new ModelException("An unexpected exception has occurred.");
}
} catch (IOException ex) {
throw new RuntimeException(ex);
} finally {
close(response);
close(httpClient);
}
}
private static void close(Closeable closeable) {
if(closeable != null) {
try {
closeable.close();
} catch (IOException e) {
;
}
}
}
}
Here is my JSFF:
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
xmlns:f="http://java.sun.com/jsf/core" xmlns:c="http://java.sun.com/jsp/jstl/core">
<af:panelGroupLayout id="pgl12" layout="vertical">
<af:button actionListener="#{bindings.loadAsRun.execute}" text="loadAsRun" disabled="#{!bindings.loadAsRun.enabled}"
id="b1" />
<af:button actionListener="#{bindings.Commit.execute}" text="Commit"
id="b2"/>
<af:inputText value="#{bindings.runNumber.inputValue}"
id="it2" autoSubmit="true" partialTriggers="b1">
<!--<f:validator binding="#{bindings.runNumber.validator}"/>-->
<!--<af:convertNumber groupingUsed="false" pattern="#{bindings.runNumber.format}"/>-->
</af:inputText>
<af:inputText value="#{bindings.title.inputValue}"
id="it3" autoSubmit="true" partialTriggers="b1">
<!--<f:validator binding="#{bindings.title.validator}"/>-->
</af:inputText>
<af:inputText value="#{bindings.description.inputValue}" partialTriggers="b1" id="it4" autoSubmit="true">
<!--<f:validator binding="#{bindings.description.validator}"/>-->
</af:inputText>
</af:panelGroupLayout>
</ui:composition>
Here's the page def:
<?xml version="1.0" encoding="UTF-8" ?>
<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel" version="12.2.1.22.48" id="stepsPageDef"
Package="fragments" SkipValidation="true">
<parameters/>
<executables>
<variableIterator id="variables"/>
<iterator Binds="root" RangeSize="25" DataControl="AsRunDataControl" id="AsRunDataControlIterator"
Refresh="always"/>
<accessorIterator MasterBinding="AsRunDataControlIterator" Binds="asRun" RangeSize="25"
DataControl="AsRunDataControl" BeanClass="my.model.AsRun"
id="asRunIterator" Refresh="always"/>
</executables>
<bindings>
<methodAction id="loadAsRun" RequiresUpdateModel="true" Action="invokeMethod" MethodName="loadAsRun"
IsViewObjectMethod="false" DataControl="AsRunDataControl"
InstanceName="bindings.loadAsRun.dataControl.dataProvider">
<NamedData NDName="asrunId" NDValue="5" NDType="java.lang.Long"/>
</methodAction>
<attributeValues IterBinding="asRunIterator" id="runNumber">
<AttrNames>
<Item Value="runNumber"/>
</AttrNames>
</attributeValues>
<attributeValues IterBinding="asRunIterator" id="title">
<AttrNames>
<Item Value="title"/>
</AttrNames>
</attributeValues>
<attributeValues IterBinding="asRunIterator" id="description">
<AttrNames>
<Item Value="description"/>
</AttrNames>
</attributeValues>
<action id="Commit" RequiresUpdateModel="true" Action="commitTransaction" DataControl="AsRunDataControl"/>
</bindings>
</pageDefinition>