Mail Archive Home | fractal-commits List | April 2008 Index
| <-- Date Index --> | <-- Thread Index --> |
various fixes (too many to list), almost ready to go;
--- sandbox/ervalerio/fractal-bf/connectors/rmi/logging.properties 2008-04-29 19:05:25 UTC (rev 7551)
+++ sandbox/ervalerio/fractal-bf/connectors/rmi/logging.properties 2008-04-29 19:09:00 UTC (rev 7552)
@@ -16,4 +16,6 @@
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# Set the default logging level for the logger named com.mycompany
-org.objectweb.fractal.bf.connectors.rmi = FINER
\ No newline at end of file
+org.objectweb.fractal.bf.connectors.rmi = ALL
+
+sun.rmi.level = INFO
\ No newline at end of file
--- sandbox/ervalerio/fractal-bf/connectors/rmi/src/main/java/org/objectweb/fractal/bf/connectors/rmi/RmiConnector.java 2008-04-29 19:05:25 UTC (rev 7551)
+++ sandbox/ervalerio/fractal-bf/connectors/rmi/src/main/java/org/objectweb/fractal/bf/connectors/rmi/RmiConnector.java 2008-04-29 19:09:00 UTC (rev 7552)
@@ -72,9 +72,10 @@
RmiConnectorAttributes rmiServiceAttributes = (RmiConnectorAttributes) compRmiSkel
.getFcInterface(RmiConnectorAttributes.RMI_CONNECTOR_ATTRIBUTES);
- // this should not be necessary if the ADL factory could take into
- // account instance of parameter
- // objects
+ /*
+ * this should not be necessary if the ADL factory could take into
+ * account instance of parameter objects
+ */
rmiServiceAttributes.setServiceObject(serverItf);
rmiServiceAttributes.setServiceName(name);
--- sandbox/ervalerio/fractal-bf/connectors/rmi/src/main/java/org/objectweb/fractal/bf/connectors/rmi/RmiRegistryCreationException.java (rev 0)
+++ sandbox/ervalerio/fractal-bf/connectors/rmi/src/main/java/org/objectweb/fractal/bf/connectors/rmi/RmiRegistryCreationException.java 2008-04-29 19:09:00 UTC (rev 7552)
@@ -0,0 +1,19 @@
+/**
+ * Author: Valerio Schiavoni <valerio.schiavoni@xxxxxxxxx>
+ */
+package org.objectweb.fractal.bf.connectors.rmi;
+
+/**
+ * This exception is thrown by the {@link RmiServerBridge} if it cannot create a
+ * local RMI registry, if necessary.
+ */
+public class RmiRegistryCreationException extends RuntimeException {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1852800273982950011L;
+
+ public RmiRegistryCreationException(String cause, Throwable t) {
+ super(cause, t);
+ }
+}
--- sandbox/ervalerio/fractal-bf/connectors/rmi/src/main/java/org/objectweb/fractal/bf/connectors/rmi/RmiServerBridge.java 2008-04-29 19:05:25 UTC (rev 7551)
+++ sandbox/ervalerio/fractal-bf/connectors/rmi/src/main/java/org/objectweb/fractal/bf/connectors/rmi/RmiServerBridge.java 2008-04-29 19:09:00 UTC (rev 7552)
@@ -36,67 +36,62 @@
public void startRmi() {
Remote rmiSkeleton = null;
+ Component interfaceOwner = ((Interface) service).getFcItfOwner();
+ Object content = null;
try {
+ content = interfaceOwner.getFcInterface("/content");
+ } catch (NoSuchInterfaceException e2) {
+ }
+
+ try {
if (Remote.class.isAssignableFrom(service.getClass())) {
log.fine("Fractal interface " + service
+ " is a subclass of java.rmi.Remote");
+
rmiSkeleton = UnicastRemoteObject.exportObject(
- (Remote) service, 0);
+ (Remote) interfaceOwner.getFcInterface("/content"), 0);
} else {
- log.fine("Fractal interface " + service
- + " is not a subclass of remote");
+ log
+ .fine("Activating runtime skeleton generation for interface: "
+ + service);
RmiEnablingInterfaceTransformer transformer = new RmiEnablingInterfaceTransformer();
- log.finest(RmiEnablingInterfaceTransformer.class.getName()
- + " created");
-
- Component interfaceOwner = ((Interface) service)
- .getFcItfOwner();
Class<?> toTransform = null;
- try {
- final Object content = interfaceOwner
- .getFcInterface("/content");
- Class<?>[] interfaces = content.getClass().getInterfaces();
- log.finest("Interfaces implemented by /content: "
- + Arrays.deepToString(interfaces));
- toTransform = interfaces[0]; // XXX
-
- } catch (NoSuchInterfaceException e1) {
- }
-
+ Class<?>[] interfaces = content.getClass().getInterfaces();
+ log.finest("Interfaces implemented by /content: "
+ + Arrays.deepToString(interfaces));
+ toTransform = interfaces[0]; // XXX
log.finest("Runtime class of interface to transform: "
+ toTransform);
-
final Class<?> remotedJavaInterface = transformer
.transform(toTransform);
-
log
.finer("Corresponding java.rmi.Remote enabled interface for fractal interface created with name: "
+ remotedJavaInterface.getCanonicalName());
UnicastRemoteObjectGenerator generator = new UnicastRemoteObjectGenerator();
- log.finest(UnicastRemoteObjectGenerator.class.getName()
- + " created");
- Class<?> remotableClassForSkeleton = generator.generate(service
- .getClass(), remotedJavaInterface);
- log.finest("Subclass of UnicastRemoteObject generated");
- Constructor<?> twoArgsConstructor;
- for (Constructor c : remotableClassForSkeleton
- .getConstructors()) {
- log.finest("Constructor on generated class: "
- + c.toString());
- }
+ Class<?> remotableClassForSkeleton = generator.generate(
+ toTransform, remotedJavaInterface);
+ log.finest("Subclass of UnicastRemoteObject generated: "
+ + remotableClassForSkeleton);
+ Constructor<?> constructor;
try {
- twoArgsConstructor = remotableClassForSkeleton
- .getConstructor(new Class[] { int.class,
- remotedJavaInterface });
- /* first parameter is the rmi registry port */
- final Object newInstance = twoArgsConstructor
- .newInstance(new Object[] { 0, service });
+ constructor = remotableClassForSkeleton
+ .getConstructor(new Class[] { toTransform });
+ log.finest("Constructor found: " + constructor);
+ final Object newInstance = constructor
+ .newInstance(new Object[] { content });
+ log.finest("Skeleton class instantiated: " + newInstance);
+ UnicastRemoteObject uro = (UnicastRemoteObject) newInstance;
+ UnicastRemoteObject.unexportObject(uro, true);
+ log.finest("Unexported...going to re-export it.");
+ /* export it in the rmi registry */
+ rmiSkeleton = UnicastRemoteObject
+ .exportObject(
+ (UnicastRemoteObject) newInstance,
+ RmiConnectorConstants.JAVA_RMI_REGISTRY_DEFAULT_PORT);
+ log.finest("Rmi skeleton exported " + rmiSkeleton);
- rmiSkeleton = UnicastRemoteObject.exportObject(
- (Remote) newInstance, 0);
-
} catch (Exception e) {
e.printStackTrace();
log
@@ -105,18 +100,56 @@
}
}
- Registry registry = LocateRegistry
- .createRegistry(RmiConnectorConstants.JAVA_RMI_REGISTRY_DEFAULT_PORT);
+ Registry registry = locateRegistry();
+ log.fine("Registry located: " + registry);
+
registry.rebind(name, rmiSkeleton);
+ log.fine("Skeleton bound into registry with name: " + name);
} catch (RemoteException e) {
e.printStackTrace();
+ } catch (NoSuchInterfaceException e) {
+ log
+ .warning("Could not find '/content' interface on service component");
+
}
log.info("Skeleton bound to the local JavaRMI registry");
}
/**
+ * @return a local reference to the RMI registry.
+ * @throws RemoteException
+ * @throw {@link RmiRegistryCreationException} if problems occur while
+ * creating a local rmi registry.
+ */
+ private Registry locateRegistry() {
+ Registry registry = null;
+ try {
+ registry = LocateRegistry
+ .getRegistry(RmiConnectorConstants.JAVA_RMI_REGISTRY_DEFAULT_PORT);
+ log.fine("RMI registry recovered :" + registry.toString());
+ } catch (RemoteException e) {
+ // create it locally
+ log
+ .warning("Could not recover a local RMI registry, going to create a new one");
+ try {
+ registry = LocateRegistry
+ .createRegistry(RmiConnectorConstants.JAVA_RMI_REGISTRY_DEFAULT_PORT);
+ } catch (RemoteException e1) {
+ log
+ .warning("Could not create a local instance of RMI registry due to: "
+ + e1.getMessage());
+ throw new RmiRegistryCreationException(
+ "Cannot create a local reference for the rmi registry",
+ e1);
+ }
+ }
+
+ return registry;
+ }
+
+ /**
* @see org.objectweb.fractal.bf.connectors.rmi.RmiConnectorAttributes#setServiceName(java.lang.String)
*/
public void setServiceName(String name) {
--- sandbox/ervalerio/fractal-bf/connectors/rmi/src/main/java/org/objectweb/fractal/bf/connectors/rmi/asm/UnicastRemoteObjectGenerator.java 2008-04-29 19:05:25 UTC (rev 7551)
+++ sandbox/ervalerio/fractal-bf/connectors/rmi/src/main/java/org/objectweb/fractal/bf/connectors/rmi/asm/UnicastRemoteObjectGenerator.java 2008-04-29 19:09:00 UTC (rev 7552)
@@ -48,6 +48,8 @@
final String generatedClassInternalName = remotableInterfazeInternalName
+ "Impl";
+ log.finest("Generated class internal name: "
+ + generatedClassInternalName);
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, generatedClassInternalName,
null, "java/rmi/server/UnicastRemoteObject",
new String[] { remotableInterfazeInternalName });
@@ -61,22 +63,20 @@
+ unremotableInterfazeInternalName + " generated");
}
- // 2 args constructor
{
- mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(IL"
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(L"
+ unremotableInterfazeInternalName + ";)V", null,
new String[] { "java/rmi/RemoteException" });
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitVarInsn(ALOAD, 0);
- mv.visitVarInsn(ILOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL,
- "java/rmi/server/UnicastRemoteObject", "<init>", "(I)V");
+ "java/rmi/server/UnicastRemoteObject", "<init>", "()V");
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitVarInsn(ALOAD, 0);
- mv.visitVarInsn(ALOAD, 2);
+ mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(PUTFIELD, generatedClassInternalName,
DELEGATED_FIELD_NAME, "L"
+ unremotableInterfazeInternalName + ";");
@@ -87,12 +87,12 @@
mv.visitLabel(l3);
mv.visitLocalVariable("this", "L" + generatedClassInternalName
+ ";", null, l0, l3, 0);
- mv.visitLocalVariable("port", "I", null, l0, l3, 1);
mv.visitLocalVariable(DELEGATED_FIELD_NAME, "L"
- + unremotableInterfazeInternalName + ";", null, l0, l3, 2);
- mv.visitMaxs(2, 3);
+ + unremotableInterfazeInternalName + ";", null, l0, l3, 1);
+ mv.visitMaxs(2, 2);
mv.visitEnd();
- log.fine("2-Args constructor generated");
+ log.fine("1-Args constructor generated.");
+
}
StringBuffer argsAndReturn = null;
@@ -101,10 +101,12 @@
argsAndReturn = new StringBuffer("(");
Class<?>[] paramTypes = method.getParameterTypes();
Class<?> returnType = method.getReturnType();
-
+ int args = 0;
for (Class<?> paramType : paramTypes) {
argsAndReturn.append(Type.getType(paramType));
+ args++;
}
+ log.finest("Method has " + args + " arguments");
argsAndReturn.append(")");
argsAndReturn.append(Type.getType(returnType));
@@ -122,6 +124,15 @@
DELEGATED_FIELD_NAME, "L"
+ unremotableInterfazeInternalName + ";");
+ // for every parameter of this method, push the actual argument on
+ // the stack
+ int i = 1;
+ while (i <= args) {
+ mv.visitVarInsn(ALOAD, i);
+ log.finest("ALOAD index: " + i);
+ i = i + 1;
+ }
+
mv.visitMethodInsn(INVOKEINTERFACE,
unremotableInterfazeInternalName, method.getName(),
argsAndReturn.toString());
@@ -154,8 +165,10 @@
RMIServiceClassLoader classloader = new RMIServiceClassLoader(
remotableInterfaze.getClassLoader());
log.fine("RMIClassLoader initialized");
- return classloader.defineClass(bytecode, generatedClassInternalName
- .replace("/", "."));
+ final Class<?> definedClazz = classloader.defineClass(bytecode,
+ generatedClassInternalName.replace("/", "."));
+ log.finest("Class defined in RMIServiceClassLoader: " + definedClazz);
+ return definedClazz;
}
}
--- sandbox/ervalerio/fractal-bf/connectors/rmi/src/test/java/org/objectweb/fractal/bf/connectors/rmi/RmiConnectorTest.java 2008-04-29 19:05:25 UTC (rev 7551)
+++ sandbox/ervalerio/fractal-bf/connectors/rmi/src/test/java/org/objectweb/fractal/bf/connectors/rmi/RmiConnectorTest.java 2008-04-29 19:09:00 UTC (rev 7552)
@@ -7,39 +7,43 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
-import java.rmi.NotBoundException;
+import java.lang.reflect.Method;
import java.rmi.Remote;
-import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.HashMap;
import java.util.Map;
+import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.objectweb.fractal.adl.Factory;
import org.objectweb.fractal.adl.FactoryFactory;
import org.objectweb.fractal.api.Component;
-import org.objectweb.fractal.bf.BindingFactoryException;
import org.objectweb.fractal.bf.CannotCreateSkeletonException;
import org.objectweb.fractal.bf.connectors.BasicServiceImpl;
-import org.objectweb.fractal.bf.connectors.rmi.fixtures.RemotableService;
-import org.objectweb.fractal.bf.connectors.rmi.fixtures.RemotableServiceImpl;
/**
* Test the Rmi connector in isolation.
*/
public class RmiConnectorTest {
+ private static final String RMI_SERVICE_NAME = "service";
+
private RmiConnector rmiConnector;
+ private Component remotableService;
+
private Component service;
+ private Registry rmiRegistry;
+
@BeforeClass
public static void initFractal() {
System.setProperty("fractal.provider",
"org.objectweb.fractal.julia.Julia");
+
}
/**
@@ -47,53 +51,95 @@
*/
@Before
public void setUp() throws Exception {
+ // System.setSecurityManager(new RMISecurityManager());
this.rmiConnector = new RmiConnector();
Factory factory = FactoryFactory
.getFactory(FactoryFactory.FRACTAL_BACKEND);
+ remotableService = (Component) factory.newComponent(
+ "org.objectweb.fractal.bf.connectors.RemotableService", null);
service = (Component) factory.newComponent(
- "org.objectweb.fractal.bf.connectors.RemotableService", null);
+ "org.objectweb.fractal.bf.connectors.Service", null);
+ rmiRegistry = LocateRegistry
+ .createRegistry(RmiConnectorConstants.JAVA_RMI_REGISTRY_DEFAULT_PORT);
+
+ assertEquals(0, rmiRegistry.list().length);
}
- /**
- * Test method for
- * {@link org.objectweb.fractal.bf.connectors.rmi.RmiConnector#createSkel(java.lang.String, java.lang.Object, org.objectweb.fractal.api.Component, java.util.Map)}.
- *
- * @throws RemoteException
- * @throws BindingFactoryException
- */
+ @After
+ public void cleanUpRmiRegistry() {
+
+ try {
+ assertEquals(1, rmiRegistry.list().length);
+ rmiRegistry.unbind(RMI_SERVICE_NAME);
+ assertEquals(0, rmiRegistry.list().length);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+
+ }
+ }
+
@Test
- public void testCreateSkel() throws RemoteException,
- BindingFactoryException {
+ public void testCreateSkelFromRemoteFcInterface() throws Exception {
try {
- final Component skeleton = this.rmiConnector.createSkel("service",
- new RemotableServiceImpl(), service, createExportHints());
+ final Component skeleton = this.rmiConnector.createSkel(
+ RMI_SERVICE_NAME, remotableService
+ .getFcInterface(RMI_SERVICE_NAME),
+ remotableService, createExportHints());
- this.rmiConnector.finalizeSkeleton(skeleton, null);
+ checkInvokeServiceMethods(skeleton);
- Registry r = LocateRegistry
- .getRegistry(RmiConnectorConstants.JAVA_RMI_REGISTRY_DEFAULT_PORT);
+ } catch (CannotCreateSkeletonException e) {
+ e.printStackTrace();
+ fail("Could not create skeleton");
+ }
- final Remote remoteService = r.lookup("service");
- assertNotNull(remoteService);
- RemotableService rs = (RemotableService) remoteService;
- rs.print();
+ }
- String answer = rs.printAndAnswer();
- assertEquals(BasicServiceImpl.SERVICE_REPLY, answer);
+ @Test
+ public void testCreateSkeletonFromNotRemotableFcInterface()
+ throws Exception {
+ try {
+ final Component skeleton = this.rmiConnector.createSkel(
+ RMI_SERVICE_NAME, service.getFcInterface(RMI_SERVICE_NAME),
+ service, createExportHints());
+ checkInvokeServiceMethods(skeleton);
+
} catch (CannotCreateSkeletonException e) {
e.printStackTrace();
fail("Could not create skeleton");
- } catch (NotBoundException e) {
- e.printStackTrace();
- fail("The remote interface was not bound in the registry with the appropriate name");
}
}
+ private void checkInvokeServiceMethods(Component skeleton) throws Exception {
+
+ this.rmiConnector.finalizeSkeleton(skeleton, null);
+
+ String[] namesOfRegisteredServices = rmiRegistry.list();
+ assertEquals(1, namesOfRegisteredServices.length);
+
+ final Remote remoteReference = rmiRegistry.lookup(RMI_SERVICE_NAME);
+ assertNotNull(remoteReference);
+
+ Method print = remoteReference.getClass().getMethod("print",
+ new Class[] {});
+
+ assertNotNull(print);
+
+ print.invoke(remoteReference, new Object[] {});
+
+ Method printAndAswer = remoteReference.getClass().getMethod(
+ "printAndAnswer", new Class[] {});
+ String answer = (String) printAndAswer.invoke(remoteReference,
+ new Object[] {});
+ assertEquals(BasicServiceImpl.SERVICE_REPLY, answer);
+ }
+
private Map<String, String> createExportHints() {
Map<String, String> exportHints = new HashMap<String, String>();
- exportHints.put(RmiConnectorConstants.SERVICE_NAME, "service");
+ exportHints.put(RmiConnectorConstants.SERVICE_NAME, RMI_SERVICE_NAME);
return exportHints;
}
--- sandbox/ervalerio/fractal-bf/connectors/rmi/src/test/java/org/objectweb/fractal/bf/connectors/rmi/asm/UnicastRemoteObjectGeneratorTest.java 2008-04-29 19:05:25 UTC (rev 7551)
+++ sandbox/ervalerio/fractal-bf/connectors/rmi/src/test/java/org/objectweb/fractal/bf/connectors/rmi/asm/UnicastRemoteObjectGeneratorTest.java 2008-04-29 19:09:00 UTC (rev 7552)
@@ -10,14 +10,13 @@
import static org.junit.Assert.fail;
import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.fractal.bf.connectors.BasicServiceImpl;
+import org.objectweb.fractal.bf.connectors.Pojo;
import org.objectweb.fractal.bf.connectors.Service;
import org.objectweb.fractal.bf.connectors.rmi.fixtures.RemotableService;
import org.objectweb.fractal.bf.connectors.rmi.fixtures.RemotableServiceImpl;
@@ -40,7 +39,7 @@
@Before
public void setUp() throws Exception {
this.generator = new UnicastRemoteObjectGenerator();
- this.serviceImpl = new RemotableServiceImpl(0, new BasicServiceImpl());
+ this.serviceImpl = new RemotableServiceImpl(new BasicServiceImpl());
}
@Test
@@ -58,35 +57,23 @@
assertEquals(1, construtors.length);
try {
- Constructor twoArgsConstructor = generated
- .getConstructor(new Class[] { int.class, Service.class });
- final Object newInstance = twoArgsConstructor
- .newInstance(new Object[] { 0, serviceImpl });
+ Constructor
+ .getConstructor(new Class[] { Service.class });
+ final Object newInstance = oneArgConstructor
+ .newInstance(new Object[] { serviceImpl });
- RemotableService newInstanceCasted = (RemotableService) newInstance;
- newInstanceCasted.print();
- String answer = newInstanceCasted.printAndAnswer();
+ RemotableService generatedRemotableService = (RemotableService) newInstance;
+ generatedRemotableService.print();
+ String answer = generatedRemotableService.printAndAnswer();
assertEquals(answer, BasicServiceImpl.SERVICE_REPLY);
+ Pojo pojoFromRMI = generatedRemotableService.getPojo();
+ assertNotNull(
+ "the pojo fom the remotable service should not be null",
+ pojoFromRMI);
- } catch (RemoteException e) {
- fail(e.getMessage());
- } catch (SecurityException e) {
- fail("cannot access generated constructor");
- } catch (NoSuchMethodException e) {
- fail("cannot find 2-args constructor");
- } catch (IllegalArgumentException e) {
+ } catch (Exception e) {
e.printStackTrace();
- fail("cannot find correct constructor for specified arguments");
- } catch (InstantiationException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
+ fail(e.getMessage());
}
-
}
}
--- sandbox/ervalerio/fractal-bf/connectors/rmi/src/test/java/org/objectweb/fractal/bf/connectors/rmi/fixtures/MyUnicastRemoteObject.java 2008-04-29 19:05:25 UTC (rev 7551)
+++ sandbox/ervalerio/fractal-bf/connectors/rmi/src/test/java/org/objectweb/fractal/bf/connectors/rmi/fixtures/MyUnicastRemoteObject.java 2008-04-29 19:09:00 UTC (rev 7552)
@@ -19,16 +19,7 @@
public Service s;
- /**
- * @param port
- * @throws RemoteException
- */
- protected MyUnicastRemoteObject(int port) throws RemoteException {
- super(port);
- }
-
- protected MyUnicastRemoteObject(int port, Service s) throws RemoteException {
- super(port);
+ protected MyUnicastRemoteObject(Service s) throws RemoteException {
this.s = s;
}
@@ -54,6 +45,10 @@
}
+ public Pojo child(Pojo p) {
+ return this.s.child(p);
+ }
+
/**
* @see org.objectweb.fractal.bf.connectors.rmi.fixtures.RemotableService#printAndAnswer()
*/
--- sandbox/ervalerio/fractal-bf/connectors/rmi/src/test/java/org/objectweb/fractal/bf/connectors/rmi/fixtures/RemotableServiceImpl.java 2008-04-29 19:05:25 UTC (rev 7551)
+++ sandbox/ervalerio/fractal-bf/connectors/rmi/src/test/java/org/objectweb/fractal/bf/connectors/rmi/fixtures/RemotableServiceImpl.java 2008-04-29 19:09:00 UTC (rev 7552)
@@ -14,7 +14,7 @@
Service s;
- public RemotableServiceImpl(int i, Service s) {
+ public RemotableServiceImpl(Service s) {
this.s = s;
}
| <-- Date Index --> | <-- Thread Index --> |
Powered by MHonArc.
Copyright © 2006-2007, OW2 Consortium | contact | webmaster.