| /******************************************************************************* |
| * Copyright (c) 2001, 2008 IBM Corporation and others. |
| * 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.wst.wsdl.ui.internal.util; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.wsdl.OperationType; |
| |
| import org.eclipse.wst.wsdl.Binding; |
| import org.eclipse.wst.wsdl.Definition; |
| import org.eclipse.wst.wsdl.Fault; |
| import org.eclipse.wst.wsdl.Input; |
| import org.eclipse.wst.wsdl.Message; |
| import org.eclipse.wst.wsdl.MessageReference; |
| import org.eclipse.wst.wsdl.Operation; |
| import org.eclipse.wst.wsdl.Output; |
| import org.eclipse.wst.wsdl.Part; |
| import org.eclipse.wst.wsdl.Port; |
| import org.eclipse.wst.wsdl.PortType; |
| import org.eclipse.wst.wsdl.Service; |
| import org.eclipse.wst.wsdl.WSDLElement; |
| import org.eclipse.wst.wsdl.XSDSchemaExtensibilityElement; |
| import org.eclipse.wst.wsdl.internal.generator.ContentGenerator; |
| import org.eclipse.wst.wsdl.internal.impl.MessageReferenceImpl; |
| import org.eclipse.wst.wsdl.internal.impl.WSDLElementImpl; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddBaseParameterCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddBindingCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddFaultCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddInputCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddInputParameterCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddMessageCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddOperationCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddOutputCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddOutputParameterCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddPartCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddPortCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddPortTypeCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddServiceCommand; |
| import org.eclipse.wst.wsdl.ui.internal.commands.AddXSDElementDeclarationCommand; |
| import org.eclipse.wst.wsdl.util.WSDLConstants; |
| import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManager; |
| import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery; |
| import org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl.CMDocumentLoader; |
| import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil; |
| import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; |
| import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML; |
| import org.eclipse.xsd.XSDElementDeclaration; |
| import org.eclipse.xsd.XSDSchema; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| |
| public class CreateWSDLElementHelper { |
| // Constants used for getting Part information |
| public static final String PART_INFO_ELEMENT_DECLARATION = "ELEMENT_DECLARATION"; //$NON-NLS-1$ |
| public static final String PART_INFO_TYPE_DEFINITION = "TYPE_DEFINITION"; //$NON-NLS-1$ |
| |
| // The following variables should be set if a name other than the computed name is to be used. |
| public static String serviceName = null; |
| public static String portName = null; |
| public static String bindingName = null; |
| public static String portTypeName = null; |
| public static String operationName = null; |
| public static String inputName = null; |
| public static String outputName = null; |
| public static String faultName = null; |
| public static String messageName = null; |
| public static String partName = null; |
| |
| public static String PART_TYPE_OR_DEFINITION = PART_INFO_TYPE_DEFINITION; |
| public static boolean CREATE_DOWN_TO_PART = true; |
| |
| /** |
| * Adds additional namespaces required by contentGenerator to definition. |
| * Also reloads the content model associated with definition if needed |
| * after adding new namespaces. |
| * |
| * @param contentGenerator |
| * @param definition |
| */ |
| public static void addRequiredNamespaces(ContentGenerator contentGenerator, Definition definition) { |
| if (contentGenerator != null && definition != null) { |
| // flag indicating if content model needs to be reloaded |
| boolean reloadContentModel = false; |
| |
| String[] namespaceNames = contentGenerator.getRequiredNamespaces(); |
| String[] preferredPrefixes = new String[namespaceNames.length]; |
| for (int index = 0; index < namespaceNames.length; index++) { |
| preferredPrefixes[index] = contentGenerator.getPreferredNamespacePrefix(namespaceNames[index]); |
| } |
| |
| Map map = definition.getNamespaces(); |
| |
| for (int i = 0; i < namespaceNames.length; i++) { |
| String namespace = namespaceNames[i]; |
| if (!map.containsValue(namespace)) { |
| String prefix = (i < preferredPrefixes.length) ? preferredPrefixes[i] : "p0"; //$NON-NLS-1$ |
| if (map.containsKey(prefix)) { |
| prefix = computeUniquePrefix("p", map); //$NON-NLS-1$ |
| } |
| definition.addNamespace(prefix, namespace); |
| |
| // a namespace was added so update reloadContentModel flag |
| reloadContentModel = true; |
| } |
| } |
| |
| if (reloadContentModel) { |
| reloadContentModel(definition); |
| } |
| } |
| } |
| |
| /** |
| * Reloads content model associated with the given definition |
| * |
| * @param definition |
| */ |
| private static void reloadContentModel(Definition definition) { |
| Document document = definition.getDocument(); |
| if (document != null) { |
| ModelQuery modelQuery = ModelQueryUtil.getModelQuery(document); |
| if (modelQuery != null) { |
| CMDocumentManager manager = modelQuery.getCMDocumentManager(); |
| if (manager != null) { |
| // check if currently async loading |
| boolean oldValue = manager.getPropertyEnabled(CMDocumentManager.PROPERTY_ASYNC_LOAD); |
| // do not async to get immediate document loading |
| if (oldValue) |
| manager.setPropertyEnabled(CMDocumentManager.PROPERTY_ASYNC_LOAD, false); |
| |
| // load content model again |
| CMDocumentLoader loader = new CMDocumentLoader(document, modelQuery); |
| loader.loadCMDocuments(); |
| |
| // reset back to old value just in case |
| if (oldValue) |
| manager.setPropertyEnabled(CMDocumentManager.PROPERTY_ASYNC_LOAD, oldValue); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Computes a unique prefix given the list of existing prefixes in table |
| * and starting with a base prefix of base |
| * |
| * @param base |
| * @param table |
| * @return |
| */ |
| private static String computeUniquePrefix(String base, Map table) { |
| int i = 0; |
| String prefix = base; |
| while (true) { |
| if (!table.containsKey(prefix)) { |
| break; |
| } |
| else { |
| prefix = base + i; |
| i++; |
| } |
| } |
| return prefix; |
| } |
| |
| /* |
| * The following methods creates the 'specified' (by calling a certain method) WSDLElement |
| * and it's 'children' all the way to the PortType level. |
| */ |
| public static Service createService(Definition definition) { |
| if (serviceName == null || serviceName.trim().equals("")) //$NON-NLS-1$ |
| serviceName = NameUtil.buildUniqueServiceName(definition); |
| |
| CreateWSDLElementHelper.portTypeName = serviceName; |
| |
| AddServiceCommand addService = new AddServiceCommand(definition, serviceName, false); |
| addService.run(); |
| Service service = (Service) addService.getWSDLElement(); |
| CreateWSDLElementHelper.createPort(service); |
| |
| return service; |
| } |
| |
| public static Port createPort(Service service) { |
| if (portName == null || portName.trim().equals("")) //$NON-NLS-1$ |
| portName = NameUtil.buildUniquePortName(service, null); |
| |
| AddPortCommand addPort = new AddPortCommand(service, portName); |
| addPort.run(); |
| Port port = (Port) addPort.getWSDLElement(); |
| Binding binding = CreateWSDLElementHelper.createBinding(port.getEnclosingDefinition(), port); |
| |
| port.setBinding(binding); |
| |
| return port; |
| } |
| |
| public static Binding createBinding(Definition definition, Port port) { |
| bindingName = port.getName(); |
| if (bindingName == null || bindingName.trim().equals("")) //$NON-NLS-1$ |
| bindingName = NameUtil.buildUniqueBindingName(definition, null); |
| |
| AddBindingCommand addBinding = new AddBindingCommand(definition, bindingName); |
| addBinding.run(); |
| Binding binding = (Binding) addBinding.getWSDLElement(); |
| PortType portType = CreateWSDLElementHelper.createPortType(binding.getEnclosingDefinition()); |
| |
| binding.setPortType(portType); |
| |
| return binding; |
| } |
| |
| public static PortType createPortType(Definition definition) { |
| if (portTypeName == null || portTypeName.trim().equals("")) //$NON-NLS-1$ |
| portTypeName = NameUtil.buildUniquePortTypeName(definition, "PortType"); //$NON-NLS-1$ |
| |
| AddPortTypeCommand addPortTypeCommand = new AddPortTypeCommand(definition, portTypeName); |
| addPortTypeCommand.run(); |
| PortType portType = (PortType) addPortTypeCommand.getWSDLElement(); |
| |
| if (CREATE_DOWN_TO_PART) { |
| CreateWSDLElementHelper.createOperation(portType); |
| } |
| |
| return portType; |
| } |
| |
| |
| /* |
| * The following methods creates the 'specified' (by calling a certain method) WSDLElement |
| * and it's 'children' all the way to the Part level. |
| */ |
| public static Operation createOperation(PortType portType) { |
| if (operationName == null || operationName.trim().equals("")) //$NON-NLS-1$ |
| operationName = NameUtil.buildUniqueOperationName(portType); |
| |
| AddOperationCommand action = new AddOperationCommand(portType, operationName); |
| action.run(); |
| Operation operation = (Operation) action.getWSDLElement(); |
| |
| int style = AddBaseParameterCommand.PART_ELEMENT_SEQ_ELEMENT; |
| if (PART_TYPE_OR_DEFINITION == PART_INFO_TYPE_DEFINITION) { |
| style = AddBaseParameterCommand.PART_SIMPLETYPE; |
| } |
| else if (PART_TYPE_OR_DEFINITION == PART_INFO_ELEMENT_DECLARATION) { |
| style = AddBaseParameterCommand.PART_ELEMENT_SEQ_ELEMENT; |
| // style = AddBaseParameterCommand.PART_ELEMENT; |
| } |
| |
| AddInputParameterCommand inputCommand = new AddInputParameterCommand(operation, style); |
| inputCommand.run(); |
| AddOutputParameterCommand outputCommand = new AddOutputParameterCommand(operation, style); |
| outputCommand.run(); |
| operation.setStyle(OperationType.REQUEST_RESPONSE); |
| |
| return operation; |
| } |
| |
| public static Input createInput(PortType portType, Operation operation, String inputName) { |
| if (inputName == null || inputName.trim().equals("")) //$NON-NLS-1$ |
| inputName = NameUtil.buildUniqueInputName(portType, operation.getName(), ""); //$NON-NLS-1$ |
| |
| AddInputCommand action = new AddInputCommand(operation, inputName); |
| action.run(); |
| Input input = (Input) action.getWSDLElement(); |
| Message mess = CreateWSDLElementHelper.createMessage(input); |
| input.setMessage(mess); |
| |
| return input; |
| } |
| |
| public static Output createOutput(PortType portType, Operation operation) { |
| if (outputName == null || outputName.trim().equals("")) //$NON-NLS-1$ |
| outputName = NameUtil.buildUniqueOutputName(portType, operation.getName(), ""); //$NON-NLS-1$ |
| |
| AddOutputCommand action = new AddOutputCommand(operation, outputName); |
| action.run(); |
| Output output = (Output) action.getWSDLElement(); |
| Message mess = CreateWSDLElementHelper.createMessage(output); |
| output.setMessage(mess); |
| |
| return output; |
| } |
| |
| public static Fault createFault(Operation operation) { |
| if (faultName == null || faultName.trim().equals("")) //$NON-NLS-1$ |
| faultName = NameUtil.buildUniqueFaultName(operation); |
| |
| AddFaultCommand action = new AddFaultCommand(operation, faultName); |
| action.run(); |
| Fault fault = (Fault) action.getWSDLElement(); |
| Message mess = CreateWSDLElementHelper.createMessage(fault); |
| fault.setMessage(mess); |
| |
| return fault; |
| } |
| |
| public static Message createMessage(MessageReference iof) { |
| if (messageName == null || messageName.trim().equals("")) //$NON-NLS-1$ |
| messageName = NameUtil.buildUniqueMessageName(iof.getEnclosingDefinition(), iof); |
| // messageName = NameUtil.buildMessageName(iof.getName()); |
| |
| Definition def = iof.getEnclosingDefinition(); |
| AddMessageCommand action = new AddMessageCommand(def, messageName); |
| action.run(); |
| Message message = (Message) action.getWSDLElement(); |
| CreateWSDLElementHelper.createPart(message); |
| Element parentNode = message.getElement(); |
| if (parentNode instanceof IDOMNode) |
| { |
| // format selected node |
| FormatProcessorXML formatProcessorXML = new FormatProcessorXML(); |
| formatProcessorXML.formatNode((IDOMNode)parentNode); |
| } |
| |
| messageName = null; |
| return message; |
| } |
| |
| public static Part createPart(Message message) { |
| Definition def = message.getEnclosingDefinition(); |
| String name = NameUtil.buildUniquePartName(message, message.getQName().getLocalPart()); |
| AddPartCommand action = null; |
| |
| if (PART_TYPE_OR_DEFINITION == PART_INFO_TYPE_DEFINITION) { |
| action = new AddPartCommand(message, name, WSDLConstants.SCHEMA_FOR_SCHEMA_URI_2001, "string", true); //$NON-NLS-1$ |
| } |
| else if (PART_TYPE_OR_DEFINITION == PART_INFO_ELEMENT_DECLARATION) { |
| //action = new AddPartCommand(message, name, WSDLConstants.SCHEMA_FOR_SCHEMA_URI_2001, "string", true); |
| String elementName = getNewNameHelper(name, def, false); |
| AddXSDElementDeclarationCommand elementAction = new AddXSDElementDeclarationCommand(def, elementName); |
| elementAction.run(); |
| action = new AddPartCommand(message, name, def.getTargetNamespace(), elementName, false); |
| } |
| |
| action.run(); |
| |
| return (Part) action.getWSDLElement(); |
| } |
| |
| /* |
| * Used to determine a name for an Element |
| */ |
| private static String getNewNameHelper(String base, Definition def, boolean isType) |
| { |
| String name = base; |
| int count = 0; |
| |
| // Ugly.... Redo this... |
| // Get a list of Elements... |
| List elementList = null; |
| if (def.getETypes() != null) { |
| List xsdsList = def.getETypes().getEExtensibilityElements(); |
| if (xsdsList != null) { |
| Iterator xsdsIterator = xsdsList.iterator(); |
| XSDSchemaExtensibilityElement xsdElement = (XSDSchemaExtensibilityElement) xsdsIterator.next(); |
| XSDSchema schema = xsdElement.getSchema(); |
| if (schema != null) { |
| elementList = schema.getElementDeclarations(); |
| } |
| } |
| } |
| |
| if (elementList != null) { |
| int index = 0; |
| while (index < elementList.size()) { |
| XSDElementDeclaration elementDeclaration = (XSDElementDeclaration) elementList.get(index); |
| |
| if (name.equals(elementDeclaration.getName())) { |
| count++; |
| name = name + count; |
| index = 0; |
| } |
| else { |
| index++; |
| } |
| } |
| } |
| |
| return name; |
| } |
| |
| /* |
| * Return the type of Part this WSDLElement should have (Element vs Type). To determine this, we filter up to the 'parent' PortType |
| * and go down to the first Part we encounter and check the type it has. If this fails, default to Type. |
| */ |
| public static String getPartInfo(WSDLElement element) { |
| String partInfo = null; |
| |
| if (element instanceof PortType) { |
| partInfo = getPartInfo((PortType) element); |
| } |
| else if (element instanceof Operation) { |
| partInfo = getPartInfo(((WSDLElementImpl) element).getContainer()); |
| } |
| else if (element instanceof MessageReferenceImpl) { |
| partInfo = getPartInfo(((WSDLElementImpl) element).getContainer()); |
| } |
| |
| if (partInfo == null) { |
| partInfo = CreateWSDLElementHelper.PART_INFO_TYPE_DEFINITION; |
| } |
| |
| return partInfo; |
| } |
| |
| private static String getPartInfo(PortType portType) { |
| String partInfo = null; |
| |
| if (portType.getOperations() != null) { |
| Iterator operationIt = portType.getOperations().iterator(); |
| while (operationIt.hasNext()) { |
| Operation op = (Operation) operationIt.next(); |
| |
| if (op.getEInput() != null) { |
| partInfo = getMessageRefPartInfo((MessageReferenceImpl) op.getEInput()); |
| } |
| |
| if (partInfo == null && op.getEOutput() != null) { |
| partInfo = getMessageRefPartInfo((MessageReferenceImpl) op.getEOutput()); |
| } |
| |
| if (op.getEFaults() != null) { |
| Iterator faultIt = op.getEFaults().iterator(); |
| while (partInfo == null && faultIt.hasNext()) { |
| Fault fault = (Fault) faultIt.next(); |
| partInfo = getMessageRefPartInfo((MessageReferenceImpl) fault); |
| } |
| } |
| |
| if (partInfo != null) |
| break; |
| } |
| } |
| |
| return partInfo; |
| } |
| |
| private static String getMessageRefPartInfo(MessageReferenceImpl iof) { |
| String partInfo = null; |
| |
| if (iof.getEMessage() != null && iof.getEMessage().getEParts() != null) { |
| Iterator partIt = iof.getEMessage().getEParts().iterator(); |
| |
| while (partInfo == null && partIt.hasNext()) { |
| Part part = (Part) partIt.next(); |
| |
| if (part.getTypeDefinition() != null) { |
| partInfo = CreateWSDLElementHelper.PART_INFO_TYPE_DEFINITION; |
| } |
| else if (part.getElementDeclaration() != null) { |
| partInfo = CreateWSDLElementHelper.PART_INFO_ELEMENT_DECLARATION; |
| } |
| } |
| } |
| |
| return partInfo; |
| } |
| } |