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

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

The newest version!
/**
 * Copyright (c) 2008-2012 EBM WebSourcing, 2012-2023 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.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 String INTERNAL_BASE_URI_STR = INTERNAL_URI_SCHEME + ":" + INTERNAL_URI_PATH;

	private static final long serialVersionUID = 1L;

	private WSDL4ComplexWsdlElement elmt = null;

	@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");
		}
	}

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

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

	@Override
	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 = new HashMap<>();
			addAllWsdlDocuments(this, imptDocs, documents);
			imptDocs.addAllDocuments(documents.values());
			this.elmt.setImportedDocuments(imptDocs);
		}
	}

	private void addAllWsdlDocuments(AbsItfDescription description, ImportedDocuments imptDocs,
			Map documents) throws WSDL4ComplexWsdlException {
		// Insert all wsdl imports in document
		for (Import imptWsdl : (List) description.getImports()) {
			final URI location = imptWsdl.getLocationURI();
			final URI internalLocation = this.createInternalLocation(location);
			if (internalLocation != null && !documents.containsKey(internalLocation)) {
				if (imptWsdl.getDescription() != null) {					
					Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);

					doc.setOriginalLocation(location);
					doc.setLocation(internalLocation);
					doc.setImportedDescription(imptWsdl.getDescription());
					documents.put(internalLocation, doc);
					// change location
					imptWsdl.setLocationURI(internalLocation);

					// add recursive import
					addAllWsdlDocuments(imptWsdl.getDescription(), imptDocs, documents);
				}
			} else {
				// change location
				imptWsdl.setLocationURI(internalLocation);
			}
		}

		// Insert all wsdl includes in document
		for (Include inclWsdl : (List) description.getIncludes()) {
			final URI location = inclWsdl.getLocationURI();
			final URI internalLocation = this.createInternalLocation(location);
			if (internalLocation != null && !documents.containsKey(internalLocation)) {
				if (inclWsdl.getDescription() != null) {
					Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);

					doc.setOriginalLocation(location);
					doc.setLocation(internalLocation);
					doc.setImportedDescription(inclWsdl.getDescription());
					documents.put(internalLocation, doc);

					// change location
					inclWsdl.setLocationURI(internalLocation);

					// add recursive includes
					addAllWsdlDocuments(inclWsdl.getDescription(), imptDocs, documents);
				}
			} else {
				// change location
				inclWsdl.setLocationURI(internalLocation);
			}
		}

		// Insert all schema imports in document
		if (description.getTypes() != null) {
			for (org.ow2.easywsdl.schema.api.Import imptSchema : (List) description
					.getTypes().getImportedSchemas()) {
				final URI location = imptSchema.getLocationURI();
				final URI internalLocation = this.createInternalLocation(location);
				if (internalLocation != null && !documents.containsKey(internalLocation)) {
					if (imptSchema.getSchema() != null) {
						Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(),
								imptDocs);

						doc.setOriginalLocation(location);
						doc.setLocation(internalLocation);
						doc.setImportedSchema(imptSchema.getSchema());
						documents.put(internalLocation, doc);

						// change location
						imptSchema.setLocationURI(internalLocation);

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

			for (Schema schema : (List) description.getTypes().getSchemas()) {
				// add recursive schema imports
				addAllSchemaDocuments(schema, imptDocs, documents);
			}
		}
	}

	private void addAllSchemaDocuments(Schema schema, ImportedDocuments imptDocs, Map documents)
			throws WSDL4ComplexWsdlException {
		for (org.ow2.easywsdl.schema.api.Import imptSchema : schema.getImports()) {
			final URI location = imptSchema.getLocationURI();
			final URI internalLocation = this.createInternalLocation(location);
			if (internalLocation != null && !documents.containsKey(internalLocation)) {
				if (imptSchema.getSchema() != null) {
					Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);

					doc.setOriginalLocation(location);
					doc.setLocation(internalLocation);
					doc.setImportedSchema(imptSchema.getSchema());
					documents.put(internalLocation, doc);

					// change location
					imptSchema.setLocationURI(internalLocation);

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

		}

		for (org.ow2.easywsdl.schema.api.Include inclSchema : schema.getIncludes()) {
			final URI location = inclSchema.getLocationURI();
			final URI internalLocation = this.createInternalLocation(location);
			if (internalLocation != null && !documents.containsKey(internalLocation)) {
				if (inclSchema.getSchema() != null) {
					Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);

					doc.setOriginalLocation(location);
					doc.setLocation(internalLocation);
					doc.setImportedSchema(inclSchema.getSchema());
					documents.put(internalLocation, doc);

					// change location
					inclSchema.setLocationURI(internalLocation);

					// add recursive schema imports
					addAllSchemaDocuments(inclSchema.getSchema(), imptDocs, documents);
				}
			} else {
				// change location
				inclSchema.setLocationURI(internalLocation);
			}
		}
		
		for (org.ow2.easywsdl.schema.api.Redefine redefineSchema : schema.getRedefines()) {
			final URI location = redefineSchema.getLocationURI();
			final URI internalLocation = this.createInternalLocation(location);
			if (internalLocation != null && !documents.containsKey(internalLocation)) {
				if (redefineSchema.getSchema() != null) {
					Document doc = new DocumentImpl(new org.ow2.easywsdl.extensions.complexwsdl.Document(), imptDocs);

					doc.setOriginalLocation(location);
					doc.setLocation(internalLocation);
					doc.setImportedSchema(redefineSchema.getSchema());
					documents.put(internalLocation, doc);

					// change location
					redefineSchema.setLocationURI(internalLocation);

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

	private boolean isAlreadyInternalised(final URI location) {
		return INTERNAL_URI_SCHEME.equals(location.getScheme())
				&& (location.getSchemeSpecificPart().startsWith(INTERNAL_URI_PATH));
	}

    /**
     * The internalised form is used as:
     * 
     * 1) a unique string to find the documents when the imports are kept inside the description
     * 
     * 2) a unique string to reference the documents relative to a prefix added with
     * {@link #deleteImportedDocumentsInWsdl(URI)} when the imports are not inside the description
     */
    private URI createInternalLocation(final URI currentLocation) {
        // examples of URIs
        // http://truc/my/super/service?wsdl
        // http://truc/my/super/service?wsdl=another/thing.xsd
        // a/relative/file.xsd
        // afile.xsd
        // http://truc/my/super/schema.xsd
        if (currentLocation != null && !isAlreadyInternalised(currentLocation)) {
            // corresponds to (for each example)
            // /my/super/service, /my/super/service, a/relative/file.xsd, afile.xsd, /my/super/schema.xsd
            String path = currentLocation.getPath();

            // corresponds to (for each example)
            // wsdl, wsdl=another/thing.xsd, null, null, null
            String query = currentLocation.getQuery();
            if (query != null) {
                // corresponds to (for the first two examples)
                // /my/super/service/wsdl, /my/super/service/wsdl/another/thing.xsd
                // Note: it's ok to lose some info about the query,
                // since it is not used to reconstruct the original URI
                path = path + "/" + query.replaceAll("=", "/");
            }

            // remove first slash to stay relative
            if (path.startsWith("/")) {
                path = path.substring(1);
            }

            return URI.create(INTERNAL_BASE_URI_STR + path);
        } else {
            return currentLocation;
        }
    }

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

	@Override
	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()));
			}
		}
	}

	private URI createExternalLocation(final URI newBaseURI, final URI currentLocation) {
		if (currentLocation != null && isAlreadyInternalised(currentLocation)) {
			// careful, calling INTERNAL_BASE_URI.relativize(currentLocation) does not work
			// if there are segments such as ".." in the URI (because relativize normalizes the URI beforehand)
            final String relativeURI = currentLocation.toString().substring(INTERNAL_BASE_URI_STR.length());
			return URI.create((newBaseURI != null ? newBaseURI.toString() : "") + relativeURI);
		} else {
			return currentLocation;
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy