OW2 Consortium
Search OW2 Mail Archive: 

Advanced Search - Powered by Google


Mail Archive Home | fractal-commits List | April 2008 Index

<--  Date Index     <--  Thread Index    

[fractal-commits] [7565] trunk/fractaladl/juliac: Separating the core of Juliac (compiler) from the ULTRA_MERGE optimization level.


Title: [7565] trunk/fractaladl/juliac: Separating the core of Juliac (compiler) from the ULTRA_MERGE optimization level.
Revision
7565
Author
seintur
Date
2008-04-30 18:31:38 +0200 (Wed, 30 Apr 2008)

Log Message

Separating the core of Juliac (compiler) from the ULTRA_MERGE optimization level.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/fractaladl/juliac/compiler/.classpath (7564 => 7565)


--- trunk/fractaladl/juliac/compiler/.classpath	2008-04-30 16:30:30 UTC (rev 7564)
+++ trunk/fractaladl/juliac/compiler/.classpath	2008-04-30 16:31:38 UTC (rev 7565)
@@ -11,7 +11,6 @@
 	<classpathentry combineaccessrules="false" kind="src" path="/fractaladl-ast-core-2.3"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/fractal-util-1.1"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/fractal-api-2.0.2"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/julia-mixins-2.5.2"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/julia-runtime-2.5.2"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/koch-runtime-2.5.2"/>
 	<classpathentry kind="output" path="target/classes"/>

Modified: trunk/fractaladl/juliac/compiler/TODO.txt (7564 => 7565)


--- trunk/fractaladl/juliac/compiler/TODO.txt	2008-04-30 16:30:30 UTC (rev 7564)
+++ trunk/fractaladl/juliac/compiler/TODO.txt	2008-04-30 16:31:38 UTC (rev 7565)
@@ -1,9 +1,5 @@
 * append a juliac- prefix to all artifact names (suggested by Philippe)
 * factorize initializer classes by membrane descriptors (suggested by Philippe)
-* merge all except content when the generic factory is invoked with an instance
-* MERGE_ALL: interceptors on client interfaces
-* MERGE_ALL: take into account .cfg Tree for instantiating a controller (see OO)
-* MERGE_ALL: interceptors on control interfaces (see OO)
 * COMP: provide a membrane factory
 * COMP: interceptors on control interfaces (see OO)
 

Modified: trunk/fractaladl/juliac/compiler/pom.xml (7564 => 7565)


--- trunk/fractaladl/juliac/compiler/pom.xml	2008-04-30 16:30:30 UTC (rev 7564)
+++ trunk/fractaladl/juliac/compiler/pom.xml	2008-04-30 16:31:38 UTC (rev 7565)
@@ -32,11 +32,6 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.objectweb.fractal.julia</groupId>
-            <artifactId>julia-mixins</artifactId>
-            <version>2.5.2</version>
-        </dependency>
-        <dependency>
             <groupId>fr.inria.gforge.spoon</groupId>
             <artifactId>spoon-core</artifactId>
             <version>1.3</version>

Property changes: trunk/fractaladl/juliac/opt/merge-all


Name: svn:ignore
   + target

Added: trunk/fractaladl/juliac/opt/merge-all/.classpath (0 => 7565)


--- trunk/fractaladl/juliac/opt/merge-all/.classpath	                        (rev 0)
+++ trunk/fractaladl/juliac/opt/merge-all/.classpath	2008-04-30 16:31:38 UTC (rev 7565)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/juliac-compiler"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/spoon-1.3"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/fractal-api-2.0.2"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/julia-runtime-2.5.2"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/julia-mixins-2.5.2"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Added: trunk/fractaladl/juliac/opt/merge-all/.project (0 => 7565)


--- trunk/fractaladl/juliac/opt/merge-all/.project	                        (rev 0)
+++ trunk/fractaladl/juliac/opt/merge-all/.project	2008-04-30 16:31:38 UTC (rev 7565)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>juliac-opt-merge-all</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: trunk/fractaladl/juliac/opt/merge-all/TODO.txt (0 => 7565)


--- trunk/fractaladl/juliac/opt/merge-all/TODO.txt	                        (rev 0)
+++ trunk/fractaladl/juliac/opt/merge-all/TODO.txt	2008-04-30 16:31:38 UTC (rev 7565)
@@ -0,0 +1,4 @@
+* merge all except content when the generic factory is invoked with an instance
+* interceptors on client interfaces
+* take into account .cfg Tree for instantiating a controller (see OO)
+* interceptors on control interfaces (see OO)

Added: trunk/fractaladl/juliac/opt/merge-all/pom.xml (0 => 7565)


--- trunk/fractaladl/juliac/opt/merge-all/pom.xml	                        (rev 0)
+++ trunk/fractaladl/juliac/opt/merge-all/pom.xml	2008-04-30 16:31:38 UTC (rev 7565)
@@ -0,0 +1,29 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.objectweb.fractal.fractaladl.juliac.opt</groupId>
+        <artifactId>parent</artifactId>
+        <version>1.3-SNAPSHOT</version>
+    </parent>
+
+  <groupId>org.objectweb.fractal.fractaladl.juliac</groupId>
+  <artifactId>merge-all</artifactId>
+  <packaging>jar</packaging>
+  <name>Juliac Optimization Level MERGE_ALL</name>
+ 
+    <dependencies>
+        <dependency>
+            <groupId>org.objectweb.fractal.fractaladl.juliac</groupId>
+            <artifactId>compiler</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.objectweb.fractal.julia</groupId>
+            <artifactId>julia-mixins</artifactId>
+            <version>2.5.2</version>
+        </dependency>
+    </dependencies>
+
+</project>

Copied: trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/AbstractProxyCtClassGenerator.java (from rev 7562, trunk/fractaladl/juliac/compiler/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/AbstractProxyCtClassGenerator.java) (0 => 7565)


--- trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/AbstractProxyCtClassGenerator.java	                        (rev 0)
+++ trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/AbstractProxyCtClassGenerator.java	2008-04-30 16:31:38 UTC (rev 7565)
@@ -0,0 +1,163 @@
+/***
+ * Juliac
+ * Copyright (C) 2007 INRIA, France Telecom, USTL
+ *
+ * This library 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 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Contact: Lionel.Seinturier@xxxxxxx
+ *
+ * Author: Lionel Seinturier
+ */
+
+package org.objectweb.fractal.adl.juliac.opt.mergeall;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedClass;
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedClassFactory;
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedClassFactoryItf;
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedMethod;
+import org.objectweb.fractal.api.type.InterfaceType;
+
+import spoon.reflect.CoreFactory;
+import spoon.reflect.Factory;
+import spoon.reflect.code.CtBlock;
+import spoon.reflect.code.CtCodeSnippetStatement;
+import spoon.reflect.declaration.CtClass;
+import spoon.reflect.declaration.CtMethod;
+import spoon.reflect.declaration.CtParameter;
+import spoon.reflect.declaration.ModifierKind;
+import spoon.reflect.factory.ClassFactory;
+import spoon.reflect.factory.MethodFactory;
+import spoon.reflect.factory.TypeFactory;
+import spoon.reflect.reference.CtTypeReference;
+
+/**
+ * Super class for code generators which generate proxy {@link CtClass}es for
+ * the methods defined in a specified {@link InterfaceType}.
+ * 
+ * @author Lionel Seinturier <Lionel.Seinturier@xxxxxxx>
+ */
+public abstract class AbstractProxyCtClassGenerator {
+        
+    // ----------------------------------------------------------------------
+    // Protected methods to be defined by subclasses
+    // ----------------------------------------------------------------------
+    
+    /**
+     * Return the array of statement code snippets associated to the specified
+     * method.
+     */
+    abstract protected String[] getBodySnippets( UnifiedMethod m );
+
+    /**
+     * Return the name of the target class.
+     */
+    abstract protected String getTargetClassName( InterfaceType it );
+    
+    
+    // ----------------------------------------------------------------------
+    // Regular constructor and methods
+    // ----------------------------------------------------------------------
+    
+    public AbstractProxyCtClassGenerator( Factory factory ) {
+        this.factory = factory;
+    }
+    
+    protected Factory factory;
+    
+    /**
+     * Generate a proxy class for the methods defined in the specified {@link
+     * InterfaceType}.
+     * 
+     * @param it  the corresponding interface type
+     * @return    the generated class
+     */
+    public CtClass<?> generateCtClass( InterfaceType it ) {
+        
+        ClassFactory cf = factory.Class();
+        MethodFactory mf = factory.Method();
+        CoreFactory coref = factory.Core();
+        TypeFactory tf = factory.Type();
+        
+        String targetClassName = getTargetClassName(it);
+        CtClass<?> ctclass = cf.create(targetClassName);
+        
+        /*
+         * Let the created class implement the Java interface defined in the
+         * interface type.
+         */
+        UnifiedClassFactoryItf ucf = UnifiedClassFactory.get();
+        UnifiedClass cl = ucf.create(it.getFcItfSignature());
+        CtTypeReference<?> ittr = tf.createReference(cl.getName());
+        ctclass.getSuperInterfaces().add(ittr);
+        
+        /*
+         * Iterate over the array of methods defined in the interface type.
+         */
+        UnifiedMethod[] methods = cl.getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            
+            UnifiedMethod m = methods[i];
+            String mname = m.getName();
+            UnifiedClass[] ptypes = m.getParameterTypes();
+            UnifiedClass rtype = m.getReturnType();
+            UnifiedClass[] etypes = m.getExceptionTypes();
+            
+            Set<ModifierKind> mods = new HashSet<ModifierKind>();
+            mods.add(ModifierKind.PUBLIC);
+            CtTypeReference<?> rctype = tf.createReference(rtype.getName());
+            
+            // Parameters
+            List<CtParameter<?>> params = new ArrayList<CtParameter<?>>();
+            int p = 0;
+            for (UnifiedClass ptype : ptypes) {
+                CtTypeReference<?> pctype = tf.createReference(ptype.getName());
+                String pname = "arg"+p;
+                p++;
+                CtParameter<?> param = mf.createParameter(null, pctype, pname);
+                params.add(param);
+            }
+            
+            // Exceptions
+            Set<CtTypeReference<? extends Throwable>> ectype =
+                new HashSet<CtTypeReference<? extends Throwable>>();
+            for (UnifiedClass etype : etypes) {
+                CtTypeReference<?> tr =
+                    tf.createReference(etype.getName());
+                ectype.add((CtTypeReference<? extends Throwable>)tr);
+            }
+            
+            // Body
+            CtBlock<?> body = factory.Core().createBlock();
+            String[] snippets = getBodySnippets(m);
+            for (String snippet : snippets) {
+                CtCodeSnippetStatement ctsnippet = coref.createCodeSnippetStatement();
+                ctsnippet.setValue(snippet);
+                body.insertEnd(ctsnippet);
+            }
+
+            // Method creation and insertion
+            CtMethod<?> ctmethod =
+                mf.create(ctclass,mods,rctype,mname,params,ectype,(CtBlock)body);
+            ctclass.getMethods().add(ctmethod);
+        }
+
+        return ctclass;
+    }
+}

Copied: trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/ContentBindingControllerCtClassGenerator.java (from rev 7562, trunk/fractaladl/juliac/compiler/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/ContentBindingControllerCtClassGenerator.java) (0 => 7565)


--- trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/ContentBindingControllerCtClassGenerator.java	                        (rev 0)
+++ trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/ContentBindingControllerCtClassGenerator.java	2008-04-30 16:31:38 UTC (rev 7565)
@@ -0,0 +1,111 @@
+/***
+ * Juliac
+ * Copyright (C) 2007 INRIA, France Telecom, USTL
+ *
+ * This library 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 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Contact: Lionel.Seinturier@xxxxxxx
+ *
+ * Author: Lionel Seinturier
+ */
+
+package org.objectweb.fractal.adl.juliac.opt.mergeall;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedClass;
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedMethod;
+import org.objectweb.fractal.api.type.InterfaceType;
+
+import spoon.reflect.Factory;
+
+/**
+ * This class generates an implementation of the {@link
+ * org.objectweb.fractal.julia.control.binding.ContentBindingController}
+ * interface.
+ * 
+ * When the content of a component and the controllers are merged, the
+ * implementation of the {@link
+ * org.objectweb.fractal.api.control.BindingController} interface assumes that
+ * an implementation of the ContentBindingController interface is available.
+ * The class which is generated here provides such an implementation.
+ * 
+ * The generated class calls the BindingController methods which are supposed to
+ * be defined in the super class.
+ * 
+ * @author Lionel Seinturier <Lionel.Seinturier@xxxxxxx>
+ */
+public class ContentBindingControllerCtClassGenerator
+extends AbstractProxyCtClassGenerator {
+    
+    public ContentBindingControllerCtClassGenerator( Factory factory ) {
+        super(factory);
+    }
+    
+    /**
+     * Return the name of the target class.
+     */
+    protected String getTargetClassName( InterfaceType it ) {
+        String targetClassName =
+            it.getFcItfSignature()+"ContentBindingControllerMixin";
+        return targetClassName;
+    }
+
+    /**
+     * Return the array of statement code snippets associated to the specified
+     * method.
+     */
+    protected String[] getBodySnippets( UnifiedMethod m ) {
+
+        UnifiedClass[] ptypes = m.getParameterTypes();
+        UnifiedClass rtype = m.getReturnType();
+
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        if( ! rtype.getName().equals("void") ) {
+            pw.print("return ");
+        }
+        pw.print("super.");
+        
+        String name = m.getName();
+        if( name.equals("listFcContent") ) {
+            pw.print("listFc");
+        }
+        else if( name.equals("lookupFcContent") ) {
+            pw.print("lookupFc");
+        }
+        else if( name.equals("bindFcContent") ) {
+            pw.print("bindFc");
+        }
+        else if( name.equals("unbindFcContent") ) {
+            pw.print("unbindFc");
+        }
+        else {
+            throw new IllegalArgumentException(name);
+        }
+        
+        pw.print("(");
+        for (int j = 0; j < ptypes.length; j++) {
+            if(j!=0)  pw.print(", ");
+            pw.print("arg");
+            pw.print(j);
+        }
+        pw.println(")");
+        pw.close();
+        String snippet = sw.toString();
+        return new String[]{snippet};
+    }    
+}

