1 /*
2  * Portions of this file Copyright 1999-2005 University of Chicago
3  * Portions of this file Copyright 1999-2005 The University of Southern California.
4  *
5  * This file or a portion of this file is licensed under the
6  * terms of the Globus Toolkit Public License, found at
7  * http://www.globus.org/toolkit/download/license.html.
8  * If you redistribute this file, with or without
9  * modifications, you must include this notice in the file.
10  */
11
12
13 #include "globus_common.h"
14 #include "version.h"
15 #include "globus_i_wsdl_parser.h"
16
17 #include "libxml/xmlschemas.h"
18 #include "libxml/schemasInternals.h"
19
20 #include "wsdl.h"
21
22 static int globus_l_wsdl_parser_activate();
23 static int globus_l_wsdl_parser_deactivate();
24
25 globus_module_descriptor_t              globus_i_wsdl_parser_module =
26 {
27     "globus_wsdl_parser",
28     globus_l_wsdl_parser_activate,
29     globus_l_wsdl_parser_deactivate,
30     GLOBUS_NULL,
31     GLOBUS_NULL,
32     &local_version
33 };
34
35 0 GlobusDebugDefine(GLOBUS_WSDL_PARSER);
36
37 static
38 int
39 globus_l_wsdl_parser_activate()
40 {
41 16     int                                 res = (int) GLOBUS_SUCCESS;
42
43 16     res = (int) globus_module_activate(GLOBUS_COMMON_MODULE);
44
45 16     GlobusDebugInit(GLOBUS_WSDL_PARSER, ERROR WARN TRACE INFO TEMPLATE XSDDUMP JSDEBUG);
46
47 16     return res;
48 }
49
50 static
51 int
52 globus_l_wsdl_parser_deactivate()
53 16 {
54 16     globus_result_t                     result = GLOBUS_SUCCESS;
55 16     globus_module_deactivate(GLOBUS_COMMON_MODULE);
56
57 16     GlobusDebugDestroy(GLOBUS_WSDL_PARSER);
58
59 16     return (int) result;
60 }
61
62 static void
63 internal_error_func(
64     void *                              context,
65     const char *                        message,
66     ...)
67 5 {
68 5     char *                              message_string;
69 5     va_list                             ap;
70 5     va_start(ap, message);
71 5     message_string = globus_common_v_create_string(message, ap);
72 5     va_end(ap);
73
74 5     if(GlobusWSDLDebug(GLOBUS_WSDL_DEBUG_WARN))
75     {
76 0         GlobusWSDLDebugPrintf(GLOBUS_WSDL_DEBUG_WARN, 
77                               (message_string ? 
78                                message_string : "Unknown Error"));
79     }
80     
81 5     *((globus_result_t *)context) = GlobusWSDLErrorParsingSchema(
82         (*((globus_result_t *)context)),
83         (message_string ? message_string : "Unknown Error"));
84     
85 5     if(message_string)
86     {
87 5         globus_free(message_string);
88     }
89 }
90
91 static void
92 internal_warn_func(
93     void *                              context,
94     const char *                        message,
95     ...)
96 0 {
97 0     if(GlobusWSDLDebug(GLOBUS_WSDL_DEBUG_WARN))
98     {
99 0         va_list                             ap;
100 0         va_start(ap, message);
101 0         vfprintf(GlobusWSDLDebugStream, message, ap);
102 0         va_end(ap);
103
104 0         *((globus_result_t *)context) = GLOBUS_SUCCESS;
105     }
106 }
107
108 void
109 xmlSchemaImportDump(void * payload, void * data, xmlChar * name)
110 0 {
111 0     FILE *                              output = (FILE *) data;
112 0     xmlSchemaImportPtr                  import = (xmlSchemaImportPtr) payload;
113
114 0     if(import == NULL)
115     {
116 0         fprintf(output, "Import: NULL\n");
117     }
118
119 0     xmlSchemaDump(output, import->schema);
120 }
121
122 void
123 wsdlImportDump(void * payload, void * data, xmlChar * name)
124 0 {
125 0     wsdlSchemaPtr                       schema;
126 0     wsdlImportPtr                       import = (wsdlImportPtr) payload;
127 0     FILE *                              output = (FILE *) data;
128
129 0     if(import == NULL)
130     {
131 0         fprintf(output, "WSDL Import: NULL\n");
132     }
133     
134 0     schema = import->schema;
135  
136 0     if(GlobusWSDLDebug(GLOBUS_WSDL_DEBUG_XSD_DUMP))
137     {
138 0         xmlSchemaPtr                    xsd;
139 0         xsd = schema->schemaTypes;
140 0         while(xsd)
141         {
142 0             xmlHashScan(xsd->schemasImports,
143                         xmlSchemaImportDump,
144                         GlobusWSDLDebugStream);
145 0             xmlSchemaDump(GlobusWSDLDebugStream, xsd);
146         
147 0             xsd = (xmlSchemaPtr) xsd->_private;
148         }
149
150 0         xmlHashScan(schema->importsDecl, 
151                     wsdlImportDump, GlobusWSDLDebugStream);
152     }
153 }
154
155 globus_result_t
156 globus_i_wsdl_parse_schema(
157     const char *                        schema_filename, 
158     wsdlSchemaPtr *                     schema)
159 16 {
160 16     xmlErrorPtr                         error = NULL;
161 16     wsdlParserCtxtPtr                   parser = NULL;
162 16     globus_result_t                     wsdl_result = GLOBUS_SUCCESS;
163 16     globus_result_t                     xsd_result = GLOBUS_SUCCESS;
164 16     globus_result_t                     result = GLOBUS_SUCCESS;
165 16     GlobusFuncName(globus_i_wsdl_parse_schema);
166 16     GlobusWSDLDebugEnter();
167
168 16     parser = wsdlNewParserCtxt(schema_filename);
169 16     if(!parser)
170     {
171 0         error = xmlGetLastError();
172 0         result = GlobusWSDLErrorParsingSchema(
173             GLOBUS_SUCCESS,
174             (error && error->message) ? error->message : "Parser Error");
175 0         goto exit;
176     }
177
178 16     wsdlSetParserErrors(parser, 
179                         internal_error_func, 
180                         internal_warn_func,
181                         (void *)&wsdl_result);
182
183 16     *schema = wsdlParse(parser);
184 16     if(!*schema)
185     {
186 5         if(wsdl_result != GLOBUS_SUCCESS)
187         {
188 5             if(GlobusWSDLDebug(GLOBUS_WSDL_DEBUG_WARN))
189             {
190 0                 GlobusWSDLDebugPrintf(
191                     GLOBUS_WSDL_DEBUG_WARN,
192                     (globus_error_print_chain(globus_error_peek(wsdl_result))));
193             }
194         }
195
196 5         wsdlSetParserErrors(parser, 
197                             internal_error_func, 
198                             internal_warn_func,
199                             (void *)&xsd_result);
200 5         *schema = wsdlParseXmlSchema(parser);
201 5         if(xsd_result != GLOBUS_SUCCESS)
202         {
203 0             if(wsdl_result != GLOBUS_SUCCESS)
204             {
205 0                 result = GlobusWSDLErrorParsingSchema(
206                     wsdl_result, "Parser Error");
207 0                 goto exit;
208             }
209             
210 0             result = GlobusWSDLErrorParsingSchema(
211                 xsd_result, "Parser Error");
212 0             goto exit;
213         }
214         
215 5         if(!*schema)
216         {
217 0             result = GlobusWSDLErrorParsingSchema(
218                 result, "Parser Error");
219 0             goto exit;
220         }
221
222 5         result = GLOBUS_SUCCESS;
223     }
224
225 16     if(GlobusWSDLDebug(GLOBUS_WSDL_DEBUG_XSD_DUMP))
226     {
227 0         xmlSchemaPtr                    xsd;
228 0         xsd = (*schema)->schemaTypes;
229 0         while(xsd)
230         {
231 0             xmlHashScan(xsd->schemasImports,
232                         xmlSchemaImportDump,
233                         GlobusWSDLDebugStream);
234 0             xmlSchemaDump(GlobusWSDLDebugStream, xsd);
235         
236 0             xsd = (xmlSchemaPtr) xsd->_private;
237         }
238
239 0         xmlHashScan((*schema)->importsDecl, 
240                     wsdlImportDump, GlobusWSDLDebugStream);
241     }
242
243   exit:
244
245 16     if(parser)
246     {
247 16         wsdlFreeParserCtxt(parser);
248     }
249
250 16     GlobusWSDLDebugExit();
251 16     return result;