]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/c-apps/dump_idl.c
adding Scott's dump_idl utility, and adding jump support; makefile support for dump_idl
[Evergreen.git] / Open-ILS / src / c-apps / dump_idl.c
1 /*
2 *  C Implementation: dump_idl
3 *
4 * Description: 
5 *
6 *
7 * Author: Scott McKellar <scott@esilibrary.com>, (C) 2009
8 *
9 * Copyright: See COPYING file that comes with this distribution
10 *
11 */
12
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <opensrf/string_array.h>
16 #include <opensrf/osrf_hash.h>
17 #include <openils/oils_idl.h>
18
19 static void dump_idl( osrfHash* IDLHash );
20 static void dump_class( osrfHash* class_hash, const char* class_name );
21 static void dump_fields( osrfHash* field_hash );
22 static void dump_one_field( osrfHash* field_hash, const char* field_name );
23 static void dump_links( osrfHash* links_hash );
24 static void dump_one_link( osrfHash* link_hash, const char* link_name );
25 static void dump_permacrud( osrfHash* pcrud_hash );
26 static void dump_action( osrfHash* action_hash, const char* action_name );
27 static void dump_foreign_context( osrfHash* fc_hash );
28 static void dump_fc_class( osrfHash* fc_class_hash, const char* class_name );
29 static void dump_string_array( 
30         osrfStringArray* sarr, const char* name, const char* indent );
31
32 int main( int argc, char* argv[] ) {
33         int rc = 0;
34         
35         // Suppress informational messages
36         osrfLogSetLevel( OSRF_LOG_WARNING );
37
38         // Get name of IDL file, if specified on command line
39         const char* IDL_filename = NULL;
40         int filename_expected = 0;              // boolean
41         int i;
42         for( i = 1; i < argc; ++i ) {
43                 const char* arg = argv[ i ];
44                 printf( "%s\n", arg );
45                 if( filename_expected ) {
46                         IDL_filename = arg;
47                         filename_expected = 0;
48                 } else {
49                         if( '-' == arg[ 0 ] && 'f' == arg[1] ) {
50                                 if( IDL_filename ) {
51                                         fprintf( stderr, "Only one IDL file may be specified\n" );
52                                         return 1;
53                                 } else {
54                                         if( arg[ 2 ] )
55                                                 IDL_filename = arg + 2;
56                                         else
57                                                 filename_expected = 1;
58                                 }
59                         }
60                         else
61                                 break;
62                 }
63         }
64         
65         if( filename_expected ) {
66                 fprintf( stderr, "IDL filename expected on command line, not found\n" );
67                 return 1;
68         }
69
70         // No filename?  Look in the environment
71         if( !IDL_filename )
72                 IDL_filename = getenv( "OILS_IDL_FILENAME" );
73
74         // Still no filename?  Apply a default
75         if( !IDL_filename )
76                 IDL_filename = "/openils/conf/fm_IDL.xml";
77         
78         printf( "IDL filename: %s\n", IDL_filename );
79         
80         osrfHash* IDL = oilsIDLInit( IDL_filename );
81         if( NULL == IDL ) {
82                 fputs( "Failed to build IDL\n", stderr );
83                 rc = 1;
84         }
85
86         if( i >= argc )
87                 // No classes specified?  Dump them all
88                 dump_idl( IDL );
89         else do {
90                 // Dump the requested classes
91                 dump_class( osrfHashGet( IDL, argv[ i ] ), argv[ i ] );
92                 ++i;
93         } while( i < argc );
94                 
95         return rc;
96 }
97
98 static void dump_idl( osrfHash* IDLHash ) {
99         if( NULL == IDLHash )
100                 return;
101
102         if( 0 == osrfHashGetCount( IDLHash ) )
103                 return;
104
105         osrfHashIterator* iter = osrfNewHashIterator( IDLHash );
106         osrfHash* class_hash = NULL;
107         
108         // Dump each class
109         for( ;; ) {
110                 class_hash = osrfHashIteratorNext( iter );
111                 if( class_hash )
112                         dump_class( class_hash, osrfHashIteratorKey( iter ) );
113                 else
114                         break;
115         }
116
117         osrfHashIteratorFree( iter );
118 }
119
120 static void dump_class( osrfHash* class_hash, const char* class_name )
121 {
122         if( !class_hash || !class_name )
123                 return;
124         
125         if( 0 == osrfHashGetCount( class_hash ) )
126                 return;
127
128         printf( "Class %s\n", class_name );
129         const char* indent = "    ";
130         
131         osrfHashIterator* iter = osrfNewHashIterator( class_hash );
132         
133         // Dump each attribute, etc. of the class hash
134         for( ;; ) {
135                 void* class_attr = osrfHashIteratorNext( iter );
136                 if( class_attr ) {
137                         const char* attr_name = osrfHashIteratorKey( iter );
138                         if( !strcmp( attr_name, "classname" ) )
139                                 printf( "%s%s: %s\n", indent, attr_name, (char*) class_attr );
140                         else if( !strcmp( attr_name, "fieldmapper" ) )
141                                 printf( "%s%s: %s\n", indent, attr_name, (char*) class_attr );
142                         else if( !strcmp( attr_name, "tablename" ) )
143                                 printf( "%s%s: %s\n", indent, attr_name, (char*) class_attr );
144                         else if( !strcmp( attr_name, "virtual" ) )
145                                 printf( "%s%s: %s\n", indent, attr_name, (char*) class_attr );
146                         else if( !strcmp( attr_name, "controller" ) )
147                                 dump_string_array( (osrfStringArray*) class_attr, attr_name, indent );
148                         else if( !strcmp( attr_name, "fields" ) )
149                                 dump_fields( (osrfHash*) class_attr );
150                         else if( !strcmp( attr_name, "links" ) )
151                                 dump_links( (osrfHash*) class_attr );
152                         else if( !strcmp( attr_name, "primarykey" ) )
153                                 printf( "%s%s: %s\n", indent, attr_name, (char*) class_attr );
154                         else if( !strcmp( attr_name, "sequence" ) )
155                                 printf( "%s%s: %s\n", indent, attr_name, (char*) class_attr );
156                         else if( !strcmp( attr_name, "permacrud" ) )
157                                 dump_permacrud( (osrfHash*) class_attr );
158                         else if( !strcmp( attr_name, "source_definition" ) )
159                                 printf( "%s%s:\n%s\n", indent, attr_name, (char*) class_attr );
160                         else
161                                 printf( "%s%s (unknown)\n", indent, attr_name );
162                 } else
163                         break;
164         }
165 }
166
167 static void dump_fields( osrfHash* fields_hash ) {
168         if( NULL == fields_hash )
169                 return;
170
171         if( 0 == osrfHashGetCount( fields_hash ) )
172                 return;
173
174         fputs( "    fields\n", stdout );
175         
176         osrfHashIterator* iter = osrfNewHashIterator( fields_hash );
177         osrfHash* fields_attr = NULL;
178         
179         // Dump each field
180         for( ;; ) {
181                 fields_attr = osrfHashIteratorNext( iter );
182                 if( fields_attr )
183                         dump_one_field( fields_attr, osrfHashIteratorKey( iter ) );
184                 else
185                         break;
186         }
187
188         osrfHashIteratorFree( iter );
189 }
190
191 static void dump_one_field( osrfHash* field_hash, const char* field_name ) {
192         if( !field_hash || !field_name )
193                 return;
194         
195         if( 0 == osrfHashGetCount( field_hash ) )
196                 return;
197
198         printf( "        %s\n", field_name  );
199         
200         osrfHashIterator* iter = osrfNewHashIterator( field_hash );
201         const char* field_attr = NULL;
202         const char* indent = "            ";
203         
204         // Dump each field attribute
205         for( ;; ) {
206                 field_attr = osrfHashIteratorNext( iter );
207                 if( field_attr )
208                         printf( "%s%s: %s\n", indent, osrfHashIteratorKey( iter ), field_attr );
209                 else
210                         break;
211         }
212
213         osrfHashIteratorFree( iter );
214 }
215
216 static void dump_links( osrfHash* links_hash ) {
217         if( NULL == links_hash )
218                 return;
219
220         if( 0 == osrfHashGetCount( links_hash ) )
221                 return;
222
223         fputs( "    links\n", stdout );
224         
225         osrfHashIterator* iter = osrfNewHashIterator( links_hash );
226         osrfHash* links_attr = NULL;
227         
228         // Dump each link
229         for( ;; ) {
230                 links_attr = osrfHashIteratorNext( iter );
231                 if( links_attr )
232                         dump_one_link( links_attr, osrfHashIteratorKey( iter ) );
233                 else
234                         break;
235         }
236
237         osrfHashIteratorFree( iter );
238 }
239
240 static void dump_one_link( osrfHash* link_hash, const char* link_name ) {
241         if( !link_hash || !link_name )
242                 return;
243         
244         if( 0 == osrfHashGetCount( link_hash ) )
245                 return;
246
247         printf( "        %s\n", link_name  );
248         
249         osrfHashIterator* iter = osrfNewHashIterator( link_hash );
250         const void* link_attr = NULL;
251         const char* indent = "            ";
252         
253         // Dump each link attribute
254         for( ;; ) {
255                 link_attr = osrfHashIteratorNext( iter );
256                 if( link_attr ) {
257                         const char* link_attr_name = osrfHashIteratorKey( iter );
258                         if( !strcmp( link_attr_name, "reltype" ) )
259                                 printf( "%s%s: %s\n", indent, link_attr_name, (char*) link_attr );
260                         else if( !strcmp( link_attr_name, "key" ) )
261                                 printf( "%s%s: %s\n", indent, link_attr_name, (char*) link_attr );
262                         else if( !strcmp( link_attr_name, "class" ) )
263                                 printf( "%s%s: %s\n", indent, link_attr_name, (char*) link_attr );
264                         else if( !strcmp( link_attr_name, "map" ) ) 
265                                 dump_string_array( (osrfStringArray*) link_attr, link_attr_name, indent );
266                         else if( !strcmp( link_attr_name, "field" ) )
267                                 printf( "%s%s: %s\n", indent, link_attr_name, (char*) link_attr );
268                         else
269                                 printf( "%s%s (unknown)\n", indent, link_attr_name );
270                 } else
271                         break;
272         }
273
274         osrfHashIteratorFree( iter );
275 }
276
277 static void dump_permacrud( osrfHash* pcrud_hash ) {
278         if( NULL == pcrud_hash )
279                 return;
280
281         if( 0 == osrfHashGetCount( pcrud_hash ) )
282                 return;
283
284         fputs( "    permacrud\n", stdout );
285         
286         osrfHashIterator* iter = osrfNewHashIterator( pcrud_hash );
287         osrfHash* pcrud_attr = NULL;
288
289         // Dump each action
290         for( ;; ) {
291                 pcrud_attr = osrfHashIteratorNext( iter );
292                 if( pcrud_attr )
293                         dump_action( pcrud_attr, osrfHashIteratorKey( iter ) );
294                 else
295                         break;
296         }
297
298         osrfHashIteratorFree( iter );
299 }
300
301 static void dump_action( osrfHash* action_hash, const char* action_name ) {
302         if( !action_hash || !action_name )
303                 return;
304
305         if( 0 == osrfHashGetCount( action_hash ) )
306                 return;
307
308         printf( "        %s\n", action_name );
309
310         osrfHashIterator* iter = osrfNewHashIterator( action_hash );
311         void* action_attr = NULL;
312         const char* indent = "            ";
313
314         // Dump each attribute of the action
315         for( ;; ) {
316                 action_attr = osrfHashIteratorNext( iter );
317                 if( action_attr ) {
318                         const char* attr_name = osrfHashIteratorKey( iter );
319                         if( !strcmp( attr_name, "permission" ) )
320                                 dump_string_array( action_attr, attr_name, indent );
321                         else if( !strcmp( attr_name, "global_required" ) )
322                                 printf( "%s%s: %s\n", indent, attr_name, (char*) action_attr );
323                         else if( !strcmp( attr_name, "local_context" ) )
324                                 dump_string_array( action_attr, attr_name, indent );
325                         else if( !strcmp( attr_name, "foreign_context" ) )
326                                 dump_foreign_context( action_attr );
327                         else
328                                 printf( "%s%s (unknown)\n", indent, attr_name );
329                 } else
330                         break;
331         }
332
333         osrfHashIteratorFree( iter );
334 }
335
336 static void dump_foreign_context( osrfHash* fc_hash ) {
337         if( !fc_hash )
338                 return;
339         
340         if( 0 == osrfHashGetCount( fc_hash ) )
341                 return;
342
343         fputs( "            foreign_context\n", stdout );
344
345         osrfHashIterator* iter = osrfNewHashIterator( fc_hash );
346         osrfHash* fc_attr = NULL;
347
348         // Dump each foreign context attribute
349         for( ;; ) {
350                 fc_attr = osrfHashIteratorNext( iter );
351                 if( fc_attr )
352                         dump_fc_class( (osrfHash*) fc_attr, osrfHashIteratorKey( iter ) );
353                 else
354                         break;
355         }
356
357         osrfHashIteratorFree( iter );
358 }
359
360 static void dump_fc_class( osrfHash* fc_class_hash, const char* class_name )
361 {
362         if( ! fc_class_hash )
363                 return;
364         
365         if( 0 == osrfHashGetCount( fc_class_hash ) )
366                 return;
367         
368         printf( "                %s\n", class_name );
369
370         osrfHashIterator* iter = osrfNewHashIterator( fc_class_hash );
371         void* fc_class_attr = NULL;
372         const char* indent = "                    ";
373
374         // Dump each foreign context attribute
375         for( ;; ) {
376                 fc_class_attr = osrfHashIteratorNext( iter );
377                 if( fc_class_attr ) {
378                         const char* fc_class_attr_name = osrfHashIteratorKey( iter );
379                         if( !strcmp( fc_class_attr_name, "field" ) )
380                                 printf( "%s%s: %s\n", indent, fc_class_attr_name, (const char*) fc_class_attr );
381                         else if( !strcmp( fc_class_attr_name, "fkey" ) )
382                                 printf( "%s%s: %s\n", indent, fc_class_attr_name, (const char*) fc_class_attr );
383                         else if( !strcmp( fc_class_attr_name, "jump" ) )
384                                 dump_string_array( (osrfStringArray*) fc_class_attr, fc_class_attr_name, indent );
385                         else if( !strcmp( fc_class_attr_name, "context" ) )
386                                 dump_string_array( (osrfStringArray*) fc_class_attr, fc_class_attr_name, indent );
387                         else
388                                 printf( "%s%s\n", indent, fc_class_attr_name );
389                 } else
390                         break;
391         }
392
393         osrfHashIteratorFree( iter );
394 }
395
396 static void dump_string_array( 
397         osrfStringArray* sarr, const char* name, const char* indent ) {
398         if( !sarr || !name || !indent )
399                 return;
400
401         int size = sarr->size;
402
403         // Ignore an empty array
404         if( 0 == size )
405                 return;
406
407         printf( "%s%s (string array)\n", indent, name );
408
409         int i;
410         for( i = 0; i < size; ++i )
411                 printf( "%s\t%s\n", indent, osrfStringArrayGetString( sarr, i ) );
412 }