/******************************************************************************* * Copyright (c) 2012 VMware, Inc. * 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: * VMware, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.config.core; import java.io.IOException; import java.io.StringReader; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.internal.text.html.HTML2TextReader; import org.eclipse.wst.xml.core.internal.contentmodel.util.NamespaceTable; import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument; import org.osgi.framework.Version; import org.springframework.ide.eclipse.beans.ui.namespaces.INamespaceDefinition; import org.springframework.ide.eclipse.beans.ui.namespaces.NamespaceUtils; import org.springframework.ide.eclipse.config.core.contentassist.Messages; import org.springsource.ide.eclipse.commons.core.StatusHandler; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; /** * Static utilities of use throughout the configuration editor. * @author Leo Dos Santos * @author Christian Dupuis * @since STS 2.0.0 */ @SuppressWarnings("restriction") public class ConfigCoreUtils { public static String ATTR_DEFAULT_NAMESPACE = "xmlns"; //$NON-NLS-1$ public static String ATTR_NAMESPACE_PREFIX = "xmlns:"; //$NON-NLS-1$ public static String ATTR_SCHEMA_LOCATION = "xsi:schemaLocation"; //$NON-NLS-1$ private static final Pattern VERSION_PATTERN = Pattern.compile(".*-([0-9,.]*)\\.xsd"); //$NON-NLS-1$ /** * Returns the default namespace URI by searching the document for the * namespace declaration, or null if none found. * * @param doc document object model of the XML source file * @return default namespace URI of the given document */ public static String getDefaultNamespaceUri(IDOMDocument doc) { if (doc != null) { Element root = doc.getDocumentElement(); if (root != null) { NamedNodeMap attrs = root.getAttributes(); for (int i = 0; i < attrs.getLength(); i++) { Node item = attrs.item(i); String itemName = item.getLocalName(); if (itemName.equals(ATTR_DEFAULT_NAMESPACE)) { return item.getNodeValue(); } } } } return null; } /** * Returns the namespace prefix for the given URI. * * @param doc document object model of the XML source file * @param namespaceUri namespace URI to examine * @return namespace prefix for the given URI */ public static String getPrefixForNamespaceUri(IDOMDocument doc, String namespaceUri) { if (doc != null && namespaceUri != null) { NamespaceTable table = new NamespaceTable(doc); Element elem = doc.getDocumentElement(); table.addElementLineage(elem); return table.getPrefixForURI(namespaceUri); } return null; } /** * Returns the selected schema version for the given URI. * * @param doc document object model of the XML source file * @param namespaceUri namespace URI to examine * @return selected schema version for the given URI */ public static Version getSchemaVersion(IDOMDocument doc, String namespaceUri) { String versLocation = getSelectedSchemaLocation(doc, namespaceUri); Matcher matcher = VERSION_PATTERN.matcher(versLocation); if (matcher.matches()) { return new Version(matcher.group(1)); } else { List<INamespaceDefinition> defs = NamespaceUtils.getNamespaceDefinitions(); for (INamespaceDefinition def : defs) { Version version = Version.emptyVersion; if (namespaceUri.equals(def.getNamespaceURI())) { Version tempVersion = Version.emptyVersion; for (String location : def.getSchemaLocations()) { matcher = VERSION_PATTERN.matcher(location); if (matcher.matches()) { tempVersion = new Version(matcher.group(1)); } if (tempVersion.compareTo(version) >= 0) { version = tempVersion; } } return version; } } return Version.emptyVersion; } } /** * Returns the selected schema version location for the given URI. * * @param doc document object model of the XML source file * @param namespaceUri namespace URI to examine * @return selected schema version location for the given URI */ public static String getSelectedSchemaLocation(IDOMDocument doc, String namespaceUri) { List<String> schemaInfo = ConfigCoreUtils.parseSchemaLocationAttr(doc); if (schemaInfo != null) { Iterator<String> iter = schemaInfo.iterator(); while (iter.hasNext()) { String currSchema = iter.next(); if (currSchema.equals(namespaceUri) && iter.hasNext()) { // String after the schema is the version return iter.next(); } } } return ""; //$NON-NLS-1$ } /** * Parses the XML document for schema information and returns it as an * array, paired by namespace URI and schema version. * * @param doc document object model of the XML source file * @return array of paired namespace URIs and schema versions for the given * document */ public static List<String> parseSchemaLocationAttr(IDOMDocument doc) { if (doc != null) { Element root = doc.getDocumentElement(); if (root != null) { String schemaLocationValue = root.getAttribute(ATTR_SCHEMA_LOCATION); if (schemaLocationValue != null) { // Remove all line breaks and tabs schemaLocationValue = schemaLocationValue.replaceAll("\\n|\\t|\\r", " "); //$NON-NLS-1$ //$NON-NLS-2$ // Remove any extra spaces schemaLocationValue = schemaLocationValue.replaceAll(" +", " "); //$NON-NLS-1$ //$NON-NLS-2$ // Trim any remaining whitespace on the ends schemaLocationValue = schemaLocationValue.trim(); // Split along spaces into just the schema content return Arrays.asList(schemaLocationValue.split(" ")); //$NON-NLS-1$ } } } return null; } /** * Strips text content of all HTML tags and formatting information. * * @param html text content containing HTML tags * @return the given content stripped of HTML tags */ public static String stripTags(String html) { if (html != null) { try { StringReader reader = new StringReader(html); HTML2TextReader parser = new HTML2TextReader(reader, null); return parser.getString().trim(); } catch (IOException e) { StatusHandler.log(new Status(IStatus.ERROR, ConfigCorePlugin.PLUGIN_ID, Messages.XmlBackedContentProposalProvider_ERROR_STRIP_TAGS, e)); } } return html; } }