Class Dtd2Def

java.lang.Object
eu.bandm.tools.d2d2.base.Dtd2Def

public class Dtd2Def extends Object
Simple dtd to d2d2 module converter, returns an instantiated Module or null in case of error.

Usage: Create an instance (always anew, no re-usage) and call convert().

Currently called by the ModuleRegistry, when a file (or resource) with ".dtd" is found relevant as a text format definition, and by Main directly when "task == dtd2def", because error handling is slightly different.

This code works on the DTM model of a dtd. It accepts a dtd in two cases

  1. No single name contains a colon character.
  2. Otherwise: No single name contains more than one(1) colon character. The pre-colon parts are considered namespace prefices. All occuring namespace prefices p are declared by a <?tdom xmlns:p="name_space_uri" ?> declaration. These declarations have the whole dtd (incl. all inclusions) as their scope, and do not conflict.

In the second mode, we need dis-ambiguation w.r.t. tags and w.r.t. names. In the current approach both is done by name mangling:
       xml:lang   --> xml_lang or xml_0_lang or xml_1_lang etc.
 
Currently, the "namespace" declarations on the d2d-module-level are indeed reconstructed, but they are not needed since explicit "xmlrep" modifiers are added to each constructed definition.

A different approach would generate local modules and import them again, but this would only avoid clashes of definition names, not of input tags!

What is done, is

  1. create top-level tags-parser for every element
  2. create one top-level dummy definition as container for local definitions for attributes.
  3. create a global attribute definition in this global container, if this is possible without a name clash.
  4. otherwise create a local definition.
  5. if the attribute's tag conflicts with the tag of a child element in the "first set" of the element's content model, than disambiguate by adding some prefix to the attribute's name to create an unambiguous tag.

    Technically this class returns an instance of Module, but it is completely resolved, thus can replace a genuine d2d ResolvedModule.

  • Field Details

    • msg

      Receiver of all error messages.
    • debuglevel

      protected final int debuglevel
      Evident
    • msgCounter

      protected final MessageCounter msgCounter
      Evident
    • input_dtd

      protected final DTD.Dtd input_dtd
      Evident
    • name

      protected final String name
      The name for the d2d definition module to create.
    • accesses

      Analyses the "<?tdom public ..?>" processing instructions. etc.
    • dtd2dtm

      final DTD2DTM dtd2dtm
      One single converter instance
    • result

      protected Module result
      Evident.
    • attContainer

      protected TagsRegExp attContainer
      One synthetic definition, used only for containing all common attribute definitions as its local definitions.
    • defaultNamespaceURI

      @Opt protected @Opt String defaultNamespaceURI
      Declared as the default name space by an explicit "<?tdom xmlns=...?>" processing instruction.
    • dtdname2ddfname

      protected final Map<NamespaceName,String> dtdname2ddfname
      Maps the names of the element and tttribute definitions in the dtd to the names of the generated d2d defintions. (The name is a little misleading, because the resolved names as stored in the DTM are contained, not those from the original DTD.)
    • namespacesDeclared

      protected boolean namespacesDeclared
      Whether a single "<?tdom xmlns...?>" has been found. If not, all DTD names are considered non-namespace-mode, and the colon ":" is not allowed to appear.
  • Constructor Details

  • Method Details

    • convert

      @Opt public @Opt Module convert()
      Convert one DTD.Dtd to a d2d module.
      1. Decide whether we are in namespace mode by collecting the corresponding tdom pi-s.
      2. Convert the DTD.Dtd to a DTM.Dtd, which may fail.
      3. Create a translation table for all namespace names in the Dtd.
      4. Visit all elements and translate their content model and attribute declarations.
    • mapNames

      protected void mapNames(NamespaceName nn, String s, Location<XMLDocumentIdentifier> elloc)
      Maps the dtd NamespaceName to an internal element name, after checking that not illegal characters are in the latter by calling Chars.checkName(String,Location,MessageReceiver).
      Parameters:
      nn - the name as occuring in the dtd
      s - the name as occuring in the constructed d2d definition
      elloc - the location of the source element declaration, for error messages.
    • tryMangle

      protected boolean tryMangle(NamespaceName nn, String name, Location<XMLDocumentIdentifier> elloc)
      If the name is already used, return false. Then the caller can try a different disambiguation mangling. Otherwise store it as a counterpart of the namespace name. Only called locally from makeElementNameTranslations_namespaceMode.
    • makeElementNameTranslations_namespaceMode

      protected void makeElementNameTranslations_namespaceMode(DTM.Dtd dtd)
      Make element name translation map. First add all names without uri (non-namespace name) and with the uri selected as default (no prefix) as directly corresponding to the d2d definition name. Afterwards mangle all those with different uris, using the prefices as hint for disambiguation mangling.

      (This assumes that a prefix carries some semantics, namely refers to the mapping which was in effect when reading the dtd. This shall be preserved for the programmer as a mere hint. Normally we ignore "prefix" and consider only uri and localName.)

    • makeElementNameTranslations_nonNamespaceMode

      protected void makeElementNameTranslations_nonNamespaceMode(DTM.Dtd dtd)
      Make element name translation map. Assumes that no dtd-name contains a colon ":". So the name for element from the dtd can be taken as a d2d definition name directly.