All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.easywsdl.extensions.wsdl4complexwsdl.impl.DescriptionImpl Maven / Gradle / Ivy

There is a newer version: 2.8.0
Show newest version
/**
 * Copyright (c) 2008-2012 EBM WebSourcing, 2012-2016 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the New BSD License (3-clause license).
 *
 * This program/library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the New BSD License (3-clause license)
 * for more details.
 *
 * You should have received a copy of the New BSD License (3-clause license)
 * along with this program/library; If not, see http://directory.fsf.org/wiki/License:BSD_3Clause/
 * for the New BSD License (3-clause license).
 */
 
package org.ow2.easywsdl.extensions.wsdl4complexwsdl.impl;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.ow2.easywsdl.extensions.wsdl4complexwsdl.WSDL4ComplexWsdlFactory;
import org.ow2.easywsdl.extensions.wsdl4complexwsdl.api.Description;
import org.ow2.easywsdl.extensions.wsdl4complexwsdl.api.Document;
import org.ow2.easywsdl.extensions.wsdl4complexwsdl.api.ImportedDocuments;
import org.ow2.easywsdl.extensions.wsdl4complexwsdl.api.WSDL4ComplexWsdlElement;
import org.ow2.easywsdl.extensions.wsdl4complexwsdl.api.WSDL4ComplexWsdlException;
import org.ow2.easywsdl.schema.SchemaFactory;
import org.ow2.easywsdl.schema.api.Redefine;
import org.ow2.easywsdl.schema.api.Schema;
import org.ow2.easywsdl.schema.api.SchemaException;
import org.ow2.easywsdl.wsdl.WSDLFactory;
import org.ow2.easywsdl.wsdl.api.Binding;
import org.ow2.easywsdl.wsdl.api.Endpoint;
import org.ow2.easywsdl.wsdl.api.Import;
import org.ow2.easywsdl.wsdl.api.Include;
import org.ow2.easywsdl.wsdl.api.InterfaceType;
import org.ow2.easywsdl.wsdl.api.Service;
import org.ow2.easywsdl.wsdl.api.Types;
import org.ow2.easywsdl.wsdl.api.WSDLException;
import org.ow2.easywsdl.wsdl.api.abstractItf.AbsItfDescription;
import org.ow2.easywsdl.wsdl.decorator.DecoratorDescriptionImpl;

/**
 * @author Nicolas Salatge - EBM WebSourcing
 */
public class DescriptionImpl extends DecoratorDescriptionImpl implements Description {

	private final static String INTERNAL_URI_SCHEME = "xpath";
	private final static String INTERNAL_URI_PATH = "description/importedDocuments/document";
	private final static URI INTERNAL_BASE_URI;

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	private WSDL4ComplexWsdlElement elmt = null;

	static {
		try {
			INTERNAL_BASE_URI = new URI(INTERNAL_URI_SCHEME + "://" + INTERNAL_URI_PATH);
		} catch (final URISyntaxException e) {
			// The exception must be not thrown, otherwise an error has been
			// introduced in source code constants.
			throw new RuntimeException("Unable to build the default INTERNAL BASE URI.", e);
		}
	}

	@SuppressWarnings("unchecked")
	public DescriptionImpl(final AbsItfDescription wsdl) throws WSDLException {
		super(wsdl, null);

		AbsItfDescription firstWsdl = wsdl;
		if (wsdl instanceof DecoratorDescriptionImpl) {
			firstWsdl = ((DecoratorDescriptionImpl) wsdl).getFirstDescription();
		}

		if (firstWsdl instanceof org.ow2.easywsdl.wsdl.api.Description) {
			this.elmt = new WSDL4ComplexWsdlElementImpl(firstWsdl);
		} else {
			throw new WSDL4ComplexWsdlException("Impossible to find the correct first description");
		}
	}

	public ImportedDocuments getImportedDocuments() {
		return this.elmt.getImportedDocuments();
	}

	public void setImportedDocuments(ImportedDocuments docs) throws WSDL4ComplexWsdlException {
		this.elmt.setImportedDocuments(docs);
	}

	public void addImportedDocumentsInWsdl() throws WSDL4ComplexWsdlException {
		if(this.elmt.getImportedDocuments() == null || this.elmt.getImportedDocuments().getDocuments().isEmpty()) {
			ImportedDocuments imptDocs = new ImportedDocumentsImpl(new org.ow2.easywsdl.extensions.complexwsdl.ImportedDocuments(), this);
			Map documents = getAllWsdlDocuments(this, imptDocs);
			imptDocs.addAllDocuments(documents.values());
			this.elmt.setImportedDocuments(imptDocs);
		}
	}

	private Map getAllWsdlDocuments(AbsItfDescription description, ImportedDocuments imptDocs) throws WSDL4ComplexWsdlException {
		Map res = new HashMap();

		List wsdlImports = description.getImports();
		List wsdlIncludes = description.getIncludes();
		List schemaImports = null;
		if (description.getTypes() != null) {
			schemaImports = description.getTypes().getImportedSchemas();
		}
		//Map map = description.getSchemaLocation();

		// Insert all wsdl imports in document
		for (Import imptWsdl : wsdlImports) {
			URI internalLocation = this.createInternalLocation(imptWsdl.getLocationURI());
			if (!res.containsKey(internalLocation)) {
				if (imptWsdl.getDescription() != null) {					
					Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);
					doc.setOriginalLocation(imptWsdl.getLocationURI());
					doc.setLocation(internalLocation);
					doc.setImportedDescription(imptWsdl.getDescription());
					res.put(internalLocation, doc);
					// change location
					imptWsdl.setLocationURI(internalLocation);

					// add recursive import
					res.putAll(getAllWsdlDocuments(imptWsdl.getDescription(), imptDocs));
				}
			} else {
				// change location
				imptWsdl.setLocationURI(internalLocation);
			}

		}

