User: fleury
Date: 00/06/01 14:02:13
Modified: src/main/org/jboss/ejb ContainerFactory.java
Log:
Building the right container for Stateless and Stateful. Also got tired of the
indentation so "beautified" it with anyJ default settings... he
Revision Changes Path
1.14 +358 -354 jboss/src/main/org/jboss/ejb/ContainerFactory.java
Index: ContainerFactory.java
===================================================================
RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/ContainerFactory.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- ContainerFactory.java 2000/05/31 21:43:07 1.13
+++ ContainerFactory.java 2000/06/01 21:02:12 1.14
@@ -1,9 +1,9 @@
- /*
- * jBoss, the OpenSource EJB server
- *
- * Distributable under GPL license.
- * See terms of license at gnu.org.
- */
+/*
+* jBoss, the OpenSource EJB server
+*
+* Distributable under GPL license.
+* See terms of license at gnu.org.
+*/
package org.jboss.ejb;
import java.beans.Beans;
@@ -52,105 +52,105 @@
import org.jboss.ejb.plugins.*;
/**
- * A ContainerFactory is used to deploy EJB applications. It can be given a URL
to
- * an EJB-jar or EJB-JAR XML file, which will be used to instantiate containers
and make
- * them available for invocation.
- *
- * @see Container
- * @author Rickard �berg ([EMAIL PROTECTED])
- * @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
- * @version $Revision: 1.13 $
- */
+* A ContainerFactory is used to deploy EJB applications. It can be given a URL to
+* an EJB-jar or EJB-JAR XML file, which will be used to instantiate containers
and make
+* them available for invocation.
+*
+* @see Container
+* @author Rickard �berg ([EMAIL PROTECTED])
+* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
+* @version $Revision: 1.14 $
+*/
public class ContainerFactory
- implements ContainerFactoryMBean, MBeanRegistration
+implements ContainerFactoryMBean, MBeanRegistration
{
- // Constants -----------------------------------------------------
+ // Constants -----------------------------------------------------
public static String DEFAULT_STATELESS_CONFIGURATION = "Default Stateless
SessionBean";
public static String DEFAULT_STATEFUL_CONFIGURATION = "Default Stateful
SessionBean";
public static String DEFAULT_ENTITY_BMP_CONFIGURATION = "Default BMP
EntityBean";
public static String DEFAULT_ENTITY_CMP_CONFIGURATION = "Default CMP
EntityBean";
- // Attributes ----------------------------------------------------
+ // Attributes ----------------------------------------------------
// The logger of this service
- Log log = new Log("Container factory");
-
+ Log log = new Log("Container factory");
+
// The JMX agent
- MBeanServer server;
-
+ MBeanServer server;
+
// A map of current deployments. If a deployment is made and it is already in
this map,
// then undeploy it first (i.e. make it a re-deploy).
- HashMap deployments = new HashMap();
-
- // Public --------------------------------------------------------
-
+ HashMap deployments = new HashMap();
+
+ // Public --------------------------------------------------------
+
/**
- * Deploy the file at this URL. This method is typically called from
remote administration
- * tools that cannot handle java.net.URL's as parameters to methods
- *
- * @param url
- * @exception MalformedURLException
- * @exception DeploymentException
- */
- public void deploy(String url)
- throws MalformedURLException, DeploymentException
- {
+ * Deploy the file at this URL. This method is typically called from
remote administration
+ * tools that cannot handle java.net.URL's as parameters to methods
+ *
+ * @param url
+ * @exception MalformedURLException
+ * @exception DeploymentException
+ */
+ public void deploy(String url)
+ throws MalformedURLException, DeploymentException
+ {
// Delegate to "real" deployment
- deploy(new URL(url));
- }
-
-
+ deploy(new URL(url));
+ }
+
+
+ /**
+ * Undeploy the file at this URL. This method is typically called from
remote administration
+ * tools that cannot handle java.net.URL's as parameters to methods
+ *
+ * @param url
+ * @exception MalformedURLException
+ * @exception DeploymentException
+ */
+ public void undeploy(String url)
+ throws MalformedURLException, DeploymentException
+ {
+ // Delegate to "real" undeployment
+ undeploy(new URL(url));
+ }
+
/**
- * Undeploy the file at this URL. This method is typically called from
remote administration
- * tools that cannot handle java.net.URL's as parameters to methods
- *
- * @param url
- * @exception MalformedURLException
- * @exception DeploymentException
- */
- public void undeploy(String url)
- throws MalformedURLException, DeploymentException
- {
- // Delegate to "real" undeployment
- undeploy(new URL(url));
- }
-
- /**
- * Deploy EJBs pointed to by an URL.
- * The URL may point to an EJB-JAR, an EAR-JAR, or an codebase
- * whose structure resembles that of an EJB-JAR.
- *
- * The latter is useful for development since no packaging is required
- *
- * @param url URL where EJB deployment information is contained
- * @return The created containers
- * @exception DeploymentException
- */
- public synchronized void deploy(URL url)
- throws DeploymentException
- {
- try
- {
- // Check if already deployed -> undeploy first, this is re-deploy
- if (deployments.containsKey(url))
- undeploy(url);
-
- // Create application
- Application app = new Application();
- app.setURL(url);
-
- Log.setLog(log);
- log.log("Deploying:"+url);
-
+ * Deploy EJBs pointed to by an URL.
+ * The URL may point to an EJB-JAR, an EAR-JAR, or an codebase
+ * whose structure resembles that of an EJB-JAR.
+ *
+ * The latter is useful for development since no packaging is required
+ *
+ * @param url URL where EJB deployment information is contained
+ * @return The created containers
+ * @exception DeploymentException
+ */
+ public synchronized void deploy(URL url)
+ throws DeploymentException
+ {
+ try
+ {
+ // Check if already deployed -> undeploy first, this is
re-deploy
+ if (deployments.containsKey(url))
+ undeploy(url);
+
+ // Create application
+ Application app = new Application();
+ app.setURL(url);
+
+ Log.setLog(log);
+ log.log("Deploying:"+url);
+
// Create a file manager with which to load the files
- jBossFileManagerFactory fact = new jBossFileManagerFactory();
- jBossFileManager efm = (jBossFileManager)fact.createFileManager();
-
- // Setup beancontext
- BeanContextServicesSupport beanCtx = new BeanContextServicesSupport();
- beanCtx.add(Beans.instantiate(getClass().getClassLoader(),
"com.dreambean.ejx.xml.ProjectX"));
- beanCtx.add(efm);
-
- // Load XML
+ jBossFileManagerFactory fact = new jBossFileManagerFactory();
+ jBossFileManager efm =
(jBossFileManager)fact.createFileManager();
+
+ // Setup beancontext
+ BeanContextServicesSupport beanCtx = new
BeanContextServicesSupport();
+ beanCtx.add(Beans.instantiate(getClass().getClassLoader(),
"com.dreambean.ejx.xml.ProjectX"));
+ beanCtx.add(efm);
+
+ // Load XML
jBossEjbJar jar;
if (url.getProtocol().startsWith("file"))
{
@@ -164,151 +164,155 @@
}
// Create classloader for this application
-// ClassLoader cl = new EJBClassLoader(new URL[] {url},
getClass().getClassLoader(), jar.isSecure());
- ClassLoader cl = efm.getClassLoader();
-
+ // ClassLoader cl = new EJBClassLoader(new URL[]
{url}, getClass().getClassLoader(), jar.isSecure());
+ ClassLoader cl = efm.getClassLoader();
+
// Get list of beans for which we will create containers
- Iterator beans = jar.getEnterpriseBeans().iterator();
-
+ Iterator beans = jar.getEnterpriseBeans().iterator();
+
// Create list of containers
- ArrayList containers = new ArrayList();
-
- // Deploy beans
- Context ctx = new InitialContext();
- while(beans.hasNext())
- {
- Container con = null;
- jBossEnterpriseBean bean = (jBossEnterpriseBean)beans.next();
+ ArrayList containers = new ArrayList();
+
+ // Deploy beans
+ Context ctx = new InitialContext();
+ while(beans.hasNext())
+ {
+ Container con = null;
+ jBossEnterpriseBean bean =
(jBossEnterpriseBean)beans.next();
- log.log("Deploying "+bean.getEjbName());
+ log.log("Deploying "+bean.getEjbName());
- if (bean instanceof jBossSession) // Is session?
- {
- if (((jBossSession)bean).getSessionType().equals("Stateless")) // Is
stateless?
- {
+ if (bean instanceof jBossSession) // Is session?
+ {
+ if
(((jBossSession)bean).getSessionType().equals("Stateless")) // Is stateless?
+ {
// Create container
- con = new StatelessSessionContainer();
-
+ con = new StatelessSessionContainer();
+
// Create classloader for this
container
- con.setClassLoader(new BeanClassLoader(cl));
+ con.setClassLoader(new
BeanClassLoader(cl));
// Set metadata
- con.setMetaData(bean);
-
+ con.setMetaData(bean);
+
// Get container configuration
- ContainerConfiguration conf =
jar.getContainerConfigurations().getContainerConfiguration(bean.getConfigurationName());
-
+ ContainerConfiguration conf =
jar.getContainerConfigurations().getContainerConfiguration(bean.getConfigurationName());
+
// Make sure we have a default
configuration
- if (conf == null)
- {
+ if (conf == null)
+ {
log.warning("No configuration
chosen. Using default configuration");
-
+
// Get the container default
configuration
conf =
jar.getContainerConfigurations().getContainerConfiguration(DEFAULT_STATELESS_CONFIGURATION);
-
+
// Make sure this bean knows
the configuration he is using
bean.setConfigurationName(DEFAULT_STATELESS_CONFIGURATION);
}
// Set container invoker
-
((StatelessSessionContainer)con).setContainerInvoker((ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance());
+
((StatelessSessionContainer)con).setContainerInvoker((ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance());
- // Set instance pool
-
con.setInstancePool((InstancePool)cl.loadClass(conf.getInstancePool()).newInstance());
-
- // Create interceptors
-// con.addInterceptor(new LogInterceptor());
-// con.addInterceptor(new SecurityInterceptor());
-// con.addInterceptor(new TxInterceptor());
- con.addInterceptor(new StatelessSessionInstanceInterceptor());
-
- con.addInterceptor(con.createContainerInterceptor());
+ // Set instance pool
+
con.setInstancePool((InstancePool)cl.loadClass(conf.getInstancePool()).newInstance());
- // Add container to application
- containers.add(con);
- } else // Stateful
- {
- boolean implemented = false;
-
- if (!implemented) throw new Error("Stateful
Container not implemented yet");
+ // Create interceptors
- // Create container
- con = new StatefulSessionContainer();
-
- // Create classloader for this container
- con.setClassLoader(new BeanClassLoader(cl));
-
- // Set metadata
- con.setMetaData(bean);
+ //
con.addInterceptor(new LogInterceptor());
+ //
con.addInterceptor(new SecurityInterceptor());
+ //
con.addInterceptor(new TxInterceptor());
+
+ con.addInterceptor(new
StatelessSessionInstanceInterceptor());
+
+ // Finally we add the last interceptor
from the container
+
con.addInterceptor(con.createContainerInterceptor());
+
+ // Add container to application
+ containers.add(con);
- // Get container configuration
- ContainerConfiguration conf =
jar.getContainerConfigurations().getContainerConfiguration(bean.getConfigurationName());
-
- // Make sure we have a default configuration
- if (conf == null)
+ } else // Stateful
{
- log.warning("No configuration chosen.
Using default configuration");
+ boolean implemented = false;
- conf =
jar.getContainerConfigurations().getContainerConfiguration(DEFAULT_STATEFUL_CONFIGURATION);
-
- // Make sure this bean knows the
configuration he is using
-
bean.setConfigurationName(DEFAULT_STATEFUL_CONFIGURATION);
- }
-
- // Set container invoker
-
((StatefulSessionContainer)con).setContainerInvoker((ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance());
-
- // Set instance cache
-
((StatefulSessionContainer)con).setInstanceCache((InstanceCache)cl.loadClass(conf.getInstanceCache()).newInstance());
-
- // Set persistence manager
-
((StatefulSessionContainer)con).setPersistenceManager((StatefulSessionPersistenceManager)cl.loadClass(conf.getPersistenceManager()).newInstance());
-
-
- // Create interceptors
- con.addInterceptor(new LogInterceptor());
- con.addInterceptor(new TxInterceptor());
- //con.addInterceptor(new
EntityInstanceInterceptor());
- con.addInterceptor(new SecurityInterceptor());
- //con.addInterceptor(new
EntitySynchronizationInterceptor());
-
-
con.addInterceptor(con.createContainerInterceptor());
-
- // Add container to application
- containers.add(con);
+ if (!implemented) throw new
Error("Stateful Container not implemented yet");
+
+ // Create container
+ con = new StatefulSessionContainer();
+
+ // Create classloader for this
container
+ con.setClassLoader(new
BeanClassLoader(cl));
+
+ // Set metadata
+ con.setMetaData(bean);
+
+ // Get container configuration
+ ContainerConfiguration conf =
jar.getContainerConfigurations().getContainerConfiguration(bean.getConfigurationName());
+
+ // Make sure we have a default
configuration
+ if (conf == null)
+ {
+ log.warning("No configuration
chosen. Using default configuration");
+
+ conf =
jar.getContainerConfigurations().getContainerConfiguration(DEFAULT_STATEFUL_CONFIGURATION);
+
+ // Make sure this bean knows
the configuration he is using
+
bean.setConfigurationName(DEFAULT_STATEFUL_CONFIGURATION);
+ }
+
+ // Set container invoker
+
((StatefulSessionContainer)con).setContainerInvoker((ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance());
+
+ // Set instance cache
+
((StatefulSessionContainer)con).setInstanceCache((InstanceCache)cl.loadClass(conf.getInstanceCache()).newInstance());
+
+ // Set persistence manager
+
((StatefulSessionContainer)con).setPersistenceManager((StatefulSessionPersistenceManager)cl.loadClass(conf.getPersistenceManager()).newInstance());
+
+
+ // Create interceptors
+ con.addInterceptor(new
LogInterceptor());
+ con.addInterceptor(new
TxInterceptor());
+ //con.addInterceptor(new
EntityInstanceInterceptor());
+ con.addInterceptor(new
SecurityInterceptor());
+ //con.addInterceptor(new
EntitySynchronizationInterceptor());
+
+
con.addInterceptor(con.createContainerInterceptor());
+
+ // Add container to application
+ containers.add(con);
- }
- } else // Entity
- {
+ }
+ } else // Entity
+ {
// Create container
con = new EntityContainer();
-
+
// Create classloader for this container
con.setClassLoader(new BeanClassLoader(cl));
// Set metadata
con.setMetaData(bean);
-
+
// Get container configuration
ContainerConfiguration conf =
jar.getContainerConfigurations().getContainerConfiguration(bean.getConfigurationName());
-
+
// Make sure we have a default configuration
if (conf == null)
{
log.warning("No configuration chosen.
Using default configuration");
if (((jBossEntity)
bean).getPersistenceType().equals("Bean"))
{
- // BMP case
- conf =
jar.getContainerConfigurations().getContainerConfiguration(DEFAULT_ENTITY_BMP_CONFIGURATION);
-
- // Make sure this bean knows
the configuration he is using
-
bean.setConfigurationName(DEFAULT_ENTITY_BMP_CONFIGURATION);
+ // BMP case
+ conf =
jar.getContainerConfigurations().getContainerConfiguration(DEFAULT_ENTITY_BMP_CONFIGURATION);
+
+ // Make sure this bean knows
the configuration he is using
+
bean.setConfigurationName(DEFAULT_ENTITY_BMP_CONFIGURATION);
}
else
{
// CMP case
conf =
jar.getContainerConfigurations().getContainerConfiguration(DEFAULT_ENTITY_CMP_CONFIGURATION);
-
+
// Make sure this bean knows
the configuration he is using
bean.setConfigurationName(DEFAULT_ENTITY_CMP_CONFIGURATION);
}
@@ -325,43 +329,43 @@
// Set persistence manager
((EntityContainer)con).setPersistenceManager((EntityPersistenceManager)cl.loadClass(conf.getPersistenceManager()).newInstance());
-
-
+
+
// Create interceptors
-// con.addInterceptor(new LogInterceptor());
-// con.addInterceptor(new SecurityInterceptor());
-// con.addInterceptor(new TxInterceptor());
+ //
con.addInterceptor(new LogInterceptor());
+ //
con.addInterceptor(new SecurityInterceptor());
+ //
con.addInterceptor(new TxInterceptor());
con.addInterceptor(new
EntityInstanceInterceptor());
con.addInterceptor(new
EntitySynchronizationInterceptor());
-
+
con.addInterceptor(con.createContainerInterceptor());
-
+
// Add container to application
containers.add(con);
- }
-
+ }
+
// Set callback to application
- if (con != null)
- con.setApplication(app);
- }
-
- // Init/Start container
- for (int i = 0; i < containers.size(); i++)
- {
- Container con = (Container)containers.get(i);
-
- // Init container
- con.init();
-
- // Start
- con.start();
- log.log("Started: "+con.getMetaData().getEjbName());
- }
-
- // Bind container in global JNDI namespace
- for (int i = 0; i < containers.size(); i++)
- {
- Container con = (Container)containers.get(i);
+ if (con != null)
+ con.setApplication(app);
+ }
+
+ // Init/Start container
+ for (int i = 0; i < containers.size(); i++)
+ {
+ Container con = (Container)containers.get(i);
+
+ // Init container
+ con.init();
+
+ // Start
+ con.start();
+ log.log("Started: "+con.getMetaData().getEjbName());
+ }
+
+ // Bind container in global JNDI namespace
+ for (int i = 0; i < containers.size(); i++)
+ {
+ Container con = (Container)containers.get(i);
if (con instanceof EntityContainer)
{
rebind(ctx, con.getMetaData().getJndiName(),
((EntityContainer)con).getContainerInvoker().getEJBHome());
@@ -375,139 +379,139 @@
// Done
log.log("Bound
"+con.getMetaData().getEjbName() + " to " + con.getMetaData().getJndiName());
}
- }
-
- // Add to webserver so client can access classes through dynamic class
downloading
- WebProviderMBean webServer =
(WebProviderMBean)MBeanProxy.create(WebProviderMBean.class,
WebProviderMBean.OBJECT_NAME);
- webServer.addClassLoader(cl);
-
- // Done
- log.log("Deployed application: "+app.getName());
-
- // Register deployment
- deployments.put(url, app);
- } catch (Exception e)
- {
- e.printStackTrace();
- throw new DeploymentException("Could not deploy "+url.toString(),e);
- } finally
- {
- Log.unsetLog();
- }
- }
-
-
- /**
- * Remove previously deployed EJBs.
- *
- * @param url
- * @exception DeploymentException
- */
- public void undeploy(URL url)
- throws DeploymentException
- {
+ }
+
+ // Add to webserver so client can access classes through
dynamic class downloading
+ WebProviderMBean webServer =
(WebProviderMBean)MBeanProxy.create(WebProviderMBean.class,
WebProviderMBean.OBJECT_NAME);
+ webServer.addClassLoader(cl);
+
+ // Done
+ log.log("Deployed application: "+app.getName());
+
+ // Register deployment
+ deployments.put(url, app);
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new DeploymentException("Could not deploy
"+url.toString(),e);
+ } finally
+ {
+ Log.unsetLog();
+ }
+ }
+
+
+ /**
+ * Remove previously deployed EJBs.
+ *
+ * @param url
+ * @exception DeploymentException
+ */
+ public void undeploy(URL url)
+ throws DeploymentException
+ {
// Get application from table
- Application app = (Application)deployments.get(url);
-
- // Check if deployed
- if (app == null)
- {
- throw new DeploymentException("URL not deployed");
- }
-
- // Undeploy application
- Log.setLog(log);
- log.log("Undeploying:"+url);
- try
- {
- // Unbind in JNDI
- Iterator enum = app.getContainers().iterator();
- Context ctx = new InitialContext();
- while (enum.hasNext())
- {
- Container con = (Container)enum.next();
- ctx.unbind(con.getMetaData().getJndiName());
-
- // Done
- log.log("Unbound: "+con.getMetaData().getJndiName());
- }
-
- // Stop/destroy container
- enum = app.getContainers().iterator();
- while (enum.hasNext())
- {
- Container con = (Container)enum.next();
-
- // Stop container
- con.stop();
-
- // Destroy container
- con.destroy();
-
- // Done
- log.log("Removed: "+con.getMetaData().getEjbName());
- }
-
- // Remove deployment
- deployments.remove(url);
-
- // Done
- log.log("Undeployed application: "+app.getName());
- } catch (Exception e)
- {
- log.error("Undeploy failed");
- log.exception(e);
-
- throw new DeploymentException("Undeploy failed", e);
- } finally
- {
- Log.unsetLog();
- }
- }
-
- // MBeanRegistration ---------------------------------------------
- public ObjectName preRegister(MBeanServer server, ObjectName name)
- throws java.lang.Exception
- {
- this.server = server;
-
- return new ObjectName(OBJECT_NAME);
-// return name;
- }
-
- public void postRegister(java.lang.Boolean registrationDone)
- {
- }
-
- public void preDeregister()
- throws java.lang.Exception
- {
- }
-
- public void postDeregister()
- {
- }
-
- // Protected -----------------------------------------------------
- protected void rebind(Context ctx, String name, Object val)
- throws NamingException
- {
- // Bind val to name in ctx, and make sure that all intermediate contexts exist
-
- Name n = ctx.getNameParser("").parse(name);
- while (n.size() > 1)
- {
- String ctxName = n.get(0);
- try
- {
- ctx = (Context)ctx.lookup(ctxName);
- } catch (NameNotFoundException e)
- {
- ctx = ctx.createSubcontext(ctxName);
- }
- n = n.getSuffix(1);
- }
-
- ctx.rebind(n.get(0), val);
- }
+ Application app = (Application)deployments.get(url);
+
+ // Check if deployed
+ if (app == null)
+ {
+ throw new DeploymentException("URL not deployed");
+ }
+
+ // Undeploy application
+ Log.setLog(log);
+ log.log("Undeploying:"+url);
+ try
+ {
+ // Unbind in JNDI
+ Iterator enum = app.getContainers().iterator();
+ Context ctx = new InitialContext();
+ while (enum.hasNext())
+ {
+ Container con = (Container)enum.next();
+ ctx.unbind(con.getMetaData().getJndiName());
+
+ // Done
+ log.log("Unbound: "+con.getMetaData().getJndiName());
+ }
+
+ // Stop/destroy container
+ enum = app.getContainers().iterator();
+ while (enum.hasNext())
+ {
+ Container con = (Container)enum.next();
+
+ // Stop container
+ con.stop();
+
+ // Destroy container
+ con.destroy();
+
+ // Done
+ log.log("Removed: "+con.getMetaData().getEjbName());
+ }
+
+ // Remove deployment
+ deployments.remove(url);
+
+ // Done
+ log.log("Undeployed application: "+app.getName());
+ } catch (Exception e)
+ {
+ log.error("Undeploy failed");
+ log.exception(e);
+
+ throw new DeploymentException("Undeploy failed", e);
+ } finally
+ {
+ Log.unsetLog();
+ }
+ }
+
+ // MBeanRegistration ---------------------------------------------
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws java.lang.Exception
+ {
+ this.server = server;
+
+ return new ObjectName(OBJECT_NAME);
+ // return name;
+ }
+
+ public void postRegister(java.lang.Boolean registrationDone)
+ {
+ }
+
+ public void preDeregister()
+ throws java.lang.Exception
+ {
+ }
+
+ public void postDeregister()
+ {
+ }
+
+ // Protected -----------------------------------------------------
+ protected void rebind(Context ctx, String name, Object val)
+ throws NamingException
+ {
+ // Bind val to name in ctx, and make sure that all intermediate
contexts exist
+
+ Name n = ctx.getNameParser("").parse(name);
+ while (n.size() > 1)
+ {
+ String ctxName = n.get(0);
+ try
+ {
+ ctx = (Context)ctx.lookup(ctxName);
+ } catch (NameNotFoundException e)
+ {
+ ctx = ctx.createSubcontext(ctxName);
+ }
+ n = n.getSuffix(1);
+ }
+
+ ctx.rebind(n.get(0), val);
+ }
}