/*******************************************************************************
* Copyright (c) 2010 SAP AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Emil Simeonov - initial API and implementation.
* Dimitar Donchev - initial API and implementation.
* Dimitar Tenev - initial API and implementation.
* Nevena Manova - initial API and implementation.
* Georgi Konstantinov - initial API and implementation.
* Keshav Veerapaneni - initial API and implementation.
*******************************************************************************/
package org.eclipse.wst.sse.sieditor.command.emf.wsdl;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.text.MessageFormat;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.xsd.XSDFactory;
import org.eclipse.xsd.XSDImport;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.impl.XSDImportImpl;
import org.eclipse.wst.sse.sieditor.command.common.AbstractWSDLNotificationOperation;
import org.eclipse.wst.sse.sieditor.model.Activator;
import org.eclipse.wst.sse.sieditor.model.api.IWsdlModelRoot;
import org.eclipse.wst.sse.sieditor.model.i18n.Messages;
import org.eclipse.wst.sse.sieditor.model.search.DocumentType;
import org.eclipse.wst.sse.sieditor.model.utils.EmfWsdlUtils;
import org.eclipse.wst.sse.sieditor.model.utils.ResourceUtils;
import org.eclipse.wst.sse.sieditor.model.wsdl.api.IDescription;
import org.eclipse.wst.sse.sieditor.model.wsdl.impl.Description;
import org.eclipse.wst.sse.sieditor.model.xsd.api.ISchema;
import org.eclipse.wst.sse.sieditor.model.xsd.impl.AbstractType;
import org.eclipse.wst.sse.sieditor.model.xsd.impl.Schema;
/**
* Command for adding a new service interface object
*
*
*/
public class ImportSchemaCommand extends AbstractWSDLNotificationOperation {
private final AbstractType typeHandle;
private final URI schemaUri;
private final IDescription description;
private Schema schema;
private final DocumentType docType;
private final String targetNamespace;
public ImportSchemaCommand(final IWsdlModelRoot root, final IDescription description, final URI wsdlUri, final URI schemaUri,
final AbstractType typeHandle, final DocumentType docType) {
this(root, description, schemaUri, typeHandle.getComponent().getTargetNamespace(), typeHandle, docType);
}
public ImportSchemaCommand(final IWsdlModelRoot root, final IDescription description, final URI schemaUri,
final String targetNamespace, final AbstractType typeHandle, final DocumentType docType) {
super(root, description, Messages.ImportSchemaCommand_import_schema_command_label);
this.schemaUri = schemaUri;
this.typeHandle = typeHandle;
this.description = description;
this.docType = docType;
this.targetNamespace = targetNamespace;
}
@Override
public IStatus run(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
if ("".equals(targetNamespace)) {//$NON-NLS-1$
return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportSchemaCommand_msg_namespace_is_empty);
}
if (DocumentType.XSD_SHEMA.equals(docType)) {
// try to find the schema in the already visible schemas
if (targetNamespace != null && !targetNamespace.equals("")) {//$NON-NLS-1$
final Definition definition = description.getComponent();
return importXsdSchema(definition, targetNamespace, schemaUri);
}
schema = findSchemaInVisibleSchemas(targetNamespace);
if (schema != null) {
return Status.OK_STATUS;
}
return new Status(Status.ERROR, Activator.PLUGIN_ID, MessageFormat.format(Messages.ImportSchemaCommand_0, schemaUri));
}
return Status.CANCEL_STATUS;
}
private IStatus importXsdSchema(final Definition definition, final String namespace, final URI schemaUri)
throws ExecutionException {
final Schema foundSchema = findSchemaInVisibleSchemas(namespace);
if (foundSchema != null) {
schema = foundSchema;
return Status.OK_STATUS;
}
final XSDSchema xsdSchema = getContainedEmptyNamespaceSchema();
// we need to add an import
final XSDImport xsdImport = XSDFactory.eINSTANCE.createXSDImport();
if (namespace != null) {
xsdImport.setNamespace(namespace);
}
final String wsdlLocation = definition.getLocation();
final String schemaRelativePath = ResourceUtils.makeRelativeLocation(wsdlLocation, schemaUri);
try {
xsdImport.setSchemaLocation(URLDecoder.decode(schemaRelativePath, "UTF-8")); //$NON-NLS-1$
} catch (final UnsupportedEncodingException e) {
throw new ExecutionException("Unsuported ecoding", e); //$NON-NLS-1$
}
xsdSchema.getContents().add(0, xsdImport);
final XSDSchema resolvedSchema = getResolvedSchema(xsdImport);
if (null == resolvedSchema) {
return new Status(IStatus.WARNING, Activator.PLUGIN_ID, Messages.ImportSchemaCommand_msg_can_not_resolve_XSD_schema);
}
schema = new Schema(resolvedSchema, null, schemaUri);
return Status.OK_STATUS;
}
private XSDSchema getResolvedSchema(final XSDImport xsdImport) {
XSDSchema resolvedSchema = xsdImport.getResolvedSchema();
if (null == resolvedSchema) {
if (typeHandle == null && xsdImport instanceof XSDImportImpl) {
resolvedSchema = ((XSDImportImpl) xsdImport).importSchema();
} else if (typeHandle != null) {
resolvedSchema = typeHandle.getParent().getComponent();
xsdImport.setResolvedSchema(resolvedSchema);
}
}
return resolvedSchema;
}
private Schema findSchemaInVisibleSchemas(final String namespace) {
final List<ISchema> allVisibleSchemas = description.getAllVisibleSchemas();
for (final ISchema current : allVisibleSchemas) {
final String visibleNamespace = current.getNamespace();
// if the Namespace of current schema matches the type's schema
if (visibleNamespace != null ? visibleNamespace.equals(namespace) : namespace == null) {
// check if they are one and the same, and if so return current.
if (typeHandle != null && current.equals(typeHandle.getParent())) {
return (Schema) current;
}
}
}
return null;
}
private XSDSchema getContainedEmptyNamespaceSchema() {
final ISchema[] schemas = ((Description) description).getSchema(null, false);
return schemas.length > 0 ? schemas[0].getComponent() : EmfWsdlUtils.addXSDSchema(description.getComponent(), null);
}
public Schema getSchema() {
return schema;
}
}