Fix tests!
[dbsrgits/SQL-Translator.git] / lib / SQL / Translator / Parser / XML / XMI.pm
CommitLineData
1223c9b2 1package SQL::Translator::Parser::XML::XMI;
2
3# -------------------------------------------------------------------
821a0fde 4# $Id$
1223c9b2 5# -------------------------------------------------------------------
6# Copyright (C) 2003 Mark Addison <mark.addison@itn.co.uk>,
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; version 2.
11#
12# This program is distributed in the hope that it will be useful, but
13# WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15# General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20# 02111-1307 USA
21# -------------------------------------------------------------------
22
23=head1 NAME
24
25SQL::Translator::Parser::XML::XMI - Parser to create Schema from UML
26Class diagrams stored in XMI format.
27
28=cut
29
1223c9b2 30use strict;
31
1223c9b2 32$DEBUG = 0 unless defined $DEBUG;
33
34use Data::Dumper;
35use Exporter;
36use base qw(Exporter);
37@EXPORT_OK = qw(parse);
38
39use base qw/SQL::Translator::Parser/; # Doesnt do anything at the mo!
40use SQL::Translator::Utils 'debug';
f42065cb 41use SQL::Translator::XMI::Parser;
91ed9c32 42
f42065cb 43# SQLFairy Parser
44#-----------------------------------------------------------------------------
91ed9c32 45
f42065cb 46# is_visible - Used to check visibility in filter subs
47{
48 my %vislevel = (
49 public => 1,
50 protected => 2,
51 private => 3,
52 );
5cb154e5 53
f42065cb 54 sub is_visible {
55 my ($nodevis, $vis) = @_;
56 $nodevis = ref $_[0] ? $_[0]->{visibility} : $_[0];
57 return 1 unless $vis;
58 return 1 if $vislevel{$vis} >= $vislevel{$nodevis};
59 return 0;
5cb154e5 60 }
5cb154e5 61}
91ed9c32 62
538293f0 63my ($schema, $pargs);
64
1223c9b2 65sub parse {
66 my ( $translator, $data ) = @_;
f42065cb 67 local $DEBUG = $translator->debug;
538293f0 68 $schema = $translator->schema;
69 $pargs = $translator->parser_args;
b2a00f50 70 $pargs->{classes2schema} ||= \&classes2schema;
538293f0 71
ef2d7798 72 debug "Visibility Level:$pargs->{visibility}" if $DEBUG;
73
7f1e42e5 74 my $xmip = SQL::Translator::XMI::Parser->new(xml => $data);
f42065cb 75
1223c9b2 76 # TODO
77 # - Options to set the initial context node so we don't just
78 # blindly do all the classes. e.g. Select a diag name to do.
538293f0 79
f42065cb 80 my $classes = $xmip->get_classes(
81 filter => sub {
82 return unless $_->{name};
83 return unless is_visible($_, $pargs->{visibility});
84 return 1;
85 },
86 filter_attributes => sub {
87 return unless $_->{name};
88 return unless is_visible($_, $pargs->{visibility});
89 return 1;
90 },
91 );
f8ec05fa 92 debug "Found ".scalar(@$classes)." Classes: ".join(", ",
93 map {$_->{"name"}} @$classes) if $DEBUG;
7f1e42e5 94 debug "Model:",Dumper($xmip->{model}) if $DEBUG;
f8ec05fa 95
96 #
97 # Turn the data from get_classes into a Schema
98 #
b2a00f50 99 $pargs->{classes2schema}->($schema, $classes);
538293f0 100
101 return 1;
102}
103
b2a00f50 1041;
105
106# Default conversion sub. Makes all classes into tables using all their
107# attributes.
108sub classes2schema {
109 my ($schema, $classes) = @_;
538293f0 110
f8ec05fa 111 foreach my $class (@$classes) {
1223c9b2 112 # Add the table
b2a00f50 113 debug "Adding class: $class->{name}";
f8ec05fa 114 my $table = $schema->add_table( name => $class->{name} )
1223c9b2 115 or die "Schema Error: ".$schema->error;
116
117 #
118 # Fields from Class attributes
119 #
f8ec05fa 120 foreach my $attr ( @{$class->{attributes}} ) {
121 my %data = (
122 name => $attr->{name},
f8ec05fa 123 is_primary_key => $attr->{stereotype} eq "PK" ? 1 : 0,
1223c9b2 124 #is_foreign_key => $stereotype eq "FK" ? 1 : 0,
125 );
f8ec05fa 126 $data{default_value} = $attr->{initialValue}
127 if exists $attr->{initialValue};
b2a00f50 128 $data{data_type} = $attr->{_map_taggedValues}{dataType}{dataValue}
5365ac89 129 || $attr->{dataType}{name};
b2a00f50 130 $data{size} = $attr->{_map_taggedValues}{size}{dataValue};
131 $data{is_nullable}=$attr->{_map_taggedValues}{nullable}{dataValue};
1223c9b2 132
1223c9b2 133 my $field = $table->add_field( %data ) or die $schema->error;
1223c9b2 134 $table->primary_key( $field->name ) if $data{'is_primary_key'};
1223c9b2 135 }
136
137 } # Classes loop
538293f0 138}
1223c9b2 139
b2a00f50 1401;
538293f0 141
b2a00f50 142__END__
538293f0 143
b2a00f50 144=pod
538293f0 145
b2a00f50 146=head1 SYNOPSIS
538293f0 147
b2a00f50 148 use SQL::Translator;
149 use SQL::Translator::Parser::XML::XMI;
538293f0 150
b2a00f50 151 my $translator = SQL::Translator->new(
152 from => 'XML-XMI',
153 to => 'MySQL',
154 filename => 'schema.xmi',
155 show_warnings => 1,
156 add_drop_table => 1,
157 );
158
159 print $obj->translate;
1223c9b2 160
b2a00f50 161=head1 DESCRIPTION
1223c9b2 162
b2a00f50 163Translates XMI (UML models in XML format) into Schema. This basic parser
164will just pull out all the classes as tables with fields from their attributes.
165
166For more detail you will need to use a UML profile for data modelling. These are
167supported by sub parsers. See their docs for details.
168
169=over 4
170
171=item XML::XMI::Rational
172
173The Rational Software UML Data Modeling Profile
174
175=back
176
177=head1 ARGS
178
179=over 4
180
181=item visibility
182
183 visibilty=public|protected|private
184
185What visibilty of stuff to translate. e.g when set to 'public' any private
186and package Classes will be ignored and not turned into tables. Applies
187to Classes and Attributes.
188
189If not set or false (the default) no checks will be made and everything is
190translated.
191
192=back
193
194=head1 XMI Format
195
196Uses either XMI v1.0 or v1.2. The version to use is detected automatically
197from the <XMI> tag in the source file.
198
199The parser has been built using XMI 1.2 generated by PoseidonUML 2, which
200says it uses UML 2. So the current conformance is down to Poseidon's idea
201of XMI! 1.0 support is based on a Rose file, is less complete and has little
202testing.
f8ec05fa 203
1223c9b2 204
205=head1 BUGS
206
ef2d7798 207Seems to be slow. I think this is because the XMI files can get pretty
f42065cb 208big and complex, especially all the diagram info, and XPath needs to load the
209whole tree.
ef2d7798 210
b2a00f50 211Deleting the diagrams from an XMI1.2 file (make a backup!) will really speed
212things up. Remove <UML:Diagram> tags and all their contents.
1223c9b2 213
b2a00f50 214=head1 TODO
ef2d7798 215
b2a00f50 216More profiles.
1223c9b2 217
218=head1 AUTHOR
219
220Mark D. Addison E<lt>mark.addison@itn.co.ukE<gt>.
221
222=head1 SEE ALSO
223
224perl(1), SQL::Translator, XML::XPath, SQL::Translator::Producer::XML::SQLFairy,
225SQL::Translator::Schema.
226
227=cut
f8ec05fa 228
229