home *** CD-ROM | disk | FTP | other *** search
/ ftptest.leeds.ac.uk / 2015.02.ftptest.leeds.ac.uk.tar / ftptest.leeds.ac.uk / bionet / CAE-GROUP / SCL-WIN3x / SCLTEST.EXE / SCL2HTML / SCL2HTML.CC < prev    next >
Text File  |  1994-12-13  |  13KB  |  336 lines

  1. /*
  2.  * scl2html.cc
  3.  *
  4.  * Ian Soboroff, NIST
  5.  * June, 1994
  6.  *
  7.  * scl2html is a program to lay out a given schema in HTML, suitable for
  8.  * hypertext browsing using Mosaic or any other HTML viewer/WWW surfboard.
  9.  * While this particular code as designed is linked to the Example schema
  10.  * (via tests.h), it can be "fed" any fedex_plus-compiled schema and give
  11.  * appropriate output.
  12.  *
  13.  * The Makefile defaults to building the app to use the example schema.  To
  14.  * link to another schema, build the appropriate libraries for it and
  15.  * 'make SCHEMA_NAME=my-schema'.  See the Makefile for more details.
  16.  *
  17.  * The executable is named after the schema you use, e.g., scl2html.example.
  18.  * This can be renamed to whatever you want.
  19.  *
  20.  * This program works by using the registry to walk through each entity type.
  21.  * At each entity, the supertypes, subtypes, and attributes are probed out
  22.  * and mapped into a relatively nifty-looking HTML format.
  23.  *
  24.  * This code was heavily inspired by the original scltest program,
  25.  * distributed with the DataProbe, v2.0.x.
  26.  */
  27.  
  28. /* Since scl2html doesn't use any schema-specific things except the init
  29.    function, we don't need to include the schema's header file inside
  30.    tests.h  */
  31. #define DONT_NEED_HEADER
  32. #include <tests.h>
  33. #include "MyRegistry.h"
  34.  
  35. // PrintAttrTypeWithAnchor()
  36. // Given an atribute, print out its immediate type (not fundamental).
  37. // Ah, but if life were so simple.  If this attribute is _not_ of a
  38. // fundamental type, put in an anchor to somewhere with info on the type.
  39. // This could be either the index page Type list, or an entity's page if
  40. // the attribute is an entity.
  41. // BUGS: (sort of) IMHO, the handling of aggregates here is a kludge, but
  42. // it's a kludge without a solution I can see.  While the dictionary has
  43. // ways to show you what kinds of things an aggregate holds, it won't tell
  44. // you what kind of _aggragation_ (no pun intended) you have, as in giving
  45. // you a code or "Bag" or something by itself.  It probably doesn't work
  46. // aesthetically for compound aggregates (i.e., a list of lists).
  47. void PrintAttrTypeWithAnchor(const TypeDescriptor *typeDesc, ofstream &outhtml)
  48. {
  49.     // The type, as an integer.  See src/clstepcore/baseType.h for info
  50.     int base = typeDesc->Type();
  51.  
  52.     // the type descriptor for the "referent type," if any.
  53.     // This is NULL if the attribute is a fundamental type.
  54.     // All we use it for now is checking for NULL.
  55.     const TypeDescriptor *reference = typeDesc->ReferentType();
  56.  
  57.     // Do we need an anchor?
  58.     int anchor = 0;
  59.  
  60.     // First, figure out if we need an anchor...
  61.     if (reference)  // if this has a referent type (i.e., is a non-base type)
  62.     {
  63.         if (base != 4)   // anchor all non-bases except for aggregates
  64.           anchor = 1;  // which we'll take care of recursively
  65.     }
  66.     else {
  67.         // entities and enumerations show up as base, but we want to
  68.         // anchor them anyway
  69.     if (base == 3 || base == 5) anchor = 1;
  70.     }
  71.     
  72.     // Now, print type, with anchor if necessary
  73.     if (anchor && base != 3) {
  74.         // for regular TYPEs, anchor to the index at that definition
  75.         outhtml << "<A HREF=\"" << "index.html#";
  76.     outhtml << typeDesc->Name() << "\">";
  77.     }
  78.     else if (anchor && base == 3)
  79.     {
  80.         // for entities, anchor to that entity's page
  81.     outhtml << "<A HREF=\"" << typeDesc->Name();
  82.     outhtml << ".html\">";
  83.     }
  84.  
  85.     outhtml << typeDesc->AttrTypeName();
  86.  
  87.     if (base == 4)
  88.     {
  89.     outhtml << " (contains elements of type ";
  90.     PrintAttrTypeWithAnchor(typeDesc->AggrElemTypeDescriptor(), outhtml);
  91.     outhtml << ")" << endl;
  92.     }
  93.  
  94.     if (anchor)
  95.         outhtml << "</A>";
  96. }
  97.  
  98. // PrintAttrsHTML()
  99. // Given an entity, print out to the HTML file an unordered list of
  100. // the entity's attributes and their types.  It returns the number of
  101. // explicit attributes that the entity has.
  102. int PrintAttrsHTML(const EntityDescriptor *ent, ofstream &outhtml) 
  103. {
  104.     int attrCount = 0;
  105.  
  106.     // To traverse the attributes of the entity, we're going to use
  107.     // an iterator native to the class library.  This could also have
  108.     // been done using GetHead() and NextNode() of the entity's attribute
  109.     // list (nearly identical to how the entity lists are traversed), see
  110.     // PrintParentAttrsHTML() and also main() below.
  111.     AttrDescItr aditr(ent->ExplicitAttr());
  112.     const AttrDescriptor *attrDesc = aditr.NextAttrDesc();
  113.     if (attrDesc != 0) 
  114.     {
  115.         outhtml << "\n<! -- These are the attributes for entity ";
  116.         outhtml << ent->Name() << " >\n\n";
  117.     outhtml << "<UL>" << endl;
  118.     while (attrDesc != 0) 
  119.     {
  120.         attrCount++;
  121.         outhtml << "<LI>" << attrDesc->Name() << " : ";
  122.         if ((LOGICAL)attrDesc->Optional() == sdaiTRUE)
  123.                   outhtml << "optional ";
  124.         PrintAttrTypeWithAnchor(attrDesc->ReferentType(), outhtml);
  125.         outhtml << endl;
  126.         attrDesc = aditr.NextAttrDesc();
  127.     }
  128.     outhtml << "</UL>" << endl;
  129.     }
  130.     return attrCount;
  131. }
  132.  
  133.  
  134. // PrintParentAttrsHTML()
  135. // This function, given an entity and its parent, recursively travels up
  136. // the inheritance tree of the entity, printing to the HTML file a
  137. // description-list structre showing all ancestors.  For each ancestor,
  138. // the attributes are printed using the PrintAttrsHTML() function above.
  139. void PrintParentAttrsHTML (const EntityDescriptor* ent, 
  140.     const EntityDescriptor *parent, ofstream &outhtml) 
  141. {
  142.     // Passing this function the pointer to ent is really cosmetic, so
  143.     // we can easily print out this 'header' information.
  144.     outhtml << "\n<! -- This is a parent of " << ent->Name() << ">\n\n";
  145.     outhtml << "<DL>" << endl;
  146.     outhtml << "<DT>" << ent->Name() << " inherits from ";
  147.     outhtml << "<A HREF=\"" << parent->Name() << ".html\">";
  148.     outhtml << parent->Name() << "</A>" << endl;
  149.     
  150.     // Here we're going to traverse the list of supertypes of the parent
  151.     // using the EntityDescriptorList
  152.     const EntityDescriptorList *grandpaList = &(parent->Supertypes());
  153.     EntityDescLinkNode *grandpaNode = 
  154.     (EntityDescLinkNode*)grandpaList->GetHead();
  155.     while (grandpaNode) 
  156.     {
  157.         // for each "grandparent" of ent, inside a descriptor body (<DD>)
  158.         // recursively call this function... the 'while' takes care of
  159.         // multiple inheritance: for each grandparent, trace back.
  160.     outhtml << "<DD>" << endl;
  161.     const EntityDescriptor *grandpa = grandpaNode->EntityDesc();
  162.     PrintParentAttrsHTML(parent, grandpa, outhtml);
  163.     grandpaNode = (EntityDescLinkNode*)grandpaNode->NextNode();
  164.     }
  165.     
  166.     // Now print the parent's atributes.  This calls PrintAttrsHTML() to
  167.     // actually print any existing attributes, but to see if there are
  168.     // any, we'll check to see if the head of the atribute descriptor list
  169.     // exists.  Conversely, once grabbing the head we could print out
  170.     // the attributes by following the list (attrNode->NextNode()).
  171.     const AttrDescriptorList *attrList = &(parent->ExplicitAttr());
  172.     AttrDescLinkNode *attrNode = (AttrDescLinkNode*)attrList->GetHead();
  173.     if (attrNode) 
  174.     {
  175.     outhtml << "<DT>" << parent->Name();
  176.     outhtml << " has the following attributes" << endl;
  177.     outhtml << "<DD>" << endl;
  178.     if (PrintAttrsHTML(parent, outhtml) == 0)
  179.         outhtml << "<EM>none</EM>" << endl;
  180.     }
  181.     
  182.     outhtml << "</DL>" << endl;
  183. }
  184.  
  185.  
  186. /********************  main()  ****************************/
  187.  
  188. main()
  189. {
  190.     // This has to be done before anything else.  This initializes
  191.     // all of the registry information for the schema you are using.
  192.     // The SchemaInit() function is generated by fedex_plus... see
  193.     // extern statement above.
  194.  
  195.     MyRegistry *registry = new MyRegistry(SchemaInit);
  196.  
  197.     // Rather than using the standard Registry class here, as in the treg
  198.     // example, we are using MyRegistry, which is derived from the original.
  199.     // Registry doesn`t contain a facility for browsing the types, as it
  200.     // does schemas and entities... so I added it.  See the file
  201.     // MyRegistry.h for details on how this was done. 
  202.     
  203.     // "Reset" has tables for browsing
  204.     registry->ResetEntities();
  205.     registry->ResetSchemas();
  206.     registry->ResetTypes();
  207.  
  208.     const SchemaDescriptor *schema = registry->NextSchema();
  209.     int num_ents = registry->GetEntityCnt();
  210.     cout << "Processing schema " << schema->Name();
  211.     cout << " with " << num_ents << " entities." << endl;
  212.     
  213.     // Set up root-level index of the schema, in a file called
  214.     // "index.html".  In this document are links to all objects in
  215.     // the schema.
  216.  
  217.     cout << "Creating 'index.html'" << endl;
  218.     ofstream root("index.html");
  219.     root << "<TITLE>" << schema->Name() << "</TITLE>" << endl;
  220.     root << "<H1>Schema: " << schema->Name() << "</H1>" << endl;
  221.  
  222.     // Do Type-list
  223.     cout << "Processing types ";
  224.     root << "<HR>" << endl;
  225.     root << "<H2>Types</H2>" << endl;
  226.     root << "<UL>" << endl;
  227.     
  228.     const TypeDescriptor *type;
  229.     SCLstring tmp;
  230.     type = registry->NextType();
  231.     root << "<! -- The following is a list of types, which are>\n";
  232.     root << "<! --  cross-referenced from the entities.>\n";
  233.     while (type != 0)
  234.     {
  235.         cout << ".";
  236.     root << "<LI><A NAME=\"" << type->Name() << "\">";
  237.     root << type->Name() << "</A>: ";
  238.     root << type->Description() << endl;
  239.     type = registry->NextType();
  240.     }
  241.     root << "</UL>" << endl;
  242.     cout << endl;
  243.  
  244.     // Do entity root-section and pages
  245.     root << "<HR>" << endl;
  246.     root << "<H2>Entities</H2>" << endl;
  247.     root << "<UL>" << endl;
  248.     root << "<! -- These all lead to a page for each entity>\n";
  249.     
  250.     // These are all pointers we need to wander around the registry
  251.     // information.  We'll want to not only look at the current entity
  252.     // and its attributes, but also which entites are super- and subclasses
  253.     // of the current entity.  Here, supers isn't really used beyond checking
  254.     // for ancestors, but we'll use subs to list subclasses and make links
  255.     // to them.
  256.  
  257.     const EntityDescriptor *ent;
  258.     const EntityDescriptorList *supers;
  259.     const EntityDescriptorList *subs;
  260.     EntityDescLinkNode *entNode;
  261.  
  262.     for (int i=0; i<num_ents; i++) 
  263.     {
  264.     ent = registry->NextEntity();
  265.     cout << "Processing " << ent->Name() << endl;
  266.  
  267.         // add anchor to root page
  268.         root << "<LI><A HREF=\"" << ent->Name() << ".html\">"; 
  269.     root << ent->Name() << "</A>" << endl;
  270.     
  271.         // construct page for entity
  272.         char *tmpstr = new char[strlen(ent->Name()) + 6];
  273.     ofstream entout(strcat(strcpy(tmpstr,ent->Name()),".html"));
  274.     delete [] tmpstr;
  275.     entout << "<TITLE>Entity " << ent->Name() << "</TITLE>" << endl;
  276.     entout << "<H1>" << ent->Name() << "</H1>" << endl;
  277.  
  278.         // supertypes
  279.         entout << "<HR>\n<H2>Inherited Attributes</H2>" << endl;
  280.     entout << "<! -- Below is the direct ancestry (if any) of ";
  281.     entout << ent->Name() << ">\n";
  282.         supers = &(ent->Supertypes());
  283.         entNode = (EntityDescLinkNode*)supers->GetHead();
  284.         if (!entNode)
  285.             entout << "<EM>none</EM>" << endl;
  286.         while (entNode)
  287.         {
  288.             // call PrintParentAttrsHTML to explore the parents
  289.             // of the entity, for each parent.
  290.         const EntityDescriptor *parent = entNode->EntityDesc();
  291.             PrintParentAttrsHTML(ent, parent, entout);
  292.             entNode = (EntityDescLinkNode*)entNode->NextNode();
  293.         }
  294.  
  295.         // local attributes
  296.         entout << "<HR>\n<H2>Local Attributes</H2>" << endl;
  297.         if (PrintAttrsHTML(ent, entout) == 0)
  298.             entout << "<EM>none</EM>" << endl;
  299.  
  300.         // subtypes
  301.         // We're going to traverse the subtypes by using the subtype list
  302.         // of the entity, a little more simply than in PrintParentAttrsHTML()
  303.         entout << "<HR>\n<H2>Subtypes</H2>" << endl;
  304.     entout << "<! -- The following entities inherit from this one>\n";
  305.         subs = &(ent->Subtypes());
  306.         entNode = (EntityDescLinkNode*)subs->GetHead();
  307.         if (entNode) 
  308.     {
  309.         entout << "<UL>" << endl;
  310.         EntityDescriptor *child;
  311.         while (entNode) 
  312.         {
  313.         child = entNode->EntityDesc();
  314.         entout << "<LI><A HREF=\"" << child->Name() << ".html\">";
  315.         entout << child->Name() << "</A>" << endl;
  316.         entNode = (EntityDescLinkNode*)entNode->NextNode();
  317.         }
  318.         entout << "</UL>" << endl;
  319.         }
  320.         else entout << "<EM>none</EM>" << endl;
  321.  
  322.     entout << "<HR>" << endl;
  323.         entout << "Click <A HREF=\"index.html\">here</A> to ";
  324.         entout << "return to the index." << endl;
  325.     }
  326.     root << "</UL>" << endl;
  327.     cout << "Done!" << endl;
  328. }
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.