forked from eclipse-lemminx/lemminx
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes eclipse-lemminx#778 Signed-off-by: azerr <azerr@redhat.com>
- Loading branch information
1 parent
427367b
commit 6da2665
Showing
19 changed files
with
817 additions
and
16 deletions.
There are no files selected for viewing
103 changes: 103 additions & 0 deletions
103
...src/main/java/org/eclipse/lemminx/extensions/generators/AbstractXML2GrammarGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 Red Hat Inc. and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.lemminx.extensions.generators; | ||
|
||
import java.util.List; | ||
|
||
import org.eclipse.lemminx.commons.TextDocument; | ||
import org.eclipse.lemminx.dom.DOMAttr; | ||
import org.eclipse.lemminx.services.IXMLFormatter; | ||
import org.eclipse.lemminx.settings.SharedSettings; | ||
import org.eclipse.lemminx.utils.XMLBuilder; | ||
import org.eclipse.lsp4j.Position; | ||
import org.eclipse.lsp4j.Range; | ||
import org.eclipse.lsp4j.TextEdit; | ||
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; | ||
|
||
public abstract class AbstractXML2GrammarGenerator<T extends FileContentGeneratorSettings> | ||
implements IFileContentGenerator<Document, T> { | ||
|
||
@Override | ||
public TextEdit generate(Document document, SharedSettings sharedSettings, T generatorSettings, | ||
IXMLFormatter formatter) { | ||
String newText = doConvert(document, sharedSettings, generatorSettings); | ||
if (formatter == null) { | ||
return new TextEdit(new Range(new Position(0, 0), new Position(0, 0)), newText); | ||
} | ||
List<? extends TextEdit> edits = formatter.format(new TextDocument(newText, "grammar." + getFileExtension()), | ||
null, sharedSettings); | ||
return edits.isEmpty() ? null : edits.get(0); | ||
} | ||
|
||
protected abstract String getFileExtension(); | ||
|
||
private String doConvert(Document document, SharedSettings sharedSettings, T generatorSettings) { | ||
GrammarInfo grammar = createGrammar(document); | ||
XMLBuilder builder = new XMLBuilder(sharedSettings, "", ""); | ||
generate(grammar, builder, generatorSettings); | ||
return builder.toString(); | ||
} | ||
|
||
protected abstract void generate(GrammarInfo grammar, XMLBuilder builder, T grammarSettings); | ||
|
||
private GrammarInfo createGrammar(Document document) { | ||
GrammarInfo grammar = new GrammarInfo(); | ||
// Update default namespace | ||
String defaultNamespace = null; | ||
Element documentElement = document.getDocumentElement(); | ||
if (documentElement != null) { | ||
defaultNamespace = document.getDocumentElement().getAttribute(DOMAttr.XMLNS_ATTR); | ||
} | ||
grammar.setDefaultNamespace(defaultNamespace); | ||
// Update elements information | ||
fillElements(document, grammar); | ||
return grammar; | ||
} | ||
|
||
private static void fillElements(Node node, ChildrenInfo grammar) { | ||
NodeList children = node.getChildNodes(); | ||
for (int i = 0; i < children.getLength(); i++) { | ||
Node child = children.item(i); | ||
if (child.getNodeType() == Node.ELEMENT_NODE) { | ||
Element element = (Element) child; | ||
ElementInfo grammarElt = grammar.getElement(element.getLocalName()); | ||
// Has text | ||
grammarElt.setHasCharacterContent(hasCharacterContent(element)); | ||
// Attributes | ||
NamedNodeMap attributes = element.getAttributes(); | ||
if (attributes != null) { | ||
for (int j = 0; j < attributes.getLength(); j++) { | ||
Attr attr = (Attr) attributes.item(i); | ||
grammarElt.getAttribute(attr.getName()); | ||
} | ||
} | ||
fillElements(element, grammarElt); | ||
} | ||
} | ||
} | ||
|
||
private static boolean hasCharacterContent(Element element) { | ||
NodeList children = element.getChildNodes(); | ||
for (int i = 0; i < children.getLength(); i++) { | ||
Node child = children.item(i); | ||
if (child.getNodeType() == Node.TEXT_NODE) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
...clipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/generators/AttributeInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 Red Hat Inc. and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.lemminx.extensions.generators; | ||
|
||
public class AttributeInfo { | ||
|
||
private final String name; | ||
|
||
public AttributeInfo(String name) { | ||
this.name = name; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
...eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/generators/ChildrenInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 Red Hat Inc. and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.lemminx.extensions.generators; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.HashMap; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class ChildrenInfo { | ||
|
||
private final Map<String, ElementInfo> children; | ||
|
||
public ChildrenInfo() { | ||
this.children = new LinkedHashMap<>(); | ||
} | ||
|
||
public ElementInfo getElement(String name) { | ||
ElementInfo element = children.get(name); | ||
if (element != null) { | ||
return element; | ||
} | ||
element = new ElementInfo(name); | ||
children.put(name, element); | ||
return element; | ||
} | ||
|
||
public Collection<ElementInfo> getElements() { | ||
return children.values(); | ||
} | ||
|
||
public Collection<ElementInfo> getAllElements() { | ||
List<ElementInfo> all = new ArrayList<>(); | ||
fillWithAllElements(all); | ||
return all; | ||
} | ||
|
||
protected void fillWithAllElements(List<ElementInfo> allElements) { | ||
for (ElementInfo element : getElements()) { | ||
if (!allElements.contains(element)) { | ||
allElements.add(element); | ||
element.fillWithAllElements(allElements); | ||
} | ||
} | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/generators/ElementInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 Red Hat Inc. and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.lemminx.extensions.generators; | ||
|
||
import java.util.Collection; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class ElementInfo extends ChildrenInfo { | ||
|
||
private final String name; | ||
|
||
private final Map<String, AttributeInfo> attributes; | ||
|
||
private boolean hasCharacterContent; | ||
|
||
public ElementInfo(String name) { | ||
this.name = name; | ||
this.attributes = new HashMap<>(); | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public AttributeInfo getAttribute(String name) { | ||
AttributeInfo attribute = attributes.get(name); | ||
if (attribute != null) { | ||
return attribute; | ||
} | ||
attribute = new AttributeInfo(name); | ||
attributes.put(name, attribute); | ||
return attribute; | ||
} | ||
|
||
public Collection<AttributeInfo> getAttributes() { | ||
return attributes.values(); | ||
} | ||
|
||
public boolean hasCharacterContent() { | ||
return hasCharacterContent; | ||
} | ||
|
||
public void setHasCharacterContent(boolean hasCharacterContent) { | ||
this.hasCharacterContent = hasCharacterContent; | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
.../src/main/java/org/eclipse/lemminx/extensions/generators/FileContentGeneratorManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 Red Hat Inc. and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.lemminx.extensions.generators; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import org.eclipse.lemminx.extensions.generators.xml2dtd.DTDSettings; | ||
import org.eclipse.lemminx.extensions.generators.xml2dtd.XML2DTDGenerator; | ||
import org.eclipse.lemminx.extensions.generators.xml2xsd.XML2XMLSchemaGenerator; | ||
import org.eclipse.lemminx.extensions.generators.xml2xsd.XMLSchemaSettings; | ||
import org.eclipse.lemminx.services.IXMLFormatter; | ||
import org.eclipse.lemminx.settings.SharedSettings; | ||
import org.eclipse.lsp4j.TextEdit; | ||
|
||
/** | ||
* Generator manager which is able to generate : | ||
* | ||
* <ul> | ||
* <li>XML Schema from a given XML.</li> | ||
* <li>DTD from a given XML.</li> | ||
* </ul> | ||
* | ||
*/ | ||
public class FileContentGeneratorManager { | ||
|
||
private static final FileContentGeneratorManager INSTANCE = new FileContentGeneratorManager(); | ||
private final Map<Class<? extends FileContentGeneratorSettings>, IFileContentGenerator<?, ?>> generators; | ||
|
||
private FileContentGeneratorManager() { | ||
generators = new HashMap<>(); | ||
registerDefaultGenerators(); | ||
} | ||
|
||
/** | ||
* Register default generators. | ||
*/ | ||
private void registerDefaultGenerators() { | ||
registerGenerator(new XML2DTDGenerator(), DTDSettings.class); | ||
registerGenerator(new XML2XMLSchemaGenerator(), XMLSchemaSettings.class); | ||
} | ||
|
||
public static FileContentGeneratorManager getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
/** | ||
* Register the given generator by using settings class as key generator. | ||
* | ||
* @param generator the generator. | ||
* @param generatorKey the key of the generator identified by the settings | ||
* class. | ||
*/ | ||
public void registerGenerator(IFileContentGenerator<?, ?> generator, | ||
Class<? extends FileContentGeneratorSettings> generatorKey) { | ||
generators.put(generatorKey, generator); | ||
} | ||
|
||
/** | ||
* Return the result of the generation from the source XML document and | ||
* settings. | ||
* | ||
* @param <T> the grammar settings. | ||
* @param document | ||
* @param sharedSettings | ||
* @param grammarSettings | ||
* @param formatter | ||
* @return | ||
*/ | ||
public <Source, Settings extends FileContentGeneratorSettings> TextEdit generate(Source document, | ||
SharedSettings sharedSettings, Settings grammarSettings, IXMLFormatter formatter) { | ||
@SuppressWarnings("unchecked") | ||
IFileContentGenerator<Source, Settings> generator = (IFileContentGenerator<Source, Settings>) generators | ||
.get(grammarSettings.getClass()); | ||
return generator.generate(document, sharedSettings, grammarSettings, formatter); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
...src/main/java/org/eclipse/lemminx/extensions/generators/FileContentGeneratorSettings.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 Red Hat Inc. and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.lemminx.extensions.generators; | ||
|
||
public class FileContentGeneratorSettings { | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/generators/GrammarInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 Red Hat Inc. and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.lemminx.extensions.generators; | ||
|
||
public class GrammarInfo extends ChildrenInfo{ | ||
|
||
private String defaultNamespace; | ||
|
||
public String getDefaultNamespace() { | ||
return defaultNamespace; | ||
} | ||
|
||
public void setDefaultNamespace(String defaultNamespace) { | ||
this.defaultNamespace = defaultNamespace; | ||
} | ||
|
||
} |
Oops, something went wrong.