Author: julien_viet
Date: 2010-01-14 10:09:30 -0500 (Thu, 14 Jan 2010)
New Revision: 1295
Added:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/SerializationContext.java
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/B.java
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/C1.java
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/C2.java
Removed:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/ReplicationContext.java
Modified:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/factory/DefaultObjectFactory.java
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/factory/ObjectFactory.java
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectReader.java
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectWriter.java
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/TestSerialization.java
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/TestObjectFactory.java
Log:
add unit test
Deleted:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/ReplicationContext.java
===================================================================
---
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/ReplicationContext.java 2010-01-14
13:53:24 UTC (rev 1294)
+++
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/ReplicationContext.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2009 eXo Platform SAS.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-
-package org.exoplatform.webui.application.replication;
-
-import org.exoplatform.webui.application.replication.model.TypeDomain;
-import org.exoplatform.webui.application.replication.serial.ObjectReader;
-import org.exoplatform.webui.application.replication.serial.ObjectWriter;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
- * @version $Revision$
- */
-public class ReplicationContext
-{
-
- /** . */
- private final TypeDomain typeDomain;
-
- /** . */
- private final Set<Object> creationContexts;
-
- public ReplicationContext(TypeDomain typeDomain)
- {
- this.typeDomain = typeDomain;
- this.creationContexts = new HashSet<Object>();
- }
-
- public void addCreationContext(Object o)
- {
- creationContexts.add(o);
- }
-
- public <O> O clone(O o) throws IOException, ClassNotFoundException
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectWriter writer = new ObjectWriter(typeDomain, baos);
- writer.writeObject(o);
- writer.close();
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectReader in = new ObjectReader(typeDomain, bais);
- return (O)in.readObject();
- }
-}
Copied:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/SerializationContext.java
(from rev 1292,
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/ReplicationContext.java)
===================================================================
---
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/SerializationContext.java
(rev 0)
+++
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/SerializationContext.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.exoplatform.webui.application.replication;
+
+import org.exoplatform.webui.application.replication.model.TypeDomain;
+import org.exoplatform.webui.application.replication.serial.ObjectReader;
+import org.exoplatform.webui.application.replication.serial.ObjectWriter;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class SerializationContext
+{
+
+ /** . */
+ private final TypeDomain typeDomain;
+
+ /** . */
+ private final Map<Class<?>, Object> creationContexts;
+
+ public SerializationContext(TypeDomain typeDomain)
+ {
+ this.typeDomain = typeDomain;
+ this.creationContexts = new HashMap<Class<?>, Object>();
+ }
+
+ public void addCreationContext(Object o)
+ {
+ creationContexts.put(o.getClass(), o);
+ }
+
+ public TypeDomain getTypeDomain()
+ {
+ return typeDomain;
+ }
+
+ public <C> C getContext(Class<C> contextType)
+ {
+ // This is ok
+ return (C)creationContexts.get(contextType);
+ }
+
+ public <O> O clone(O o) throws IOException, ClassNotFoundException
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectWriter writer = new ObjectWriter(this, baos);
+ writer.writeObject(o);
+ writer.close();
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectReader in = new ObjectReader(this, bais);
+ return (O)in.readObject();
+ }
+}
Modified:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/factory/DefaultObjectFactory.java
===================================================================
---
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/factory/DefaultObjectFactory.java 2010-01-14
13:53:24 UTC (rev 1294)
+++
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/factory/DefaultObjectFactory.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -23,9 +23,9 @@
* @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
* @version $Revision$
*/
-public class DefaultObjectFactory extends ObjectFactory<Object, Object>
+public final class DefaultObjectFactory extends ObjectFactory<Object, Object>
{
- public <E> E create(Class<E> type, Object context) throws CreateException
+ public <O> O create(Class<O> type, Object context) throws CreateException
{
try
{
Modified:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/factory/ObjectFactory.java
===================================================================
---
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/factory/ObjectFactory.java 2010-01-14
13:53:24 UTC (rev 1294)
+++
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/factory/ObjectFactory.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -22,10 +22,21 @@
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
* @version $Revision$
+ * @param <B> the base object type
+ * @param <C> the context type
*/
-public abstract class ObjectFactory<O, C>
+public abstract class ObjectFactory<B, C>
{
- public abstract <E extends O> E create(Class<E> type, C context) throws
CreateException;
+ /**
+ * Instantiate an object based on the provided class.
+ *
+ * @param type the type
+ * @param context the context
+ * @param <S> the sub type of the base type
+ * @return the S instance
+ * @throws CreateException anything wrong that could happen during instance creation
+ */
+ public abstract <S extends B> S create(Class<S> type, C context) throws
CreateException;
}
Modified:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectReader.java
===================================================================
---
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectReader.java 2010-01-14
13:53:24 UTC (rev 1294)
+++
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectReader.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -19,9 +19,10 @@
package org.exoplatform.webui.application.replication.serial;
+import org.exoplatform.webui.application.replication.SerializationContext;
+import org.exoplatform.webui.application.replication.factory.ObjectFactory;
import org.exoplatform.webui.application.replication.model.ClassTypeModel;
import org.exoplatform.webui.application.replication.model.FieldModel;
-import org.exoplatform.webui.application.replication.model.TypeDomain;
import org.exoplatform.webui.application.replication.model.TypeModel;
import java.io.*;
@@ -35,7 +36,7 @@
{
/** . */
- private final TypeDomain domain;
+ private final SerializationContext context;
/** . */
private final Map<Integer, Object> idToObject;
@@ -43,7 +44,7 @@
/** . */
private final Map<Integer, List<Resolution>> idToResolutions;
- public ObjectReader(TypeDomain domain, InputStream in) throws IOException
+ public ObjectReader(SerializationContext context, InputStream in) throws IOException
{
super(in);
@@ -51,11 +52,31 @@
enableResolveObject(true);
//
- this.domain = domain;
+ this.context = context;
this.idToObject = new HashMap<Integer, Object>();
this.idToResolutions = new HashMap<Integer, List<Resolution>>();
}
+ private <O, C> O instantiate(ClassTypeModel<O, C> typeModel) throws
InvalidClassException
+ {
+ try
+ {
+ ObjectFactory<? super O, C> factory = typeModel.getFactory();
+
+ //
+ C c = context.getContext(typeModel.getContextType());
+
+ //
+ return factory.create(typeModel.getObjectType(), c);
+ }
+ catch (Exception e)
+ {
+ InvalidClassException ice = new InvalidClassException("Cannot instantiate
object from class " + typeModel.getObjectType().getName());
+ ice.initCause(e);
+ throw ice;
+ }
+ }
+
@Override
protected Object resolveObject(Object obj) throws IOException
{
@@ -79,20 +100,10 @@
id = container.readInt();
Class clazz = (Class) container.readObject();
- ClassTypeModel<?, ?> typeModel = (ClassTypeModel)
domain.getTypeModel(clazz);
+ ClassTypeModel<?, ?> typeModel =
(ClassTypeModel)context.getTypeDomain().getTypeModel(clazz);
//
- Object instance;
- try
- {
- instance = typeModel.getFactory().create(clazz, null);
- }
- catch (Exception e)
- {
- InvalidClassException ice = new InvalidClassException("Cannot
instantiate object from class " + clazz.getName());
- ice.initCause(e);
- throw ice;
- }
+ Object instance = instantiate(typeModel);
//
idToObject.put(id, instance);
Modified:
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectWriter.java
===================================================================
---
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectWriter.java 2010-01-14
13:53:24 UTC (rev 1294)
+++
portal/trunk/webui/core/src/main/java/org/exoplatform/webui/application/replication/serial/ObjectWriter.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -19,6 +19,7 @@
package org.exoplatform.webui.application.replication.serial;
+import org.exoplatform.webui.application.replication.SerializationContext;
import org.exoplatform.webui.application.replication.model.ClassTypeModel;
import org.exoplatform.webui.application.replication.model.FieldModel;
import org.exoplatform.webui.application.replication.model.TypeDomain;
@@ -37,12 +38,12 @@
{
/** . */
- private final TypeDomain domain;
+ private final SerializationContext context;
/** . */
private final IdentityHashMap<Object, Integer> objectToId;
- public ObjectWriter(TypeDomain domain, OutputStream out) throws IOException
+ public ObjectWriter(SerializationContext context, OutputStream out) throws
IOException
{
super(out);
@@ -50,7 +51,7 @@
enableReplaceObject(true);
//
- this.domain = domain;
+ this.context = context;
this.objectToId = new IdentityHashMap<Object, Integer>();
}
@@ -81,7 +82,7 @@
}
else
{
- ClassTypeModel<?, ?> typeModel = (ClassTypeModel<?,
?>)domain.getTypeModel(obj.getClass());
+ ClassTypeModel<?, ?> typeModel = (ClassTypeModel<?,
?>)context.getTypeDomain().getTypeModel(obj.getClass());
//
if (typeModel == null)
Modified:
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/TestSerialization.java
===================================================================
---
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/TestSerialization.java 2010-01-14
13:53:24 UTC (rev 1294)
+++
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/TestSerialization.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -20,12 +20,9 @@
package org.exoplatform.webui.replication;
import junit.framework.TestCase;
+import org.exoplatform.webui.application.replication.SerializationContext;
import org.exoplatform.webui.application.replication.model.TypeDomain;
-import org.exoplatform.webui.application.replication.serial.ObjectReader;
-import org.exoplatform.webui.application.replication.serial.ObjectWriter;
-import java.io.*;
-
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
* @version $Revision$
@@ -41,13 +38,8 @@
a.a = "foo";
a.b = 2;
a.c = true;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectWriter writer = new ObjectWriter(domain, baos);
- writer.writeObject(a);
- writer.close();
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectReader in = new ObjectReader(domain, bais);
- a = (A)in.readObject();
+ SerializationContext context = new SerializationContext(domain);
+ a = context.clone(a);
assertEquals("foo", a.a);
assertEquals(2, a.b);
assertEquals(true, a.c);
@@ -59,12 +51,8 @@
domain.add(B.class);
B b = new B();
b.ref = new B(b);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectWriter writer = new ObjectWriter(domain, baos);
- writer.writeObject(b);
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectReader in = new ObjectReader(domain, bais);
- b = (B)in.readObject();
+ SerializationContext context = new SerializationContext(domain);
+ b = context.clone(b);
assertNotNull(b.ref);
assertSame(b, b.ref.ref);
}
@@ -80,18 +68,9 @@
e.right = new E();
e.right.left = e.left.left;
e.right.right = e.left.right;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectWriter writer = new ObjectWriter(domain, baos);
- writer.writeObject(e);
- ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
- ObjectReader in = new ObjectReader(domain, bais);
- e = (E)in.readObject();
+ SerializationContext context = new SerializationContext(domain);
+ e = context.clone(e);
assertSame(e.left.left, e.right.left);
assertSame(e.left.right, e.right.right);
}
-
- public void testCustomFactory() throws Exception
- {
-
- }
}
Added:
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/B.java
===================================================================
---
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/B.java
(rev 0)
+++
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/B.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.exoplatform.webui.replication.factory;
+
+import org.exoplatform.webui.application.replication.annotations.ReplicatedType;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+@ReplicatedType
+public class B
+{
+ public B()
+ {
+ this(true);
+ }
+
+ public B(boolean fail)
+ {
+ if (fail)
+ {
+ throw new RuntimeException();
+ }
+ }
+}
Added:
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/C1.java
===================================================================
---
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/C1.java
(rev 0)
+++
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/C1.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.exoplatform.webui.replication.factory;
+
+import junit.framework.AssertionFailedError;
+import org.exoplatform.webui.application.replication.factory.CreateException;
+import org.exoplatform.webui.application.replication.factory.ObjectFactory;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class C1 extends ObjectFactory<String, Object>
+{
+
+ @Override
+ public <E extends String> E create(Class<E> type, Object context) throws
CreateException
+ {
+ throw new AssertionFailedError();
+ }
+}
\ No newline at end of file
Added:
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/C2.java
===================================================================
---
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/C2.java
(rev 0)
+++
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/C2.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+package org.exoplatform.webui.replication.factory;
+
+import org.exoplatform.webui.application.replication.annotations.Factory;
+import org.exoplatform.webui.application.replication.annotations.ReplicatedType;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+@ReplicatedType
+@Factory(type = C1.class)
+public class C2
+{
+}
\ No newline at end of file
Modified:
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/TestObjectFactory.java
===================================================================
---
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/TestObjectFactory.java 2010-01-14
13:53:24 UTC (rev 1294)
+++
portal/trunk/webui/core/src/test/java/org/exoplatform/webui/replication/factory/TestObjectFactory.java 2010-01-14
15:09:30 UTC (rev 1295)
@@ -20,9 +20,12 @@
package org.exoplatform.webui.replication.factory;
import junit.framework.TestCase;
-import org.exoplatform.webui.application.replication.ReplicationContext;
+import org.exoplatform.webui.application.replication.SerializationContext;
import org.exoplatform.webui.application.replication.model.TypeDomain;
+import org.exoplatform.webui.application.replication.model.TypeException;
+import java.io.InvalidClassException;
+
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
* @version $Revision$
@@ -34,8 +37,43 @@
{
TypeDomain domain = new TypeDomain();
domain.add(A2.class);
- ReplicationContext context = new ReplicationContext(domain);
+ SerializationContext context = new SerializationContext(domain);
A2 a2 = new A2();
assertSame(A1.instance, context.clone(a2));
}
+
+ public void testFactoryThrowsException() throws Exception
+ {
+ TypeDomain domain = new TypeDomain();
+ domain.add(B.class);
+ SerializationContext context = new SerializationContext(domain);
+ B b = new B(false);
+ try
+ {
+ context.clone(b);
+ fail();
+ }
+ catch (InvalidClassException e)
+ {
+ }
+ }
+
+ public void testFactoryClassNotAssignable() throws Exception
+ {
+ TypeDomain domain = new TypeDomain();
+ try
+ {
+ domain.add(C2.class);
+ fail();
+ }
+ catch (TypeException e)
+ {
+ }
+ }
+
+ public void testCreationContext() throws Exception
+ {
+ TypeDomain domain = new TypeDomain();
+ }
+
}