| /******************************************************************************* |
| * 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; |
| // } |
| |
| } |