adding perl XSLT and (maybe?) finishing up the javascript one
[OpenSRF.git] / examples / fieldmapper2perl.xsl
1 <xsl:stylesheet
2         version='1.0'
3         xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
4         xmlns:opensrf="http://opensrf.org/xmlns/opensrf"
5         xmlns:cdbi="http://opensrf.org/xmlns/opensrf/cdbi"
6         xmlns:perl="http://opensrf.org/xmlns/opensrf/perl"
7         xmlns:javascript="http://opensrf.org/xmlns/opensrf/javascript"
8         xmlns:c="http://opensrf.org/xmlns/opensrf/c">
9         <xsl:output method="text" />
10         <xsl:strip-space elements="xsl:*"/>
11         <xsl:variable name="last_field_pos"/>
12
13         <xsl:template match="/">
14 package Fieldmapper;
15 use JSON;
16 use Data::Dumper;
17 use base 'OpenSRF::Application';
18
19 use OpenSRF::Utils::Logger;
20 my $log = 'OpenSRF::Utils::Logger';
21
22 sub new {                                                            
23         my $self = shift;                                            
24         my $value = shift;                                              
25         if (defined $value) {
26                 if (!ref($value) or ref($value) ne 'ARRAY') {
27                         # go fetch the object by id...
28                 }
29         } else {
30                 $value = [];
31         }
32         return bless $value => $self->class_name;                    
33 }
34
35 sub decast {
36         my $self = shift;
37         return [ @$self ];
38 }       
39
40 sub DESTROY {} 
41
42 sub class_name {
43         my $class_name = shift;
44         return ref($class_name) || $class_name;
45 }
46
47 sub isnew { return $_[0][0]; }
48 sub ischanged { return $_[0][1]; }
49 sub isdeleted { return $_[0][2]; }
50
51
52                 <xsl:apply-templates select="opensrf:fieldmapper/opensrf:classes"/>
53
54 1;
55         </xsl:template>
56
57
58
59
60
61 <!-- sub-templates -->
62         <xsl:template match="opensrf:fieldmapper/opensrf:classes">
63                 <xsl:for-each select="opensrf:class">
64                         <xsl:sort select="@id"/>
65                         <xsl:apply-templates select="."/>
66                         <xsl:apply-templates select="opensrf:links/opensrf:link[@type='has_many']"/>
67                 </xsl:for-each>
68         </xsl:template>
69
70
71
72
73         <xsl:template match="opensrf:class">
74                 <xsl:apply-templates select="@perl:class"/>
75                 <xsl:apply-templates select="opensrf:fields"/>
76         </xsl:template>
77
78
79
80
81         <xsl:template match="opensrf:fields">
82                 <xsl:apply-templates select="opensrf:field"/>
83         </xsl:template>
84
85
86
87
88
89         <xsl:template match="@perl:class">
90  
91 #-------------------------------------------------------------------------------
92 # Class definition for "<xsl:value-of select="."/>"
93 #-------------------------------------------------------------------------------
94  
95 package <xsl:value-of select="."/>;
96 use base "<xsl:value-of select="../perl:superclass"/>";
97
98 {       my @real;
99         sub real_fields {
100                 push @real, @_ if (@_);
101                 return @real;
102         }
103 }
104
105 {       my $last_real;
106         sub last_real_field : lvalue {
107                 $last_real;
108         }
109 }
110
111         <xsl:if test="../@cdbi:class">
112 sub cdbi {
113         return "<xsl:value-of select="../@cdbi:class"/>";
114 }
115         </xsl:if>
116
117 sub json_hint {
118         return "<xsl:value-of select="../@id"/>";
119 }
120
121
122 sub is_virtual {
123         <xsl:choose>
124                 <xsl:when test="../@virutal">
125         return 1;
126                 </xsl:when>
127                 <xsl:otherwise>
128         return 0;
129                 </xsl:otherwise>
130         </xsl:choose>
131 }
132
133         </xsl:template>
134
135
136
137
138
139         <!-- scalar valued fields and "has_a" relationships -->
140         <xsl:template match="opensrf:field">
141
142                 <xsl:variable name="num"><xsl:number/></xsl:variable>
143                 <xsl:variable name="field_pos" select="$num + 2"/>
144                 <xsl:variable name="last_field_pos" select="$field_pos + 1"/>
145                 <xsl:variable name="field_name" select="@name"/>
146                 <xsl:variable name="classname" select="../../@perl:class"/>
147
148 # Accessor/mutator for <xsl:value-of select="$classname"/>::<xsl:value-of select="$field_name"/>:
149 __PACKAGE__->last_real_field()++;
150 __PACKAGE__->real_fields("<xsl:value-of select="$field_name"/>");
151 sub <xsl:value-of select="$field_name"/> {
152         my $self = shift;
153         my $new_val = shift;
154         $self->[<xsl:value-of select="$field_pos"/>] = $new_val if (defined $new_val);
155
156                 <xsl:if test="../../opensrf:links/opensrf:link[@field=$field_name and @type='has_a']">
157                         <!-- We have a fkey on this field.  Go fetch the referenced object. -->
158                         <xsl:variable
159                                 name="source"
160                                 select="../../opensrf:links/opensrf:link[@field=$field_name and @type='has_a']/@source"/>
161                         <xsl:variable
162                                 name="sourceclass"
163                                 select="//*[@id=$source]/@perl:class"/>
164
165         my $val = $self->[<xsl:value-of select="$field_pos"/>];
166
167         if (defined $self->[<xsl:value-of select="$field_pos"/>]) {
168                 if (!UNIVERSAL::isa($self->[<xsl:value-of select="$field_pos"/>], <xsl:value-of select="$sourceclass"/>)) {
169                         $self->[<xsl:value-of select="$field_pos"/>] = <xsl:value-of select="$sourceclass"/>->new($val);
170                 }
171         }
172                 </xsl:if>
173
174         return $self->[<xsl:value-of select="$field_pos"/>];
175 }
176
177
178 sub clear_<xsl:value-of select="$field_name"/> {
179         my $self = shift;
180         $self->[<xsl:value-of select="$field_pos"/>] = undef;
181         return 1;
182 }
183
184         </xsl:template>
185
186
187
188
189
190
191         <!-- "has_many" relationships -->
192         <xsl:template match="opensrf:links/opensrf:link[@type='has_many']">
193                 <xsl:variable name="num"><xsl:number/></xsl:variable>
194                 <xsl:variable name="source"><xsl:value-of select="@source"/></xsl:variable>
195                 <xsl:variable name="sourceclass"><xsl:value-of select="//*[@id=$source]/@perl:class"/></xsl:variable>
196                 <xsl:variable name="classname"><xsl:value-of select="../../@perl:class"/></xsl:variable>
197                 <xsl:variable name="id"><xsl:value-of select="../../@id"/></xsl:variable>
198                 <xsl:variable name="fkey" select="//*[@id=$source]/opensrf:links/opensrf:link[@type='has_a' and @source=$id]/@field"/>
199                 <xsl:variable name="pkey" select="../../opensrf:fields/opensrf:field[@cdbi:primary='true']/@name"/>
200
201 # accessor for <xsl:value-of select="$classname"/>::<xsl:value-of select="@field"/>:
202 sub <xsl:value-of select="@field"/> {
203         my $self = shift;
204  
205         my $_pos = <xsl:value-of select="$classname"/>->last_real_field + <xsl:value-of select="$num"/>;
206  
207         if (!ref($self->[$_pos]) ne 'ARRAY') {
208                 $self->[$_pos] = [];
209  
210         if (@{$self->[$_pos]} == 0) {
211                 # get the real thing.
212                 # search where <xsl:value-of select="$sourceclass"/>-><xsl:value-of select="$fkey"/> == $self-><xsl:value-of select="$pkey"/>;
213         }
214  
215         return $self->[$_pos];
216 }
217
218         </xsl:template>
219
220
221
222
223 </xsl:stylesheet>
224