diff options
Diffstat (limited to 'sca-cpp/trunk/contrib/doc/CPPGeneratorTool.txt')
-rw-r--r-- | sca-cpp/trunk/contrib/doc/CPPGeneratorTool.txt | 362 |
1 files changed, 0 insertions, 362 deletions
diff --git a/sca-cpp/trunk/contrib/doc/CPPGeneratorTool.txt b/sca-cpp/trunk/contrib/doc/CPPGeneratorTool.txt deleted file mode 100644 index c004799791..0000000000 --- a/sca-cpp/trunk/contrib/doc/CPPGeneratorTool.txt +++ /dev/null @@ -1,362 +0,0 @@ - -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. - - - -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> |