| /******************************************************************************* |
| * Copyright (c) 2001, 2004 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.actions; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Vector; |
| import javax.xml.namespace.QName; |
| |
| |
| 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.WSDLElement; |
| import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin; |
| import org.eclipse.wst.wsdl.ui.internal.util.WSDLEditorUtil; |
| import org.eclipse.xsd.XSDElementDeclaration; |
| import org.w3c.dom.Node; |
| |
| |
| /* |
| * This class renames 'related' WSDLElements. The scenario is as follows: |
| * The user renames a WSDLElement in the editor, say a Message. This class |
| * will find the 'related' elements to this Message and rename them as well. |
| * It will only rename a 'related' element if the element name (or part of it) |
| * is generated. |
| * |
| * See NameUtil.java |
| */ |
| public class SmartRenameAction extends BaseNodeAction implements Runnable { |
| protected Object element; |
| protected String newName; |
| private List messageReferences; // This variable should be accessed by method getAllMessageReferences() |
| protected Node node; |
| |
| public SmartRenameAction(Object element, String newName) { |
| setText("Smart Rename Action"); // Do not translate |
| this.element = element; |
| this.newName = newName; |
| this.node = WSDLEditorUtil.getInstance().getNodeForObject(element); |
| } |
| |
| public Node getNode() { |
| return node; |
| } |
| |
| public String getUndoDescription() { |
| return WSDLEditorPlugin.getWSDLString("_UI_ACTION_RENAME"); //$NON-NLS-1$ |
| } |
| |
| public void run() { |
| RenameAction renamer; |
| String oldName; |
| |
| beginRecording(); |
| if (element instanceof Operation) { |
| Operation operation = (Operation) element; |
| oldName = operation.getName(); |
| |
| if (oldName.equals(newName)) { |
| return; |
| } |
| |
| // Rename Operation |
| renamer = new RenameAction(operation, newName); |
| renamer.run(); |
| |
| // Rename Input |
| Input input = operation.getEInput(); |
| /* |
| if (input != null && isInputOutputNameGenerated(oldName, input.getName())) { |
| renamer = new RenameAction(input, newName); |
| renamer.run(); |
| } |
| */ |
| |
| // Rename Output |
| Output output = operation.getEOutput(); |
| /* |
| if (output != null && isInputOutputNameGenerated(oldName, output.getName())) { |
| renamer = new RenameAction(output, newName); |
| renamer.run(); |
| } |
| */ |
| |
| // Rename Messages and Parts |
| Message msg; |
| |
| // Input |
| if (input != null && input.getEMessage() != null) { |
| msg = input.getEMessage(); |
| String oldMessageName = ""; |
| |
| if (msg != null) { |
| oldMessageName = msg.getQName().getLocalPart(); |
| |
| if (isMessageNameGenerated(oldMessageName, oldName, "Request")) { |
| renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName)); |
| |
| if (msg.getEParts() != null) |
| renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true); |
| } |
| } |
| } |
| |
| // Output |
| if (output != null && output.getMessage() != null) { |
| msg = output.getEMessage(); |
| String oldMessageName = ""; |
| |
| if (msg != null) { |
| oldMessageName = msg.getQName().getLocalPart(); |
| |
| if (isMessageNameGenerated(oldMessageName, oldName, "Response")) { |
| renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName)); |
| |
| if (msg.getEParts() != null) |
| renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true); |
| } |
| |
| } |
| } |
| |
| // Faults |
| List faults = operation.getEFaults(); |
| if (faults != null) { |
| Iterator it = faults.iterator(); |
| while (it.hasNext()) { |
| Fault fault = (Fault) it.next(); |
| msg = fault.getEMessage(); |
| String oldMessageName = ""; |
| |
| if (msg != null) { |
| oldMessageName = msg.getQName().getLocalPart(); |
| |
| if (isMessageNameGenerated(oldMessageName, oldName, fault.getName())) { |
| renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName)); |
| |
| if (msg.getEParts() != null) |
| renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true); |
| } |
| } |
| } |
| } |
| } |
| else if (element instanceof Input) { |
| Input input = (Input) element; |
| oldName = input.getName(); |
| if (oldName == null) { |
| oldName = ""; |
| } |
| |
| if (oldName.equals(newName)) { |
| return; |
| } |
| |
| input.setName(newName); |
| |
| // Rename Messages and Parts |
| Message msg; |
| |
| // Input |
| if (input != null && input.getEMessage() != null) { |
| msg = input.getEMessage(); |
| String oldMessageName = ""; |
| |
| if (msg != null) { |
| oldMessageName = msg.getQName().getLocalPart(); |
| |
| if (isMessageNameGenerated(oldMessageName, oldName, "Request")) { |
| renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName)); |
| |
| if (msg.getEParts() != null) |
| renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true); |
| } |
| } |
| } |
| } |
| else if (element instanceof Output) { |
| Output output = (Output) element; |
| oldName = output.getName(); |
| if (oldName == null) { |
| oldName = ""; |
| } |
| |
| if (oldName.equals(newName)) { |
| return; |
| } |
| |
| output.setName(newName); |
| |
| // Rename Messages and Parts |
| Message msg; |
| |
| // Output |
| if (output != null && output.getMessage() != null) { |
| msg = output.getEMessage(); |
| String oldMessageName = ""; |
| if (msg != null) { |
| oldMessageName = msg.getQName().getLocalPart(); |
| if (isMessageNameGenerated(oldMessageName, oldName, "Response")) { |
| renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName)); |
| |
| if (msg.getEParts() != null) |
| renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true); |
| } |
| } |
| } |
| } |
| else if (element instanceof Fault) { |
| Fault fault = (Fault) element; |
| Message msg = fault.getEMessage(); |
| String oldMessageName = ""; |
| oldName = fault.getName(); |
| |
| if (oldName.equals(newName)) { |
| return; |
| } |
| |
| // Rename the Fault |
| renamer = new RenameAction(fault, newName); |
| renamer.run(); |
| |
| // Rename the Message and Parts |
| if (msg != null) { |
| oldMessageName = msg.getQName().getLocalPart(); |
| |
| Operation op = (Operation) fault.eContainer(); |
| if (isMessageNameGenerated(oldMessageName, op.getName(), oldName)) { |
| renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName)); |
| |
| if (msg.getEParts() != null) |
| renameFaultParts(msg.getEParts(), op.getName(), oldName, newName); |
| } |
| } |
| } |
| else if (element instanceof Message) { |
| Message msg = (Message) element; |
| oldName = msg.getQName().getLocalPart(); |
| String oldMessageName = msg.getQName().getLocalPart(); |
| |
| if (oldName.equals(newName)) { |
| return; |
| } |
| |
| renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName)); |
| |
| if (msg.getEParts() != null) |
| renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true); |
| } |
| else if (element instanceof Part) { |
| Part part = (Part) element; |
| String oldPartName = part.getName(); |
| |
| if (oldPartName.equals(newName)) { |
| return; |
| } |
| |
| renamer = new RenameAction(element, newName); |
| renamer.run(); |
| |
| // Rename Elements |
| renameXSDElement(part, oldPartName, newName); |
| } |
| else if (element instanceof Port) { |
| Port port = (Port) element; |
| String oldPortName = port.getName(); |
| |
| renamer = new RenameAction(element, newName); |
| renamer.run(); |
| |
| // Rename Binding |
| Binding binding = port.getEBinding(); |
| if (binding != null && binding.getQName().getLocalPart().equals(oldPortName)) { |
| renamer = new RenameAction(binding, newName); |
| renamer.run(); |
| } |
| } |
| endRecording(); |
| } |
| |
| // boolean isInputOutput should be set to true if the part is an Input or Output. |
| // Set false if the part is a Fault. |
| private void renamePartsHelper(List partsList, String oldSubString, String newSubString, boolean isInputOutput) { |
| RenameAction renamer; |
| |
| if (partsList != null) { |
| Iterator pIt = partsList.iterator(); |
| while (pIt.hasNext()) { |
| Part part = (Part) pIt.next(); |
| String oldPartName = part.getName(); |
| |
| if (isPartNameGenerated(oldPartName, oldSubString)) { |
| String newPartName; |
| if (isInputOutput) { |
| newPartName = computeNewPartName(part, oldSubString, newSubString); |
| } |
| else { |
| newPartName = computeNewFaultPartName(part, oldSubString, newSubString); |
| } |
| |
| renamer = new RenameAction(part, newPartName); |
| renamer.run(); |
| |
| // Rename Elements |
| renameXSDElement(part, oldPartName, newPartName); |
| } |
| } |
| } |
| } |
| |
| // This method is used to update the Part name when the Fault name is changed. Only |
| // change the Part name if the part name is a generated name. |
| // Compare to renamePartsHelper(). The renamePartsHelper() method is called when a Fault |
| // has NOT been renamed, rather, it is triggered by some other naming (ex. Operation |
| // renaming). It will updat Input/Output, AND Fault Parts. |
| private void renameFaultParts(List partsList, String baseName, String oldSubString, String newSubString) { |
| RenameAction renamer; |
| |
| if (partsList != null) { |
| Iterator pIt = partsList.iterator(); |
| while (pIt.hasNext()) { |
| Part part = (Part) pIt.next(); |
| String oldPartName = part.getName(); |
| |
| if (isPartNameGenerated(oldPartName, baseName, oldSubString)) { |
| String newPartName; |
| newPartName = computeNewFaultPartName(part, oldSubString, newSubString); |
| renamer = new RenameAction(part, newPartName); |
| renamer.run(); |
| |
| // Rename Elements |
| renameXSDElement(part, oldPartName, newPartName); |
| } |
| } |
| } |
| } |
| |
| private String computeNewMessageName(Message message, String oldSubString, String newSubString) { |
| String string = message.getQName().getLocalPart(); |
| return replaceSectionWithSubString(string, oldSubString, newSubString, 0); |
| } |
| |
| private String computeNewFaultMessageName(Message message, String oldSubString, String newSubString) { |
| String string = message.getQName().getLocalPart(); |
| return replaceSectionWithSubString(string, oldSubString, newSubString, 1); |
| } |
| |
| // Method for Input, Output, and Fault Parts |
| // See computeNewFaultPartName() for comparison |
| private String computeNewPartName(Part part, String oldSubString, String newSubString) { |
| String string = part.getName(); |
| return replaceSectionWithSubString(string, oldSubString, newSubString, 0); |
| } |
| |
| // Method for Fault Parts |
| // This method behaves in the exact same way as computeNewPartName() except it starts searching for a match |
| // after the first character. This method is intended for users who wish to rename a generated (Fault) part |
| // where the Fault name has changed. We start our search after the first character because the generated name |
| // of the part is built by appending the Fault name after the Operation name. |
| private String computeNewFaultPartName(Part part, String oldSubString, String newSubString) { |
| String string = part.getName(); |
| return replaceSectionWithSubString(string, oldSubString, newSubString, 1); |
| } |
| |
| private String replaceSectionWithSubString(String fullString, String oldSubString, String newSubString, int startSearchIndex) { |
| StringBuffer fullSB = new StringBuffer(fullString); |
| int index = fullSB.indexOf(oldSubString, startSearchIndex); |
| if (index >= 0) { |
| return fullSB.replace(index, index + oldSubString.length(), newSubString).toString(); |
| } |
| |
| return ""; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////// |
| |
| private static boolean commonNameGeneratorCheck(String targetName, String baseName, String appendName) { |
| // First criteria is targetName must start with the baseName |
| if (!targetName.startsWith(baseName)) |
| return false; |
| |
| if (appendName.trim().length() > 0) { |
| // Second criteria. The appended name must be in the targetName and begin right |
| // after the baseName location |
| if (!targetName.startsWith(appendName, baseName.length())) |
| return false; |
| } |
| |
| // Third criteria (if necessary). If baseName + appendName is shorter than targetName, |
| // then there must be 'extra' characters at the end of targetName. These characters must |
| // make up an integer. If not, it is not a generated string. |
| int subLength = baseName.length() + appendName.length(); |
| if (targetName.length() > subLength) { |
| // We have 'extra' characters |
| String extras = targetName.substring(subLength); |
| |
| if(!isDigit(extras)) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| public static boolean isOperationNameGenerated(String opName, String name) { |
| return opName.equals(name); |
| } |
| |
| public static boolean isMessageNameGenerated(String msgName, String baseName, String appendName) { |
| return commonNameGeneratorCheck(msgName, baseName, appendName); |
| } |
| |
| public static boolean isInputOutputNameGenerated(String inOutName, String name) { |
| return inOutName.equals(name); |
| } |
| |
| public static boolean isFaultNameGenerated(String faultName, String name) { |
| return faultName.equals(name); |
| } |
| |
| public static boolean isPartNameGenerated(String partName, String baseName) { |
| return commonNameGeneratorCheck(partName, baseName, ""); |
| } |
| |
| private boolean isPartNameGenerated(String partName, String baseName, String appendName) { |
| return commonNameGeneratorCheck(partName, baseName, appendName); |
| } |
| |
| private static boolean isDigit(String string) { |
| boolean rValue = true; |
| char[] chars = string.toCharArray(); |
| |
| for (int index = 0; index < chars.length; index++) { |
| if (!Character.isDigit(chars[index])) { |
| rValue = false; |
| break; |
| } |
| } |
| |
| return rValue; |
| } |
| |
| /* |
| * The following classes aid in renaming a message |
| */ |
| private void renameMessageHelper(Message msg, String newName) { |
| List messageRefs = getReferencingMessageReferences(msg, getAllMessageReferences()); |
| |
| RenameAction renamer = new RenameAction(msg, newName); |
| renamer.run(); |
| |
| Iterator iterator = messageRefs.iterator(); |
| while (iterator.hasNext()) { |
| MessageReference messageReference = (MessageReference) iterator.next(); |
| messageReference.setEMessage(msg); |
| } |
| } |
| |
| private List getReferencingMessageReferences(Message msg, List messageRefs) { |
| Vector referencesVector = new Vector(); |
| QName messageQName = msg.getQName(); |
| Iterator iterator = messageRefs.iterator(); |
| |
| while (iterator.hasNext()) { |
| MessageReference messageReference = (MessageReference) iterator.next(); |
| if (messageReference.getEMessage() != null && messageQName.equals(messageReference.getEMessage().getQName())) { |
| referencesVector.addElement(messageReference); |
| } |
| } |
| |
| return referencesVector; |
| } |
| |
| private List getAllMessageReferences() { |
| if (messageReferences == null) { |
| messageReferences = new Vector(); |
| Definition definition = ((WSDLElement) element).getEnclosingDefinition(); |
| List portTypes = definition.getEPortTypes(); |
| |
| if (portTypes != null) { |
| Iterator portTypeIterator = portTypes.iterator(); |
| while (portTypeIterator.hasNext()) { |
| List operationsList = ((PortType) portTypeIterator.next()).getEOperations(); |
| |
| if (operationsList != null) { |
| Iterator operationsIterator = operationsList.iterator(); |
| while (operationsIterator.hasNext()) { |
| messageReferences.addAll(getAllMessageReferences((Operation) operationsIterator.next())); |
| } |
| } |
| } |
| } |
| } |
| |
| return messageReferences; |
| } |
| |
| private Vector getAllMessageReferences(Operation operation) { |
| Vector iofs = new Vector(); |
| Iterator it = operation.getEFaults().iterator(); |
| while (it.hasNext()) { |
| iofs.addElement(it.next()); |
| } |
| |
| if (iofs == null) |
| iofs = new Vector(); |
| |
| if (operation.getEInput() != null) |
| iofs.addElement(operation.getEInput()); |
| |
| if (operation.getEOutput() != null) |
| iofs.addElement(operation.getEOutput()); |
| |
| return iofs; |
| } |
| |
| private void renameXSDElement(Part part, String oldXSDName, String newXSDName) { |
| XSDElementDeclaration elementDeclaration = part.getElementDeclaration(); |
| if (elementDeclaration != null && oldXSDName.equals(elementDeclaration.getName())) { |
| renameElementDeclarationHelper(elementDeclaration, oldXSDName, newXSDName); |
| |
| // Here we rename the element reference. |
| // |
| QName qname = new QName(part.getElementName().getNamespaceURI(), newXSDName); |
| part.setElementName(qname); |
| } |
| } |
| |
| private void renameElementDeclarationHelper(XSDElementDeclaration elementDeclaration, String oldXSDName, String newXSDName) { |
| if (elementDeclaration != null && elementDeclaration.getName().equals(oldXSDName)) { |
| elementDeclaration.setName(newXSDName); |
| } |
| } |
| |
| } |