You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2006/12/04 10:03:32 UTC

svn commit: r482103 - in /incubator/tuscany/cpp/sca: Developers Guide.txt doc/CPPGeneratorTool.txt

Author: jsdelfino
Date: Mon Dec  4 01:03:31 2006
New Revision: 482103

URL: http://svn.apache.org/viewvc?view=rev&rev=482103
Log:
Moved Developers Guide.txt to doc/CPPGeneratorTool.txt

Added:
    incubator/tuscany/cpp/sca/doc/CPPGeneratorTool.txt   (with props)
Removed:
    incubator/tuscany/cpp/sca/Developers Guide.txt

Added: incubator/tuscany/cpp/sca/doc/CPPGeneratorTool.txt
URL: http://svn.apache.org/viewvc/incubator/tuscany/cpp/sca/doc/CPPGeneratorTool.txt?view=auto&rev=482103
==============================================================================
--- incubator/tuscany/cpp/sca/doc/CPPGeneratorTool.txt (added)
+++ incubator/tuscany/cpp/sca/doc/CPPGeneratorTool.txt Mon Dec  4 01:03:31 2006
@@ -0,0 +1,342 @@
+Tuscany SCA For C++ - scagen C++ generator tool
+===============================================
+
+
+See cpp/build.txt in the parent directory or the cpp/sca/INSTALL file 
+for build instructions.
+
+Building the tools
+------------------
+
+NOTE: this is built and installed by the build step above.
+
+Currently, there is only one tool: "scagen". It can be built using the
+ant build script at \tuscany\cpp\sca\tools\scagen\build.xml. 
+The default target "all" will build the java jars, documentation,
+scripts and a zip file of the whole thing. This is all the ant
+build tasks apart from "test" which runs all the junit tests. 
+
+The ant build script can be altered to add the junit tests to the
+default target. Replace the line 
+
+<property name="junit.jar.folder" value="${basedir}/lib" />
+
+The "test" task was not included in "all" as it requires a
+junit jar file to run. This jar is available here: 
+http://www.junit.org/index.htm testing has been done with
+Junit version 3.8.1. 
+
+Running the scagen tool
+-----------------------
+
+The scagen tool user interface is quite basic in this initial release. 
+It can be run from the scagen.jar file using "java -jar scagen.jar" 
+or from small scripts - scagen.bat for Windows and scagen.sh for Unix. 
+The parameters are: 
+ -dir <the path to the sca composite root directory>
+ -output <the path to an output directory where the generated file will be placed>
+
+e.g.
+	scagen -dir c:\mycomposites\composite1 -output c:\mycomposites\bld\composite1
+	
+What scagen does
+----------------
+
+The input directory passed to the scagen tools as
+the -dir parameter method is taken to be the SCA 
+composite root directory. All the sca.composite and .fragment 
+files in that directory are inspected to resolve all 
+the <component/> elements within them. 
+
+Each <component/> element found is inspected 
+to see if it has a <implementation.cpp/> element within it. 
+
+Each <implementation.cpp/> element should have a 
+header attribute that represents a C++ header file 
+that contains function prototypes for the C++ 
+implementation of the service. An optional class 
+attribute can be used to select one class if more than 
+one that is present in the header file. The default 
+class is the one with the same name as the header file. 
+The tool will verify that the implementation header 
+contains an appropriate class prototype. 
+
+The directory that contains the implementation header 
+should also contain a matching .componentType file for 
+the equivalent SCA component. So for example, a 
+MyServiceImpl.h file would have a corresponding 
+MyServiceImpl.componentType file in the same directory. 
+
+Each componentType file is inspected for <service/> 
+and <reference/> elements. For each <service/> element 
+that is found that contains a <interface.cpp/> element 
+within it,
+
+the header attribute of the <interface.cpp/> is taken 
+as the filename of the C++ interface header for the 
+SCA service.  This C++ header file is opened and used 
+as a means for specifying the SCA service resulting 
+in an appropriate wrapper and proxy being generated 
+for this service interface. Both method bodies and h
+eaders are generated in the given output directory. 
+The processing of a <reference/> element is the same 
+except that only a proxy header and implementation 
+re generated. 
+
+
+Getting started with the code
+-----------------------------
+
+The following is a list of tasks that are performed by the scagen tool
+for each task we will describe technically how it is accomplished and 
+the location of the code that can be inspected/changed to alter the 
+behaviour. 
+
+Here are the tasks listed, below is a paragraph for each one: 
+
+   o (Overall structure of the code)
+   o Walking the input directory
+   o Scanning the .composite and .fragment files
+   o finding the C++ implementation headers
+   o finding/checking the classname in the C++ implementation headers
+   o find the matching .componentTemplate files
+   o going into the componentTemplate files to extract the interface header filenames
+   o going into the interface header files and parsing them to extract the method signatures
+     into a network of objects we can inspect. 
+   o taking all the meta data stored as objects and building a DOM for XSLT processing
+   o using XSLT to produce a proxy header
+   o using XSLT to produce a proxy implementation
+   o using XSLT to produce a wrapper header
+   o using XSLT to produce a wrapper implementation
+
+
+Overall structure of the code 
+-----------------------------
+
+There are two packages org.apache.tuscany.sca.cpp.tools.common and 
+org.apache.tuscany.sca.cpp.tools.services. The ...common package is 
+taken from some existing code that was also contributed to axis that
+was used to parse C++ code and do various tasks like insert trace. 
+This code was repackaged and shipped as a tuscany package but there
+has been a desire not to change it significantly from the equivalent
+org.apache.axis.tools.common package to leave the door open for 
+future convergence. 
+
+Where the ...common package has been amended (for example to cope with
+namespaces better or the provision of an Options.reset method to reset a static
+variable and enable the tuscany junit tests to run independently) these
+have been flagged with a "Tuscany" comment. The ...common package basically
+provides two functions - 1) the ability to go into a directory (see DirectoryTree.java) 
+and process files that fit a particular filter (e.g. "*.hpp") by passing them to
+implementer of the FileActor Interface (see the classes "Headers" for the 
+actor that processes C++ headers and "XMLFileActor" for the file actor that
+processes the .componentType and sca.composite/fragment files.)
+
+The ...services package contains the majority of code written afresh for the
+scagen tool including the subclasses of XMLFileActor (see ComponentTypeFileHandler.java
+and CompositeOrFragmentFileHandler.java) that are the classes that tie this
+package to the ...common package and which are called by the 
+DirectoryTree walker.
+
+Walking the composite root input directory
+---------------------------------------
+
+The main method of the scagen class creates an instance of 
+"DirectoryScanner" and registers with it a file handler of 
+type "CompositeOrFragmentFileHandler" for all files that end 
+in ".composite" or ".fragment". On calling the "walkTree" method
+on the scanner it will in turn call the actOnFile method on the
+CompositeOrFragmentFileHandler for appropriate files. 
+
+Scanning the .composite and .fragment files
+----------------------------------------
+
+The scanning of these files by the respective  "CompositeOrFragmentFileHandler"
+and "ComponentTypeFileHandler" is mostly handled by the superclass
+"XMLFileActor". This class will recursively goes through the whole
+XML file and considers the name of the XML element it finds. 
+"XMLFileActor" contains a map of element names to element handlers
+that will "flatten out" the structure of the XML file "above" the 
+level of node we are interested in. 
+
+So for example the ComponentTypeFile handler sets up the handlers
+map as follows:
+
+  GenericDomNodeHandler gdnh = new GenericDomNodeHandler();
+        handlers.put("componentType", gdnh);
+        handlers.put("interface.cpp", gdnh);
+  ServiceDomNodeHandler sdnh = new ServiceDomNodeHandler();
+        handlers.put("service", sdnh);
+
+  ReferenceDomNodeHandler rdnh = new ReferenceDomNodeHandler();
+        handlers.put("reference", rdnh);
+        
+The majority of processing done by these DomNOdeHandlers is to 
+place the attributes and values discovered into another map that
+maps an (static version of) the XPath of a value to the value itself. 
+So for example "/componentType/service/interface.cpp/@header" might contain
+the current ("root to here") value of the header attribute of the current
+interface. 
+
+Particular handlers for the "leaves" of this tree 
+such as ServiceDomNodeHandler and ReferenceDomNodeHandler
+can then consume these values from the map without having 
+to be concerned with the actual names of things,
+like the service name, appearing in the key. It should be
+understood though that there are multiple values placed in the map
+for one "key" as the processing works its way through the 
+XML tree. For example the processing of a second component will
+overlay its data over the same keys as the first component.
+(After "wiping" the appropriate subtree.)
+
+Finding the C++ implementation headers
+--------------------------------------
+
+The "/composite/component/implementation.cpp/@header" and 
+is used to key into the name of the implementation header
+and this is opened directly and passed to the 
+actOnFileMethod of a Headers object from the ...common package
+bypassing the DirectoryScanner code. The path is relative to
+the given (-dir option) composite root directory.
+
+Finding/checking the classname in the C++ implementation headers
+-----------------------------------------------------------------
+
+This implementation header is not used to define the 
+methods of the SCA service but rather is opened to check
+ any given implementation.cpp/@class attribute 
+(or find out the name of the implementation class
+in the header if this is not specified in the XML. This
+is done using the same method that later parses the interface
+C++ headers into java objects - we just them inspect the 
+class attribute of the "Signature" objects that represent the methods
+we find in the header.
+
+Find the matching .componentType files
+------------------------------------------
+
+By SCA convention we go to the same directory as the implementation
+files and look for the XXX.componentType files with the same name. 
+A instance of the ComponentDOMNodeHandler handles the data in the 
+Component Element and pre-creates a ComponentTypeFileHandler that
+will eventually be called to process the .componentType file. This
+object receives a number of "setParameter" calls to poke into it
+matadata that is available prior/outside the the actual .componentType
+file it will read. 
+
+Go into the componentType files to extract the interface header filenames
+-----------------------------------------------------------------------------
+
+We open up the .componentTemplateFiles with exactly the same 
+mechanism as we read the sca.composite/fragment file (by creating
+a DOM and descending through it this time using a ComponentTypeFileHandler that it
+has had various data values ( e.g. the implementation class and namespace used later)
+poked into it. The ComponentTypeFileHandler itself has individual 
+handlers for the service and reference XML/DOM element/nodes
+that is comes across (ServiceDomNodeHandler and ReferenceDomNodeHandler
+respectively). Each these handlers will pull out the name of 
+a C++ interface header and use it to resolve the interface of the
+SCA Service. 
+
+Parsing the interface header files for signatures 
+-------------------------------------------------
+
+The Service/Reference DOM Node hander both call the 
+    ServicesGenerator.handleInterfaceHeader(parameters, true);
+method, the second parameter is used to differentiate
+the call source as we don't need wrapper files for 
+SCA references (just proxies). 
+
+The ServicesGenerator uses the Headers file actor from
+the ...common package to create a List of Signature
+objects that describe the interface methods in the C++
+header. 
+
+Take all the meta data stored as objects and build a DOM
+--------------------------------------------------------
+We now have a List of Signature objects and a map that
+represents the flattened information that we have pulled
+from the XML files in the ServiceGenerator class.
+We call a "createDOMofMethods" method
+to consolidate all this information into one DOM 
+(this task should be split into more than one method as the
+signature/parameter list of the method is too large).
+
+Use XSLT to produce the output files (Proxy/Wrapper headers and Implementations)
+--------------------------------------------------------------------------------
+
+The ServicesGenerator.handleInterfaceHeader(parameters, forReference);
+method closes of with the code: 
+
+            createProxyCPPFromDom(outputDir, dom);
+            createProxyHeaderFromDom(outputDir, dom);
+
+            if (!forReference) {
+                createWrapperCPPFromDom(outputDir, dom);
+                createWrapperHeaderFromDom(outputDir, dom);
+            }
+
+
+Each of the create methods sets up the output 
+file name and a different XSLT transform and calls 
+"createOutputFromDom" to transform/filter the data in the 
+"model" that is held in our DOM of the data to a particular
+"view" as expressed in the C++ output file. 
+
+The four XSLT style sheets are in rough order of the output
+file  and this corresponds very roughly to a depth first descent
+of the DOM tree so, for example, we could have in a stylesheet: 
+
+...
+    void* </xsl:text>
+    <xsl:value-of select="$class"/><xsl:text>::newImplementation()
+    {
+        return new </xsl:text><xsl:value-of select="../@implClass"/><xsl:text><xsl:text>(target);
+    }
+
+which would be output as: 
+
+    void* MyClassImpl_MyClass_Proxy::newImplementation()
+    {
+        return new MyClassImpl(target)
+    }
+
+given appropriate valies for $class and "../@implClass" and 
+$class might be defined to be:
+xsl:variable name="clazz">
+   <xsl:value-of select="../@implClass"/>
+   <xsl:text>_</xsl:text>
+   <xsl:value-of select="../@nameOfServiceOrReference"/>
+   <xsl:text>_Proxy</xsl:text>
+</xsl:variable>
+
+giving "MyClassImpl_MyClass_Proxy"
+
+The stylesheets can be found in the xsl subdirectory of the 
+org.apache.tuscany.sca.cpp.tools.services package. 
+
+Unit Testing Scagen Code Changes
+--------------------------------
+
+The junit unit test 
+   /tuscany/cpp/sca/tools/scagen/
+   junit/org/apache/tuscany/sca/cpp/tools/junit/TestAllCompositesTest.java
+
+will dynamically look for all the subdirectores of the directory
+path given by TuscanyTestCase.junit_composites and run the scagen
+tool on them as if they were composites roots. 
+
+By convention an "expected_output" directory is located
+(see the CVS tree or the test program) and the actual
+and expected results compared. This testcase is thus a
+good first/basic regression test for any changes.
+
+New test cases can thus be added without having to write
+any new junit java code by by creating new SCA composites and
+the associated expected Scagen output - perhaps by using the tool
+initially and checking the output is satisfactory before copying
+it to the expected output directory at:
+
+/tuscany/cpp/sca/tools/scagen/junit/testoutput/<composite>/expected_output
+where input data is taken from
+/tuscany/cpp/sca/tools/scagen/junit/testinput/composites/<composite>

Propchange: incubator/tuscany/cpp/sca/doc/CPPGeneratorTool.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/tuscany/cpp/sca/doc/CPPGeneratorTool.txt
------------------------------------------------------------------------------
    svn:keywords = Rev Date



---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-commits-help@ws.apache.org