package UMMF;

use 5.6.0;
use strict;
use warnings;


our $AUTHOR = q{ kstephens@users.sourceforge.net 2003/09/10 };
#our $REVISION = { my @r = (q$Revision: 1.14 $ =~ /\d+/g); sprintf '%d.' . '%03d' x $#r, @r };
our $VERSION = '0.25';

=head1 NAME

UMMF - UML Meta-Model Framework.  UML to code generation via XMI.  Implements UML 1.5 meta-model.   Provides object-oriented Perl interface for processing UML meta-models and models.  Imports XMI.  Includes XMI, Perl and Java code generation back-ends.

=head1 SYNOPSIS

  bin/ummf -e Perl someumlmodel.xmi

=head1 DESCRIPTION

Also See L<http://ummf.sourceforge.net> and the C<"examples"> directory in the distribution for more information.

=head1 What is UMMF?

UMMF is an open-source implementation of a UML Meta-meta-model, for the purposes of reifying UML meta-model implementations and to provide a platform for building flexible UML transformation tools.

It is written in Perl and provides an almost complete specification of the UML 1.5 meta-model in a human and machine-readable meta-meta-model description language. 

The meta-meta-model description is used to generate implementations of the UML meta-model in XMI, Perl and Java and other languages.  Thus, one specification of the meta-model can generate meta-model implementations in many programming languages.  Once a programming language has been targeted with an exporter, code can be generated for UML meta-models and models.

=head1 Why UMMF?

The goal of UMMF is processing of UML models and meta-models in a variety of implementation languages for the purpose of transforming UML models.

UMMF is self-hosting; for example: the Perl UMMF:UML::MetaModel package is generated by bootstrapping from the meta-meta-model.  The meta-meta-model is specified with the same specification as the meta-model.

Models can be imported from popular UML editors via XMI 1.0 and 1.2.  Meta-models and models can currently exported to XMI 1.2.

Code generated from UML models by UMMF is reflective; models can reflect on their own meta-models.  For example, the code exporters generate a C<__classifier()> method for each Class that will return the meta-model Classifier object for the model object.

Many inexpensive UML editors have inflexible or non-existant code generation tools.  Generating code using XSLT on XMI is an adventure into the pain of a W3C-sponsored hell.

UMMF allows you to control how your Model will be translated into code; add your special archtectural or environmental support without relying on third-party proprietary tools!

UMMF can provide a base UML meta-model implementation for other UML tools.

=head1 What is the development status of UMMF?

As of 2003/09/31, UMMF is still alpha software; everything and anything may change. But please keep in mind, it's not in my best interest to change it too much, because I rely on it.  UMMF is being actively developed and used for generating code for production systems.  I (Kurt Stephens) and dedicate significant resources to develop UMMF; I am building large systems in Perl using UML.

If you think that UMMF could be useful for your project or if I can help you get started, please let me know.

=head1 What does UMMF do?

UMMF transforms UML models to simplify code generation; for example:

=over 4

=item * Generate Interfaces for all Classes.

=item * Transform Classes with multiple inheritance to single inheritance using Interfaces.

=item * Resolve AssociationEnd name collisions across Generalizations.

=item * Generate interstitial Associations for AssociationClass' AssocationEnds

=item * Merge ModelElements from multiple XMI documents using Classifiers designated as 'ummf.placeholders'.  I<This functionality is very alpha.>

=back

Additional transformations will be developed to support other architectural concerns.

=head1 What can UMMF do?

As of 2004/03/30 (v0.20), UMMF can:

=over 4

=item * Generate Classifier code for UML 1.5 meta-model in Perl and Java, using code templates.

=item * Generate Classifier code for UML 1.5 meta-model for Tangram.

=item * Generate Classifier code for UML 1.5 meta-model from code generated from meta-meta-model.

=item * Generate Classifier code from UML 1.3 - 1.5 meta-model from XMI input.

=item * Import XMI 1.0 and 1.2.

=item * Export XMI 1.2.

=item * Directly read ArgoUML (XMI 1.0), Poseidon 1.x and 2.x (XMI 1.2) .zargo and .zuml files.

=item * Perform various model transformations (as listed above).

=item * Support method bodies in multiple implementation languages, by using C<"# UMMF-Lang: Perl"> or C<"// UMMF-Lang: Java"> comments to delimit different method implementations.

=item * Support model reflection in Perl.
      
Use of C<Serializable> for meta-model storage has been implemented and tested.

=item * Can export XMI for the UML-1.5 meta-model, using itself as the meta-meta-model.
      
Try running C<"bin/ummf -e XMI UML-1.5"> !!!

=item * Preliminary implementation of UML 1.5 "Behavioral Elements::Actions" meta-model package. I<This functionality is very alpha.>

=item * Preliminary implementation of OCL for UML 2.0:

=over 4

=item * AST Expression Trees I<This functionality is very alpha.>

=back

