blob: 32fc403ee87a0a9ef16fa4df4151d57b1a906611 [file] [log] [blame]
/*******************************************************************************
* 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);
}
}
}