blob: a8bb5d65b59ebc6d8539aa4f007cc9aeb13fec5d [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.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.wst.wsdl.Binding;
import org.eclipse.wst.wsdl.BindingFault;
import org.eclipse.wst.wsdl.BindingInput;
import org.eclipse.wst.wsdl.BindingOperation;
import org.eclipse.wst.wsdl.BindingOutput;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Port;
import org.eclipse.wst.wsdl.UnknownExtensibilityElement;
import org.eclipse.wst.wsdl.WSDLElement;
import org.eclipse.wst.wsdl.internal.util.WSDLSwitch;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin;
import org.eclipse.wst.wsdl.ui.internal.extension.IMenuActionContributor;
import org.eclipse.wst.wsdl.ui.internal.model.WSDLGroupObject;
import org.eclipse.wst.wsdl.ui.internal.util.WSDLEditorUtil;
import org.eclipse.wst.wsdl.util.WSDLConstants;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQueryAction;
import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilder;
import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMContentBuilderImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.util.DOMNamespaceHelper;
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.wst.xml.ui.internal.actions.MenuBuilder;
import org.eclipse.wst.xml.ui.internal.util.XMLCommonResources;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* TODO... there are likely several places where we can refactor code from AbstractNodeActionManager
*/
public class AddEEMenuActionContributor implements IMenuActionContributor
{
protected MenuBuilder menuBuilder = new MenuBuilder();
public void contributeMenuActions(final IMenuManager menu, Node node, Object object)
{
boolean isSubmenuRequired = false;
Element element = null;
if (object instanceof WSDLElement)
{
WSDLSwitch wsdlSwitch = new WSDLSwitch()
{
public Object caseBinding(Binding binding)
{
return Boolean.TRUE;
}
public Object caseBindingOperation(BindingOperation bindingOperation)
{
return Boolean.TRUE;
}
public Object caseBindingInput(BindingInput bindingInput)
{
return Boolean.TRUE;
}
public Object caseBindingOutput(BindingOutput bindingOutput)
{
return Boolean.TRUE;
}
public Object caseBindingFault(BindingFault bindingFault)
{
return Boolean.TRUE;
}
public Object caseDefinition(Definition definition)
{
return Boolean.TRUE;
}
public Object casePort(Port port)
{
return Boolean.TRUE;
}
public Object caseUnknownExtensibilityElement(UnknownExtensibilityElement unknownExtensibilityElement)
{
if (getExtensibilityElementActions(unknownExtensibilityElement.getElement()).size() > 0)
{
return Boolean.TRUE;
}
else
{
return Boolean.FALSE;
}
}
};
isSubmenuRequired = wsdlSwitch.doSwitch((WSDLElement)object) != null;
element = WSDLEditorUtil.getInstance().getElementForObject(object);
}
else if (object instanceof WSDLGroupObject)
{
WSDLGroupObject groupObject = (WSDLGroupObject)object;
switch (groupObject.getType())
{
case WSDLGroupObject.EXTENSIBILITY_ELEMENTS_GROUP :
{
isSubmenuRequired = true;
element = WSDLEditorUtil.getInstance().getElementForObject(groupObject.getDefinition());
break;
}
}
}
if (isSubmenuRequired)
{
MenuManager submenu = new MenuManager(WSDLEditorPlugin.getWSDLString("_UI_ADD_EXTENSIBILITY_ELEMENT")); //$NON-NLS-1$
// here I'm attempting to add the menu item in a 'good' place in the exisiting menu
// todo add menu groups to avoid the need for this test
//
// if (menu.find("addchild") != null)
// {
// menu.insertAfter("addchild", submenu);
// }
// else
// {
// menu.add(submenu);
// }
menu.add(submenu);
if (element != null && element instanceof IDOMNode)
{
addExtensibilityElementActions(submenu, element);
}
}
}
public void addExtensibilityElementActions(IMenuManager menu, Element element)
{
ModelQuery modelQuery = ModelQueryUtil.getModelQuery(element.getOwnerDocument());
CMElementDeclaration ed = modelQuery.getCMElementDeclaration(element);
if (ed != null)
{
addActionHelper(menu, getExtensibilityElementActions(element));
}
}
public List getExtensibilityElementActions(Element element) {
List modelQueryActionList = new ArrayList();
ModelQuery modelQuery = ModelQueryUtil.getModelQuery(element.getOwnerDocument());
CMElementDeclaration ed = modelQuery.getCMElementDeclaration(element);
if (ed != null)
{
// add insert child node actions
//
int ic = ModelQuery.INCLUDE_CHILD_NODES;
int vc = ModelQuery.VALIDITY_STRICT;
modelQuery.getInsertActions(element, ed, -1, ic, vc, modelQueryActionList);
}
return modelQueryActionList;
}
protected void addActionHelper(IMenuManager menu, List modelQueryActionList)
{
List actionList = new Vector();
for (Iterator i = modelQueryActionList.iterator(); i.hasNext(); )
{
ModelQueryAction action = (ModelQueryAction)i.next();
CMNode cmnode = action.getCMNode();
if (cmnode != null)
{
boolean isOtherNamespace = false;
CMDocument cmDocument = (CMDocument)cmnode.getProperty("CMDocument");
if (cmDocument != null)
{
String namespaceURI = (String)cmDocument.getProperty("http://org.eclipse.wst/cm/properties/targetNamespaceURI");
isOtherNamespace = namespaceURI != null && !namespaceURI.equals(WSDLConstants.WSDL_NAMESPACE_URI);
}
if (isOtherNamespace)
{
int cmNodeType = cmnode.getNodeType();
if (action.getKind() == ModelQueryAction.INSERT)
{
switch (cmNodeType)
{
case CMNode.ELEMENT_DECLARATION :
{
actionList.add(new AddNodeAction((CMElementDeclaration)cmnode, action.getParent(), action.getStartIndex()));
break;
}
}
}
}
}
}
menuBuilder.populateMenu(menu, actionList, false);
}
/**
* AddNodeAction
*/
public class AddNodeAction extends BaseNodeAction
{
protected String description;
protected String undoDescription;
protected CMNode cmnode;
protected int index;
protected Node parent;
public AddNodeAction(CMNode cmnode, Node parent, int index)
{
this.cmnode = cmnode;
this.parent = parent;
this.index = index;
String text = getLabel(parent, cmnode);
setText(text);
description = text;
undoDescription = XMLCommonResources.getInstance().getString("_UI_MENU_ADD") + " " + text;
//setImageDescriptor(imageDescriptorCache.getImageDescriptor(cmnode));
}
public String getLabel(Node parent, CMNode cmnode)
{
String result = "?" + cmnode + "?";
if (cmnode != null)
{
result = DOMNamespaceHelper.computeName(cmnode, parent, null);
}
return result;
}
public Node getNode()
{
return parent;
}
public String getUndoDescription()
{
return undoDescription;
}
public void run()
{
beginRecording();
if (cmnode != null && parent != null)
{
Document document = parent.getNodeType() == Node.DOCUMENT_NODE ? (Document)parent : parent.getOwnerDocument();
DOMContentBuilder builder = new DOMContentBuilderImpl(document);
builder.setProperty(DOMContentBuilder.PROPERTY_BUILD_BLANK_TEXT_NODES, Boolean.TRUE);
builder.setBuildPolicy(DOMContentBuilder.BUILD_ONLY_REQUIRED_CONTENT);
builder.build(parent, cmnode);
insertNodesAtIndex(parent, builder.getResult(), index, true);
}
endRecording();
}
public void insertNodesAtIndex(Node parent, List list, int index, boolean format)
{
NodeList nodeList = parent.getChildNodes();
if (index == -1)
{
index = nodeList.getLength();
}
Node refChild = (index < nodeList.getLength()) ? nodeList.item(index) : null;
// here we consider the case where the previous node is a 'white space' Text node
// we should really do the insert before this node
//
int prevIndex = index - 1;
Node prevChild = (prevIndex < nodeList.getLength()) ? nodeList.item(prevIndex) : null;
if (isWhitespaceTextNode(prevChild))
{
refChild = prevChild;
}
for (Iterator i = list.iterator(); i.hasNext(); )
{
Node newNode = (Node)i.next();
if (newNode.getNodeType() == Node.ATTRIBUTE_NODE)
{
Element parentElement = (Element)parent;
parentElement.setAttributeNode((Attr)newNode);
}
else
{
parent.insertBefore(newNode, refChild);
}
}
for (Iterator i = list.iterator(); i.hasNext(); )
{
Node newNode = (Node)i.next();
if (format)
{
FormatProcessorXML formatProcessorXML = new FormatProcessorXML();
formatProcessorXML.formatNode((IDOMNode)newNode);
}
}
//setViewerSelection(list);
}
protected boolean isWhitespaceTextNode(Node node)
{
return (node != null) && (node.getNodeType() == Node.TEXT_NODE) && (node.getNodeValue().trim().length() == 0);
}
}
}