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