Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Thienel2014-03-20 17:20:02 -0400
committerFlorian Thienel2014-03-23 05:59:06 -0400
commit0c935f16ff0519297184871087720a5333b6f344 (patch)
treefeef519ea37e7497f6173d8312e66281369d3eda
parentf863cf9c7f1167e4e687b43308aef5732f3a9997 (diff)
downloadorg.eclipse.mylyn.docs.vex-0c935f16ff0519297184871087720a5333b6f344.tar.gz
org.eclipse.mylyn.docs.vex-0c935f16ff0519297184871087720a5333b6f344.tar.xz
org.eclipse.mylyn.docs.vex-0c935f16ff0519297184871087720a5333b6f344.zip
[423130] use an IContentDescriber to associate Vex with files
Vex should be associated only with files containing documents of registered document types. Therefor the VexContentDescriber reads the DTD and the root element to decide if a file contains such a document. Furthermore it is not essentially required for bundles that register a document type to also register a new content type. This is only necessary if a custom file extension (!= xml) should be used. Bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=423130 Change-Id: I695e512c03f49f87f6221d3c3c6529ea04935477 Signed-off-by: Florian Thienel <florian@thienel.org>
-rw-r--r--org.eclipse.vex.dita/plugin.xml8
-rw-r--r--org.eclipse.vex.docbook/plugin.properties3
-rw-r--r--org.eclipse.vex.docbook/plugin.xml9
-rw-r--r--org.eclipse.vex.projectplan/plugin.properties3
-rw-r--r--org.eclipse.vex.projectplan/plugin.xml10
-rw-r--r--org.eclipse.vex.ui.tests/plugin.properties3
-rw-r--r--org.eclipse.vex.ui.tests/plugin.xml5
-rw-r--r--org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/contenttype/tests/VexContentDescriberTest.java86
-rw-r--r--org.eclipse.vex.ui/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.vex.ui/plugin.xml2
-rw-r--r--org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/contenttype/InferXmlContentTypeHandler.java141
-rw-r--r--org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/contenttype/VexContentDescriber.java58
-rw-r--r--org.eclipse.vex.xhtml/plugin.xml2
13 files changed, 296 insertions, 35 deletions
diff --git a/org.eclipse.vex.dita/plugin.xml b/org.eclipse.vex.dita/plugin.xml
index 872155dc..8703fb79 100644
--- a/org.eclipse.vex.dita/plugin.xml
+++ b/org.eclipse.vex.dita/plugin.xml
@@ -9,28 +9,28 @@
file-extensions="dita,ditamap,bookmap,ditaval"
id="org.eclipse.vex.ui.dita"
name="%contentType.name"
- priority="normal">
+ priority="low">
</content-type>
<content-type
base-type="org.eclipse.vex.ui.dita.map"
file-extensions="ditamap,bookmap"
id="org.eclipse.vex.ui.dita.map"
name="%contentType.map.name"
- priority="low">
+ priority="normal">
</content-type>
<content-type
base-type="org.eclipse.vex.ui.dita.ditaval"
file-extensions="ditaval"
id="org.eclipse.vex.ui.dita.ditaval"
name="%contentType.ditaval.name"
- priority="low">
+ priority="normal">
</content-type>
<content-type
base-type="org.eclipse.vex.ui.dita.topic"
file-extensions="dita"
id="org.eclipse.vex.ui.dita.topic"
name="%contentType.topic.name"
- priority="low">
+ priority="normal">
</content-type>
</extension>
diff --git a/org.eclipse.vex.docbook/plugin.properties b/org.eclipse.vex.docbook/plugin.properties
index 6750db3c..f42b6031 100644
--- a/org.eclipse.vex.docbook/plugin.properties
+++ b/org.eclipse.vex.docbook/plugin.properties
@@ -15,5 +15,4 @@ doctype.docbook4_5=DocBook v4.5
doctype.docbook5_0_DTD=DocBook v5.0 (DTD)
doctype.docbook5_0_XSD2=DocBook v5.0 (XML Schema)
-style.docbook-plain=DocBook Plain
-contentType.name=DocBook XML Document
+style.docbook-plain=DocBook Plain
diff --git a/org.eclipse.vex.docbook/plugin.xml b/org.eclipse.vex.docbook/plugin.xml
index 65a9911e..4d7fecb7 100644
--- a/org.eclipse.vex.docbook/plugin.xml
+++ b/org.eclipse.vex.docbook/plugin.xml
@@ -2,15 +2,6 @@
<?eclipse version="3.2"?>
<plugin>
- <extension point="org.eclipse.core.contenttype.contentTypes">
- <content-type
- base-type="org.eclipse.vex.ui.XmlDocument"
- file-extensions="xml,docbook"
- id="org.eclipse.vex.ui.docbook"
- name="%contentType.name"
- priority="low">
- </content-type>
- </extension>
<extension
point="org.eclipse.wst.xml.core.catalogContributions">
<catalogContribution
diff --git a/org.eclipse.vex.projectplan/plugin.properties b/org.eclipse.vex.projectplan/plugin.properties
index c2039492..d3605f5c 100644
--- a/org.eclipse.vex.projectplan/plugin.properties
+++ b/org.eclipse.vex.projectplan/plugin.properties
@@ -13,5 +13,4 @@ providerName= Eclipse.org
doctype.plan=Eclipse Project Plan
-style.plain=Plain
-contentType.name=Eclipse Project Plan
+style.plain=Plain
diff --git a/org.eclipse.vex.projectplan/plugin.xml b/org.eclipse.vex.projectplan/plugin.xml
index d8cfc60f..b03dbdf1 100644
--- a/org.eclipse.vex.projectplan/plugin.xml
+++ b/org.eclipse.vex.projectplan/plugin.xml
@@ -2,16 +2,6 @@
<?eclipse version="3.4"?>
<plugin>
<extension
- point="org.eclipse.core.contenttype.contentTypes">
- <content-type
- base-type="org.eclipse.vex.ui.XmlDocument"
- file-extensions="xml,projectplan"
- id="org.eclipse.vex.projectplan"
- name="%contentType.name"
- priority="low">
- </content-type>
- </extension>
- <extension
point="org.eclipse.wst.xml.core.catalogContributions">
<catalogContribution>
<uri
diff --git a/org.eclipse.vex.ui.tests/plugin.properties b/org.eclipse.vex.ui.tests/plugin.properties
index 3d85c6a1..d3422877 100644
--- a/org.eclipse.vex.ui.tests/plugin.properties
+++ b/org.eclipse.vex.ui.tests/plugin.properties
@@ -9,5 +9,4 @@
# David Carver - initial API and implementation
###############################################################################
pluginName= Vex UI Tests
-providerName= Eclipse.org
-contentType.name=Vex Test XML Document Type
+providerName= Eclipse.org
diff --git a/org.eclipse.vex.ui.tests/plugin.xml b/org.eclipse.vex.ui.tests/plugin.xml
index dd04ca3b..8bbfd6de 100644
--- a/org.eclipse.vex.ui.tests/plugin.xml
+++ b/org.eclipse.vex.ui.tests/plugin.xml
@@ -1,11 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
- <extension point="org.eclipse.core.contenttype.contentTypes">
- <content-type id="org.eclipse.vex.ui.tests" name="%contentType.name"
- base-type="org.eclipse.vex.ui.XmlDocument" file-extensions="xml">
- </content-type>
- </extension>
<extension
point="org.eclipse.wst.xml.core.catalogContributions">
<catalogContribution
diff --git a/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/contenttype/tests/VexContentDescriberTest.java b/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/contenttype/tests/VexContentDescriberTest.java
new file mode 100644
index 00000000..bca79cf7
--- /dev/null
+++ b/org.eclipse.vex.ui.tests/src/org/eclipse/vex/ui/internal/contenttype/tests/VexContentDescriberTest.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Florian Thienel 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:
+ * Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.ui.internal.contenttype.tests;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.content.IContentDescriber;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.vex.ui.internal.contenttype.VexContentDescriber;
+import org.junit.Test;
+
+/**
+ * @author Florian Thienel
+ */
+public class VexContentDescriberTest {
+
+ private static final String REGISTERED_VEX_DOCTYPE = "<?xml version=\"1.0\"?><!DOCTYPE section PUBLIC \"-//Vex//DTD Test//EN\" \"test.dtd\"><section/>";
+ private static final String ARBITRARY_XML = "<?xml version=\"1.0\"?><someRootElement/>";
+ private static final String SIMPLE_TEXT = "Hello World";
+
+ @Test
+ public void givenRegisteredVexDoctype_shouldDescribeAsValid() throws Exception {
+ assertDescribesAs(IContentDescriber.VALID, REGISTERED_VEX_DOCTYPE);
+ }
+
+ @Test
+ public void givenArbitraryXml_shouldDescribeAsIndeterminate() throws Exception {
+ assertDescribesAs(IContentDescriber.INDETERMINATE, ARBITRARY_XML);
+ }
+
+ @Test
+ public void givenSimpleText_shouldDescribeAsInvalid() throws Exception {
+ assertDescribesAs(IContentDescriber.INVALID, SIMPLE_TEXT);
+ }
+
+ private static void assertDescribesAs(final int expectedDescription, final String contents) throws Exception {
+ final VexContentDescriber describer = new VexContentDescriber();
+ final IContentDescription description = new DummyContentDescription();
+ assertEquals(expectedDescription, describer.describe(new ByteArrayInputStream(contents.getBytes()), description));
+ }
+
+ private static class DummyContentDescription implements IContentDescription {
+
+ private final Map<QualifiedName, Object> properties = new HashMap<QualifiedName, Object>();
+
+ @Override
+ public boolean isRequested(final QualifiedName key) {
+ return true;
+ }
+
+ @Override
+ public String getCharset() {
+ return System.getProperty("file.encoding");
+ }
+
+ @Override
+ public IContentType getContentType() {
+ return null;
+ }
+
+ @Override
+ public Object getProperty(final QualifiedName key) {
+ return properties.get(key);
+ }
+
+ @Override
+ public void setProperty(final QualifiedName key, final Object value) {
+ properties.put(key, value);
+ }
+
+ }
+}
diff --git a/org.eclipse.vex.ui/META-INF/MANIFEST.MF b/org.eclipse.vex.ui/META-INF/MANIFEST.MF
index 31e9886b..b7d471c2 100644
--- a/org.eclipse.vex.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.vex.ui/META-INF/MANIFEST.MF
@@ -24,6 +24,7 @@ Require-Bundle: org.eclipse.vex.core;bundle-version="[1.1.0,2.0.0)",
org.eclipse.core.filesystem;bundle-version="[1.3.0,2.0.0)"
Export-Package: org.eclipse.vex.ui.internal;x-friends:="org.eclipse.vex.ui.tests",
org.eclipse.vex.ui.internal.config;x-friends:="org.eclipse.vex.ui.tests",
+ org.eclipse.vex.ui.internal.contenttype;x-friends:="org.eclipse.vex.ui.tests",
org.eclipse.vex.ui.internal.editor;
x-friends:="org.eclipse.vex.docbook,
org.eclipse.vex.ui.tests,
diff --git a/org.eclipse.vex.ui/plugin.xml b/org.eclipse.vex.ui/plugin.xml
index 5a1ce818..363cf228 100644
--- a/org.eclipse.vex.ui/plugin.xml
+++ b/org.eclipse.vex.ui/plugin.xml
@@ -9,6 +9,8 @@
<extension point="org.eclipse.core.contenttype.contentTypes">
<content-type
base-type="org.eclipse.core.runtime.xml"
+ describer="org.eclipse.vex.ui.internal.contenttype.VexContentDescriber"
+ file-extensions="xml"
id="org.eclipse.vex.ui.XmlDocument"
name="%contentType.XmlDocument.name"
priority="low">
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/contenttype/InferXmlContentTypeHandler.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/contenttype/InferXmlContentTypeHandler.java
new file mode 100644
index 00000000..ae08a147
--- /dev/null
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/contenttype/InferXmlContentTypeHandler.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Florian Thienel 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:
+ * Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.ui.internal.contenttype;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.core.runtime.QualifiedName;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * @author Florian Thienel
+ */
+public class InferXmlContentTypeHandler extends DefaultHandler implements LexicalHandler {
+
+ private String dtdPublicId;
+ private String dtdSystemId;
+ private QualifiedName rootElementName;
+
+ public String getMainDocumentTypeIdentifier() {
+ if (dtdPublicId != null) {
+ return dtdPublicId;
+ }
+ if (dtdSystemId != null) {
+ return dtdSystemId;
+ }
+ return rootElementName.getQualifier();
+ }
+
+ public QualifiedName getRootElementName() {
+ return rootElementName;
+ }
+
+ public boolean parseContents(final InputSource contents) {
+ try {
+ final SAXParserFactory factory = SAXParserFactory.newInstance();
+ if (factory == null) {
+ return false;
+ }
+ factory.setNamespaceAware(true);
+ final SAXParser parser = createParser(factory);
+ contents.setSystemId("/"); //$NON-NLS-1$
+ parser.parse(contents, this);
+ } catch (final AbortParsingException e) {
+ // Abort the parsing normally. Fall through...
+ } catch (final ParserConfigurationException e) {
+ return false;
+ } catch (final SAXException e) {
+ return false;
+ } catch (final IOException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private SAXParser createParser(final SAXParserFactory parserFactory) throws ParserConfigurationException, SAXException, SAXNotRecognizedException, SAXNotSupportedException {
+ final SAXParser parser = parserFactory.newSAXParser();
+ final XMLReader reader = parser.getXMLReader();
+ reader.setProperty("http://xml.org/sax/properties/lexical-handler", this); //$NON-NLS-1$
+ try {
+ reader.setFeature("http://xml.org/sax/features/validation", false); //$NON-NLS-1$
+ reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$
+ } catch (final SAXNotRecognizedException e) {
+ // not a big deal if the parser does not recognize the features
+ } catch (final SAXNotSupportedException e) {
+ // not a big deal if the parser does not support the features
+ }
+ return parser;
+ }
+
+ @Override
+ public void startDTD(final String name, final String publicId, final String systemId) throws SAXException {
+ dtdPublicId = publicId;
+ dtdSystemId = systemId;
+ }
+
+ @Override
+ public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException {
+ rootElementName = new QualifiedName(uri, localName);
+ throw new AbortParsingException();
+ }
+
+ @Override
+ public void endDTD() throws SAXException {
+ // ignore
+ }
+
+ @Override
+ public void startEntity(final String name) throws SAXException {
+ // ignore
+ }
+
+ @Override
+ public void endEntity(final String name) throws SAXException {
+ // ignore
+ }
+
+ @Override
+ public void startCDATA() throws SAXException {
+ // ignore
+ }
+
+ @Override
+ public void endCDATA() throws SAXException {
+ // ignore
+ }
+
+ @Override
+ public void comment(final char[] ch, final int start, final int length) throws SAXException {
+ // ignore
+ }
+
+ @Override
+ public InputSource resolveEntity(final String publicId, final String systemId) throws IOException, SAXException {
+ return new InputSource(new StringReader(""));
+ }
+
+ private static class AbortParsingException extends SAXException {
+ private static final long serialVersionUID = 1L;
+ }
+
+}
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/contenttype/VexContentDescriber.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/contenttype/VexContentDescriber.java
new file mode 100644
index 00000000..8319497b
--- /dev/null
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/contenttype/VexContentDescriber.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Florian Thienel 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:
+ * Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.ui.internal.contenttype;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.content.XMLContentDescriber;
+import org.eclipse.vex.ui.internal.VexPlugin;
+import org.eclipse.vex.ui.internal.config.DocumentType;
+import org.xml.sax.InputSource;
+
+/**
+ * @author Florian Thienel
+ */
+public class VexContentDescriber extends XMLContentDescriber {
+
+ @Override
+ public int describe(final InputStream contents, final IContentDescription description) throws IOException {
+ if (super.describe(contents, description) == INVALID) {
+ return INVALID;
+ }
+ contents.reset();
+ return checkCriteria(new InputSource(contents), description);
+ }
+
+ @Override
+ public int describe(final Reader contents, final IContentDescription description) throws IOException {
+ if (super.describe(contents, description) == INVALID) {
+ return INVALID;
+ }
+ contents.reset();
+ return checkCriteria(new InputSource(contents), description);
+ }
+
+ private int checkCriteria(final InputSource contents, final IContentDescription description) {
+ final InferXmlContentTypeHandler handler = new InferXmlContentTypeHandler();
+ if (!handler.parseContents(contents)) {
+ return INVALID;
+ }
+
+ final DocumentType documentType = VexPlugin.getDefault().getConfigurationRegistry().getDocumentType(handler.getMainDocumentTypeIdentifier(), "");
+ if (documentType != null) {
+ return VALID;
+ }
+ return INDETERMINATE;
+ }
+}
diff --git a/org.eclipse.vex.xhtml/plugin.xml b/org.eclipse.vex.xhtml/plugin.xml
index 18c38e21..46ff03e6 100644
--- a/org.eclipse.vex.xhtml/plugin.xml
+++ b/org.eclipse.vex.xhtml/plugin.xml
@@ -4,7 +4,7 @@
<extension point="org.eclipse.core.contenttype.contentTypes">
<content-type
base-type="org.eclipse.vex.ui.XmlDocument"
- file-extensions="xml,xhtml"
+ file-extensions="xhtml"
id="org.eclipse.vex.ui.xhtml"
name="%contentType.name"
priority="low">

Back to the top