/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.common.text.ext.util; import java.util.StringTokenizer; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.Region; import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; import org.eclipse.wst.xml.core.internal.document.AttrImpl; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode; import org.jboss.tools.common.text.ext.ExtensionsPlugin; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author Jeremy */ public class Utils { public static String trimQuotes(String word) { if(word == null) return null; String attrText = word; int bStart = 0; int bEnd = word.length() - 1; StringBuffer sb = new StringBuffer(attrText); //find start and end of path property while (bStart < bEnd && (sb.charAt(bStart) == '\'' || sb.charAt(bStart) == '\"' || Character.isWhitespace(sb.charAt(bStart)))) { bStart++; } while (bEnd >= 0 && (sb.charAt(bEnd) == '\'' || sb.charAt(bEnd) == '\"' || Character.isWhitespace(sb.charAt(bEnd)))) { bEnd--; } bEnd++; if (bEnd < bStart) bEnd = bStart; return sb.substring(bStart, bEnd); } static public Node findNodeForOffset(Node node, int offset) { return (node instanceof IDOMNode) ? findNodeForOffset((IDOMNode)node, offset) : null; } static public Node findNodeForOffset(IDOMNode node, int offset) { if(node == null) return null; if (!node.contains(offset)) return null; // Try to find the node in children NodeList children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { IDOMNode child = (IDOMNode)children.item(i); if (child.contains(offset)) { return findNodeForOffset(child, offset); } } // Not found in children or have no children if (node.hasAttributes()) { // Try to find in the node attributes NamedNodeMap attributes = node.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { IDOMNode attr = (IDOMNode)attributes.item(i); if (attr.contains(offset)) { return attr; } } } // Return the node itself return node; } public static String getParentAxisForNode(Document xmlDocument, Node node) { String axis = ""; //$NON-NLS-1$ if (node == null) return null; Node parent = (node instanceof Attr)? ((Attr)node).getOwnerElement():node.getParentNode(); while (parent instanceof Element) { String nodeName = parent.getNodeName(); axis = "/" + nodeName + axis; //$NON-NLS-1$ parent = parent.getParentNode(); } if (axis == null || axis.length() == 0) axis = null; return axis + "/"; //$NON-NLS-1$ } public static String trimFilePath(String name) { if(name == null) return null; StringTokenizer st = new StringTokenizer(name.replace('\\', '/'), "/"); //$NON-NLS-1$ String result = ""; //$NON-NLS-1$ while(st.hasMoreTokens()) { String token = st.nextToken(); if (!".".equals(token)){ //$NON-NLS-1$ result += (result.length() == 0 ? token : "/" + token); //$NON-NLS-1$ } } if (name.startsWith("/")) //$NON-NLS-1$ result = "/" + result; //$NON-NLS-1$ return result; } public static IPath getRelativePath (final IPath base, final IPath path) { // Make web-root path to be relative to project IPath relativePath = new Path("/"); //$NON-NLS-1$ String last = path.lastSegment(); IPath absolutePath = path.removeLastSegments(1); while (base.isPrefixOf(absolutePath)) { relativePath = new Path(last).append(relativePath); last = absolutePath.lastSegment(); absolutePath = absolutePath.removeLastSegments(1); } return relativePath; } public static String getTrimmedValue(IDocument document, Attr attr) throws BadLocationException { if(!(attr instanceof IDOMAttr)) return null; IDOMAttr domAttr = (IDOMAttr)attr; return Utils.trimQuotes(document.get(domAttr.getValueRegionStartOffset(), domAttr.getEndOffset() - domAttr.getValueRegionStartOffset())); } /** * Returns IRegion for the value of the given attribute * * @param document * @param attr * @return * @throws BadLocationException */ public static IRegion getAttributeValueRegion(IDocument document, Attr attr) throws BadLocationException { if(!(attr instanceof IDOMAttr)) return null; IDOMAttr domAttr = (IDOMAttr)attr; String attrText = document.get(domAttr.getValueRegionStartOffset(), domAttr.getEndOffset() - domAttr.getValueRegionStartOffset()); int bStart = 0; int bEnd = attrText.length() - 1; StringBuffer sb = new StringBuffer(attrText); //find start and end of path property while (bStart < bEnd && (sb.charAt(bStart) == '\'' || sb.charAt(bStart) == '\"' || Character.isWhitespace(sb.charAt(bStart)))) { bStart++; } while (bEnd >= 0 && (sb.charAt(bEnd) == '\'' || sb.charAt(bEnd) == '\"' || Character.isWhitespace(sb.charAt(bEnd)))) { bEnd--; } bEnd++; if (bEnd < bStart) bEnd = bStart; return new Region(domAttr.getValueRegionStartOffset()+bStart, bEnd - bStart); } public static String getAttributeValue (IDocument document, Node node, String attrName) { if(node == null || attrName == null || node.getAttributes() == null) return null; Attr attr = (Attr)node.getAttributes().getNamedItem(attrName); try { return Utils.getTrimmedValue(document, attr); } catch (BadLocationException x) { ExtensionsPlugin.getPluginLog().logError(x); return null; } } public static int getValueStart(Node n) { return (n instanceof IDOMAttr) ? ((IDOMAttr)n).getValueRegionStartOffset() : (n instanceof IndexedRegion) ? ((IndexedRegion)n).getStartOffset() : -1; } public static int getValueEnd(Node n) { return (n instanceof IndexedRegion) ? ((IndexedRegion)n).getEndOffset() : -1; } static public AttrNodePair findAttrNodePairForOffset(Node node, int offset) { return (node instanceof IDOMNode) ? findAttrNodePairForOffset((IDOMNode)node, offset) : null; } static public AttrNodePair findAttrNodePairForOffset(IDOMNode node, int offset) { if(node == null) return null; if (!node.contains(offset)) return null; // Try to find the node in children NodeList children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { IDOMNode child = (IDOMNode)children.item(i); if (child.contains(offset)) { return findAttrNodePairForOffset(child, offset); } } // Not found in children or have no children if (node.hasAttributes()) { // Try to find in the node attributes NamedNodeMap attributes = node.getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { IDOMNode attr = (IDOMNode)attributes.item(i); if (attr.contains(offset) && attr instanceof AttrImpl) { return new AttrNodePair((IDOMNode)node, (AttrImpl)attr); } } } // Return the node itself return new AttrNodePair(node, null); } public static class AttrNodePair{ AttrImpl attribute; IDOMNode node; public AttrNodePair(IDOMNode node, AttrImpl attribute){ this.attribute = attribute; this.node = node; } public IDOMNode getNode(){ return node; } public AttrImpl getAttribute(){ return attribute; } } }