Seite 1 von 1

Klassen mit Dia/UML generieren

Verfasst: Montag 20. März 2006, 13:23
von henning
Södele hier mal ein kleines zusammengehacktes script, mit dem man aus nem UML-Modell in dia python-klassen generieren kann.
Bitte keine Schimpfe für das teilweise unschöne geparse, lieber gleich verbessern :-)

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

"""
    mkclasses.py - Generate python classes from inside "dia"
    ========================================================
    
    Copyright (C) 2006  Henning Hasemann

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of
    the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    Known Bugs
    ----------
    * If class has no attributes or operations, no "pass" keyword is inserted.
    * Attributes without default value arent represented in any way
    * The parsing of the attribute- and operations-strings is quick and dirty
    * The output-filename is hardcoded below
    * This handles nothing more but UML classes and UML generalizations
    * This program will fail if you dont connect generalizations poperly

    Usage
    -----
    * Save this file in the directory you start dia from.
    * Start dia and open your project.
    * Make sure just that one project is open
    * Open the dia python console
    * type: "import mkclasses" (or whatever tha basename of this file is)
    * type: "mkclasses.generate(dia)"
    * This will hopefully produce a file "output.py" with contents looking
      rhoughly like a python file which represents your classes.
    * Improve this program

    History
    -------
    :2006-20-03: Created, Henning Hasemann (hhasemann at web dot de)
"""

__docformat__ = "restructuredtext"

output_file = "output.py"

import sys
import re
if sys.version_info < (2, 4):
  from sets import Set as set

def resolve_deps(d):
  fullfilled = set()

  while len(d):
    for k, v in d.items():
      if set(v.get("SUPER", [])) <= fullfilled:
        yield v
        fullfilled.add(k)
        del d[k]
        break
    else:
      raise StandardError("Zirkuläre Abhängigkeit")


def generate(dia):
  objs = dia.diagrams()[0].active_layer.objects

  classes = {}
  for o in objs:
    # A class store its properties
    if o.type.name == "UML - Class":
      name = o.properties["name"].value
      if not classes.has_key(name):
        classes[name] = {}
      classes[name].update(dict(o.properties))

    # Generalization, store superclass information
    if o.type.name == "UML - Generalization":
      superclass = o.handles[0].connected_to.object.properties["name"].value
      subclass = o.handles[1].connected_to.object.properties["name"].value

      if not classes.has_key(subclass):
        classes[subclass] = {}
      if not classes[subclass].has_key("SUPER"):
        classes[subclass]["SUPER"] = []
      classes[subclass]["SUPER"].append(superclass)

  # Now print out the classes
  r = ""
  for c in resolve_deps(classes):
    r += "class %s" % c["name"].value
    if c.has_key("SUPER"):
      r += "(%s)" % ",".join(c["SUPER"])
    r += ":\n"

    for a in c["attributes"].value:
      if "=" in a:
        r += "  %s = %s\n" % (a[1:].split(":")[0], a[1:].split("=")[1].strip())

    for a in c["operations"].value:
      fname, arglist = a[1:].split("(")
      args = arglist[:-1].split(",")
      r += "  def %s(%s): pass\n" % (fname, ", ".join([x.split(":")[0] for x in args]))

    r += "\n\n"

  f = open(output_file, "w")
  f.write(r)
  f.close()