View Javadoc

1   /***
2    * Cecilia ADL Compiler
3    * Copyright (C) 2006-2007 STMicroelectronics
4    *
5    * This library is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10   * This library is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with this library; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   *
19   * Contact: fractal@objectweb.org
20   *
21   * Author: Matthieu Leclercq, Ali Erdem Ozcan
22   */
23  
24  package org.objectweb.fractal.cecilia.primitive.thinkMC.components;
25  
26  import static org.objectweb.fractal.api.type.TypeFactory.OPTIONAL;
27  import static org.objectweb.fractal.cecilia.adl.SourceCodeHelper.appendSortedSourceCodes;
28  
29  import java.util.HashMap;
30  import java.util.List;
31  import java.util.Map;
32  
33  import org.objectweb.fractal.adl.ADLException;
34  import org.objectweb.fractal.adl.ComponentVisitor;
35  import org.objectweb.fractal.adl.Node;
36  import org.objectweb.fractal.adl.components.ComponentContainer;
37  import org.objectweb.fractal.api.Component;
38  import org.objectweb.fractal.cecilia.adl.AbstractDefinitionTask;
39  import org.objectweb.fractal.cecilia.adl.SourceCodeProvider;
40  import org.objectweb.fractal.cecilia.adl.file.CodeWriter;
41  import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
42  import org.objectweb.fractal.task.core.TaskException;
43  import org.objectweb.fractal.task.core.primitive.annotations.ClientInterface;
44  import org.objectweb.fractal.task.core.primitive.annotations.ServerInterface;
45  import org.objectweb.fractal.task.core.primitive.annotations.ServerInterfaces;
46  import org.objectweb.fractal.task.core.primitive.annotations.TaskParameters;
47  
48  /**
49   * Visitor component that builds the definition of the component data structure
50   * of the component for <code>ThinkMC</code> dialect.
51   */
52  public class ComponentDefinitionVisitor extends AbstractTaskFactoryUser
53      implements
54        ComponentVisitor {
55  
56    // ---------------------------------------------------------------------------
57    // Implementation of the ComponentVisitor interface
58    // ---------------------------------------------------------------------------
59  
60    /**
61     * Visits {@link ComponentContainer} nodes and creates a task that writes the
62     * source code containing the definition of the component data structure.
63     */
64    public Component visit(final List<Node> path,
65        final ComponentContainer container, final Map<Object, Object> context)
66        throws ADLException, TaskException {
67      return taskFactoryItf.newPrimitiveTask(new ComponentDefinitionTask(),
68          container);
69    }
70  
71    // ---------------------------------------------------------------------------
72    // Task classes
73    // ---------------------------------------------------------------------------
74  
75    /**
76     * Builds source code for the definition of the component data structure for
77     * the given component node. This task provides the produced source code. It
78     * uses the source code provided for client/server interfaces, controllers,
79     * and the attributes of the component.
80     */
81    @TaskParameters("componentNode")
82    @ServerInterfaces(@ServerInterface(name = "component-definition-provider", signature = SourceCodeProvider.class, record = "role:componentDefinition, id:%", parameters = "componentNode"))
83    public static class ComponentDefinitionTask extends AbstractDefinitionTask {
84  
85      // -------------------------------------------------------------------------
86      // Task client interfaces
87      // -------------------------------------------------------------------------
88  
89      /** Source code to be included for interface definitions (optional). */
90      @ClientInterface(name = "interface-definition-provider", contingency = OPTIONAL, record = "role:interfaceDefinition, id:%", parameters = "componentNode")
91      public SourceCodeProvider                    interfaceDefinitionsProviderItf;
92  
93      /** Source code to be included for attribute definitions (optional). */
94      @ClientInterface(name = "attribute-definition-provider", contingency = OPTIONAL, record = "role:attributeDefinition, id:%", parameters = "componentNode")
95      public SourceCodeProvider                    attributeDefintionsProviderItf;
96  
97      /** Source codes to be included for controllers definition. */
98      @ClientInterface(name = "controller-definition-provider", signature = SourceCodeProvider.class, record = "role:controllerDefinition, id:%", parameters = "componentNode")
99      public final Map<String, SourceCodeProvider> controllerDefintionsProviderItf = new HashMap<String, SourceCodeProvider>();
100 
101     // -------------------------------------------------------------------------
102     // Implementation of abstract methods of AbstractDefinitionTask
103     // -------------------------------------------------------------------------
104     @Override
105     protected String processSourceCode() throws Exception {
106       final CodeWriter cw = new CodeWriter("Primitive Definition Builder");
107       final String componentCName = typeNameProviderItf.getCTypeName();
108 
109       if (interfaceDefinitionsProviderItf != null)
110         cw.appendln(interfaceDefinitionsProviderItf.getSourceCode()).endl();
111 
112       if (attributeDefintionsProviderItf != null)
113         cw.appendln(attributeDefintionsProviderItf.getSourceCode()).endl();
114 
115       cw.append("#define __CECILIA__DEFINE_COMPONENT_TYPE \\").endl();
116 
117       cw.append("struct ").append(componentCName).append("_t { \\").endl();
118 
119       if (interfaceDefinitionsProviderItf != null)
120         cw.append("struct ").append(componentCName).append("_type type; \\")
121             .endl();
122 
123       if (attributeDefintionsProviderItf != null)
124         cw.append(componentCName).append("_attributes_t attributes; \\").endl();
125 
126       cw.append("  struct ").append(componentCName).append(
127           "_instancedata data ; \\").endl();
128       cw.append("} ;").endl();
129 
130       cw.endl();
131 
132       // To ensure reproducible code generation, append controller definition
133       // codes in their alphabetic order.
134       appendSortedSourceCodes(cw, controllerDefintionsProviderItf.values());
135 
136       return cw.toString();
137     }
138   }
139 
140 }