		// Insert all wsdl includes in document
		for (Include inclWsdl : wsdlIncludes) {
			final URI internalLocation = this.createInternalLocation(inclWsdl.getLocationURI());
			if (!res.containsKey(internalLocation)) {
				if (inclWsdl.getDescription() != null) {
					Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);
					doc.setOriginalLocation(inclWsdl.getLocationURI());
					doc.setLocation(internalLocation);
					doc.setImportedDescription(inclWsdl.getDescription());
					res.put(internalLocation, doc);

					// change location
					inclWsdl.setLocationURI(internalLocation);

					// add recursive includes
					res.putAll(getAllWsdlDocuments(inclWsdl.getDescription(), imptDocs));
				}
			} else {
				// change location
				inclWsdl.setLocationURI(internalLocation);
			}
		}

		// Insert all schema imports in document
		if (description.getTypes() != null) {
			if (schemaImports != null) {
				for (org.ow2.easywsdl.schema.api.Import imptSchema : schemaImports) {
					final URI internalLocation = this.createInternalLocation(imptSchema.getLocationURI());
					if (!res.containsKey(internalLocation)) {
						if (imptSchema.getSchema() != null) {
							Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);
							doc.setOriginalLocation(imptSchema.getLocationURI());
							doc.setLocation(internalLocation);
							doc.setImportedSchema(imptSchema.getSchema());
							res.put(internalLocation, doc);

							// change location
							imptSchema.setLocationURI(internalLocation);

							// add recursive schema imports
							res.putAll(getAllSchemaDocuments(imptSchema.getSchema(), imptDocs));
						}
					} else {
						// change location
						imptSchema.setLocationURI(internalLocation);
					}

				}
			}


			for (Schema schema : (List) description.getTypes().getSchemas()) {
				// add recursive schema imports
				res.putAll(getAllSchemaDocuments(schema, imptDocs));
			}
		}
		return res;
	}

	private Map getAllSchemaDocuments(Schema schema, ImportedDocuments imptDocs) throws WSDL4ComplexWsdlException {
		Map res = new HashMap();

		for (org.ow2.easywsdl.schema.api.Import imptSchema : schema.getImports()) {
			final URI internalLocation = this.createInternalLocation(imptSchema.getLocationURI());
			if (!res.containsKey(internalLocation) && (imptSchema.getLocationURI() != null) && !(INTERNAL_URI_SCHEME.equals(imptSchema.getLocationURI().getScheme()) && imptSchema.getLocationURI().getSchemeSpecificPart().startsWith(INTERNAL_URI_PATH))) {
				if (imptSchema.getSchema() != null) {
					Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);

					doc.setOriginalLocation(imptSchema.getLocationURI());
					doc.setLocation(internalLocation);
					doc.setImportedSchema(imptSchema.getSchema());
					res.put(internalLocation, doc);

					// change location
					imptSchema.setLocationURI(internalLocation);

					// add recursive schema imports
					res.putAll(getAllSchemaDocuments(imptSchema.getSchema(), imptDocs));
				}
			} else {
				// change location
				if(internalLocation != null) {
					imptSchema.setLocationURI(internalLocation);
				}
			}

		}

		for (org.ow2.easywsdl.schema.api.Include inclSchema : schema.getIncludes()) {
			URI internalLocation = this.createInternalLocation(inclSchema.getLocationURI());
			if (!res.containsKey(internalLocation) && !(INTERNAL_URI_SCHEME.equals(inclSchema.getLocationURI().getScheme()) && inclSchema.getLocationURI().getSchemeSpecificPart().startsWith(INTERNAL_URI_PATH))) {
				if (inclSchema.getSchema() != null) {
					Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);

					doc.setOriginalLocation(inclSchema.getLocationURI());
					doc.setLocation(internalLocation);
					doc.setImportedSchema(inclSchema.getSchema());
					res.put(internalLocation, doc);

					// change location
					inclSchema.setLocationURI(internalLocation);

					// add recursive schema imports
					res.putAll(getAllSchemaDocuments(inclSchema.getSchema(), imptDocs));
				}
			} else {
				// change location
				inclSchema.setLocationURI(internalLocation);
			}
		}
		
		for (org.ow2.easywsdl.schema.api.Redefine redefineSchema : schema.getRedefines()) {
			URI internalLocation = this.createInternalLocation(redefineSchema.getLocationURI());
			if (!res.containsKey(internalLocation) && !(INTERNAL_URI_SCHEME.equals(redefineSchema.getLocationURI().getScheme()) && redefineSchema.getLocationURI().getSchemeSpecificPart().startsWith(INTERNAL_URI_PATH))) {
				if (redefineSchema.getSchema() != null) {
					Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);

					doc.setOriginalLocation(redefineSchema.getLocationURI());
					doc.setLocation(internalLocation);
					doc.setImportedSchema(redefineSchema.getSchema());
					res.put(internalLocation, doc);

					// change location
					redefineSchema.setLocationURI(internalLocation);

					// add recursive schema imports
					res.putAll(getAllSchemaDocuments(redefineSchema.getSchema(), imptDocs));
				}
			} else {
				// change location
				redefineSchema.setLocationURI(internalLocation);
			}
		}

		return res;
	}

	private URI createInternalLocation(URI currentLocation) throws WSDL4ComplexWsdlException {

		final URI internalLocation;
		if (currentLocation != null &&
				(!(currentLocation.toString().startsWith(INTERNAL_URI_SCHEME))) ) {


			String query = currentLocation.getQuery();
			if(query == null) {
				query = currentLocation.toString().substring(currentLocation.toString().lastIndexOf("/")+1);
			}

			String path = currentLocation.getPath();
			if(query.equals(path)) {
				path = null;
			} else {
				if(path == null) {
					path = currentLocation.toString();
				}
				if((path.toString().lastIndexOf("/") != -1)) {
					path = path.toString().substring(0, path.lastIndexOf("/"));
				} else {
					path = null;
				}
			}

			if(path == null) {
				path = "";
			} else if(path.lastIndexOf("/") != path.length()) {
				path = path + "/";
			}

			internalLocation = URI.create(INTERNAL_URI_SCHEME + "://" + INTERNAL_URI_PATH + "/" + path + query);

		}
		else {
			internalLocation = currentLocation;
		}
		return internalLocation;

	}

	/**
	 * {@inheritDoc}
	 */
	public Map deleteImportedDocumentsInWsdl() throws WSDL4ComplexWsdlException {
		return this.deleteImportedDocumentsInWsdl((URI)null);
	}

	/**
	 * {@inheritDoc}
	 */
	public Map deleteImportedDocumentsInWsdl(final URI newBaseURI) throws WSDL4ComplexWsdlException {
		Map imports = new HashMap();
		try {
			// The following has to be done only when the importedDocuments is not null ;-)
			if (this.getImportedDocuments() != null) {
				// get All imports
				URI externalLocation = null;
				org.w3c.dom.Document document = null;

				// get All import and include schema
				List schemaImportList = new ArrayList();

				if(this.getTypes() != null) {
					schemaImportList.addAll(this.getTypes().getImportedSchemas());
					for(Schema schema: this.getTypes().getSchemas()) {
						schemaImportList.addAll(schema.getImports());
						schemaImportList.addAll(schema.getIncludes());
						schemaImportList.addAll(schema.getRedefines());
					}
				}
				for (Document doc : this.getImportedDocuments().getDocuments()) {
					if (newBaseURI != null) {
						externalLocation = this.createExternalLocation(newBaseURI, doc.getLocation());
					} else if (doc.getOriginalLocation() != null) {
						externalLocation = doc.getOriginalLocation();
					}
					if (externalLocation != null) {
						List descriptionImportList = this.findImportWithLocation(this.getImports(), doc.getLocation());
						for (Import descriptionImport : descriptionImportList) {
							descriptionImport.setLocationURI(externalLocation);
						}
						List descriptionIncludeList = this.findIncludeWithLocation(this.getIncludes(), doc.getLocation());
						for (Include descriptionInclude : descriptionIncludeList) {
							descriptionInclude.setLocationURI(externalLocation);
						}
						
						for (org.ow2.easywsdl.schema.api.absItf.AbsItfInclude schemaImport : schemaImportList) {
							if(schemaImport.getLocationURI() != null && schemaImport.getLocationURI().equals(doc.getLocation())) {
								schemaImport.setLocationURI(externalLocation);
							}
						}
						if (doc.getImportedDescription() != null) {
							changeImportedLocationInWsdl(doc.getImportedDescription(), newBaseURI);
							if(doc.getImportedDescription() instanceof Description) {
								document = WSDL4ComplexWsdlFactory.newInstance().newWSDLWriter().getDocument((Description) doc.getImportedDescription());
							} else {
								document = WSDLFactory.newInstance().newWSDLWriter().getDocument(doc.getImportedDescription());
							}
						} else if (doc.getImportedSchema() != null) {
							changeImportedLocationInSchema(doc.getImportedSchema(), newBaseURI);
							document = SchemaFactory.newInstance().newSchemaWriter().getDocument(doc.getImportedSchema());
						}
						imports.put(externalLocation, document);
					}
				}
				// remove imported documents
				this.setImportedDocuments(null);
			}
		} catch (WSDLException e) {
			throw new WSDL4ComplexWsdlException(e);
		} catch (SchemaException e) {
			throw new WSDL4ComplexWsdlException(e);
		}
		return imports;
	}



	private List findIncludeWithLocation(List includes,
			URI location) {
		List res = new ArrayList();
		if(includes != null) {
			for(Include incl: includes) {
				if(incl.getLocationURI().equals(location)) {
					res.add(incl);
				}
			}
		}
		return res;
	}
	
	private List findRedefineWithLocation(List redefines,
			URI location) {
		List res = new ArrayList();
		if(redefines != null) {
			for(Redefine red: redefines) {
				if(red.getLocationURI().equals(location)) {
					res.add(red);
				}
			}
		}
		return res;
	}

	private List findImportWithLocation(List imports,
			URI location) {
		List res = new ArrayList();
		if(imports != null) {
			for(Import impt: imports) {
				if(impt.getLocationURI().equals(location)) {
					res.add(impt);
				}
			}
		}
		return res;
	}

	/**
	 * 
	 * @param description
	 * @param newBaseURI
	 *            The base URI of the new location to create. If null, the
	 *            original name of the document is used if not null too.
	 */
	private void changeImportedLocationInWsdl(AbsItfDescription description, final URI newBaseURI) {

		// TODO: change schemaLocation import

		List wsdlImports = description.getImports();
		List wsdlIncludes = description.getIncludes();
		List schemaImports = null;
		if (description.getTypes() != null) {
			schemaImports = description.getTypes().getImportedSchemas();
		}

		// change location in wsdl import
		for (Import impt : wsdlImports) {
			impt.setLocationURI(this.createExternalLocation(newBaseURI, impt.getLocationURI()));
		}

		// change location in wsdl include
		for (Include incl : wsdlIncludes) {
			incl.setLocationURI(this.createExternalLocation(newBaseURI, incl.getLocationURI()));
		}

		// change location in schema import
		if (schemaImports != null) {
			for (org.ow2.easywsdl.schema.api.Import impt : schemaImports) {
				impt.setLocationURI(this.createExternalLocation(newBaseURI, impt.getLocationURI()));
			}
		}

		// change location all schema imports in document
		if (description.getTypes() != null) {
			for (Schema schema : (List) description.getTypes().getSchemas()) {
				this.changeImportedLocationInSchema(schema, newBaseURI);
			}
		}
	}

	/**
	 * 
	 * @param schema
	 * @param newBaseURI
	 *            The base URI of the new location to create. If null, the
	 *            original name of the document is used if not null too.
	 */
	private void changeImportedLocationInSchema(Schema schema, final URI newBaseURI) {

		// change location in schema import
		for (org.ow2.easywsdl.schema.api.Import impt : schema.getImports()) {
			if(impt.getLocationURI() != null) {
				impt.setLocationURI(this.createExternalLocation(newBaseURI, impt.getLocationURI()));
			}
		}

		// change location in schema include
		for (org.ow2.easywsdl.schema.api.Include incl : schema.getIncludes()) {
			if(incl.getLocationURI() != null) {
				incl.setLocationURI(this.createExternalLocation(newBaseURI, incl.getLocationURI()));
			}
		}
		
		// change location in schema redefine
		for (org.ow2.easywsdl.schema.api.Redefine red : schema.getRedefines()) {
			if(red.getLocationURI() != null) {
				red.setLocationURI(this.createExternalLocation(newBaseURI, red.getLocationURI()));
			}
		}
	}

	/**
	 * 
	 * @param newBaseURI
	 *            The base URI of the new location to create. If null, the
	 *            original name of the document is used if not null too.
	 * @param currentLocation
	 * @return
	 */
	private URI createExternalLocation(final URI newBaseURI, final URI currentLocation) {
		URI externalLocation = null;
		if (currentLocation.toString().startsWith(INTERNAL_URI_SCHEME)) {
			final URI relativeURI = INTERNAL_BASE_URI.relativize(currentLocation);
			if (newBaseURI != null) {
				externalLocation = URI.create(newBaseURI.toString() + relativeURI.toString());
			}
			else {
				externalLocation = relativeURI;
			}
		} else {
			externalLocation = currentLocation;
		}
		return externalLocation;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy