/******************************************************************************* * Copyright (c) 2006 Sybase, Inc. 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: * Sybase, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.jst.pagedesigner.properties; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectNature; import org.eclipse.gef.editparts.AbstractEditPart; import org.eclipse.gef.ui.parts.GraphicalEditor; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jst.pagedesigner.IHTMLConstants; import org.eclipse.jst.pagedesigner.PDPlugin; import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID; import org.eclipse.jst.pagedesigner.dom.DOMUtil; import org.eclipse.jst.pagedesigner.editors.HTMLEditor; import org.eclipse.jst.pagedesigner.utils.SelectionHelper; import org.eclipse.jst.pagedesigner.viewer.DesignRange; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.views.contentoutline.ContentOutline; import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration; import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap; 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.modelquery.ModelQueryUtil; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; import org.w3c.dom.Attr; import org.w3c.dom.CDATASection; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.Text; /** * This is util class most used by Property related operation. * * @author mengbo */ public class DesignerPropertyTool { /** * @param fNode * @param attributeDesc * @return attribute value */ public static String getAttributeValue(Element fNode, CMNode attributeDesc) { if (attributeDesc == null) { return ""; //$NON-NLS-1$ } String returnedValue = ""; //$NON-NLS-1$ NamedNodeMap attrMap = fNode.getAttributes(); if (attrMap != null) { Node attribute = attrMap.getNamedItem(attributeDesc.getNodeName()); if (attribute != null) { if (attribute instanceof IDOMNode) { returnedValue = ((IDOMNode) attribute).getValueSource(); } else { returnedValue = attribute.getNodeValue(); } } } return returnedValue; } // /** // * @param fNode // * @param filter // * @return array of attributes as objects // * (unused) // */ // public static Object[] getElementReferedAttributes(Element fNode, // String[] filter) { // List result = new ArrayList(); // CMNamedNodeMap cmnnm = getElementDeclaredAttributes(fNode); // for (int i = 0, n = cmnnm.getLength(); i < n; i++) { // String name = cmnnm.item(i).getNodeName(); // if (Arrays.asList(filter).contains(name)) { // result.add(cmnnm.item(i)); // } // } // return result.toArray(new CMNode[result.size()]); // } /** * @param fNode * @return CMNamedNodeMap */ public static CMNamedNodeMap getElementDeclaredAttributes(Node fNode) { IStructuredModel structModel = null; if (fNode instanceof IDOMNode) { structModel = ((IDOMNode) fNode).getModel(); } if (null == structModel) { return null; } CMElementDeclaration cmde = null; CMNamedNodeMap cmnnm = null; if (fNode == null || fNode.getNodeType() != Node.ELEMENT_NODE) { cmde = null; } ModelQuery modelQuery = ModelQueryUtil.getModelQuery(fNode .getOwnerDocument()); if (modelQuery != null) { cmde = modelQuery.getCMElementDeclaration((Element) fNode); } if (cmde != null) { cmnnm = cmde.getAttributes(); } return cmnnm; } /** * the selection could be different kinds of selection, including: 1. * ITextSelection 2. IStructuredSelection (Node) 3. IStructuredSelection * (EditPart) 4. DesignRange we want to normalize it to only #2. If the node * is ATTR or TEXT/CDATA_SECTION, will use it's parent node. * * @param selectingPart * @param selection * @param htmlEditor * @return null if can't normalize. */ public static Node normalizeSelectionToElement( IWorkbenchPart selectingPart, ISelection selection, HTMLEditor htmlEditor) { Node node = null; if (selectingPart instanceof HTMLEditor) { IEditorPart part = ((HTMLEditor) selectingPart).getActiveEditor(); if (part instanceof TextEditor) { if (selection instanceof ITextSelection) { IStructuredModel model = ((HTMLEditor) selectingPart) .getModel(); node = SelectionHelper.toNode(model, (ITextSelection) selection); } } else if (part instanceof GraphicalEditor) { if (selection instanceof IStructuredSelection) { node = SelectionHelper .toNode((IStructuredSelection) selection); } else if (selection instanceof DesignRange) { node = SelectionHelper.toNode((DesignRange) selection); } } if (node instanceof Attr) { node = ((Attr) node).getOwnerElement(); } else if (node instanceof Text || node instanceof CDATASection) { node = node.getParentNode(); } } else if (selectingPart instanceof ContentOutline) { if (selection instanceof IStructuredSelection && ((ContentOutline) selectingPart).getCurrentPage() != null && ((ContentOutline) selectingPart).getCurrentPage() .getControl().isFocusControl()) { node = SelectionHelper.toNode((IStructuredSelection) selection); if (node == null) { node = htmlEditor.getDOMDocument(); } } } return node; } /** * @param node as Object * @return element */ public static Element getElementNode(Object node) { Object model; Element element = null; if (node == null) { return null; } if (node instanceof Element) { element = (Element) node; } else if (node instanceof AbstractEditPart) { model = ((AbstractEditPart) node).getModel(); if (model instanceof Element) { element = (Element) model; } } else if (node instanceof ISelection) { element = getElement(null, (ISelection) node); } return element; } /** * @param element * @param filter * @return list of attribute names */ public static List getNameList(Element element, String[] filter) { List result = new ArrayList(); CMNamedNodeMap attributes = getElementDeclaredAttributes(element); if (attributes != null) { for (int i = 0, n = attributes.getLength(); i < n; i++) { String name = attributes.item(i).getNodeName(); if (Arrays.asList(filter).contains(name)) result.add(name); } } return result; } /** * @param selection * should be a normalized selection * @return node */ public static Node getCommonParent(ISelection selection) { if (selection instanceof IStructuredSelection) { Object obj = ((IStructuredSelection) selection).getFirstElement(); return (Node) obj; } else if (selection instanceof DesignRange) { DesignRange range = (DesignRange) selection; Node node1 = range.getStartPosition().getContainerNode(); Node node2 = range.getEndPosition().getContainerNode(); return DOMUtil.findCommonAncester(node1, node2); } else { // should not happen return null; } } /** * The passed in selection should be normalized selection. * * @param selectingPart * @param selection * @return element */ public static Element getElement(IWorkbenchPart selectingPart, ISelection selection) { Node node = getCommonParent(selection); if (node instanceof Element) { return (Element) node; } else if (node != null) { node = node.getParentNode(); if (node instanceof Element) { return (Element) node; } } return null; } // reserved for future native use. // public static void dumpChildren(Element element) // { // // In this function we are using logger to dump message out. // Logger logger = PDPlugin.getLogger(DesignerPropertyTool.class); // if (element == null || !DEBUG) // return; // NodeList nl = element.getChildNodes(); // // It's our pattern for dumping message // logger.debug("\n----------------------------"); //$NON-NLS-1$ // logger.debug("Element:" + element.getNodeName()); //$NON-NLS-1$ // for (int i = 0; i < nl.getLength(); i++) // { // Node node = nl.item(i); // logger.debug("child[" + i + "]:" + node.getNodeName()); //$NON-NLS-1$ // //$NON-NLS-2$ // } // logger.debug("----------------------------\n"); //$NON-NLS-1$ // } /** * @param element * @return bool * (unused) */ public static boolean isMultiSelection(Element element) { if (element.getNodeName().equalsIgnoreCase(IHTMLConstants.TAG_OPTION)) { return element.getAttribute(ICSSPropertyID.ATTR_MULTIPLE) != null; } return false; } // /** // * @param element // * @return if elementImpl, return source, else null // * (unused) // */ // public static String getElementTextSource(Element element) { // if (element == null) { // return null; // } // if (element instanceof ElementImpl) { // return ((ElementImpl) element).getSource(); // } // return null; // } /** * @param project * @return IJavaProject */ public static IJavaProject getJavaProject(Object project) { if (project == null) { return null; } if (project instanceof IJavaProject) { return (IJavaProject) project; } else if (project instanceof IProject) { try { IProjectNature nature = ((IProject) project) .getNature(JavaCore.NATURE_ID); if (nature == null) { return null; } return (IJavaProject) nature; } catch (Exception e) { // Error.DesignerPropertyTool.NatureQuerying = Error in project // java nature querying PDPlugin.getLogger(DesignerPropertyTool.class).error( "Error.DesignerPropertyTool.NatureQuerying", e); //$NON-NLS-1$ // Should be error tolerable? return null; } } return null; } // // /** // * @param project as Object // * @return IProject or null // */ // public static IProject getProject(Object project) { // if (project instanceof IProject) { // return (IProject) project; // } else if (project instanceof IJavaProject) { // return ((IJavaProject) project).getProject(); // } // return null; // } }