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: Ali Erdem Ozcan, Alessio Pace, Lionel Debroux
22   */
23  
24  package org.objectweb.fractal.cecilia.adl.idl;
25  
26  import java.io.File;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.logging.Level;
30  import java.util.logging.Logger;
31  
32  import org.objectweb.fractal.adl.ADLException;
33  import org.objectweb.fractal.adl.Node;
34  import org.objectweb.fractal.adl.timestamp.Timestamp;
35  import org.objectweb.fractal.adl.util.FractalADLLogManager;
36  import org.objectweb.fractal.api.Component;
37  import org.objectweb.fractal.cecilia.adl.SourceCodeProvider;
38  import org.objectweb.fractal.cecilia.adl.file.CodeWriter;
39  import org.objectweb.fractal.cecilia.adl.file.SourceFile;
40  import org.objectweb.fractal.cecilia.adl.file.SourceFileProvider;
41  import org.objectweb.fractal.cecilia.adl.file.SourceFileWriter;
42  import org.objectweb.fractal.cecilia.adl.idl.ast.UnionDefinition;
43  import org.objectweb.fractal.cecilia.adl.idl.ast.IDLDefinition;
44  import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
45  import org.objectweb.fractal.task.core.Executable;
46  import org.objectweb.fractal.task.core.TaskException;
47  import org.objectweb.fractal.task.core.primitive.annotations.ClientInterface;
48  import org.objectweb.fractal.task.core.primitive.annotations.ServerInterface;
49  import org.objectweb.fractal.task.core.primitive.annotations.ServerInterfaces;
50  import org.objectweb.fractal.task.core.primitive.annotations.TaskParameters;
51  
52  /**
53   * Visitor component for {@link UnionDefinition} nodes.
54   */
55  public class CUnionFileVisitor extends AbstractTaskFactoryUser
56      implements
57        IDLDefinitionVisitor {
58  
59    // The logger
60    protected static Logger logger = FractalADLLogManager.getLogger("dep");
61  
62    // ---------------------------------------------------------------------------
63    // Implementation of the IDLVisitor interface
64    // ---------------------------------------------------------------------------
65  
66    /**
67     * Visits {@link UnionDefiniton} nodes, and creates a task that creates a
68     * source file containing the corresponding C code.
69     */
70    public Component visit(final List<Node> path,
71        final IDLDefinition idlDefinition, final Map<Object, Object> context)
72        throws ADLException, TaskException {
73      if (idlDefinition instanceof UnionDefinition) {
74        return taskFactoryItf.newPrimitiveTask(new CUnionFileTask(
75            (UnionDefinition) idlDefinition, (File) context
76                .get("idlBuildDirectory")), idlDefinition);
77      } else
78        return null;
79    }
80  
81    // ---------------------------------------------------------------------------
82    // Task classes
83    // ---------------------------------------------------------------------------
84  
85    /**
86     * Builds interface definitions file and puts the source code that is received
87     * for a given unionDefinitionNode. Provides a server interface giving access
88     * to this file. Provides another server interface that returns the #include
89     * file to be included in the files referencing the union defined by the given
90     * unionDefinitionNode.
91     */
92    @TaskParameters("unionDefinitionNode")
93    @ServerInterfaces({
94        @ServerInterface(name = "c-union-definition-provider", signature = SourceCodeProvider.class, record = "role:cUnionHeaderSource, id:%", parameters = {"unionDefinitionNode"}),
95        @ServerInterface(name = "c-union-header-file-provider", signature = SourceFileProvider.class, record = "role:cUnionHeaderFile, id:%", parameters = {"unionDefinitionNode"})})
96    public static class CUnionFileTask
97        implements
98          Executable,
99          SourceCodeProvider,
100         SourceFileProvider {
101 
102     // constructor parameters
103     protected final UnionDefinition unionDefinition;
104     protected final File           idlBuildDirectory;
105 
106     // The produced source file
107     protected SourceFile           sourceFile;
108     // The produced source code
109     protected String               sourceCode;
110     // The name of the produced source file
111     protected String               headerFileName;
112 
113     // -------------------------------------------------------------------------
114     // Task client interfaces
115     // -------------------------------------------------------------------------
116 
117     /** Client interface used to retrieve the content of the generated files. */
118     @ClientInterface(name = "c-union-definition", record = "role:cUnionDefinition, id:%", parameters = "unionDefinitionNode")
119     public SourceCodeProvider      cItfSourceItf;
120 
121     // -------------------------------------------------------------------------
122     // Task constructor
123     // -------------------------------------------------------------------------
124 
125     /**
126      * @param unionDefinition The union definition node for which this task must
127      *            generate C source code.
128      * @param idlBuildDirectory The directory into which the generated file will
129      *            be placed.
130      */
131     public CUnionFileTask(final UnionDefinition unionDefinition,
132         final File idlBuildDirectory) {
133       this.unionDefinition = unionDefinition;
134       this.idlBuildDirectory = idlBuildDirectory;
135     }
136 
137     // -------------------------------------------------------------------------
138     // Implementation of the Executable interface
139     // -------------------------------------------------------------------------
140 
141     public void execute() throws Exception {
142       // The execute method may be reentrant. To avoid stack overflow, generate
143       // code only if it has not been already generated.
144       if (sourceFile == null) {
145         headerFileName = unionDefinition.getName().replace('.',
146             File.separatorChar)
147             + ".idl.h";
148         prepareSourceCode();
149         prepareSourceFile();
150       }
151     }
152 
153     // -------------------------------------------------------------------------
154     // Implementation of the SourceCodeProvider interface
155     // -------------------------------------------------------------------------
156 
157     public String getSourceCode() {
158       return sourceCode;
159     }
160 
161     // -------------------------------------------------------------------------
162     // Implementation of the SourceFileProvider interface
163     // -------------------------------------------------------------------------
164 
165     public SourceFile getSourceFile() {
166       return sourceFile;
167     }
168 
169     // -------------------------------------------------------------------------
170     // Utility methods
171     // -------------------------------------------------------------------------
172 
173     protected void prepareSourceCode() {
174       final CodeWriter cw = new CodeWriter();
175       cw.append("#include \"").append(headerFileName).append("\"").endl();
176       sourceCode = cw.toString();
177     }
178 
179     protected void prepareSourceFile() throws Exception {
180       final File file = new File(idlBuildDirectory, headerFileName);
181       sourceFile = new SourceFile(unionDefinition.getName(), file);
182 
183       if (Timestamp.isNodeMoreRecentThan(unionDefinition, file)) {
184         SourceFileWriter.createOutputDir(file.getParentFile());
185         SourceFileWriter.writeToFile(file, cItfSourceItf.getSourceCode());
186       } else if (logger.isLoggable(Level.FINE)) {
187         logger.fine("IDL file '" + file + "' is uptodate");
188       }
189     }
190   }
191 }