package UMMF;

use 5.6.0;
use strict;
use warnings;

our $AUTHOR = q{ kurt@umleta.com 2003/09/10 };
#our $REVISION = { my @r = (q$Revision: 1.17 $ =~ /\d+/g); sprintf '%d.' . '%03d' x $#r, @r };
our $VERSION = '1.02';

=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 VERSION

1.02

=head1 DESCRIPTION

See L<http://ummf.umleta.com/> 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 other 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 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 2006/05/13 (v1.02), 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 MOF 1.3 and MOF 1.4.1 meta-models (PRELIMINARY)

=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<XMI> 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 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.1/.

More information is available at http://ummf.umleta.com/

=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*"

=item * See "ummf/test/*.pl"

=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-simple

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

=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 COMPATABILITY

UMMF 1.x is not namespace compatable with UMMF 0.x.  

However, most code that used UML metamodel packages named "UMMF::UML::MetaModel::..." 
will now work with "UMMF::UML1_5::..".

Most other modules under "UMMF::UML::..." moved to "UMMF::Core::..." or "UMMF::Boot::...".


=head1 ENVIRONMENT VARIABLES

=over

=item UMMF_BOOTSTRAPPING

Defined to be true during bootstrapping into C<gen/perl>.

=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 EXPORT

None exported.

=head1 AUTHOR

Kurt Stephens, kurt@umleta.com 2006/05/13

=head1 SEE ALSO

L<http://ummf.umleta.com>

=head1 REVISION

$Revision: 1.17 $

=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;

use File::Basename;

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

sub version { $VERSION }

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

sub bootstrapping
{
  $ENV{'UMMF_BOOTSTRAPPING'};
}

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

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

  $module_dir;
}

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

our $module_base_dir;
sub module_base_dir
{
  unless ( $module_base_dir ) {
    $module_base_dir = dirname(module_dir);
    $module_base_dir =~ s@/lib/perl$@@s;
  }
  $module_base_dir;
}

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

  $base_dir = $x;
}

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" ) : ( ),

       &module_base_dir ? ( &module_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'},
	      ),
	  '/usr/tmp',
	  '/var/tmp',
	  'c:/temp',
	  '/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: ###