=item * Support for Tangram, the pure-Perl, orthogonal, object-relational persistence mapping layer. I<This functionality is out of beta!>

=back

=head1 What doesn't UMMF do?

As of 2003/09/31:

=over 4

=item * Does not support model reflection in Java.

=item * Does not correctly propagate UML documentation into template-generated code documentation (embedded POD).  I<This is implemented, but is not working correctly.>

=back

=head1 What should UMMF do?

=over 4

=item * Have more documentation.  More pod and maybe a Wiki?

=item * Have more examples.

=item * Have more test cases.

=item * Process OCL: An OCL parser and expression model is being built, based on the OCL for UML 2.0 RFP response draft.

=item * Have more exporters: IDL, C++, Objective-C, Scheme, PHP, etc.

=item * Generate code for UML State Machines and other models.

=item * Handle multiple UML meta-model versions.  A UML 2.0 meta-model specification file is currently being built.

=item * The things you wish UML editors did for you, like generate Perl or Befunge code the way you like it.  Please contribute!

=item * Bootstrap from the meta-meta-model with minimal assumptions.

=back

=head1 Where can I get UMMF?

The SourceForge site, http://sourceforge.net/projects/ummf/ or a pre-built version from CPAN.  You may want to check the CVS repository for the latests changes; point your browser at http://cvs.sourceforge.net/viewcvs.py/ummf/ummf/1.0/.

=head1 What does UMMF need?

As of 2004/03/30, UMMF requires:

=over 4

=item * Perl 5.6.1 (or later?)

=item * CPAN libnet 1.16 (or later)

=item * CPAN libxml-perl 0.07 (or later)

=item * CPAN Template 2.10 (or later)

=item * CPAN Set::Object 1.05 (or later)

=item * CPAN XML::Writer 0.4 (or later)

=item * CPAN XML::Parser 2.31 (or later)

=item * CPAN XML::DOM 1.42 (or later)

=item * CPAN Archive::Zip 1.06 (or later) (for .zargo and .zuml file support)

=item * CPAN Scalar::Util 1.13 (or later)

=item * CPAN Devel::StackTrace 1.03 (or later)

=item * CPAN Class::Multimethods 1.70 (or later)

=item * CPAN YAML

=back

Bootstrapping dependencies:

=over

=item * POSIX shell. (bin/sh)

=item * GNU make. (If you're stuck on Windoze, cygwin saves the day :)

=back


=head1 How do I use UMMF?

=over 4

=item * See "perldoc bin/ummf.pl"

=item * See other POD or see HTML documentation built in doc/html/index.html. (On-line version doc/html/index.html)

=item * See "ummf/example/ex*"

=back


=head1 How do I build (bootstrap) UMMF?

=over 4

=item 1. Make sure Perl is in your PATH.

=item 2. tar -zxvf ummf-*.tar.gz

=item 3. cd ummf-*

=item 4. If you do not have all the prerequise modules already installed:

C<perl sbin/ummf_install.pl>

=item 5. make bootstrap

This will build the UML meta-model classes in gen/perl.

=item 6. make

This will build the bin, gen/perl and doc/html directories.

=back


=head1 What mailing lists are available for UMMF?

=over 4

=item * UMMF-announce@lists.sourceforge.net

Low-volume list for new releases and other announcements.

=item * UMMF-user@lists.sourceforge.net

List for UMMF user issues, problems and support (may become high-volume)

=item * UMMF-devl@lists.sourceforge.net

Low-volume list for UMMF developers only.

=item * UMMF-cvs@lists.sourceforge.net

CVS notifications (may become high-volume)

=back


=head1 Not So Frequently Asked Questions


=head2 What is the relationship of this to MOF?

UMMF does not implement MOF, yet.  IMHO, MOF is simply a subset of UML "Foundation" meta-model Package with all the class names prefixed with "Meta" and plenty of CORBA IDL to keep OMG happy.  Maybe it exists because a lot of work was invested in hand-coded UML meta-model implementations.  :)  Actually, there significant differences between MOF and UML, but for purposes of handing UML models, specifying the UML meta-model as UML, as it is documented in the OMG specifications, instead of as a MOF model, works quite well.

If we need CORBA IDLs, then UMMF could have an IDL exporter that could generate IDL for *all* the M* layers.  Actually, a UMMF IDL exporter should generate the exact same IDLs from a MOF specification as the ones published by OMG, which look, to me, to be generated from *something*, just like the XMI DTDs.

To select a subset of the UML meta-model to represent MOF, the meta-model specification in UMMF could be annotated with C preprocessor #ifdef and #define to select the appropriate subset as specified in the table on p. xiii of the MOF 1.4 specification.

UMMF uses its UML meta-model description as its own meta-meta-model; the two are interchangable in UMMF since they mostly have the same task in UMMF: represent UML models and transform them; the UML meta-model is just a model in UMMF.

