1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20
21 package org.apache.axis2.deployment.repository.util;
22
23 import org.apache.axiom.om.OMElement;
24 import org.apache.axiom.om.OMNamespace;
25 import org.apache.axis2.AxisFault;
26 import org.apache.axis2.context.ConfigurationContext;
27 import org.apache.axis2.deployment.DeploymentConstants;
28 import org.apache.axis2.deployment.DeploymentErrorMsgs;
29 import org.apache.axis2.deployment.DeploymentException;
30 import org.apache.axis2.deployment.DescriptionBuilder;
31 import org.apache.axis2.deployment.ModuleBuilder;
32 import org.apache.axis2.deployment.ServiceBuilder;
33 import org.apache.axis2.deployment.ServiceGroupBuilder;
34 import org.apache.axis2.deployment.resolver.AARBasedWSDLLocator;
35 import org.apache.axis2.deployment.resolver.AARFileBasedURIResolver;
36 import org.apache.axis2.deployment.resolver.WarBasedWSDLLocator;
37 import org.apache.axis2.deployment.resolver.WarFileBasedURIResolver;
38 import org.apache.axis2.description.AxisModule;
39 import org.apache.axis2.description.AxisService;
40 import org.apache.axis2.description.AxisServiceGroup;
41 import org.apache.axis2.description.WSDL11ToAllAxisServicesBuilder;
42 import org.apache.axis2.description.WSDL11ToAxisServiceBuilder;
43 import org.apache.axis2.description.WSDL20ToAllAxisServicesBuilder;
44 import org.apache.axis2.description.WSDL2Constants;
45 import org.apache.axis2.description.WSDLToAxisServiceBuilder;
46 import org.apache.axis2.engine.AxisConfiguration;
47 import org.apache.axis2.i18n.Messages;
48 import org.apache.axis2.namespace.Constants;
49 import org.apache.axis2.util.Utils;
50 import org.apache.axis2.util.XMLUtils;
51 import org.apache.commons.logging.Log;
52 import org.apache.commons.logging.LogFactory;
53
54 import javax.xml.stream.XMLStreamException;
55 import java.io.ByteArrayInputStream;
56 import java.io.ByteArrayOutputStream;
57 import java.io.File;
58 import java.io.FileInputStream;
59 import java.io.FileNotFoundException;
60 import java.io.IOException;
61 import java.io.InputStream;
62 import java.util.ArrayList;
63 import java.util.HashMap;
64 import java.util.List;
65 import java.util.zip.ZipEntry;
66 import java.util.zip.ZipInputStream;
67
68 public class ArchiveReader implements DeploymentConstants {
69 private static final Log log = LogFactory.getLog(ArchiveReader.class);
70
71 public ArrayList<AxisService> buildServiceGroup(InputStream zin, DeploymentFileData currentFile,
72 AxisServiceGroup axisServiceGroup, HashMap<String, AxisService> wsdlServices,
73 ConfigurationContext configCtx)
74 throws XMLStreamException, AxisFault {
75
76 DescriptionBuilder builder = new DescriptionBuilder(zin, configCtx);
77 OMElement rootElement = builder.buildOM();
78 String elementName = rootElement.getLocalName();
79
80 if (TAG_SERVICE.equals(elementName)) {
81 AxisService axisService = null;
82 String serviceName = DescriptionBuilder.getShortFileName(currentFile.getName());
83 if (serviceName != null) {
84 axisService = (AxisService) wsdlServices.get(serviceName);
85 }
86 if (axisService == null) {
87 axisService = (AxisService) wsdlServices.get(
88 DescriptionBuilder.getShortFileName(currentFile.getName()));
89 }
90 if (axisService == null) {
91 axisService = new AxisService(serviceName);
92 } else {
93 axisService.setWsdlFound(true);
94 axisService.setCustomWsdl(true);
95 }
96
97 axisService.setParent(axisServiceGroup);
98 axisService.setClassLoader(currentFile.getClassLoader());
99
100 ServiceBuilder serviceBuilder = new ServiceBuilder(configCtx, axisService);
101 serviceBuilder.setWsdlServiceMap(wsdlServices);
102 AxisService service = serviceBuilder.populateService(rootElement);
103
104 ArrayList<AxisService> serviceList = new ArrayList<AxisService>();
105 serviceList.add(service);
106 return serviceList;
107 } else if (TAG_SERVICE_GROUP.equals(elementName)) {
108 ServiceGroupBuilder groupBuilder = new ServiceGroupBuilder(rootElement, wsdlServices,
109 configCtx);
110 return groupBuilder.populateServiceGroup(axisServiceGroup);
111 }
112 throw new AxisFault("Invalid services.xml found");
113 }
114
115 /**
116 * Extracts Service XML files and builds the service groups.
117 *
118 * @param filename
119 * @param axisServiceGroup
120 * @param extractService
121 * @param wsdlServices
122 * @param configCtx
123 * @return Returns ArrayList.
124 * @throws DeploymentException
125 */
126 public ArrayList<AxisService> processServiceGroup(String filename, DeploymentFileData currentFile,
127 AxisServiceGroup axisServiceGroup,
128 boolean extractService,
129 HashMap<String, AxisService> wsdlServices,
130 ConfigurationContext configCtx)
131 throws AxisFault {
132 // get attribute values
133 if (!extractService) {
134 ZipInputStream zin = null;
135 FileInputStream fin = null;
136 try {
137 fin = new FileInputStream(filename);
138 zin = new ZipInputStream(fin);
139 ZipEntry entry;
140 while ((entry = zin.getNextEntry()) != null) {
141 if (entry.getName().equalsIgnoreCase(SERVICES_XML)) {
142 axisServiceGroup.setServiceGroupName(
143 DescriptionBuilder.getShortFileName(currentFile.getName()));
144 return buildServiceGroup(zin, currentFile, axisServiceGroup, wsdlServices,
145 configCtx);
146 }
147 }
148 throw new DeploymentException(
149 Messages.getMessage(DeploymentErrorMsgs.SERVICE_XML_NOT_FOUND, filename));
150 } catch (Exception e) {
151 throw new DeploymentException(e);
152 } finally {
153 if (zin != null) {
154 try {
155 zin.close();
156 } catch (IOException e) {
157 log.info(Messages.getMessage("errorininputstreamclose"));
158 }
159 }
160 if (fin != null) {
161 try {
162 fin.close();
163 } catch (IOException e) {
164 log.info(Messages.getMessage("errorininputstreamclose"));
165 }
166 }
167 }
168 } else {
169 File file = new File(filename, SERVICES_XML);
170 if (!file.exists()) {
171 // try for meta-inf
172 file = new File(filename, SERVICES_XML.toLowerCase());
173 }
174 if (file.exists()) {
175 InputStream in = null;
176 try {
177 in = new FileInputStream(file);
178 axisServiceGroup.setServiceGroupName(currentFile.getName());
179 return buildServiceGroup(in, currentFile, axisServiceGroup, wsdlServices, configCtx);
180 } catch (FileNotFoundException e) {
181 throw new DeploymentException(
182 Messages.getMessage(DeploymentErrorMsgs.FILE_NOT_FOUND,
183 e.getMessage()));
184 } catch (XMLStreamException e) {
185 throw new DeploymentException(
186 Messages.getMessage(DeploymentErrorMsgs.XML_STREAM_EXCEPTION,
187 e.getMessage()));
188 } finally {
189 if (in != null) {
190 try {
191 in.close();
192 } catch (IOException e) {
193 log.info(Messages.getMessage("errorininputstreamclose"));
194 }
195 }
196 }
197 } else {
198 throw new DeploymentException(
199 Messages.getMessage(DeploymentErrorMsgs.SERVICE_XML_NOT_FOUND));
200 }
201 }
202 }
203
204 /**
205 * Creats AxisService.
206 *
207 * @param in
208 * @return Returns AxisService.
209 * @throws DeploymentException
210 */
211 private List<AxisService> processWSDLFile(WSDLToAxisServiceBuilder axisServiceBuilder,
212 File serviceArchiveFile,
213 boolean isArchive, InputStream in, String baseURI)
214 throws DeploymentException {
215 try {
216
217 if (serviceArchiveFile != null && isArchive) {
218 axisServiceBuilder.setCustomResolver(
219 new AARFileBasedURIResolver(serviceArchiveFile));
220 if (axisServiceBuilder instanceof WSDL11ToAllAxisServicesBuilder) {
221
222 ((WSDL11ToAllAxisServicesBuilder) axisServiceBuilder).setCustomWSDLResolver(
223 new AARBasedWSDLLocator(baseURI, serviceArchiveFile, in));
224
225 ((WSDL11ToAllAxisServicesBuilder) axisServiceBuilder).setDocumentBaseUri(
226 serviceArchiveFile.getCanonicalFile().toURI().toString());
227
228 } else if (axisServiceBuilder instanceof WSDL20ToAllAxisServicesBuilder) {
229 ((WSDL20ToAllAxisServicesBuilder) axisServiceBuilder).setCustomWSDLResolver(
230 new AARBasedWSDLLocator(baseURI, serviceArchiveFile, in));
231 // trying to use the jar scheme as the base URI. I think this can be used to handle
232 // wsdl 1.1 as well without using a custom URI resolver. Need to look at it later.
233 axisServiceBuilder.setBaseUri(
234 "jar:file://" + serviceArchiveFile.toURI() + "!/" + baseURI);
235 }
236 } else {
237 if (serviceArchiveFile != null) {
238 axisServiceBuilder.setBaseUri(
239 serviceArchiveFile.getParentFile().toURI().toString());
240
241 if (axisServiceBuilder instanceof WSDL11ToAllAxisServicesBuilder) {
242 ((WSDL11ToAllAxisServicesBuilder) axisServiceBuilder).setDocumentBaseUri(
243 serviceArchiveFile.getCanonicalFile().toURI().toString());
244 }
245 }
246 }
247 if (axisServiceBuilder instanceof WSDL11ToAllAxisServicesBuilder) {
248 return ((WSDL11ToAllAxisServicesBuilder) axisServiceBuilder).populateAllServices();
249 } else if (axisServiceBuilder instanceof WSDL20ToAllAxisServicesBuilder) {
250 return ((WSDL20ToAllAxisServicesBuilder) axisServiceBuilder).populateAllServices();
251 }
252 } catch (AxisFault axisFault) {
253 log.info("Trouble processing wsdl file :" + axisFault.getMessage());
254 if (log.isDebugEnabled()) {
255 log.debug(axisFault);
256 }
257 } catch (IOException ioex) {
258 log.info("Trouble processing wsdl file :" + ioex.getMessage());
259 if (log.isDebugEnabled()) {
260 log.debug(ioex);
261 }
262 }
263 return null;
264 }
265
266 /**
267 * Creates service objects from wsdl file inside a service archive file.
268 *
269 * @param file <code>ArchiveFileData</code>
270 * @throws DeploymentException <code>DeploymentException</code>
271 */
272 public HashMap<String, AxisService> processWSDLs(DeploymentFileData file)
273 throws DeploymentException {
274 File serviceFile = file.getFile();
275 // to store service come from wsdl files
276 HashMap<String, AxisService> servicesMap = new HashMap<String, AxisService>();
277 boolean isDirectory = serviceFile.isDirectory();
278 if (isDirectory) {
279 try {
280 File metaInfFolder = new File(serviceFile, META_INF);
281
282 if (!metaInfFolder.exists()) {
283 metaInfFolder = new File(serviceFile, META_INF.toLowerCase());
284 if (!metaInfFolder.exists()) {
285 throw new DeploymentException(
286 Messages.getMessage(
287 DeploymentErrorMsgs.META_INF_MISSING,
288 serviceFile.getName()));
289 }
290 }
291
292 processFilesInFolder(metaInfFolder, servicesMap);
293
294 } catch (FileNotFoundException e) {
295 throw new DeploymentException(e);
296 } catch (IOException e) {
297 throw new DeploymentException(e);
298 } catch (XMLStreamException e) {
299 throw new DeploymentException(e);
300 }
301 } else {
302 ZipInputStream zin;
303 FileInputStream fin;
304 try {
305 fin = new FileInputStream(serviceFile);
306 zin = new ZipInputStream(fin);
307
308 //TODO Check whether this WSDL is empty
309
310 ZipEntry entry;
311 byte[] buf = new byte[1024];
312 int read;
313 ByteArrayOutputStream out;
314 while ((entry = zin.getNextEntry()) != null) {
315 String entryName = entry.getName().toLowerCase();
316 if (entryName.startsWith(META_INF.toLowerCase())
317 && entryName.endsWith(SUFFIX_WSDL)) {
318 out = new ByteArrayOutputStream();
319
320 // we do not want to generate the services for the
321 // imported wsdl of one file.
322 if ((entryName.indexOf("/") != entryName.lastIndexOf("/"))
323 || (entryName.indexOf("wsdl_") != -1)) {
324 //only care abt the toplevel wsdl
325 continue;
326 }
327
328 while ((read = zin.read(buf)) > 0) {
329 out.write(buf, 0, read);
330 }
331
332 ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
333
334 // now the question is which version of WSDL file this archive contains.
335 // lets check the namespace of the root element and decide. But since we are
336 // using axiom (dude, you are becoming handy here :)), we will not build the
337 // whole thing.
338 OMNamespace documentElementNS =
339 ((OMElement) XMLUtils.toOM(in)).getNamespace();
340 if (documentElementNS != null) {
341 WSDLToAxisServiceBuilder wsdlToAxisServiceBuilder;
342 if (WSDL2Constants.WSDL_NAMESPACE
343 .equals(documentElementNS.getNamespaceURI())) {
344 // we have a WSDL 2.0 document here.
345 wsdlToAxisServiceBuilder = new WSDL20ToAllAxisServicesBuilder(
346 new ByteArrayInputStream(out.toByteArray()));
347 wsdlToAxisServiceBuilder.setBaseUri(entryName);
348 } else if (Constants.NS_URI_WSDL11.
349 equals(documentElementNS.getNamespaceURI())) {
350 wsdlToAxisServiceBuilder = new WSDL11ToAllAxisServicesBuilder(
351 new ByteArrayInputStream(out.toByteArray()));
352 ((WSDL11ToAxisServiceBuilder) wsdlToAxisServiceBuilder).setDocumentBaseUri(entryName);
353 } else {
354 throw new DeploymentException(Messages.getMessage("invalidWSDLFound"));
355 }
356 List<AxisService> services = processWSDLFile(wsdlToAxisServiceBuilder,
357 serviceFile, true,
358 new ByteArrayInputStream(
359 out.toByteArray()),
360 entry.getName());
361 if (services != null) {
362 for (int i = 0; i < services.size(); i++) {
363 AxisService axisService = (AxisService) services.get(i);
364 if (axisService != null) {
365 servicesMap.put(axisService.getName(), axisService);
366 }
367 }
368 }
369 }
370 }
371 }
372 try {
373 zin.close();
374 } catch (IOException e) {
375 log.info(e);
376 }
377 try {
378 fin.close();
379 } catch (IOException e) {
380 log.info(e);
381 }
382 } catch (FileNotFoundException e) {
383 throw new DeploymentException(e);
384 } catch (IOException e) {
385 throw new DeploymentException(e);
386 } catch (XMLStreamException e) {
387 throw new DeploymentException(e);
388 }
389 }
390 return servicesMap;
391 }
392
393 public List<AxisService> getAxisServiceFromWsdl(InputStream in,
394 ClassLoader loader, String wsdlUrl) throws Exception {
395 // ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
396
397 // now the question is which version of WSDL file this archive contains.
398 // lets check the namespace of the root element and decide. But since we are
399 // using axiom (dude, you are becoming handy here :)), we will not build the
400 // whole thing.
401 OMElement element = (OMElement) XMLUtils.toOM(in);
402 OMNamespace documentElementNS = element.getNamespace();
403 if (documentElementNS != null) {
404 WSDLToAxisServiceBuilder wsdlToAxisServiceBuilder;
405 ByteArrayOutputStream out = new ByteArrayOutputStream();
406 element.serialize(out);
407 if (Constants.NS_URI_WSDL11.
408 equals(documentElementNS.getNamespaceURI())) {
409 wsdlToAxisServiceBuilder = new WSDL11ToAllAxisServicesBuilder(
410 new ByteArrayInputStream(out.toByteArray()));
411 ((WSDL11ToAllAxisServicesBuilder)wsdlToAxisServiceBuilder).setCustomWSDLResolver(new WarBasedWSDLLocator(wsdlUrl,
412 loader,
413 new ByteArrayInputStream(
414 out.toByteArray())));
415 wsdlToAxisServiceBuilder.setCustomResolver(
416 new WarFileBasedURIResolver(loader));
417 return ((WSDL11ToAllAxisServicesBuilder)wsdlToAxisServiceBuilder).populateAllServices();
418 } else if (WSDL2Constants.WSDL_NAMESPACE.
419 equals(documentElementNS.getNamespaceURI())){
420 wsdlToAxisServiceBuilder = new WSDL20ToAllAxisServicesBuilder(
421 new ByteArrayInputStream(out.toByteArray()));
422 ((WSDL20ToAllAxisServicesBuilder)wsdlToAxisServiceBuilder).setCustomWSDLResolver(new WarBasedWSDLLocator(wsdlUrl,
423 loader,
424 new ByteArrayInputStream(
425 out.toByteArray())));
426 wsdlToAxisServiceBuilder.setCustomResolver(
427 new WarFileBasedURIResolver(loader));
428 return ((WSDL20ToAllAxisServicesBuilder)wsdlToAxisServiceBuilder).populateAllServices();
429 }
430 else {
431 throw new DeploymentException(Messages.getMessage("invalidWSDLFound"));
432 }
433 }
434 return null;
435 }
436
437 public void processFilesInFolder(File folder, HashMap<String, AxisService> servicesMap)
438 throws FileNotFoundException, XMLStreamException, DeploymentException {
439 File files[] = folder.listFiles();
440 for (int i = 0; i < files.length; i++) {
441 File file1 = files[i];
442 if (file1.getName().toLowerCase().endsWith(SUFFIX_WSDL)) {
443 InputStream in = new FileInputStream(file1);
444 FileInputStream in2;
445
446 // now the question is which version of WSDL file this archive contains.
447 // lets check the namespace of the root element and decide. But since we are
448 // using axiom (dude, you are becoming handy here :)), we will not build the
449 // whole thing.
450 OMNamespace documentElementNS = ((OMElement) XMLUtils.toOM(in)).getNamespace();
451 if (documentElementNS != null) {
452 WSDLToAxisServiceBuilder wsdlToAxisServiceBuilder;
453 if (WSDL2Constants.WSDL_NAMESPACE
454 .equals(documentElementNS.getNamespaceURI())) {
455 // we have a WSDL 2.0 document here.
456 in2 = new FileInputStream(file1);
457 wsdlToAxisServiceBuilder = new WSDL20ToAllAxisServicesBuilder(in2);
458 } else if (Constants.NS_URI_WSDL11.
459 equals(documentElementNS.getNamespaceURI())) {
460 in2 = new FileInputStream(file1);
461 wsdlToAxisServiceBuilder = new WSDL11ToAllAxisServicesBuilder(in2);
462 ((WSDL11ToAxisServiceBuilder) wsdlToAxisServiceBuilder).setDocumentBaseUri(file1.toURI()
463 .toString());
464 } else {
465 throw new DeploymentException(Messages.getMessage("invalidWSDLFound"));
466 }
467
468 FileInputStream in3 = new FileInputStream(file1);
469 List<AxisService> services = processWSDLFile(wsdlToAxisServiceBuilder, file1, false,
470 in2, file1.toURI().toString());
471
472 if (services != null) {
473 for (int j = 0; j < services.size(); j++) {
474 AxisService axisService = (AxisService) services.get(j);
475 if (axisService != null) {
476 servicesMap.put(axisService.getName(), axisService);
477 }
478 }
479 }
480 try {
481 in2.close();
482 in3.close();
483 } catch (IOException e) {
484 log.info(e);
485 }
486 }
487 try {
488 in.close();
489 } catch (IOException e) {
490 log.info(e);
491 }
492 }
493 }
494 }
495
496 public void readModuleArchive(DeploymentFileData deploymentFile,
497 AxisModule module, boolean explodedDir,
498 AxisConfiguration axisConfig)
499 throws DeploymentException {
500
501 // get attribute values
502 boolean moduleXMLFound = false;
503 String shortFileName = DescriptionBuilder.getShortFileName(deploymentFile.getName());
504 if (!explodedDir) {
505 ZipInputStream zin;
506 FileInputStream fin;
507 try {
508 fin = new FileInputStream(deploymentFile.getAbsolutePath());
509 zin = new ZipInputStream(fin);
510 ZipEntry entry;
511 while ((entry = zin.getNextEntry()) != null) {
512 if (entry.getName().equalsIgnoreCase(MODULE_XML)) {
513 moduleXMLFound = true;
514 ModuleBuilder builder = new ModuleBuilder(zin, module, axisConfig);
515 // setting module name
516 module.setName(Utils.getModuleName(shortFileName));
517 module.setVersion(Utils.getModuleVersion(shortFileName));
518 builder.populateModule();
519 break;
520 }
521 }
522 zin.close();
523 fin.close();
524 if (!moduleXMLFound) {
525 throw new DeploymentException(
526 Messages.getMessage(
527 DeploymentErrorMsgs.MODULE_XML_MISSING,
528 deploymentFile.getAbsolutePath()));
529 }
530 } catch (Exception e) {
531 throw new DeploymentException(e);
532 }
533 } else {
534 File file = new File(deploymentFile.getAbsolutePath(), MODULE_XML);
535
536 if (file.exists() ||
537 (file = new File(deploymentFile.getAbsolutePath(), MODULE_XML.toLowerCase()))
538 .exists()) {
539 InputStream in = null;
540 try {
541 in = new FileInputStream(file);
542 ModuleBuilder builder = new ModuleBuilder(in, module, axisConfig);
543 // setting module name
544 module.setName(Utils.getModuleName(shortFileName));
545 module.setVersion(Utils.getModuleVersion(shortFileName));
546 builder.populateModule();
547 } catch (FileNotFoundException e) {
548 throw new DeploymentException(
549 Messages.getMessage(DeploymentErrorMsgs.FILE_NOT_FOUND,
550 e.getMessage()));
551 } finally {
552 if (in != null) {
553 try {
554 in.close();
555 } catch (IOException e) {
556 log.info(Messages.getMessage("errorininputstreamclose"));
557 }
558 }
559 }
560 } else {
561 throw new DeploymentException(
562 Messages.getMessage(
563 DeploymentErrorMsgs.MODULE_XML_MISSING,
564 deploymentFile.getAbsolutePath()));
565 }
566 }
567 }
568 }