Copied: trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/ContentCallCtClassGenerator.java (from rev 7562, trunk/fractaladl/juliac/compiler/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/ContentCallCtClassGenerator.java) (0 => 7565)


--- trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/ContentCallCtClassGenerator.java	                        (rev 0)
+++ trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/ContentCallCtClassGenerator.java	2008-04-30 16:31:38 UTC (rev 7565)
@@ -0,0 +1,84 @@
+/***
+ * Juliac
+ * Copyright (C) 2007 INRIA, France Telecom, USTL
+ *
+ * This library 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 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Contact: Lionel.Seinturier@xxxxxxx
+ *
+ * Author: Lionel Seinturier
+ */
+
+package org.objectweb.fractal.adl.juliac.opt.mergeall;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedClass;
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedMethod;
+import org.objectweb.fractal.api.type.InterfaceType;
+
+import spoon.reflect.Factory;
+
+/**
+ * This class generates methods which delegate invocations to
+ * <code>super</code>. These methods are used in classes generated by {@link
+ * FCSourceCodeGenerator} to invoke the content class.
+ * 
+ * @author Lionel Seinturier <Lionel.Seinturier@xxxxxxx>
+ */
+public class ContentCallCtClassGenerator
+extends AbstractProxyCtClassGenerator {
+    
+    public ContentCallCtClassGenerator( Factory factory ) {
+        super(factory);
+    }
+    
+    /**
+     * Return the name of the target class.
+     */
+    protected String getTargetClassName( InterfaceType it ) {
+        return "ContentCallImpl";
+    }
+
+    /**
+     * Return the array of statement code snippets associated to the specified
+     * method.
+     */
+    protected String[] getBodySnippets( UnifiedMethod m ) {
+
+        UnifiedClass[] ptypes = m.getParameterTypes();
+        UnifiedClass rtype = m.getReturnType();
+
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        if( ! rtype.getName().equals("void") ) {
+            pw.print("return ");
+        }
+        pw.print("super.");
+        pw.print(m.getName());
+        pw.print("(");
+        for (int j = 0; j < ptypes.length; j++) {
+            if(j!=0)  pw.print(", ");
+            pw.print("arg");
+            pw.print(j);
+        }
+        pw.println(")");
+        pw.close();
+        String snippet = sw.toString();
+        return new String[]{snippet};
+    }
+    
+}

Copied: trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/FCMergeAllSourceCodeGenerator.java (from rev 7562, trunk/fractaladl/juliac/compiler/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/FCMergeAllSourceCodeGenerator.java) (0 => 7565)


--- trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/FCMergeAllSourceCodeGenerator.java	                        (rev 0)
+++ trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/FCMergeAllSourceCodeGenerator.java	2008-04-30 16:31:38 UTC (rev 7565)
@@ -0,0 +1,690 @@
+/***
+ * Juliac
+ * Copyright (C) 2007 INRIA, France Telecom, USTL
+ *
+ * This library 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 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Contact: Lionel.Seinturier@xxxxxxx
+ *
+ * Author: Lionel Seinturier
+ */
+
+package org.objectweb.fractal.adl.juliac.opt.mergeall;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.objectweb.fractal.adl.juliac.ControllerDesc;
+import org.objectweb.fractal.adl.juliac.InitializerSourceCodeGenerator;
+import org.objectweb.fractal.adl.juliac.Juliac;
+import org.objectweb.fractal.adl.juliac.JuliacLoader;
+import org.objectweb.fractal.adl.juliac.MembraneDesc;
+import org.objectweb.fractal.adl.juliac.NoSuchControllerDescriptorException;
+import org.objectweb.fractal.adl.juliac.OptLevelDefaultSourceCodeGenerator;
+import org.objectweb.fractal.adl.juliac.SourceCodeGenerator;
+import org.objectweb.fractal.adl.juliac.Utils;
+import org.objectweb.fractal.adl.juliac.proxy.InterceptorSourceCodeGenerator;
+import org.objectweb.fractal.adl.juliac.proxy.MergedInterceptorsSourceCodeGenerator;
+import org.objectweb.fractal.adl.juliac.spoon.MixinClassGenerator;
+import org.objectweb.fractal.adl.juliac.spoon.SpoonHelper;
+import org.objectweb.fractal.adl.juliac.spoon.SpoonSupportImpl;
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedClass;
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedClassFactory;
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedClassFactoryItf;
+import org.objectweb.fractal.adl.juliac.ucf.UnifiedMethod;
+import org.objectweb.fractal.adl.juliac.visit.ClassSourceCodeVisitor;
+import org.objectweb.fractal.adl.juliac.visit.FileSourceCodeVisitor;
+import org.objectweb.fractal.adl.juliac.visit.FileSourceCodeWriter;
+import org.objectweb.fractal.adl.juliac.visit.MethodSourceCodeVisitor;
+import org.objectweb.fractal.api.NoSuchInterfaceException;
+import org.objectweb.fractal.api.control.BindingController;
+import org.objectweb.fractal.api.control.IllegalBindingException;
+import org.objectweb.fractal.api.control.IllegalLifeCycleException;
+import org.objectweb.fractal.api.type.ComponentType;
+import org.objectweb.fractal.api.type.InterfaceType;
+import org.objectweb.fractal.julia.BasicControllerMixin;
+import org.objectweb.fractal.julia.control.binding.BasicBindingControllerMixin;
+import org.objectweb.fractal.julia.control.binding.ContentBindingController;
+import org.objectweb.fractal.julia.loader.BasicLoader;
+import org.objectweb.fractal.julia.loader.Tree;
+import org.objectweb.fractal.julia.type.BasicInterfaceType;
+
+import spoon.reflect.Factory;
+import spoon.reflect.declaration.CtClass;
+import spoon.reflect.factory.ClassFactory;
+import spoon.reflect.reference.CtTypeReference;
+
+/**
+ * This class generates the source code associated to Fractal components.
+ * Two classes are generated: the membrane implementation and the
+ * initializer implementation.
+ * 
+ * The membrane implementation is generated by merging the content, the
+ * interceptors and the controllers.
+ * 
+ * @author Lionel Seinturier <Lionel.Seinturier@xxxxxxx>
+ */
+public class FCMergeAllSourceCodeGenerator extends OptLevelDefaultSourceCodeGenerator {
+    
+    public FCMergeAllSourceCodeGenerator() {
+        super();
+    }
+
+    // -----------------------------------------------------------------------
+    // Implementation of the FCSourceCodeGenerator interface
+    // -----------------------------------------------------------------------
+
+    /**
+     * Initialize this generator.
+     * 
+     * The initialization process is kept separated from the constructor in
+     * order to be able to customize the julia.config system property.
+     */
+    @Override
+    public void init() throws IOException {
+        JuliacLoader loader = Juliac.get().getJuliacLoader();
+        loader.loadConfigFile(BasicLoader.DEFAULT_CONFIGURATION);
+        super.init();
+    }
+
+    // -----------------------------------------------------------------------
+    // Implementation of abstract methods defined in super classes
+    // -----------------------------------------------------------------------
+    
+    /**
+     * Return the source code generators for the initializer classes associated
+     * with this component source code generator.
+     */
+    protected InitializerSourceCodeGenerator[] getInitializerSourceCodeGenerators() {
+        return
+            new InitializerSourceCodeGenerator[]{
+                new InitializerMergeAllSourceCodeGenerator()
+            };
+    }
+    
+    /**
+     * Generate the implementation of the membrane associated to a Fractal
+     * component.
+     * 
+     * @param ct                the component type
+     * @param ctrldesc          the component controller descriptor
+     * @param contentClassName  the name of the component content class
+     * @param context           contextual information
+     * @return                  data about the membrane implementation
+     */
+    public MembraneDesc generateMembraneImpl(
+        ComponentType ct, String ctrldesc, String contentClassName,
+        Map<?,?> context )
+    throws IOException, NoSuchControllerDescriptorException {
+        
+        String membraneClassName =
+            Utils.getMembraneClassName(ctrldesc,contentClassName);        
+
+        /*
+         * Generate business and control interface implementations.
+         */
+        InterfaceType[] its = ct.getFcInterfaceTypes();
+        generateInterfaceImpl(its,ctrldesc);
+        InterfaceType[] membraneits = getMembraneType(ctrldesc,context);
+        generateInterfaceImpl(membraneits,ctrldesc);
+        
+        /*
+         * Prepare a membrane descriptor.
+         */
+        MembraneDesc md = new MembraneDesc(null,ctrldesc,membraneits,null);
+
+        /*
+         * Retrieve the list of interceptor and control layers.
+         * Interceptor layers are the last ones. Last layers are executed first.
+         */
+        List<CtClass<?>> layers = new ArrayList<CtClass<?>>();
+        List<CtClass<?>> interceptorLayers = getInterceptorLayers(ct,context,md);
+        List<CtClass<?>> controlLayers = getControlLayers(ct, ctrldesc, context);
+        layers.addAll(controlLayers);
+        layers.addAll(interceptorLayers);
+        
+        /*
+         * Layers specific to components with a content.
+         */
+        if( contentClassName != null ) {
+            
+            // Perform checks on the content class
+            checkContentClass( contentClassName );
+            
+            List<CtClass<?>> contentCallLayers = getContentCallLayers(ct);
+            layers.addAll(0,contentCallLayers);            
+
+            /*
+             * Membranes such as primitives, assume that the content provides an
+             * implementation of the BindingController interface. If this is the
+             * case, add the layer which will call this implementation.
+             */
+            CtClass<?> contentBCLayer =
+                getContentBindingControllerLayer(ct, context, layers);
+            if( contentBCLayer != null ) {
+                layers.add(contentBCLayer);
+            }
+        }
+        
+        /*
+         * Generate and register the class by merging the content, controllers
+         * and interceptors.
+         * Avoid duplicate generation.
+         */
+        Juliac jc = Juliac.get();
+        if( ! jc.hasBeenGenerated(membraneClassName) ) {
+            
+            SpoonSupportImpl spoon = (SpoonSupportImpl) jc.getSpoon();
+            Factory factory = spoon.getSpoonFactory();
+            MixinClassGenerator spmcg = new MixinClassGenerator(factory);
+
+            CtClass<?>[] ctLayers = (CtClass<?>[])
+                layers.toArray(new CtClass<?>[layers.size()]);
+            CtClass<?> generated = spmcg.generate(membraneClassName,ctLayers);
+            
+            /*
+             * Set the superclass to be the content class.
+             */
+            if( contentClassName != null ) {
+                ClassFactory cf = factory.Class();
+                CtTypeReference<?> ref = cf.createReference(contentClassName);
+                generated.setSuperclass(ref);
+            }
+            
+            /*
+             * Dump the generated class.
+             */
+            spoon.generateSourceCode(generated);        
+        }
+        
+        /*
+         * Prepare a membrane descriptor.
+         */
+        List<ControllerDesc> ctrlDescs = new ArrayList<ControllerDesc>();
+        ctrlDescs.add(new ControllerDesc(membraneClassName,null,null));
+        MembraneDesc newmd = new MembraneDesc(null,ctrldesc,membraneits,ctrlDescs);
+        newmd.setInterceptorSourceCodeGenerator(md.getInterceptorSourceCodeGenerator());
+
+        /*
+         * Set the interceptor source code generator for latter use in the
+         * generation of the initializer class for generating interceptors on
+         * client interfaces (interceptors on server interfaces are merged).
+         */
+        setInterceptorSourceCodeGenerator(context, newmd);
+        
+        return newmd;
+    }
+
+    /**
+     * Generate the implementation of interceptors associated to the specified
+     * component type and the specified controller desc.
+     */
+    @Override
+    protected void setInterceptorSourceCodeGenerator(
+        Map<?,?> context, MembraneDesc membraneDesc )
+    throws NoSuchControllerDescriptorException {
+        
+        // Get the interceptor source code generators from the Julia config file
+        boolean mergeable = false;
+        String ctrldesc = membraneDesc.getDescriptor();
+        InterceptorSourceCodeGenerator[] scgs =
+            getInterceptorSourceCodeGenerator( ctrldesc, context, mergeable );
+        if( scgs == null ) {
+            // No interceptor
+            return;
+        }
+        
+        // Prepare a MergedInterceptorsSourceCodeGenerator
+        InterceptorSourceCodeGenerator mpscg =
+            new MergedInnerInterceptorsSourceCodeGenerator(scgs);
+        membraneDesc.setInterceptorSourceCodeGenerator(mpscg);
+    }
+    
+    /**
+     * This class is a {@link InterceptorSourceCodeGenerator} which aggregates
+     * the source code generated by several {@link
+     * InterceptorSourceCodeGenerator}s.
+     * 
+     * The generated class has an empty package name which makes it suitable for
+     * embedding as an inner class.
+     * 
+     * @author Lionel Seinturier <Lionel.Seinturier@xxxxxxx>
+     */
+    static class MergedInnerInterceptorsSourceCodeGenerator
+    extends MergedInterceptorsSourceCodeGenerator {
+        
+        public MergedInnerInterceptorsSourceCodeGenerator(InterceptorSourceCodeGenerator[] iscgs) {
+            super(iscgs);
+        }
+
+        public MergedInnerInterceptorsSourceCodeGenerator(
+            InterceptorSourceCodeGenerator[] iscgs,
+            InterfaceType it, MembraneDesc membraneDesc, boolean mergeable ) {
+            super(iscgs,it,membraneDesc,mergeable);
+        }
+        
+        /**
+         * Return the name of the class generated by this generator.
+         * Return a name with an empty package name.
+         */
+        @Override
+        public String getTargetClassName() {
+            String javaItfSignature = it.getFcItfSignature();
+            int lastdot = javaItfSignature.lastIndexOf('.');
+            String name =
+                (lastdot==-1) ?
+                javaItfSignature :
+                javaItfSignature.substring(lastdot+1);
+            String suffix = getClassNameSuffix();
+            String targetClassname = name + suffix;
+            return targetClassname;
+        }
+    }
+    
+    
+    // ------------------------------------------------------------------
+    // Implementation specific
+    // ------------------------------------------------------------------
+    
+    /**
+     * Perform checks on the content class.
+     */
+    protected void checkContentClass( String contentClassName )
+    throws IOException {
+        
+        /*
+         * Check that the binding control methods in the content class declare
+         * in their throws clause NoSuchInterfaceException,
+         * IllegalBindingException and IllegalLifeCycleException. In the merge
+         * all mode, the membrane class extends the content class, the Java
+         * compiler complains if the content class does not throw these
+         * exceptions.
+         * 
+         * If the content class does not throw these exceptions, report a
+         * warning and generate runtime exceptions.
+         */
+
+        UnifiedClassFactoryItf ucf = UnifiedClassFactory.get();
+        UnifiedClass bcuc = ucf.create(BindingController.class.getName());
+        UnifiedClass cl = ucf.create(contentClassName);
+        if( ! bcuc.isAssignableFrom(cl) ) {
+            return;
+        }
+        
+        UnifiedMethod mbind=null, mlookup=null, munbind=null;
+        try {
+            mbind = cl.getMethod("bindFc", new Class<?>[]{String.class,Object.class});
+            mlookup = cl.getMethod("lookupFc", new Class<?>[]{String.class});
+            munbind = cl.getMethod("unbindFc", new Class<?>[]{String.class});
+        } 
+        catch (NoSuchMethodException e) {
+            // As cl implements BindingController, these methods should be found
+            throw new RuntimeException(e);
+        }
+        
+        UnifiedMethod[] meths = new UnifiedMethod[]{mbind,mlookup,munbind};
+        checkMethodsThrowsException(contentClassName, meths, NoSuchInterfaceException.class);
+        
+        meths = new UnifiedMethod[]{mbind,munbind};
+        checkMethodsThrowsException(contentClassName, meths, IllegalBindingException.class);
+        checkMethodsThrowsException(contentClassName, meths, IllegalLifeCycleException.class);
+    }
+    
+    /**
+     * Check that the specified methods declare the specified exception.
+     * 
+     * If this is not the case, generate the source code of a {@link
+     * RuntimeException} for the specified exception.
+     */
+    private void checkMethodsThrowsException(
+        String contentClassName, UnifiedMethod[] meths, Class<? extends Throwable> e )
+    throws IOException {
+
+        String ms = "";
+        for (UnifiedMethod meth : meths) {
+            boolean t = checkThrowsException(meth,e);
+            if(!t) ms+= meth.getName()+" ";
+        }
+        
+        if( ms.length() > 0 ) {
+            String msg =
+                "Method(s) "+ms+"in class "+contentClassName+ " should throw "+
+                e.getName()+". This exception will be weaken to a RuntimeException.";
+            Juliac.reportWarning(msg);
+
+            Juliac jc = Juliac.get();
+            String targetClassName = e.getName();
+            SourceCodeGenerator scg =
+                new RuntimeExceptionSourceCodeGenerator(targetClassName);
+            jc.generateSourceCodeOverride(scg);
+        }
+    }
+    
+    /**
+     * A {@link SourceCodeGenerator} for generating {@link RuntimeException}s.
+     * 
+     * @author Lionel Seinturier <Lionel.Seinturier@xxxxxxx>
+     */
+    private static class RuntimeExceptionSourceCodeGenerator implements SourceCodeGenerator {
+        
+        private String targetClassName;
+        
+        /**
+         * @param targetClassName  the name of the exception class
+         */
+        public RuntimeExceptionSourceCodeGenerator( String targetClassName ) {
+            this.targetClassName = targetClassName;
+        }
+        
+        public String getTargetClassName() { return targetClassName;}
+
+        public void generate( FileSourceCodeVisitor fv ) {
+            
+            int lastdot = targetClassName.lastIndexOf('.');
+            String packagename = (lastdot==-1) ? null : targetClassName.substring(0,lastdot);
+            
+            if( packagename != null ) {
+                fv.visitPackageName(packagename);
+            }
+            
+            ClassSourceCodeVisitor cv = fv.visitPublicClass();
+            generate(cv);
+        }
+        
+        public void generate( ClassSourceCodeVisitor cv ) {
+
+            int lastdot = targetClassName.lastIndexOf('.');
+            String classname = targetClassName.substring(lastdot+1);
+            
+            cv.visit(Modifier.PUBLIC, classname, null, "RuntimeException", null);
+            
+            MethodSourceCodeVisitor mv =
+                cv.visitConstructor(
+                    Modifier.PUBLIC, null, new String[]{"String msg"}, null );
+            mv.visitBegin();
+            mv.visitln("    super(msg);");
+            mv.visitEnd();
+            
+            cv.visitEnd();
+        }
+    }
+    
+    /**
+     * Return true if the specified method declares the specified exception in
+     * its throws clause.
+     */
+    private boolean checkThrowsException( UnifiedMethod m, Class<? extends Throwable> e ) {
+        
+        UnifiedClassFactoryItf ucf = UnifiedClassFactory.get();
+        UnifiedClass euc = ucf.create(e.getName());
+        UnifiedClass[] exceptions = m.getExceptionTypes();
+        for (UnifiedClass exception : exceptions) {
+            if( euc.isAssignableFrom(exception) ) {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+    
+    /**
+     * Return the list of mixin layers which call the content class (super
+     * call).
+     */
+    private List<CtClass<?>> getContentCallLayers( ComponentType ct ) {
+        
+        Juliac jc = Juliac.get();
+        SpoonSupportImpl spoon = (SpoonSupportImpl) jc.getSpoon();
+        Factory factory = spoon.getSpoonFactory();
+        
+        ContentCallCtClassGenerator ccscg =
+            new ContentCallCtClassGenerator(factory);
+        
+        List<CtClass<?>> contentCallLayers = new ArrayList<CtClass<?>>();
+        InterfaceType[] its = ct.getFcInterfaceTypes();
+        for (InterfaceType it : its) {
+            
+            if( it.isFcClientItf() ) {
+                continue;   // Skip client interface types
+            }
+
+            CtClass<?> contentCallLayer = ccscg.generateCtClass(it);
+            contentCallLayers.add(contentCallLayer);            
+        }
+        
+        return contentCallLayers;
+    }
+    
+    /**
+     * Return the list of mixin layers which implement the interceptor code for
+     * the specified component type and the specified membrane descriptor.
+     */
+    private List<CtClass<?>> getInterceptorLayers(
+        ComponentType ct, Map<?,?> context, MembraneDesc membraneDesc )
+    throws IOException, NoSuchControllerDescriptorException {
+        
+        List<CtClass<?>> interceptorLayers = new ArrayList<CtClass<?>>();
+
+        String ctrldesc = membraneDesc.getDescriptor();
+        InterceptorSourceCodeGenerator[] scgs =
+            getInterceptorSourceCodeGenerator(ctrldesc, context, true);
+        if( scgs == null ) {
+            // No interceptor
+            return interceptorLayers;
+        }
+        
+        Juliac jc = Juliac.get();
+        SpoonSupportImpl spoon = (SpoonSupportImpl) jc.getSpoon();
+        Factory factory = spoon.getSpoonFactory();
+        
+        for (int i = 0; i < scgs.length; i++) {
+            scgs[i].setMembraneDesc(membraneDesc);
+            
+            /*
+             * The set of interface signatures for which an interception layer
+             * has already been generated.
+             */ 
+            Set<String> signatures = new HashSet<String>();
+            
+            InterfaceType[] its = ct.getFcInterfaceTypes();
+            for (InterfaceType it : its) {
+                
+                // Skip client and attribute-controller            
+                if( it.isFcClientItf() ||
+                    it.getFcItfName().equals("attribute-controller") ) {
+                    continue;
+                }
+                
+                // Skip if a layer has already been generated for this signature
+                String signature = it.getFcItfSignature();
+                if( signatures.contains(signature) ) {
+                    continue;
+                }
+
+                scgs[i].setInterfaceType(it);
+                String targetClassname = scgs[i].getTargetClassName();
+                
+                StringWriter sw = new StringWriter();
+                PrintWriter pw = new PrintWriter(sw);
+                FileSourceCodeVisitor fw = new FileSourceCodeWriter(pw);
+                scgs[i].generate(fw);
+                pw.close();
+                sw.close();
+                String interceptorSnippet = sw.toString();
+                
+                CtClass<?> interceptorLayer =
+                    SpoonHelper.getCtClass4ClassSnippet(
+                        factory, targetClassname, interceptorSnippet);
+                interceptorLayers.add(interceptorLayer);
+                signatures.add(signature);
+            }
+        }        
+        
+        return interceptorLayers;
+    }
+    
+    /**
+     * Return the layers associated to the specified control descriptor.
+     */
+    private List<CtClass<?>> getControlLayers(
+        ComponentType ct, String ctrlDesc, Map<?,?> context )
+    throws NoSuchControllerDescriptorException {
+        
+        List<String> layers = getMembraneImplLayers(ctrlDesc,context);
+
+        if( layers.contains(BasicControllerMixin.class.getName()) ) {
+            /*
+             * Julia assumes that BasicControllerMixin is always the first layer
+             * for controller. This layer does not propagate calls to
+             * initFcController. Julia reports an error if one tries to modify
+             * this (not super method). The policy implemented by
+             * MembraneMixinLayersDef for managing duplicate layers may lead to
+             * cases where BasicControllerMixin is not the first layer if it
+             * appears several times (only the last occurrence is kept). In
+             * order to deal with such a situation, reintroduce
+             * BasicControllerMixin as the first layer.
+             */
+            layers.remove(BasicControllerMixin.class.getName());
+            layers.add(0,BasicControllerMixin.class.getName());
+        }
+        
+        Juliac jc = Juliac.get();
+        SpoonSupportImpl spoon = (SpoonSupportImpl) jc.getSpoon();
+        Factory factory = spoon.getSpoonFactory();
+        List<CtClass<?>> ctLayers = SpoonHelper.toCtClass(factory,layers);
+        
+        return ctLayers;
+    }
+    
+    /**
+     * Control membranes such as primitive expect that the content class
+     * provides an implementation for the {@link BindingController} interface.
+     * When this is the case, a layer implementing the {@link
+     * ContentBindingController} must be provided. This method returns this
+     * layer or null if the layer is not needed.
+     */
+    protected CtClass<?> getContentBindingControllerLayer(
+        ComponentType ct, Map<?,?> context, List<CtClass<?>> layers ) {
+        
+        if( ! isAssignableFrom(layers,BindingController.class) ||
+            layers.contains(BasicBindingControllerMixin.class) ||
+            ! containsClientInterfaceType(ct) ) {
+            
+            return null;
+        }
+        
+        /*
+         * ContentBindingControllerSourceCodeGenerator generates a default
+         * implementation of the ContentBindingController interface. This
+         * implementation is expected by control membranes such as
+         * primitives, which expect that their content class will provides
+         * an implementation of the BindingController interface (if the
+         * component defines a client interface).
+         */
+
+        Juliac jc = Juliac.get();
+        SpoonSupportImpl spoon = (SpoonSupportImpl) jc.getSpoon();
+        Factory factory = spoon.getSpoonFactory();
+        ContentBindingControllerCtClassGenerator cbcscg =
+            new ContentBindingControllerCtClassGenerator(factory);
+        
+        InterfaceType it =
+            new BasicInterfaceType(
+                "cbci",ContentBindingController.class.getName(),
+                false,false,false);
+        CtClass<?> generated = cbcscg.generateCtClass(it);
+        return generated;
+    }
+    
+    /**
+     * Return true if the specified component type defines a client interface.
+     */
+    private static boolean containsClientInterfaceType( ComponentType ct ) {
+        InterfaceType[] its = ct.getFcInterfaceTypes();
+        for (InterfaceType it : its) {
+            if( it.isFcClientItf() ) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    /**
+     * Return true if the specified interface is assignable from one of the
+     * classes of the specified list.
+     */
+    private boolean isAssignableFrom( List<CtClass<?>> layers, Class<?> itf ) {
+        
+        Juliac jc = Juliac.get();
+        SpoonSupportImpl spoon = (SpoonSupportImpl) jc.getSpoon();
+        Factory factory = spoon.getSpoonFactory();
+        CtTypeReference<?> itftr = factory.Type().createReference(itf);
+        
+        for (CtClass<?> layer : layers) {
+            CtTypeReference<?> layertr = layer.getReference();
+            if( itftr.isAssignableFrom(layertr) ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return the list of mixin layers which are associated with the specified
+     * controller descriptor.
+     */
+    private List<String> getMembraneImplLayers( String ctrlDesc, Map<?,?> context )
+    throws NoSuchControllerDescriptorException {
+        
+        Tree[] ctrlTrees = getCtrlImplTrees(ctrlDesc, context);
+
+        List<String> layers = new ArrayList<String>();
+        for (Tree ctrlTree : ctrlTrees) {
+            
+            if( ctrlTree.getSize() == 0 ) {
+                /*
+                 * Special case where the name of the controller implementation
+                 * is directly specified (not generated with
+                 * MixinClassGenerartor).
+                 */
+                String name = ctrlTree.toString();
+                layerInsert(layers, name);
+            }
+            else {
+                Tree t = ctrlTree.getSubTree(0);
+                Tree[] ts = t.getSubTrees();
+                
+                /*
+                 * Skip
+                 * [0]: org.objectweb.fractal.julia.asm.MixinClassGenerator
+                 * [1]: class name (e.g. NameControllerImpl)
+                 */
+                for (int i = 2; i < ts.length; i++) {
+                    String name = ts[i].toString();
+                    layerInsert(layers, name);
+                }
+            }
+        }
+        
+        return layers;
+    }
+}

Copied: trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/InitializerMergeAllSourceCodeGenerator.java (from rev 7562, trunk/fractaladl/juliac/compiler/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/InitializerMergeAllSourceCodeGenerator.java) (0 => 7565)


--- trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/InitializerMergeAllSourceCodeGenerator.java	                        (rev 0)
+++ trunk/fractaladl/juliac/opt/merge-all/src/main/java/org/objectweb/fractal/adl/juliac/opt/mergeall/InitializerMergeAllSourceCodeGenerator.java	2008-04-30 16:31:38 UTC (rev 7565)
@@ -0,0 +1,271 @@
+/***
+ * Juliac
+ * Copyright (C) 2007 INRIA, France Telecom, USTL
+ *
+ * This library 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 of the License, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Contact: Lionel.Seinturier@xxxxxxx
+ *
+ * Author: Lionel Seinturier
+ */
+
+package org.objectweb.fractal.adl.juliac.opt.mergeall;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.objectweb.fractal.adl.juliac.ControllerDesc;
+import org.objectweb.fractal.adl.juliac.InitializerSourceCodeGenerator;
+import org.objectweb.fractal.adl.juliac.Utils;
+import org.objectweb.fractal.adl.juliac.proxy.AttributeSourceCodeGenerator;
+import org.objectweb.fractal.adl.juliac.proxy.InterceptorSourceCodeGenerator;
+import org.objectweb.fractal.adl.juliac.proxy.ProxySourceCodeGenerator;
+import org.objectweb.fractal.adl.juliac.visit.ClassSourceCodeVisitor;
+import org.objectweb.fractal.adl.juliac.visit.MethodSourceCodeVisitor;
+import org.objectweb.fractal.api.Component;
+import org.objectweb.fractal.api.Interface;
+import org.objectweb.fractal.api.NoSuchInterfaceException;
+import org.objectweb.fractal.api.type.InterfaceType;
+import org.objectweb.fractal.julia.Controller;
+import org.objectweb.fractal.julia.InitializationContext;
+import org.objectweb.fractal.julia.type.BasicInterfaceType;
+
+/**
+ * Initializer generator for Fractal components with an object-oriented control
+ * membrane and with a optimization level where the content, the interceptors
+ * and the controllers are merged.
+ * 
+ * @author Lionel Seinturier <Lionel.Seinturier@xxxxxxx>
+ */
+public class InitializerMergeAllSourceCodeGenerator extends InitializerSourceCodeGenerator {
+
+    public String getTargetClassName() {
+        String ctrlDesc = membraneDesc.getDescriptor();
+        String contentClassName = Utils.getContentClassName(ctrlDesc,contentDesc);
+        String membraneClassName = Utils.getMembraneClassName(ctrlDesc,contentClassName);
+        String initializerClassName = Utils.getInitializerClassName(ct,membraneClassName);
+       return initializerClassName;
+    }
+    
+    @Override
+    protected void generateGetFcControllerDescMethod( MethodSourceCodeVisitor mv ) {
+        mv.visit  ("      return \"");
+        mv.visit  (membraneDesc.getDescriptor());
+        mv.visitln("\";");
+    }
+    
+    @Override
+    protected void generateGetFcContentDescMethod( MethodSourceCodeVisitor mv ) {
+        mv.visit  ("      return ");
+        mv.visit  (Utils.javaifyContentDesc(contentDesc).toString());
+        mv.visitln(";");
+    }
+
+    @Override
+    protected void generateNewFcInstanceMethod( MethodSourceCodeVisitor mv ) {
+        
+        List<ControllerDesc> ctrlDescs = membraneDesc.getCtrlDescs();
+        if( ctrlDescs.size() != 1 ) {
+            String msg = "membraneDesc.getCtrlDescs should return a list of size 1";
+            throw new IllegalArgumentException(msg);
+        }
+        
+        String membraneClassName = ctrlDescs.get(0).getImplName();
+        String ctrlDesc = membraneDesc.getDescriptor();
+        InterfaceType[] membraneits = membraneDesc.getCtrlItfTypes();
+        String contentClassName = Utils.getContentClassName(ctrlDesc,contentDesc);
+        
+        // Instantiate the content
+        mv.visitln("    Object content = new "+membraneClassName+"();");
+
+        // Check that the content class implements the server interfaces
+        generateContentChecks(mv);
+        
+        // Prepare an InitializationContext
+        mv.visitln("    "+InitializationContext.class.getName()+" ic = new "+InitializationContext.class.getName()+"();");
+        mv.visitln("    ic.controllers = new "+ArrayList.class.getName()+"();");
+        mv.visitln("    ic.interfaces = new "+HashMap.class.getName()+"();");
+        mv.visitln("    ic.internalInterfaces = new "+HashMap.class.getName()+"();");
+
+        // Instantiate the content
+        generateInitializationContextForContent(mv);
+                
+        // Content and controllers are merged
+        mv.visitln("    ic.controllers.add(content);");
+
+        // Component controller
+        InterfaceType compctrlit =
+            new BasicInterfaceType("component",Component.class.getName(),false,false,false);
+        ProxySourceCodeGenerator itfscg = getInterfaceSourceCodeGenerator(compctrlit);
+        String fcitfClassname = itfscg.getTargetClassName();
+        String itstring = Utils.javaify(compctrlit).toString();
+        mv.visit  ("    "+Interface.class.getName()+" proxy = ");
+        mv.visit  ("new "+fcitfClassname+"(");
+        mv.visitln("("+Component.class.getName()+")content,\"component\","+itstring+",false,content);");
+        mv.visit  ("    "+Component.class.getName()+" proxyForCompCtrl = ");
+        mv.visitln("("+Component.class.getName()+") proxy;");
+        mv.visitln("    ic.interfaces.put(\"component\",proxy);");
+
+        boolean attrimplgenerated = false;
+        
+        // Controllers other than the component controller
+        for (int i = 0; i < membraneits.length; i++) {
+            String itname = membraneits[i].getFcItfName();
+            if( ! itname.equals("component") ) {
+                itfscg = getInterfaceSourceCodeGenerator(membraneits[i]);
+                fcitfClassname = itfscg.getTargetClassName();
+                itstring = Utils.javaify(membraneits[i]).toString();
+                
+                // Control external interface
+                if( itname.equals("/cloneable-attribute-controller") ) {
+                    InterfaceType attrit = null;
+                    try {
+                        attrit = ct.getFcInterfaceType("attribute-controller");
+                    }
+                    catch (NoSuchInterfaceException e) {
+                        throw new RuntimeException(e);
+                    }
+                    ProxySourceCodeGenerator attrscg =
+                        new AttributeSourceCodeGenerator(attrit,null,false,null);
+                    String s = attrscg.getTargetClassName();
+                    mv.visitln("    Object attrimpl = new "+s+"();");
+                    attrimplgenerated = true;
+                }
+                mv.visit  ("    proxy = ");
+                mv.visit  ("new "+fcitfClassname+"(");
+                mv.visit  ("proxyForCompCtrl,\""+itname+"\","+itstring+",false,");
+                if( itname.equals("/cloneable-attribute-controller") ) {
+                    mv.visit("attrimpl");
+                }
+                else {
+                    mv.visit("content");
+                }
+                mv.visitln(");");
+                mv.visitln("    ic.interfaces.put(\""+itname+"\",proxy);");
+                
+                // Control internal interface
+                if( itname.equals("factory") ) {
+                    InterfaceType intit = Utils.newSymetricInterfaceType(membraneits[i]);
+                    itfscg = getInterfaceSourceCodeGenerator(intit);
+                    fcitfClassname = itfscg.getTargetClassName();
+                    itstring = Utils.javaify(intit).toString();
+                    mv.visit  ("    proxy = ");
+                    mv.visit  ("new "+fcitfClassname+"(");
+                    mv.visitln("proxyForCompCtrl,\""+itname+"\","+itstring+",true,content);");
+                    mv.visitln("    ic.internalInterfaces.put(\""+itname+"\",proxy);");
+                }
+            }
+        }
+        
+        // Component type
+        InterfaceType[] its = ct.getFcInterfaceTypes();
+        InterfaceType[] fullits = new InterfaceType[ membraneits.length + its.length ];
+        System.arraycopy(membraneits, 0, fullits, 0, membraneits.length);
+        System.arraycopy(its, 0, fullits, membraneits.length, its.length);
+        mv.visitln("    ic.type = "+Utils.javaify(fullits)+";");
+        
+        // Business interfaces
+        mv.visitln("    Object intercept = null;");
+        for (int i = 0; i < its.length; i++) {
+            
+            String itname = its[i].getFcItfName();
+            
+            if( its[i].isFcCollectionItf() ) {
+                // Julia naming convention for collection interfaces
+                itname = "/collection/" + itname;
+            }
+
+            // Interceptors
+            if( its[i].isFcClientItf() ) {
+                if( ! generateInterceptorCreation(mv,its[i],"content") ) {
+                    mv.visitln("    intercept = null;");
+                }
+            }
+            else {
+                mv.visit("    intercept = ");
+                mv.visit( contentClassName==null ? "null" : "content" );
+                mv.visitln(";");
+            }
+
+            // External interface
+            itfscg = getInterfaceSourceCodeGenerator(its[i]);
+            fcitfClassname = itfscg.getTargetClassName();
+            itstring = Utils.javaify(its[i]).toString();
+            mv.visit("    proxy = ");
+            mv.visit("new "+fcitfClassname+"(");
+            mv.visit("proxyForCompCtrl,\""+itname+"\","+itstring+",false,");
+            if( itname.equals("attribute-controller") && attrimplgenerated ) {
+                mv.visit("attrimpl");
+            }
+            else {
+                mv.visit("intercept");  // interceptor or content or null
+            }
+            mv.visitln(");");
+            mv.visitln("    ic.interfaces.put(\""+itname+"\",proxy);");
+            
+            // Internal interface
+            if( ! itname.equals("attribute-controller") ) {
+                InterfaceType intit = Utils.newSymetricInterfaceType(its[i]);
+                itfscg = getInterfaceSourceCodeGenerator(intit);
+                fcitfClassname = itfscg.getTargetClassName();
+                itstring = Utils.javaify(intit).toString();
+                mv.visit("    proxy = ");
+                mv.visit("new "+fcitfClassname+"(");
+                mv.visit("proxyForCompCtrl,\""+itname+"\","+itstring);
+                mv.visitln(",true,intercept);");
+                mv.visitln("    ic.internalInterfaces.put(\""+itname+"\",proxy);");
+            }
+        }
+        
+        // Initialize controllers
+        // merged content-controllers + interceptors on client interfaces
+        mv.visitln("    for( int i=0 ; i < ic.controllers.size() ; i++ ) {");
+        mv.visitln("      Object ctrl = ic.controllers.get(i);");
+        mv.visitln("      if( ctrl instanceof "+Controller.class.getName()+" ) {");
+        mv.visitln("        (("+Controller.class.getName()+")ctrl).initFcController(ic);");
+        mv.visitln("      }");
+        mv.visitln("    }");
+        
+        // Return the fcinterface for the component controller
+        mv.visitln("    return proxyForCompCtrl;");
+    }
+
+    @Override
+    protected void generateExtraCode( ClassSourceCodeVisitor cv ) {
+        
+        InterceptorSourceCodeGenerator iscg =
+            membraneDesc.getInterceptorSourceCodeGenerator();
+        InterfaceType[] its = ct.getFcInterfaceTypes();
+
+        /*
+         * Interceptors (inner classes).
+         */
+        if( iscg != null ) {
+            Set<String> inners = new HashSet<String>();
+            for (InterfaceType it : its) {
+                iscg.setInterfaceType(it);
+                String inner = iscg.getTargetClassName();
+                if( it.isFcClientItf() && iscg.match() && !inners.contains(inner) ) {
+                    ClassSourceCodeVisitor innercv = cv.visitInnerClass();
+                    iscg.generate(innercv);
+                    inners.add(inner);
+                }
+            }
+        }        
+    }
+}

Modified: trunk/fractaladl/juliac/opt/oo/pom.xml (7564 => 7565)


--- trunk/fractaladl/juliac/opt/oo/pom.xml	2008-04-30 16:30:30 UTC (rev 7564)
+++ trunk/fractaladl/juliac/opt/oo/pom.xml	2008-04-30 16:31:38 UTC (rev 7565)
@@ -11,7 +11,7 @@
   <groupId>org.objectweb.fractal.fractaladl.juliac</groupId>
   <artifactId>oo</artifactId>
   <packaging>jar</packaging>
-  <name>Juliac OO Optimization Level</name>
+  <name>Juliac Optimization Level OO</name>
  
     <dependencies>
         <dependency>

Modified: trunk/fractaladl/juliac/opt/pom.xml (7564 => 7565)


--- trunk/fractaladl/juliac/opt/pom.xml	2008-04-30 16:30:30 UTC (rev 7564)
+++ trunk/fractaladl/juliac/opt/pom.xml	2008-04-30 16:31:38 UTC (rev 7565)
@@ -14,6 +14,7 @@
 	<packaging>pom</packaging>
 
 	<modules>
+		<module>merge-all</module>
 		<module>oo</module>
 		<module>ultra-merge</module>
 	</modules>

Modified: trunk/fractaladl/juliac/opt/ultra-merge/pom.xml (7564 => 7565)


--- trunk/fractaladl/juliac/opt/ultra-merge/pom.xml	2008-04-30 16:30:30 UTC (rev 7564)
+++ trunk/fractaladl/juliac/opt/ultra-merge/pom.xml	2008-04-30 16:31:38 UTC (rev 7565)
@@ -11,7 +11,7 @@
   <groupId>org.objectweb.fractal.fractaladl.juliac</groupId>
   <artifactId>ultra-merge</artifactId>
   <packaging>jar</packaging>
-  <name>Juliac Ultra-Merge Optimization Level</name>
+  <name>Juliac Optimization Level ULTRA_MERGE</name>
  
     <dependencies>
         <dependency>

Modified: trunk/fractaladl/juliac/tests-conf/pom.xml (7564 => 7565)


--- trunk/fractaladl/juliac/tests-conf/pom.xml	2008-04-30 16:30:30 UTC (rev 7564)
+++ trunk/fractaladl/juliac/tests-conf/pom.xml	2008-04-30 16:31:38 UTC (rev 7565)
@@ -144,6 +144,13 @@
 							<genclass>target/test-classes</genclass>
 							<!-- debug>true</debug -->
 						</configuration>
+						<dependencies>
+							<dependency>
+								<groupId>org.objectweb.fractal.fractaladl.juliac</groupId>
+								<artifactId>merge-all</artifactId>
+								<version>${project.version}</version>
+							</dependency>
+						</dependencies>
 					</plugin>
 		
 					<!-- ============= -->


<--  Date Index     <--  Thread Index    

Reply via email to:

Powered by MHonArc.

Copyright © 2006-2007, OW2 Consortium | contact | webmaster.