At some point it might make sense to have drop the hard-coded UML meta-model specification I wrote and generate its meta-model directly from analysis of the MOF IDLs published by OMG.  Then when OMG publishes new IDL mappings for subsequent versions of the MOF, we all get code for free.  But that may not work, since MOF is not UML.  Maybe I'm just getting myself confused here.  :)  Maybe when UML 2.0 makes it's sweeping changes to the UML meta-model, that will make sense. 

UMMF is a work in progress, but I think it has the potental to be the thing that generates standard UML meta-model implementions across many languages and environments.  Think of it as the "XML DOM" generator for the UML meta-model.


=head2 Why isn't UMMF written in Java? or C++?  or Cobol?

=over 4

=item * Perl has C<eval().> 

=item * Perl is better at string processing. 

=item * In Perl, you change an object's class at runtime, which makes bootstrapping the M2 layer really easy.

=item * Perl has real closures.

=item * Perl supports multiple inheritance; which supports the UML meta-model use of multiple Generalization parents directly.

=item * Perl is dynamically typed, which allows code to be reused across the M* layers, without resorting to a festering tree of interfaces; (either an object responds to foo() or it just doesn't :) 

=item * Perl has mechanisms for trapping and dispatching messages with undefined methods at run-time (via AUTOLOAD).

=item * Because Perl is a floor wax and a dessert topping!

=back

=head1 EXPORT

None exported.

=head1 ENVIRONMENT VARIABLES

=over

=item UMMF_RESOURCE_PATH

List of ":"-separated paths to search for UMMF resources.  If you are using the compiled CPAN distribution, you must include the C<"data"> directory from the distribution in this variable, or you can copy the C<"data"> directory to the directory named C<"UMMF"> where C<"UMMF.pm"> was installed by C<make install>.

=item UMMF_TEMPLATE_PATH

List of ":"-separated paths to search for UMMF Exporter templates.

=back

=head1 AUTHOR

Kurt Stephens, kstephens@users.sourceforge.net 2003/09/10

=head1 SEE ALSO

L<http://ummf.sourceforge.net>

=head1 VERSION

0.25

=head1 REVISION

$Revision: 1.14 $

=head1 METHODS

=cut


#######################################################################
# Global module dependencies
#

# Required by UMMF itself.
use Parse::RecDescent 1.94;
use XML::RegExp 0.02;
use XML::Parser 2.29; #2.34;
#use XML::SAX2Perl;
use XML::DOM 1.43; # lib-net-1.18, libwww-perl-5.76
#use Devel::StackTrace;
use Template 2.10;
use Archive::Zip 1.06;
use YAML 0.35;

# Required by generated Perl code.
use Carp qw(confess);
use Set::Object 1.05;
use Scalar::Util 1.13;
use Class::Multimethods 1.70;

#######################################################################


our $base_dir;
sub base_dir
{
  $base_dir;
}
sub set_base_dir
{
  my ($self, $x) = @_;

  $base_dir = $x;
}

$DB::single = 1;
my $package = __PACKAGE__;
$package =~ s@::@/@sg;
our $module_dir = $INC{"$package.pm"};
$module_dir =~ s/\.pm$//;

our $path_sep = ':';

=head2 resource_path

  UMMF->resource_path($type);

Returns a list of directories to search for files of type C<$type>.

=cut
sub resource_path
{
  my ($self, $type) = @_;

  no warnings;

  my $TYPE = uc($type);

  (
   # Explicit type path.
   split($path_sep, $ENV{"UMMF_${TYPE}_PATH"}),

   # Implicit type path.
   map(
       (
	$type ? ( "$_/ummf/$type" ) : ( ),
	"$_/ummf",
       ),
       split($path_sep, $ENV{'UMMF_RESOURCE_PATH'}),
       $base_dir ? ( "$base_dir/lib" ) : ( ),

       # Default installation path.
       "$module_dir/data",
      ),
     );
}


=head2 tmp_dir

  my $dir = UMMF->tmp_dir;

Returns directory to be used for temporary files.

=cut
my $tmp_dir;
sub tmp_dir
{
  $tmp_dir ||=
    (
     grep(-d $_ && -w $_,
	  grep(defined, 
	       $ENV{'TMP'},
	       $ENV{'TEMP'},
	      ),
	  '/tmp',
	  'c:/temp',
	  '/usr/tmp',
	  '/var/tmp',
	 ),
     '/tmp',
    )[0];
}


my $tempfile_id = 0;

=head2 make_tempfile

  my $filename = UMMF->make_tempfile;

Returns a temporary file.

=cut
sub make_tempfile
{
  my $self = shift;

  use UMMF;

  join('.', $self->tmp_dir . '/ummf', $$, ++ $tempfile_id, @_);
}


#######################################################################

1;

#######################################################################


### Keep these comments at end of file: kstephens@users.sourceforge.net 2003/09/10 ###
### Local Variables: ###
### mode:perl ###
### perl-indent-level:2 ###
### perl-continued-statement-offset:0 ###
### perl-brace-offset:0 ###
### perl-label-offset:0 ###
### End: ###

