diff --git a/app/build.gradle b/app/build.gradle
index 2848520a6..5d27b5d6e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,7 +1,10 @@
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
-apply plugin: com.github.megatronking.stringfog.plugin.StringFogPlugin
+
+if(rootProject.ext.stringfogEnabled) {
+ apply plugin: com.github.megatronking.stringfog.plugin.StringFogPlugin
+}
android {
compileSdkVersion rootProject.ext.compileSdk
@@ -61,13 +64,11 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
- stringfog.enable false
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
- stringfog.enable true
}
}
@@ -79,10 +80,12 @@ android {
}
}
-stringfog {
- key 'WVV0aGMwaEFZVzVFVW05SlJFbGtaUT09'
- enable true
- implementation 'com.github.megatronking.stringfog.xor.StringFogImpl'
+if(rootProject.ext.stringfogEnabled) {
+ stringfog {
+ key 'WVV0aGMwaEFZVzVFVW05SlJFbGtaUT09'
+ enable true
+ implementation 'com.github.megatronking.stringfog.xor.StringFogImpl'
+ }
}
task copyBindings(type: Copy) {
@@ -114,7 +117,7 @@ dependencies {
implementation 'androidx.annotation:annotation:1.2.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.cardview:cardview:1.0.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
implementation 'androidx.drawerlayout:drawerlayout:1.1.1'
implementation 'androidx.gridlayout:gridlayout:1.0.0'
@@ -126,7 +129,7 @@ dependencies {
implementation 'com.google.android.material:material:1.4.0'
// Firebase
- implementation platform('com.google.firebase:firebase-bom:28.1.0')
+ implementation platform('com.google.firebase:firebase-bom:28.4.2')
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-crashlytics'
implementation 'com.google.firebase:firebase-messaging'
@@ -137,8 +140,7 @@ dependencies {
implementation project(':emulator')
implementation project(':emulatorview')
implementation project(':javapoet')
-
- api project(':lemminx')
+ implementation project(':lsp')
// LSP4J
implementation 'org.eclipse.lsp4j:org.eclipse.lsp4j:0.12.0'
diff --git a/app/src/main/java/com/itsaky/androidide/EditorActivity.java b/app/src/main/java/com/itsaky/androidide/EditorActivity.java
index 214df4cbc..470bc03fc 100644
--- a/app/src/main/java/com/itsaky/androidide/EditorActivity.java
+++ b/app/src/main/java/com/itsaky/androidide/EditorActivity.java
@@ -996,10 +996,6 @@ public class EditorActivity extends StudioActivity implements FileTreeFragment.F
Optional result = LSP.Java.init(mProject.getProjectPath());
LSP.Java.initialized();
});
- LSP.XML.start(() -> {
- Optional result = LSP.XML.init(mProject.getProjectPath());
- LSP.XML.initialized();
- });
}
private void getProjectFromIntent() {
diff --git a/app/src/main/java/com/itsaky/androidide/fragments/EditorFragment.java b/app/src/main/java/com/itsaky/androidide/fragments/EditorFragment.java
index 4e316f3d4..980201aa1 100644
--- a/app/src/main/java/com/itsaky/androidide/fragments/EditorFragment.java
+++ b/app/src/main/java/com/itsaky/androidide/fragments/EditorFragment.java
@@ -285,7 +285,7 @@ public class EditorFragment extends BaseFragment implements EditorEventListener
mBinding.editor.setEditorLanguage(new EmptyLanguage());
}
- // File must be set only after setting the language server
+ // File must be set only after setting the language
// This will make sure that textDocument/didOpen is sent
mBinding.editor.setFile(getFile());
diff --git a/app/src/main/java/com/itsaky/androidide/language/groovy/GroovyAutoComplete.java b/app/src/main/java/com/itsaky/androidide/language/groovy/GroovyAutoComplete.java
index 69b7e457d..95dedfec6 100644
--- a/app/src/main/java/com/itsaky/androidide/language/groovy/GroovyAutoComplete.java
+++ b/app/src/main/java/com/itsaky/androidide/language/groovy/GroovyAutoComplete.java
@@ -16,7 +16,7 @@ public class GroovyAutoComplete implements AutoCompleteProvider {
private static final List OTHERS = createOtherCompletions();
@Override
- public List getAutoCompleteItems(String fileUri, String prefix, boolean isInCodeBlock, TextAnalyzeResult colors, int index, int line, int column) throws Exception {
+ public List getAutoCompleteItems(CharSequence content, String fileUri, String prefix, boolean isInCodeBlock, TextAnalyzeResult colors, int index, int line, int column) throws Exception {
List result = new ArrayList<>();
for(String artifact : ANDROIDX_ARTIFACTS) {
diff --git a/app/src/main/java/com/itsaky/androidide/language/java/JavaAutoComplete.java b/app/src/main/java/com/itsaky/androidide/language/java/JavaAutoComplete.java
index 5f2dcb325..9bedc33c7 100644
--- a/app/src/main/java/com/itsaky/androidide/language/java/JavaAutoComplete.java
+++ b/app/src/main/java/com/itsaky/androidide/language/java/JavaAutoComplete.java
@@ -22,7 +22,7 @@ public class JavaAutoComplete implements AutoCompleteProvider {
private CompletableFuture, CompletionList>> future;
@Override
- public List getAutoCompleteItems(String fileUri, String prefix, boolean isInCodeBlock, TextAnalyzeResult colors, int index, int line, int column) throws Exception {
+ public List getAutoCompleteItems(CharSequence content, String fileUri, String prefix, boolean isInCodeBlock, TextAnalyzeResult colors, int index, int line, int column) throws Exception {
IDELanguageServer languageServer = LSPProvider.getServerForLanguage(LSPProvider.LANGUAGE_JAVA);
if(languageServer != null && fileUri != null) {
diff --git a/app/src/main/java/com/itsaky/androidide/language/logs/LogLanguageImpl.java b/app/src/main/java/com/itsaky/androidide/language/logs/LogLanguageImpl.java
index 09b6b32e6..7e944702c 100644
--- a/app/src/main/java/com/itsaky/androidide/language/logs/LogLanguageImpl.java
+++ b/app/src/main/java/com/itsaky/androidide/language/logs/LogLanguageImpl.java
@@ -105,7 +105,7 @@ public class LogLanguageImpl extends BaseLanguage {
private static class LogCompletor implements AutoCompleteProvider {
@Override
- public List getAutoCompleteItems(String fileUri, String prefix, boolean isInCodeBlock, TextAnalyzeResult colors, int index, int line, int column) {
+ public List getAutoCompleteItems(CharSequence content, String fileUri, String prefix, boolean isInCodeBlock, TextAnalyzeResult colors, int index, int line, int column) {
return new ArrayList();
}
}
diff --git a/app/src/main/java/com/itsaky/androidide/language/xml/XMLAutoComplete.java b/app/src/main/java/com/itsaky/androidide/language/xml/XMLAutoComplete.java
index db3ee6531..ecf5f6db3 100644
--- a/app/src/main/java/com/itsaky/androidide/language/xml/XMLAutoComplete.java
+++ b/app/src/main/java/com/itsaky/androidide/language/xml/XMLAutoComplete.java
@@ -1,72 +1,34 @@
package com.itsaky.androidide.language.xml;
-import com.itsaky.androidide.lsp.LSPProvider;
-import com.itsaky.lsp.services.IDELanguageServer;
+import com.itsaky.androidide.app.StudioApp;
+import com.itsaky.androidide.language.xml.completion.XMLCompletionService;
+import com.itsaky.androidide.utils.Logger;
import io.github.rosemoe.editor.interfaces.AutoCompleteProvider;
import io.github.rosemoe.editor.text.TextAnalyzeResult;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-import java.util.concurrent.CompletableFuture;
import org.eclipse.lsp4j.CompletionItem;
-import org.eclipse.lsp4j.CompletionList;
-import org.eclipse.lsp4j.CompletionParams;
-import org.eclipse.lsp4j.Position;
-import org.eclipse.lsp4j.TextDocumentIdentifier;
-import org.eclipse.lsp4j.jsonrpc.messages.Either;
-import com.itsaky.androidide.utils.Logger;
public class XMLAutoComplete implements AutoCompleteProvider {
-
+
private static final Logger LOG = Logger.instance("XMLAutoComplete");
private Comparator RESULTS_SORTER = new Comparator(){
@Override
public int compare(CompletionItem p1, CompletionItem p2) {
- if(p1.getSortText() == null && p1.getSortText() != null) return -1;
- if(p1.getSortText() != null && p1.getSortText() == null) return 1;
- if(p1.getSortText() == null && p1.getSortText() == null) return 0;
+ if(p1.getSortText() == null && p2.getSortText() != null) return -1;
+ if(p1.getSortText() != null && p2.getSortText() == null) return 1;
+ if(p1.getSortText() == null && p2.getSortText() == null) return 0;
return p1.getSortText().compareTo(p2.getSortText());
}
};
- private CompletableFuture, CompletionList>> lastRequest;
-
- /**
- * TODO: Change this to a language server implementation and remove the use of passing editor content
- */
@Override
- public List getAutoCompleteItems(String fileUri, String prefix, boolean isInCodeBlock, TextAnalyzeResult colors, int index, int line, int column) {
- final IDELanguageServer server = LSPProvider.getServerForLanguage(LSPProvider.LANGUAGE_XML);
- if(server == null)
- return List.of();
-
- if(lastRequest != null && !lastRequest.isDone()) {
- lastRequest.cancel(true);
- }
-
- final CompletionParams params = new CompletionParams();
- params.setTextDocument(new TextDocumentIdentifier(fileUri));
- params.setPosition(new Position(line, column));
-
- lastRequest = server.getTextDocumentService().completion(params);
-
- try {
- Either, CompletionList> result = lastRequest.get();
- if(result != null) {
- if(result.isLeft()) {
- return sort(result.getLeft());
- } else if(result.isRight()) {
- return sort(result.getRight().getItems());
- }
- }
- } catch (Throwable th) {
- LOG.error("XML Completion error", th);
- return List.of();
- }
-
- return List.of();
+ public List getAutoCompleteItems(CharSequence content, String fileUri, String prefix, boolean isInCodeBlock, TextAnalyzeResult colors, int index, int line, int column) {
+ final XMLCompletionService service = StudioApp.getInstance().getXmlCompletionService();
+ return sort(service.complete(content, index, line, column, prefix.toLowerCase().trim()));
}
private List sort(List result) {
diff --git a/app/src/main/java/com/itsaky/androidide/language/xml/XMLLanguage.java b/app/src/main/java/com/itsaky/androidide/language/xml/XMLLanguage.java
index 94eb0c99b..23f6432cf 100644
--- a/app/src/main/java/com/itsaky/androidide/language/xml/XMLLanguage.java
+++ b/app/src/main/java/com/itsaky/androidide/language/xml/XMLLanguage.java
@@ -14,13 +14,14 @@ import java.io.File;
import java.io.StringReader;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.Token;
+import com.itsaky.androidide.lsp.LanguageServerWrapper;
public class XMLLanguage extends BaseLanguage {
private XMLAnalyzer analyzer;
private XMLAutoComplete completer;
private NewlineHandler[] newlineHandlers = new NewlineHandler[] {};
-
+
public XMLLanguage() {
super(null);
}
@@ -34,7 +35,7 @@ public class XMLLanguage extends BaseLanguage {
@Override
public IDELanguageServer getLanguageServer() {
- return LSPProvider.getServerForLanguage(getLanguageCode());
+ return null;
}
@Override
diff --git a/app/src/main/java/com/itsaky/androidide/language/xml/completion/XMLCompletionService.java b/app/src/main/java/com/itsaky/androidide/language/xml/completion/XMLCompletionService.java
index eae0f2b53..a19803bd4 100644
--- a/app/src/main/java/com/itsaky/androidide/language/xml/completion/XMLCompletionService.java
+++ b/app/src/main/java/com/itsaky/androidide/language/xml/completion/XMLCompletionService.java
@@ -3,7 +3,6 @@ package com.itsaky.androidide.language.xml.completion;
import com.itsaky.androidide.language.xml.lexer.XMLLexer;
import com.itsaky.androidide.utils.Environment;
import com.itsaky.androidide.utils.FileUtil;
-import io.github.rosemoe.editor.widget.CodeEditor;
import java.io.File;
import java.io.StringReader;
import java.util.ArrayList;
@@ -17,16 +16,16 @@ import java.util.Set;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.Token;
import org.eclipse.lsp4j.CompletionItem;
+import org.eclipse.lsp4j.CompletionItemKind;
+import org.eclipse.lsp4j.InsertTextFormat;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
-import org.eclipse.lsp4j.InsertTextFormat;
-import org.eclipse.lsp4j.CompletionItemKind;
public class XMLCompletionService {
private HashMap attrs;
- private List widgets;
+ private List widgets;
private final File ANDROID_ATTRS;
private final File ANDROID_WIDGETS;
@@ -37,6 +36,7 @@ public class XMLCompletionService {
this.ANDROID_WIDGETS = new File(Environment.BOOTCLASSPATH.getParentFile(), "data/widgets.txt");
this.attrs = new HashMap<>();
this.widgets = new ArrayList<>();
+
if(ANDROID_ATTRS.exists() && ANDROID_ATTRS.isFile()) {
addAttributesFrom(ANDROID_ATTRS, true);
}
@@ -51,8 +51,7 @@ public class XMLCompletionService {
return initiated;
}
-
- public List complete(int index, int line, int column, String prefix) {
+ public List complete(CharSequence content, int index, int line, int column, String prefix) {
final List result = new ArrayList<>();
if(prefix.startsWith("<") || prefix.startsWith("")) {
boolean slash = false;
@@ -61,16 +60,12 @@ public class XMLCompletionService {
slash = true;
prefix = prefix.substring(1);
}
- for(String name : widgets) {
- if(simpleName(name).toLowerCase(Locale.US).startsWith(prefix))
- result.add(widgetNameAsCompletion(name, slash));
+ for(Widget view : widgets) {
+ if(view.simpleName.toLowerCase(Locale.US).startsWith(prefix))
+ result.add(widgetNameAsCompletion(view, slash));
}
return handleResults(result);
} else {
- /**
- * TODO: Change to LSP
- */
- final String content = "";
final IsInValueScanner scanner = new IsInValueScanner(index);
final String name = scanner.scan(content);
if(name != null) {
@@ -110,24 +105,64 @@ public class XMLCompletionService {
CompletionItem item = new CompletionItem();
item.setLabel(attr.name);
item.setDetail("Attribute");
- item.setInsertText(attr.prefix + ":" + attr.name + "=\"" + (attr.prefix.equals("android") && attr.name.equals("id") ? "@+id/\"" : "\""));
+ item.setInsertText(createAttributeInsertText(attr));
item.setInsertTextFormat(InsertTextFormat.PlainText);
item.setSortText("1" + attr.name);
item.setKind(CompletionItemKind.Snippet);
return item;
}
- private CompletionItem widgetNameAsCompletion(String name, boolean slash) {
- final String n = simpleName(name);
+ private String createAttributeInsertText(Attr attr) {
+ StringBuilder xml = new StringBuilder();
+ xml.append(attr.prefix);
+ xml.append(":");
+ xml.append(attr.name);
+ xml.append("=");
+ xml.append("\"");
+
+ if(attr.prefix.equals("android")
+ && attr.name.equals("id")) {
+ xml.append("@+id/");
+ }
+
+ xml.append("$0");
+ xml.append("\"");
+
+ return xml.toString();
+ }
+
+ private CompletionItem widgetNameAsCompletion(Widget view, boolean slash) {
CompletionItem item = new CompletionItem();
- item.setLabel(n);
- item.setDetail(name);
- item.setInsertText("<" + (slash ? "/" : "") + n);
+ item.setLabel(view.simpleName);
+ item.setDetail(view.name);
+ item.setInsertText(createTagInsertText(view, slash));
item.setInsertTextFormat(InsertTextFormat.PlainText);
- item.setSortText("2" + n);
+ item.setSortText("2" + view.simpleName);
item.setKind(CompletionItemKind.Value);
return item;
}
+
+ private String createTagInsertText(Widget view, boolean closing) {
+ StringBuilder sb = new StringBuilder();
+
+ // Don't append leading '<' and trailing '>'
+ // They may have been already inserted by editor upon typing '<'
+
+ sb.append(view.simpleName);
+
+ if(!closing) {
+ if(view.isViewGroup) {
+ sb.append(">$0");
+ sb.append(view.simpleName);
+ } else {
+ sb.append("$0/");
+ }
+ } else {
+ sb.append(">$0");
+ }
+
+ return sb.toString();
+ }
private String simpleName(String name) {
return name.substring(name.lastIndexOf(".") + 1);
@@ -142,9 +177,19 @@ public class XMLCompletionService {
if(read != null && read.length() > 0) {
widgets.clear();
for(String line : read.split("\\n")) {
- String name = line.split("\\s")[0];
- name = name.substring(1);
- widgets.add(name);
+ final String name = line.split("\\s")[0];
+ if(name == null || name.trim().isEmpty()) continue;
+
+ final char code = name.charAt(0);
+
+ final String viewName = name.substring(1);
+ final String simpleViewName = simpleName(viewName);
+ final boolean isViewGroup = code == 'L'; // L -> Layout, W -> Widget, P -> LayoutParam
+
+ // Don't add layout params
+ if(code != 'P') {
+ widgets.add(new Widget(viewName, simpleViewName, isViewGroup));
+ }
}
Collections.sort(widgets);
}
@@ -199,9 +244,9 @@ public class XMLCompletionService {
return start <= cursorIndex && cursorIndex <= end;
}
- public String scan(String xmlContent) {
+ public String scan(CharSequence xmlContent) {
try {
- XMLLexer lexer = new XMLLexer(CharStreams.fromReader(new StringReader(xmlContent)));
+ XMLLexer lexer = new XMLLexer(CharStreams.fromReader(new StringReader(xmlContent.toString())));
Token token;
String attrName = null;
while((token = lexer.nextToken()) != null && token.getType() != XMLLexer.EOF) {
@@ -219,7 +264,7 @@ public class XMLCompletionService {
}
- private class Attr {
+ class Attr {
public String prefix;
public String name;
@@ -240,4 +285,25 @@ public class XMLCompletionService {
return String.format("[%s=%s]", name, possibleValues.toString());
}
}
+
+ class Widget implements Comparable {
+ String name;
+ String simpleName;
+ boolean isViewGroup;
+
+ public Widget(String name, String simpleName, boolean isViewGroup) {
+ this.name = name;
+ this.simpleName = simpleName;
+ this.isViewGroup = isViewGroup;
+ }
+
+ @Override
+ public int compareTo(Object p1) {
+ if(p1 instanceof Widget) {
+ final Widget that = (Widget) p1;
+ return this.simpleName.compareTo(that.simpleName);
+ }
+ return -1;
+ }
+ }
}
diff --git a/app/src/main/java/com/itsaky/androidide/lsp/LSP.java b/app/src/main/java/com/itsaky/androidide/lsp/LSP.java
index a047b1914..06d8aa6cc 100644
--- a/app/src/main/java/com/itsaky/androidide/lsp/LSP.java
+++ b/app/src/main/java/com/itsaky/androidide/lsp/LSP.java
@@ -2,8 +2,6 @@ package com.itsaky.androidide.lsp;
import com.itsaky.androidide.interfaces.EditorActivityProvider;
import com.itsaky.androidide.lsp.handlers.JLSHandler;
-import com.itsaky.androidide.lsp.handlers.LSPHandler;
-import com.itsaky.androidide.lsp.handlers.XMLLanguageServerHandler;
import com.itsaky.androidide.utils.Logger;
import com.itsaky.lsp.services.IDELanguageServer;
import java.io.File;
@@ -40,13 +38,7 @@ public class LSP {
public static EditorActivityProvider PROVIDER;
private static final Logger LOG = Logger.instance("LSP");
- public static LSPHandler Java = new JLSHandler();
- public static LSPHandler XML = new XMLLanguageServerHandler();
-
- public static void startAll(Runnable onStarted) {
- LSP.Java.start(onStarted);
- LSP.XML.start(onStarted);
- }
+ public static JLSHandler Java = new JLSHandler();
/**
* Stores information about ports at which the specified language server must be started
@@ -142,7 +134,6 @@ public class LSP {
public static void shutdownAll() {
// Shutdown language servers one by one
LSP.Java.shutdown();
- LSP.XML.shutdown();
}
/**
diff --git a/app/src/main/java/com/itsaky/androidide/lsp/client/xml/XMLLanguageClient.java b/app/src/main/java/com/itsaky/androidide/lsp/client/xml/XMLLanguageClient.java
deleted file mode 100644
index 9b927d3fa..000000000
--- a/app/src/main/java/com/itsaky/androidide/lsp/client/xml/XMLLanguageClient.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.itsaky.androidide.lsp.client.xml;
-
-import com.itsaky.androidide.lsp.AbstractLanguageClient;
-import com.itsaky.androidide.utils.JSONUtility;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-import org.eclipse.lemminx.customservice.ActionableNotification;
-import org.eclipse.lemminx.customservice.XMLLanguageClientAPI;
-import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
-import org.eclipse.lsp4j.ApplyWorkspaceEditResponse;
-import org.eclipse.lsp4j.ConfigurationParams;
-import org.eclipse.lsp4j.ExecuteCommandParams;
-import org.eclipse.lsp4j.MessageActionItem;
-import org.eclipse.lsp4j.MessageParams;
-import org.eclipse.lsp4j.ProgressParams;
-import org.eclipse.lsp4j.RegistrationParams;
-import org.eclipse.lsp4j.SetTraceParams;
-import org.eclipse.lsp4j.ShowMessageRequestParams;
-import org.eclipse.lsp4j.UnregistrationParams;
-import org.eclipse.lsp4j.WorkDoneProgressCreateParams;
-import org.eclipse.lsp4j.WorkspaceFolder;
-
-public class XMLLanguageClient extends AbstractLanguageClient implements XMLLanguageClientAPI {
-
- public XMLLanguageClient(StarterListener starterListener, OnConnectedListener onConnectedListener) {
- super(starterListener, onConnectedListener);
- }
-
- @Override
- public void actionableNotification(ActionableNotification p1) {
- LOG.info("XMLLS: actionableNotification: " + JSONUtility.prettyPrinter.toJson(p1));
- }
-
- @Override
- public CompletableFuture
- *
- *
- * will return null.
- *
- *
- * @param offset the offset
- * @return the parameter (start/end offset) at the given offset and null
- * otherwise.
- */
- public DTDDeclParameter getParameterAt(int offset) {
- // Check if offset is in the collector) {
- DTDDeclParameter name = getNameParameter();
- if (name == null) {
- return;
- }
- int start = name.getEnd();
- int end = getEnd();
-
- String text = getOwnerDocument().getText();
- int wordStart = -1;
- int wordEnd = -1;
- // Loop for content after text which starts at
- * wordStart offset and ends at wordEnd matches the
- * given searchWord
- *
- * @param searchWord the word to search
- * @param text the text
- * @param wordStart the word start offset
- * @param wordEnd the word end offset
- * @return true if the word in the given text which starts at
- * wordStart offset and ends at wordEnd
- * matches the given searchName
- */
- private static boolean isMatchName(String searchWord, String text, int wordStart, int wordEnd) {
- int length = wordEnd - wordStart;
- if (searchWord.length() != length) {
- return false;
- }
- for (int j = 0; j < length; j++) {
- if ((searchWord.charAt(j) != text.charAt(wordStart + j))) {
- return false;
- }
- }
- return true;
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/DTDEntityDecl.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/DTDEntityDecl.java
deleted file mode 100644
index 6541cc44b..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/DTDEntityDecl.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.dom;
-
-import org.w3c.dom.Entity;
-import org.w3c.dom.Node;
-
-/**
- * DOM Entity declaration
- *
- * or
- *
- *
- *
- * or
- *
- *
- *
- * or
- *
- *
- *
- * or
- *
- *
- *
- * or
- *
- *
- */
- DTDDeclParameter percent;
- DTDDeclParameter value;
- DTDDeclParameter kind;
- DTDDeclParameter publicId;
- DTDDeclParameter systemId;
-
- public DTDEntityDecl(int start, int end) {
- super(start, end);
- setDeclType(start + 2, start + 8);
- }
-
- public String getPercent() {
- return percent != null ? percent.getParameter() : null;
- }
-
- public void setPercent(int start, int end) {
- percent = addNewParameter(start, end);
- }
-
- public String getValue() {
- return value != null ? value.getParameterWithoutFirstAndLastChar() : null;
- }
-
- public void setValue(int start, int end) {
- value = addNewParameter(start, end);
- }
-
- public String getKind() {
- return kind != null ? kind.getParameter() : null;
- }
-
- public void setKind(int start, int end) {
- kind = addNewParameter(start, end);
- }
-
- @Override
- public short getNodeType() {
- return Node.ENTITY_NODE;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.w3c.dom.Entity#getInputEncoding()
- */
- @Override
- public String getInputEncoding() {
- throw new UnsupportedOperationException();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.w3c.dom.Entity#getNotationName()
- */
- @Override
- public String getNotationName() {
- return getValue();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.w3c.dom.Entity#getPublicId()
- */
- @Override
- public String getPublicId() {
- return publicId != null ? publicId.getParameterWithoutFirstAndLastChar() : null;
- }
-
- public void setPublicId(int start, int end) {
- publicId = addNewParameter(start, end);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.w3c.dom.Entity#getSystemId()
- */
- @Override
- public String getSystemId() {
- return systemId != null ? systemId.getParameterWithoutFirstAndLastChar() : null;
- }
-
- public void setSystemId(int start, int end) {
- systemId = addNewParameter(start, end);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.w3c.dom.Entity#getXmlEncoding()
- */
- @Override
- public String getXmlEncoding() {
- throw new UnsupportedOperationException();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.w3c.dom.Entity#getXmlVersion()
- */
- @Override
- public String getXmlVersion() {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/DTDNotationDecl.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/DTDNotationDecl.java
deleted file mode 100644
index 36131e152..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/DTDNotationDecl.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2018 Red Hat Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * 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.dom;
-
-/**
- * DTDNotationDecl
- */
-public class DTDNotationDecl extends DTDDeclNode {
-
- /**
- * Format:
- *
- *
- *
- * or
- *
- *
- *
- * or
- *
- *
- */
-
- DTDDeclParameter kind;
- DTDDeclParameter publicId;
- DTDDeclParameter systemId;
-
- public DTDNotationDecl(int start, int end) {
- super(start, end);
- setDeclType(start + 2, start + 10);
- }
-
- void setKind(int start, int end) {
- kind = addNewParameter(start, end);
- }
-
- public String getKind() {
- return kind != null ? kind.getParameter() : null;
- }
-
- void setPublicId(int start, int end) {
- publicId = addNewParameter(start, end);
- }
-
- public String getPublicId() {
- return publicId != null ? publicId.getParameterWithoutFirstAndLastChar() : null;
- }
-
- void setSystemId(int start, int end) {
- systemId = addNewParameter(start, end);
- }
-
- public String getSystemId() {
- return systemId != null ? systemId.getParameterWithoutFirstAndLastChar() : null;
- }
-
- @Override
- public short getNodeType() {
- return DOMNode.DTD_NOTATION_DECL;
- }
-}
\ No newline at end of file
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/LineIndentInfo.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/LineIndentInfo.java
deleted file mode 100644
index 4e52b9488..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/LineIndentInfo.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2018 Red Hat Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr. - initial API and implementation
- *
- *******************************************************************************/
-package org.eclipse.lemminx.dom;
-
-public class LineIndentInfo {
-
- private final String lineDelimiter;
- private final String whitespacesIndent;
-
- public LineIndentInfo(String lineDelimiter, String whitespacesIndent) {
- this.lineDelimiter = lineDelimiter;
- this.whitespacesIndent = whitespacesIndent;
- }
-
- public String getLineDelimiter() {
- return lineDelimiter;
- }
-
- public String getWhitespacesIndent() {
- return whitespacesIndent;
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/NoNamespaceSchemaLocation.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/NoNamespaceSchemaLocation.java
deleted file mode 100644
index ee89b0d7d..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/NoNamespaceSchemaLocation.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.dom;
-
-/**
- *
- * The declared "xsi:noNamespaceSchemaLocation"
- */
-public class NoNamespaceSchemaLocation {
-
- private final DOMAttr attr;
-
- public NoNamespaceSchemaLocation(DOMAttr attr) {
- this.attr = attr;
- }
-
- public DOMAttr getAttr() {
- return attr;
- }
-
- /**
- * Returns the location declared in the attribute value of
- * "xsi:noNamespaceSchemaLocation"
- *
- * @return the location declared in the attribute value of
- * "xsi:noNamespaceSchemaLocation"
- */
- public String getLocation() {
- return attr.getValue();
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/SchemaLocation.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/SchemaLocation.java
deleted file mode 100644
index d34342f02..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/SchemaLocation.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.dom;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- *
- * The declared "xsi:schemaLocation"
- */
-public class SchemaLocation {
-
- private final Map schemaLocationValuePairs;
-
- private final DOMAttr attr;
-
- // The text to match is of the form:
- // http://example.org/schema/root root.xsd http://example.org/schema/bison bison.xsd http://example.org/schema/potato potato.xsd
- private static final Pattern SCHEMA_LOCATION_PAIR_PATTERN = Pattern.compile("\\s*([^\\s]+)\\s+([^\\s]+)\\s*");
-
- public SchemaLocation(DOMAttr attr) {
- this.attr = attr;
- this.schemaLocationValuePairs = new HashMap<>();
- String value = attr.getValue();
- Matcher locPairMatcher = SCHEMA_LOCATION_PAIR_PATTERN.matcher(value);
- while (locPairMatcher.find()) {
- String namespaceURI = locPairMatcher.group(1);
- String locationHint = locPairMatcher.group(2);
- if (namespaceURI == null || locationHint == null) {
- break;
- }
- DOMNode valNode = attr.getNodeAttrValue();
- // http://example.org/schema/root |root.xsd http://example.org/schema/bison bison.xsd
- int start = valNode.getStart() + locPairMatcher.start(2) + 1;
- // http://example.org/schema/root root.xsd| http://example.org/schema/bison bison.xsd
- int end = valNode.getStart() + locPairMatcher.end(2) + 1;
- schemaLocationValuePairs.put(namespaceURI,
- new SchemaLocationHint(start, end, locationHint, this));
- }
- }
-
- /**
- * Returns the location hint, as a string, that is associated with the given namespace URI.
- *
- * If the given namespace URI was not referred to in this xsi:schemaLocation, then null is returned.
- *
- * @param namespaceURI The namespace URI to find the location hint for
- * @return The associated location hint, as a string, or null
- * if the namespace was not referred to in xsi:schemaLocation
- */
- public SchemaLocationHint getLocationHint(String namespaceURI) {
- return schemaLocationValuePairs.get(namespaceURI);
- }
-
- public DOMAttr getAttr() {
- return attr;
- }
-
- /**
- * Returns all the location hints given in this xsi:schemaLocation attribute
- *
- * @return A Collection of all the location hints as SchemaLocationHint
- */
- public Collection getSchemaLocationHints() {
- return schemaLocationValuePairs.values();
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/SchemaLocationHint.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/SchemaLocationHint.java
deleted file mode 100644
index 497a14a41..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/SchemaLocationHint.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * Copyright (c) 2020 Red Hat Inc.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * 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.dom;
-
-/**
- * Represents one of the location hints provided in an xsi:schemaLocation
- * attribute.
- */
-public class SchemaLocationHint implements DOMRange {
-
- private final int start, end;
-
- private final String hint;
-
- private final SchemaLocation parent;
-
- /**
- * Create a new SchemaLocationHint object that represents one of the location
- * hints given in the parent SchemaLocation.
- *
- * @param start The offset from the beginning of the document where this
- * location hint starts
- * @param end The offset from the beginning of the document where this
- * location hint ends
- * @param hint The hint to the location of a schema (A URI that points to a
- * schema)
- * @param parent The SchemaLocation in which this hint was given
- */
- public SchemaLocationHint(int start, int end, String hint, SchemaLocation parent) {
- this.start = start;
- this.end = end;
- this.hint = hint;
- this.parent = parent;
- }
-
- /**
- * Returns the location hint that this SchemaLocationHint represents
- *
- * @return The location hint, a URI to a schema, as a String
- */
- public String getHint() {
- return this.hint;
- }
-
- /**
- * Returns the offset from the beginning of the document where this location
- * hint starts
- *
- * @return The offset from the beginning of the document where this location
- * hint starts
- */
- @Override
- public int getStart() {
- return this.start;
- }
-
- /**
- * Returns the offset from the beginning of the document where this location
- * hint ends
- *
- * @return The offset from the beginning of the document where this location
- * hint ends
- */
- @Override
- public int getEnd() {
- return this.end;
- }
-
- @Override
- public DOMDocument getOwnerDocument() {
- return parent.getAttr().getOwnerDocument();
- }
-
-}
\ No newline at end of file
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/TargetRange.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/TargetRange.java
deleted file mode 100644
index df0532012..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/TargetRange.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Copyright (c) 2020 Red Hat, Inc. and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * 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.dom;
-
-import org.eclipse.lsp4j.Range;
-
-/**
- * Target range API.
- *
- */
-public interface TargetRange {
-
- /**
- * Returns the target range.
- *
- * @return the target range.
- */
- Range getTargetRange();
-
- /**
- * Returns the target URI.
- *
- * @return the target URI.
- */
- String getTargetURI();
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/XMLModel.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/XMLModel.java
deleted file mode 100644
index 6f19125ff..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/XMLModel.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*******************************************************************************
-* 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.dom;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.eclipse.lemminx.extensions.xerces.xmlmodel.XMLModelDeclaration;
-import org.w3c.dom.ProcessingInstruction;
-
-/**
- * XML model processing instruction.
- *
- *
- *
- *
- * @see https://www.w3.org/TR/xml-model/
- */
-public class XMLModel {
-
- private static final String XML_MODEL_PI = "xml-model";
-
- private final DOMProcessingInstruction processingInstruction;
- private XMLModelDeclaration declaration;
-
- private DOMRange hrefNode;
-
- private static class SimpleDOMRange implements DOMRange {
-
- private final int start;
-
- private final int end;
-
- private final DOMDocument ownerDocument;
-
- public SimpleDOMRange(int start, int end, DOMDocument ownerDocument) {
- this.start = start;
- this.end = end;
- this.ownerDocument = ownerDocument;
- }
-
- @Override
- public int getStart() {
- return start;
- }
-
- @Override
- public int getEnd() {
- return end;
- }
-
- @Override
- public DOMDocument getOwnerDocument() {
- return ownerDocument;
- }
-
- }
-
- public XMLModel(DOMProcessingInstruction processingInstruction) {
- this.processingInstruction = processingInstruction;
- }
-
- /**
- * Returns the location of the referenced schema
- *
- * @return the location of the referenced schema
- */
- public String getHref() {
- XMLModelDeclaration declaration = getModelDeclaration();
- return declaration != null ? declaration.getHref() : null;
- }
-
- private XMLModelDeclaration getModelDeclaration() {
- String data = processingInstruction.getData();
- if (data == null) {
- return null;
- }
- if (declaration == null) {
- declaration = XMLModelDeclaration.parse(data.toCharArray(), 0, data.length());
- }
- return declaration;
- }
-
- /**
- * Returns the declared xml-model list.
- *
- * @param document the DOM document.
- *
- * @return the declared xml-model list.
- */
- static List createXMLModels(DOMDocument document) {
- List children = document.getChildren();
- if (children != null && !children.isEmpty()) {
- return children.stream().filter(XMLModel::isXMLModel)
- .map(node -> new XMLModel((DOMProcessingInstruction) node)).collect(Collectors.toList());
- }
- return Collections.emptyList();
- }
-
- /**
- * Returns true if the given node is a xml-model processing instruction and
- * false otherwise.
- *
- * @param node the DOM node.
- * @return true if the given node is a xml-model processing instruction and
- * false otherwise.
- */
- public static boolean isXMLModel(DOMNode node) {
- return node.isProcessingInstruction() && XML_MODEL_PI.equals(((ProcessingInstruction) node).getTarget());
- }
-
- /**
- * Returns the href range and null otherwise.
- *
- * @return the href range and null otherwise.
- */
- public DOMRange getHrefNode() {
- if (hrefNode == null) {
- XMLModelDeclaration declaration = getModelDeclaration();
- if (declaration == null || declaration.getHref() == null) {
- return null;
- }
- int start = processingInstruction.getStartContent() + declaration.getHrefOffset() - 1;
- int end = start + declaration.getHref().length() + 2;
- hrefNode = new SimpleDOMRange(start, end, processingInstruction.getOwnerDocument());
- }
- return hrefNode;
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/Constants.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/Constants.java
deleted file mode 100644
index f09d14601..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/Constants.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Initial code from https://github.com/Microsoft/vscode-html-languageservice
- * Initial copyright Copyright (C) Microsoft Corporation. All rights reserved.
- * Initial license: MIT
- *
- * Contributors:
- * - Microsoft Corporation: Initial code, written in TypeScript, licensed under MIT license
- * - Angelo Zerr - translation and adaptation to Java
- */
-package org.eclipse.lemminx.dom.parser;
-
-import java.util.regex.Pattern;
-
-public class Constants {
-
- public final static int _EXL = "!".codePointAt(0);
- public final static int _MIN = "-".codePointAt(0);
- public final static int _UDS = "_".codePointAt(0);
- public final static int _DDT = ":".codePointAt(0);
- public final static int _DOT = ".".codePointAt(0);
- public final static int _LAN = "<".codePointAt(0);
- public final static int _RAN = ">".codePointAt(0);
- public final static int _FSL = "/".codePointAt(0);
- public final static int _EQS = "=".codePointAt(0);
- public final static int _CMA = ",".codePointAt(0);
- public final static int _DQO = "\"".codePointAt(0);
- public final static int _SQO = "\"".codePointAt(0);
- public final static int _SIQ = "\'".codePointAt(0);
- public final static int _NWL = "\n".codePointAt(0);
- public final static int _CAR = "\r".codePointAt(0);
- public final static int _LFD = "\f".codePointAt(0);
- public final static int _WSP = " ".codePointAt(0);
- public final static int _TAB = "\t".codePointAt(0);
- public final static int _OSB = "[".codePointAt(0);
- public final static int _CSB = "]".codePointAt(0);
- public final static int _ORB = "(".codePointAt(0);
- public final static int _CRB = ")".codePointAt(0);
- public final static int _OCB = "{".codePointAt(0);
- public final static int _CCB = "}".codePointAt(0);
- public final static int _CVL = "C".codePointAt(0);
- public final static int _DVL = "D".codePointAt(0);
- public final static int _AVL = "A".codePointAt(0);
- public final static int _TVL = "T".codePointAt(0);
- public final static int _OVL = "O".codePointAt(0);
- public final static int _YVL = "Y".codePointAt(0);
- public final static int _PVL = "P".codePointAt(0);
- public final static int _EVL = "E".codePointAt(0);
- public final static int _LVL = "L".codePointAt(0);
- public final static int _MVL = "M".codePointAt(0);
- public final static int _NVL = "N".codePointAt(0);
- public final static int _IVL = "I".codePointAt(0);
- public final static int _SVL = "S".codePointAt(0);
- public final static int _QMA = "?".codePointAt(0);
- public final static int _XVL = "x".codePointAt(0);
- public final static int _mVL = "m".codePointAt(0);
- public final static int _lVL = "l".codePointAt(0);
- public final static int _PCT = "%".codePointAt(0);
- public final static int _AST = "*".codePointAt(0);
- public final static int _PLS = "+".codePointAt(0);
-
- public static final Pattern ENTITY_NAME_REGEX = Pattern.compile("");
-
- public static final Pattern ELEMENT_NAME_REGEX = Pattern.compile("^[_:\\w][_:\\w-.\\d]*");
-
- public static final Pattern ATTRIBUTE_NAME_REGEX = Pattern.compile("^[^\\s\\?\"'<>/=\\x00-\\x0F\\x7F\\x80-\\x9F]*");
-
- public static final Pattern ATTRIBUTE_VALUE_REGEX = Pattern.compile("^(\"[^\"]*\"?)|(\'[^\']*\'?)");
-
- public static final Pattern URL_VALUE_REGEX = Pattern.compile("^(\"[^<>\"]*\")|(\'[^<>\']*\')");
-
- public static final Pattern PROLOG_NAME_OPTIONS = Pattern.compile("^(xml)[\\s<>?]?");
-
- public static final Pattern PI_TAG_NAME = Pattern.compile("^[a-zA-Z0-9]+");
-
- // Add coming processing instructions that are defined to have attributes as
- // content
- public static final Pattern PI_WITH_VARIABLES = Pattern.compile("^(xml-stylesheet)[\\s<>?]?");
-
- public static final Pattern DOCTYPE_KIND_OPTIONS = Pattern.compile("^(PUBLIC|SYSTEM)([\\s<>\"'])");
-
- public static final Pattern DTD_ELEMENT_CATEGORY = Pattern.compile("^(EMPTY|ANY)([\\s<>\"'])");
-
- public static final Pattern DTD_ELEMENT_CONTENT = Pattern.compile("^(\\((([^\\s,]+,)*[^\\s,]+)\\))|\\(\\)");
-
- public static final Pattern DTD_PCDATA = Pattern.compile("^#PCDATA");
-
- public static final Pattern DTD_ATTLIST_ATTRIBUTE_TYPE = Pattern
- .compile("^(CDATA|IDREFS|IDREF|ID|NMTOKENS|NMTOKEN|ENTITIES|ENTITY|NOTATION|xml:|\\(.*\\))([\\s<>\"'])");
-
- public static final Pattern DTD_ATTLIST_ATTRIBUTE_VALUE = Pattern
- .compile("^(#REQUIRED|#IMPLIED|\".*\"|#FIXED \".*\")([\\s<>\"'])");
-
- public static final Pattern DTD_ENTITY_VALUE = Pattern.compile("^\".*\"");
-
- public static final Pattern DOCTYPE_NAME = Pattern.compile("^[_:\\w][_:\\w-.\\d]*");
-
- public static final Pattern DOCUMENTATION_CONTENT = Pattern.compile(".*<[\\S]+:?documentation[^\\>]*>(.*)<\\/[\\S]+:?documentation[\\s]*>.*");
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/MultiLineStream.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/MultiLineStream.java
deleted file mode 100644
index b6f9a4a13..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/MultiLineStream.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Initial code from https://github.com/Microsoft/vscode-html-languageservice
- * Initial copyright Copyright (C) Microsoft Corporation. All rights reserved.
- * Initial license: MIT
- *
- * Contributors:
- * - Microsoft Corporation: Initial code, written in TypeScript, licensed under MIT license
- * - Angelo Zerr - translation and adaptation to Java
- */
-package org.eclipse.lemminx.dom.parser;
-
-import static org.eclipse.lemminx.dom.parser.Constants._CAR;
-import static org.eclipse.lemminx.dom.parser.Constants._CSB;
-import static org.eclipse.lemminx.dom.parser.Constants._LAN;
-import static org.eclipse.lemminx.dom.parser.Constants._LFD;
-import static org.eclipse.lemminx.dom.parser.Constants._NWL;
-import static org.eclipse.lemminx.dom.parser.Constants._OSB;
-import static org.eclipse.lemminx.dom.parser.Constants._RAN;
-import static org.eclipse.lemminx.dom.parser.Constants._TAB;
-import static org.eclipse.lemminx.dom.parser.Constants._WSP;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Predicate;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Multi line stream.
- *
- */
-public class MultiLineStream {
-
- private static final Predicate WHITESPACE_PREDICATE = ch -> {
- return ch == _WSP || ch == _TAB || ch == _NWL || ch == _LFD || ch == _CAR;
- };
-
- private final String source;
- private final int len;
- private int position;
- private final Map regexpCache;
-
- public MultiLineStream(String source, int position) {
- this.source = source;
- this.len = source.length();
- this.position = position;
- this.regexpCache = new HashMap<>();
- }
-
- public boolean eos() {
- return this.len <= this.position;
- }
-
- public String getSource() {
- return this.source;
- }
-
- public int pos() {
- return this.position;
- }
-
- public void goBackTo(int pos) {
- this.position = pos;
- }
-
- public void goBack(int n) {
- this.position -= n;
- }
-
- public void advance(int n) {
- this.position += n;
- }
-
- public void goToEnd() {
- this.position = len;
- }
-
- /*
- * public int nextChar() { // return this.source.codePointAt(this.position++) ||
- * 0; int next = this.source.codePointAt(this.position++); return next >= 0 ?
- * next : 0; }
- */
-
- public int peekChar() {
- return peekChar(0);
- }
-
- /**
- * Peeks at next char at position + n. peekChar() == peekChar(0)
- * @param n
- * @return
- */
- public int peekChar(int n) {
- int pos = this.position + n;
- if (pos >= len) {
- return -1;
- }
- return this.source.codePointAt(pos);
- }
-
- /**
- * Peeks at the char at position 'offset' of the whole document
- * @param offset
- * @return
- */
- public int peekCharAtOffset(int offset) {
- if (offset >= len || offset < 0) {
- return -1;
- }
- return this.source.codePointAt(offset);
- }
-
- public boolean advanceIfChar(int ch) {
- if (ch == peekChar()) {
- this.position++;
- return true;
- }
- return false;
- }
-
- public boolean advanceIfChars(int... ch) {
- int i;
- if (this.position + ch.length > this.len) {
- return false;
- }
- for (i = 0; i < ch.length; i++) {
- if (peekChar(i) != ch[i]) {
- return false;
- }
- }
- this.advance(i);
- return true;
- }
-
- public int advanceIfAnyOfChars(int... ch) {
- int i;
- if (this.position + 1 > this.len) {
- return -1;
- }
- for (i = 0; i < ch.length; i++) {
- if (advanceIfChar(ch[i])) {
- return ch[i];
- }
- }
- return -1;
- }
-
- public String advanceIfRegExp(Pattern regex) {
- Matcher match = getCachedMatcher(regex);
- // Initialize start region where search must be started.
- match.region(this.position, this.len);
- if (match.find()) {
- this.position = match.end();
- return match.group(0);
- }
- return "";
- }
-
- /**
- * Advances stream on regex, but will grab the first group
- * @param regex
- * @return
- */
- public String advanceIfRegExpGroup1(Pattern regex) {
- Matcher match = getCachedMatcher(regex);
- // Initialize start region where search must be started.
- match.region(this.position, this.len);
- if (match.find()) {
- this.position = match.end(1);
- return match.group(1);
- }
- return "";
- }
-
- /**
- * Advances stream.position no matter what until it hits ch or eof(this.len)
- *
- * @return boolean: was the char found
- */
- public boolean advanceUntilChar(int ch) {
- while (this.position < this.len) {
- if (peekChar() == ch) {
- return true;
- }
- this.advance(1);
- }
- return false;
- }
-
- /**
- * Will advance until any of the provided chars are encountered
- */
- public boolean advanceUntilAnyOfChars(int... ch) {
- while (this.position < this.len) {
- for (int i = 0; i < ch.length; i++) {
- if (peekChar() == ch[i]) {
- return true;
- }
- }
-
- this.advance(1);
- }
- return false;
- }
-
- /**
- * Will advance the stream position until ch or '<'
- */
- public boolean advanceUntilCharOrNewTag(int ch) {
- while (this.position < this.len) {
- if (peekChar() == ch || peekChar() == _LAN) {
- return true;
- }
- this.advance(1);
- }
- return false;
- }
-
- /**
- * Will advance the stream position until 'closingBracket' or using a stack
- * to consider possible open/closed bracket pairs in between.
- *
- * 'closingBracket' should be the closing bracket eg: > | ]
- */
- public boolean advanceUntilCharUsingStack(int closingBracket) {
-
- int openingBracket;
- if(closingBracket == _RAN) { // >
- openingBracket = _LAN;// <
- }
- else if(closingBracket == _CSB) { // ]
- openingBracket = _OSB; // [
- }
- else {
- return false; // The provided closingBracket is not implemented
- }
- int stack = 0;
- while (this.position < this.len) {
- if(peekChar() == openingBracket) {
- stack ++;
- }
- else if(peekChar() == closingBracket) {
- if(stack == 0) {
- return true;
- }
- stack--;
- }
- this.advance(1);
- }
- return false;
- }
-
- public boolean advanceUntilChars(int... ch) {
- while (this.position + ch.length <= this.len) {
- int i = 0;
- for (; i < ch.length && peekChar(i) == ch[i]; i++) {
- }
- if (i == ch.length) {
- return true;
- }
- this.advance(1);
- }
- this.goToEnd();
- return false;
- }
-
- /**
- * Advances until it matches int[] ch OR it hits '<' If this returns true, peek
- * if next char is '<' to check which case was hit
- */
- public boolean advanceUntilCharsOrNewTag(int... ch) {
- while (this.position + ch.length <= this.len) {
- int i = 0;
- if (peekChar(0) == _LAN) { // <
- return true;
- }
- for (; i < ch.length && peekChar(i) == ch[i]; i++) {
- }
- if (i == ch.length) {
- return true;
- }
- this.advance(1);
- }
- this.goToEnd();
- return false;
- }
-
- /**
- * Advances until it reaches a whitespace character
- */
- public boolean skipWhitespace() {
- int n = this.advanceWhileChar(WHITESPACE_PREDICATE);
- return n > 0;
- }
-
- public int advanceWhileChar(Predicate condition) {
- int posNow = this.position;
- while (this.position < this.len && condition.test(peekChar())) {
- this.position++;
- }
- return this.position - posNow;
- }
-
- /**
- * Returns the cached matcher from the given regex.
- *
- * @param regex the regex pattern.
- * @return the cached matcher from the given regex.
- */
- private Matcher getCachedMatcher(Pattern regex) {
- Matcher matcher = regexpCache.get(regex);
- if (matcher == null) {
- matcher = regex.matcher(source);
- regexpCache.put(regex, matcher);
- } else {
- matcher.reset(); // Cached regex caused issues, needed to reset it.
- }
- return matcher;
- }
-
- public int getLastNonWhitespaceOffset() {
- int posNow = this.position;
- while (posNow > 0 && WHITESPACE_PREDICATE.test(peekCharAtOffset(posNow - 1))) {
- posNow--;
- }
- return posNow;
- }
-}
\ No newline at end of file
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/Scanner.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/Scanner.java
deleted file mode 100644
index 8513acfa0..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/Scanner.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Initial code from https://github.com/Microsoft/vscode-html-languageservice
- * Initial copyright Copyright (C) Microsoft Corporation. All rights reserved.
- * Initial license: MIT
- *
- * Contributors:
- * - Microsoft Corporation: Initial code, written in TypeScript, licensed under MIT license
- * - Angelo Zerr - translation and adaptation to Java
- */
-package org.eclipse.lemminx.dom.parser;
-
-/**
- * Scanner API.
- *
- */
-public interface Scanner {
-
- TokenType scan();
-
- TokenType getTokenType();
-
- /**
- * Starting offset position of the current token
- *
- * @return int of token's start offset
- */
- int getTokenOffset();
-
- int getTokenLength();
-
- /**
- * Ending offset position of the current token
- *
- * @return int of token's end offset
- */
- int getTokenEnd();
-
- String getTokenText();
-
- String getTokenError();
-
- ScannerState getScannerState();
-
- /**
- * @return True if the token's Text is empty or all whitespace
- */
- boolean isTokenTextBlank();
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/ScannerState.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/ScannerState.java
deleted file mode 100644
index d0a804978..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/ScannerState.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Initial code from https://github.com/Microsoft/vscode-html-languageservice
- * Initial copyright Copyright (C) Microsoft Corporation. All rights reserved.
- * Initial license: MIT
- *
- * Contributors:
- * - Microsoft Corporation: Initial code, written in TypeScript, licensed under MIT license
- * - Angelo Zerr - translation and adaptation to Java
- * - Nikolas Komonen - additions for CDATA and Processing Instruction
- */
-package org.eclipse.lemminx.dom.parser;
-
-/**
- * XML Scanner state.
- *
- */
-public enum ScannerState {
- WithinContent, AfterOpeningStartTag, AfterOpeningEndTag, WithinProlog, WithinTag, WithinEndTag,
- WithinComment, AfterAttributeName, BeforeAttributeValue, WithinCDATA, AfterClosingCDATATag, StartCDATATag,
- AfterPrologOpen, PrologOrPI, WithinPI,
-
- // DTD
- DTDWithinDoctype, DTDAfterDoctypeName, DTDAfterDoctypePUBLIC, DTDAfterDoctypeSYSTEM,
- DTDAfterDoctypePublicId,DTDWithinContent, DTDWithinElement, DTDWithinAttlist, DTDWithinEntity,
- DTDElementAfterName, DTDElementWithinContent, DTDAfterAttlistName, DTDAfterAttlistElementName,
- DTDAfterAttlistAttributeName, DTDAfterAttlistAttributeType, DTDAfterEntityName, DTDUnrecognizedParameters,
- DTDWithinNotation, DTDAfterNotationName, DTDAfterNotationPUBLIC, DTDAfterNotationSYSTEM,
- DTDAfterNotationPublicId, DTDAfterEntityPUBLIC, DTDAfterEntitySYSTEM, DoctypeUnrecognizedParameters;
-
-}
\ No newline at end of file
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/TokenType.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/TokenType.java
deleted file mode 100644
index 43ed6e3c3..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/TokenType.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Initial code from https://github.com/Microsoft/vscode-html-languageservice
- * Initial copyright Copyright (C) Microsoft Corporation. All rights reserved.
- * Initial license: MIT
- *
- * Contributors:
- * - Microsoft Corporation: Initial code, written in TypeScript, licensed under MIT license
- * - Angelo Zerr - translation and adaptation to Java
- */
-package org.eclipse.lemminx.dom.parser;
-
-/**
- * XML Token type.
- *
- */
-public enum TokenType {
-
- StartCommentTag,
- Comment,
- EndCommentTag,
- CDATATagOpen,
- CDATAContent,
- CDATATagClose,
- StartTagOpen,
- StartTagClose,
- StartTagSelfClose,
- StartTag,
- EndTagOpen,
- EndTagClose,
- EndTag,
- DelimiterAssign,
- AttributeName,
- AttributeValue,
- StartPrologOrPI,
- PrologName,
- PIName,
- PIContent,
- PIEnd,
- PrologEnd,
- Content,
- Whitespace,
- Unknown,
- EOS,
- // DTD
- DTDStartDoctypeTag,
- DTDDoctypeName,
- DTDDocTypeKindPUBLIC,
- DTDDocTypeKindSYSTEM,
- DTDDoctypePublicId,
- DTDDoctypeSystemId,
- DTDEndDoctypeTag,
- DTDStartInternalSubset,
- DTDEndInternalSubset,
- // DTD Element declaration
- DTDStartElement,
- DTDElementDeclName,
- DTDElementCategory,
- DTDStartElementContent,
- DTDElementContent,
- DTDEndElementContent,
-
- // DTD AttrList declaration
- DTDStartAttlist,
- DTDAttlistElementName,
- DTDAttlistAttributeValue,
- DTDAttlistAttributeType,
- DTDAttlistAttributeName,
-
- // DTD Entity
- DTDStartEntity,
- DTDEntityPercent,
- DTDEntityKindPUBLIC,
- DTDEntityKindSYSTEM,
- DTDEntityPublicId,
- DTDEntitySystemId,
- DTDEntityName,
- DTDEntityValue,
-
- // DTD Notation
- DTDStartNotation,
- DTDNotationName,
- DTDNotationKindPUBLIC,
- DTDNotationKindSYSTEM,
- DTDNotationPublicId,
- DTDNotationSystemId,
-
- //For any DTD Decl Tag that has an unrecognized parameter
- DTDUnrecognizedParameters,
-
- //End of any DTD Decl Tag
- DTDEndTag;
-
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/XMLScanner.java b/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/XMLScanner.java
deleted file mode 100644
index 2a305737b..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/dom/parser/XMLScanner.java
+++ /dev/null
@@ -1,1063 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Initial code from https://github.com/Microsoft/vscode-html-languageservice
- * Initial copyright Copyright (C) Microsoft Corporation. All rights reserved.
- * Initial license: MIT
- *
- * Contributors:
- * - Microsoft Corporation: Initial code, written in TypeScript, licensed under MIT license
- * - Angelo Zerr - translation and adaptation to Java
- */
-package org.eclipse.lemminx.dom.parser;
-
-import static org.eclipse.lemminx.dom.parser.Constants.ATTRIBUTE_NAME_REGEX;
-import static org.eclipse.lemminx.dom.parser.Constants.DOCTYPE_KIND_OPTIONS;
-import static org.eclipse.lemminx.dom.parser.Constants.DTD_ELEMENT_CATEGORY;
-import static org.eclipse.lemminx.dom.parser.Constants.ELEMENT_NAME_REGEX;
-import static org.eclipse.lemminx.dom.parser.Constants.PROLOG_NAME_OPTIONS;
-import static org.eclipse.lemminx.dom.parser.Constants.URL_VALUE_REGEX;
-import static org.eclipse.lemminx.dom.parser.Constants._AST;
-import static org.eclipse.lemminx.dom.parser.Constants._AVL;
-import static org.eclipse.lemminx.dom.parser.Constants._CAR;
-import static org.eclipse.lemminx.dom.parser.Constants._CRB;
-import static org.eclipse.lemminx.dom.parser.Constants._CSB;
-import static org.eclipse.lemminx.dom.parser.Constants._CVL;
-import static org.eclipse.lemminx.dom.parser.Constants._DDT;
-import static org.eclipse.lemminx.dom.parser.Constants._DOT;
-import static org.eclipse.lemminx.dom.parser.Constants._DQO;
-import static org.eclipse.lemminx.dom.parser.Constants._DVL;
-import static org.eclipse.lemminx.dom.parser.Constants._EQS;
-import static org.eclipse.lemminx.dom.parser.Constants._EVL;
-import static org.eclipse.lemminx.dom.parser.Constants._EXL;
-import static org.eclipse.lemminx.dom.parser.Constants._FSL;
-import static org.eclipse.lemminx.dom.parser.Constants._IVL;
-import static org.eclipse.lemminx.dom.parser.Constants._LAN;
-import static org.eclipse.lemminx.dom.parser.Constants._LVL;
-import static org.eclipse.lemminx.dom.parser.Constants._MIN;
-import static org.eclipse.lemminx.dom.parser.Constants._MVL;
-import static org.eclipse.lemminx.dom.parser.Constants._NVL;
-import static org.eclipse.lemminx.dom.parser.Constants._NWL;
-import static org.eclipse.lemminx.dom.parser.Constants._ORB;
-import static org.eclipse.lemminx.dom.parser.Constants._OSB;
-import static org.eclipse.lemminx.dom.parser.Constants._OVL;
-import static org.eclipse.lemminx.dom.parser.Constants._PCT;
-import static org.eclipse.lemminx.dom.parser.Constants._PLS;
-import static org.eclipse.lemminx.dom.parser.Constants._PVL;
-import static org.eclipse.lemminx.dom.parser.Constants._QMA;
-import static org.eclipse.lemminx.dom.parser.Constants._RAN;
-import static org.eclipse.lemminx.dom.parser.Constants._SIQ;
-import static org.eclipse.lemminx.dom.parser.Constants._SVL;
-import static org.eclipse.lemminx.dom.parser.Constants._TVL;
-import static org.eclipse.lemminx.dom.parser.Constants._UDS;
-import static org.eclipse.lemminx.dom.parser.Constants._WSP;
-import static org.eclipse.lemminx.dom.parser.Constants._YVL;
-
-import java.util.function.Predicate;
-
-import org.eclipse.lemminx.dom.DOMDocumentType.DocumentTypeKind;
-import org.eclipse.lemminx.utils.StringUtils;;
-
-/**
- * XML scanner implementation.
- *
- */
-public class XMLScanner implements Scanner {
-
- private static final Predicate START_ELEMENT_NAME_PREDICATE = ch -> {
- // ^[_:\w]
- return ch == _UDS || ch == _DDT || Character.isLetter(ch);
- };
-
- private static final Predicate ELEMENT_NAME_PREDICATE = ch -> {
- // [_:\w-.\d]*
- return ch == _UDS /* '_' */ || ch == _DDT /* ':' */ || ch == _DOT /* '.' */ || ch == _MIN /* '-' */
- || Character.isLetterOrDigit(ch);
- };
-
- private static final Predicate ATTRIBUTE_NAME_PREDICATE = ch -> {
- // ^[^\s\?\"'<>\/=\x00-\x0F\x7F\x80-\x9F]*
- return !Character.isWhitespace(ch) && ch != _QMA && ch != _DQO && ch != _SIQ && ch != _LAN && ch != _RAN
- && ch != _FSL && ch != _EQS && !(ch >= 0x00 && ch <= 0x0F) && ch != 0x7F && !(ch >= 0x80 && ch <= 0x9F);
- };
-
- MultiLineStream stream;
- ScannerState state;
- int tokenOffset;
- TokenType tokenType;
- String tokenError;
-
- String lastDoctypeKind;
- String url;
- boolean isInsideDTDContent = false; // Either internal dtd in xml file OR external dtd in dtd file
- boolean isDeclCompleted = false; // If any type of DTD declaration was supplied with all the required properties
- TokenType tempToken;
- boolean isDTDFile;
- /**
- * boolean completedInitialAttDef;
- *
- * If the first attribute definition was completed in an ATTLIST declaration
- * eg:
- *
- */
- boolean isInitialAttlistDeclCompleted = false;
- private int nbBraceOpened;
-
- public XMLScanner(String input, int initialOffset, ScannerState initialState, boolean isDTDFile) {
- stream = new MultiLineStream(input, initialOffset);
- state = initialState;
- tokenOffset = 0;
- isInsideDTDContent = ScannerState.DTDWithinContent.equals(initialState);
- tokenType = TokenType.Unknown;
- this.isDTDFile = isDTDFile;
- }
-
- /**
- * Returns true if the current token is an element name and false otherwise.
- *
- * @return true if the current token is an element name and false otherwise.
- */
- boolean hasNextElementName() {
- // Element name regexp : ^[_:\w][_:\w-.\d]*
- // ^[_:\w]
- if (!START_ELEMENT_NAME_PREDICATE.test(stream.peekChar())) {
- return false;
- }
- stream.advance(1);
- // [_:\w-.\d]*
- stream.advanceWhileChar(ELEMENT_NAME_PREDICATE);
- return true;
- }
-
- /**
- * Returns true if the current token is an attribute name and false otherwise.
- *
- * @return true if the current token is an attribute name and false otherwise.
- */
- boolean hasNextAttributeName() {
- // ^[^\s\?\"'<>\/=\x00-\x0F\x7F\x80-\x9F]*
- return stream.advanceWhileChar(ATTRIBUTE_NAME_PREDICATE) > 0;
- }
-
- /**
- * Returns true if the current token is an attribute value and false otherwise.
- *
- * @return true if the current token is an attribute value and false otherwise.
- */
- boolean hasNextAttributeValue() {
- // ^("[^"]*"?)|('[^']*'?)
- int first = stream.peekChar();
- if (first == _SIQ || first == _DQO) {
- stream.advance(1);
- if( stream.advanceUntilChar(first)) {
- stream.advance(1);
- }
- return true;
- }
- return false;
- }
-
- String doctypeName() {
- return stream.advanceIfRegExp(ELEMENT_NAME_REGEX);
- }
-
- /**
- * Tries to advance off the regex for either 'PUBLIC' or 'SYSTEM'
- *
- * @return "PUBLIC" or "SYSTEM" or "" otherwise
- */
- String doctypeKind() {
- return stream.advanceIfRegExpGroup1(DOCTYPE_KIND_OPTIONS);
- }
-
- TokenType finishToken(int offset, TokenType type) {
- return finishToken(offset, type, null);
- }
-
- TokenType finishToken(int offset, TokenType type, String errorMessage) {
- tokenType = type;
- tokenOffset = offset;
- tokenError = errorMessage;
- return type;
- }
-
- @Override
- public TokenType scan() {
- int offset = stream.pos();
- ScannerState oldState = state;
- TokenType token = internalScan();
- if (token != TokenType.EOS && offset == stream.pos()) {
- log("Scanner.scan has not advanced at offset " + offset + ", state before: " + oldState + " after: "
- + state);
- stream.advance(1);
- return finishToken(offset, TokenType.Unknown);
- }
- return token;
- }
-
- private void log(String message) {
- System.err.println(message);
- }
-
- TokenType internalScan() {
- int offset = stream.pos();
- if (stream.eos()) {
- return finishToken(offset, TokenType.EOS);
- }
- String errorMessage = null;
-
- switch (state) {
- case WithinComment:
- if (stream.advanceIfChars(_MIN, _MIN, _RAN)) { // -->
- state = !isInsideDTDContent ? ScannerState.WithinContent : ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.EndCommentTag);
- }
- stream.advanceUntilChars(_MIN, _MIN, _RAN); // -->
- return finishToken(offset, TokenType.Comment);
-
- case PrologOrPI:
- if (stream.advanceIfChars(_QMA, _RAN)) { // ?>
- state = getWithinContentState();
- return finishToken(offset, TokenType.PIEnd);
- }
- if (stream.advanceUntilAnyOfChars(_NWL, _CAR, _WSP, _QMA, _RAN) || stream.eos()) { // \n or \r or ' ' or '?'
- String name = getTokenTextFromOffset(offset);
- if (PROLOG_NAME_OPTIONS.matcher(name).matches()) { // name eg: xml
- state = ScannerState.WithinTag;
- return finishToken(offset, TokenType.PrologName);
- }
- // if(PI_WITH_VARIABLES.matcher(name).matches()) { // name eg: xml-stylesheet
- // state = ScannerState.WithinTag;
- // return finishToken(offset, TokenType.PIName);
- // }
- if (ATTRIBUTE_NAME_REGEX.matcher(name).matches()) { // {name} eg: m2e
- state = ScannerState.WithinPI;
- return finishToken(offset, TokenType.PIName);
- }
- }
- stream.advanceUntilCharsOrNewTag(_QMA, _RAN); // ?>
- if (stream.peekChar() == _LAN) {
- state = ScannerState.WithinContent; // TODO: check if EOF causes issues
- }
- return internalScan();
-
- case WithinPI:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (stream.advanceIfChars(_QMA, _RAN)) {
- state = getWithinContentState();
- return finishToken(offset, TokenType.PIEnd);
- }
- if (stream.advanceUntilCharsOrNewTag(_QMA, _RAN)) { // ?>
- if (stream.peekChar() == _LAN) {
- state = getWithinContentState();
- }
- if (getTokenTextFromOffset(offset).length() == 0) {
- return finishToken(offset, TokenType.PIEnd);
- }
- }
- return finishToken(offset, TokenType.PIContent);
-
- case WithinContent:
- if (stream.advanceIfChar(_LAN)) { // <
- if (!stream.eos() && stream.peekChar() == _EXL) { // !
- if (stream.advanceIfChars(_EXL, _MIN, _MIN)) { // !--
- state = ScannerState.WithinComment;
- return finishToken(offset, TokenType.StartCommentTag);
- }
- if (stream.advanceIfChars(_EXL, _OSB, _CVL, _DVL, _AVL, _TVL, _AVL, _OSB)) { // ![CDATA[
- state = ScannerState.WithinCDATA;
- return finishToken(offset, TokenType.CDATATagOpen);
- }
-
- if (stream.advanceIfChars(_EXL, _DVL, _OVL, _CVL, _TVL, _YVL, _PVL, _EVL)) { // !DOCTYPE
- isDeclCompleted = false;
- state = ScannerState.DTDWithinDoctype;
- return finishToken(offset, TokenType.DTDStartDoctypeTag);
- }
-
- } else if (!stream.eos() && stream.advanceIfChar(_QMA)) { // ?
- state = ScannerState.PrologOrPI;
- return finishToken(offset, TokenType.StartPrologOrPI);
- }
- if (stream.advanceIfChar(_FSL)) { // /
- state = ScannerState.AfterOpeningEndTag;
- return finishToken(offset, TokenType.EndTagOpen);
- }
- state = ScannerState.AfterOpeningStartTag;
- return finishToken(offset, TokenType.StartTagOpen);
- }
- stream.advanceUntilChar(_LAN); // <
- return finishToken(offset, TokenType.Content);
-
- case WithinCDATA:
- if (stream.advanceIfChars(_CSB, _CSB, _RAN)) { // ]]>
- state = ScannerState.WithinContent;
- return finishToken(offset, TokenType.CDATATagClose);
- }
- stream.advanceUntilChars(_CSB, _CSB, _RAN); // ]]>
- return finishToken(offset, TokenType.CDATAContent);
-
- case AfterOpeningEndTag:
- if (hasNextElementName()) {
- state = ScannerState.WithinEndTag;
- return finishToken(offset, TokenType.EndTag);
- }
- if (stream.skipWhitespace()) { // white space is not valid here
- return finishToken(offset, TokenType.Whitespace,
- localize("error.unexpectedWhitespace", "Tag name must directly follow the open bracket."));
- }
- state = ScannerState.WithinEndTag;
- if (stream.advanceUntilCharOrNewTag(_RAN)) { // >
- if (stream.peekChar() == _LAN) { // <
- state = ScannerState.WithinContent;
- }
- return internalScan();
- }
- return finishToken(offset, TokenType.Unknown);
-
- case WithinEndTag:
- if (stream.skipWhitespace()) { // white space is valid here
- return finishToken(offset, TokenType.Whitespace);
- }
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.WithinContent;
- return finishToken(offset, TokenType.EndTagClose);
- }
- if (stream.advanceUntilChar(_LAN)) { // <
- state = ScannerState.WithinContent;
- return internalScan();
- }
- return finishToken(offset, TokenType.Whitespace);
-
- case AfterOpeningStartTag:
- if (hasNextElementName()) {
- state = ScannerState.WithinTag;
- return finishToken(offset, TokenType.StartTag);
- }
- if (stream.skipWhitespace()) { // white space is not valid here
- return finishToken(offset, TokenType.Whitespace,
- localize("error.unexpectedWhitespace", "Tag name must directly follow the open bracket."));
- }
- state = ScannerState.WithinTag;
- if (stream.advanceUntilCharOrNewTag(_RAN)) { // >
- if (stream.peekChar() == _LAN) { // <
- state = ScannerState.WithinContent;
- }
- return internalScan();
- }
- return finishToken(offset, TokenType.Unknown);
-
- case WithinTag: {
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
- if (stream.advanceIfChars(_QMA, _RAN)) { // ?>
- state = getWithinContentState();
- return finishToken(offset, TokenType.PrologEnd);
- }
-
- if (hasNextAttributeName()) {
- state = ScannerState.AfterAttributeName;
- return finishToken(offset, TokenType.AttributeName);
- }
-
- if (stream.advanceIfChar(_FSL)) { // /
- state = ScannerState.WithinTag;
- if(stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.WithinContent;
- return finishToken(offset, TokenType.StartTagSelfClose);
- }
- return finishToken(offset, TokenType.Unknown);
- }
- int c = stream.peekChar();
- if (c == _DQO || c == _SIQ) { // " || '
- state = ScannerState.BeforeAttributeValue;
- return internalScan();
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.WithinContent;
- return finishToken(offset, TokenType.StartTagClose);
- }
-
- if (stream.advanceUntilChar(_LAN)) { // <
- state = ScannerState.WithinContent;
- return internalScan();
- }
- return finishToken(offset, TokenType.Unknown);
- }
- case AfterAttributeName:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (stream.advanceIfChar(_EQS)) { // =
- state = ScannerState.BeforeAttributeValue;
- return finishToken(offset, TokenType.DelimiterAssign);
- }
- state = ScannerState.WithinTag;
- return internalScan(); // no advance yet - jump to WithinTag
-
- case BeforeAttributeValue:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
- if (hasNextAttributeValue()) {
- state = ScannerState.WithinTag;
- return finishToken(offset, TokenType.AttributeValue);
- }
- state = ScannerState.WithinTag;
- return internalScan();
-
- // DTD
-
- case DTDWithinDoctype:
- // Possible formats:
- // https://en.wikipedia.org/wiki/Document_type_declaration#Syntax
-
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (stream.advanceIfChar(_OSB)) { // [
- state = ScannerState.DTDWithinContent;
- isInsideDTDContent = true;
- return finishToken(offset, TokenType.DTDStartInternalSubset);
- }
-
- if (stream.advanceIfChar(_CSB)) { // ]
- state = ScannerState.DTDWithinDoctype;
- isInsideDTDContent = false;
- isDeclCompleted = true;
- return finishToken(offset, TokenType.DTDEndInternalSubset);
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.WithinContent;
- return finishToken(offset, TokenType.DTDEndDoctypeTag);
- }
-
- if(stream.peekChar() == _LAN) { // <
- state = ScannerState.WithinContent;
- return internalScan();
- }
-
-
- if (isDeclCompleted == false) {
- String doctypeName = doctypeName();
- if(!doctypeName.equals("")) {
- state = ScannerState.DTDAfterDoctypeName;
- return finishToken(offset, TokenType.DTDDoctypeName);
- }
- }
- stream.advanceUntilCharOrNewTag(_RAN); // > || <
- return finishToken(offset, TokenType.DTDUnrecognizedParameters);
-
- case DTDAfterDoctypeName:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
- if (stream.advanceIfChar(_OSB)) { // [
- state = ScannerState.DTDWithinContent;
- isInsideDTDContent = true;
- return finishToken(offset, TokenType.DTDStartInternalSubset);
- }
- lastDoctypeKind = doctypeKind(); // eg: PUBLIC || SYSTEM
- if (lastDoctypeKind.equals(DocumentTypeKind.PUBLIC.name())) {
- state = ScannerState.DTDAfterDoctypePUBLIC;
- return finishToken(offset, TokenType.DTDDocTypeKindPUBLIC);
- } else if (lastDoctypeKind.equals(DocumentTypeKind.SYSTEM.name())) {
- state = ScannerState.DTDAfterDoctypeSYSTEM;
- return finishToken(offset, TokenType.DTDDocTypeKindSYSTEM);
- }
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterDoctypePUBLIC:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
- url = stream.advanceIfRegExp(URL_VALUE_REGEX);
- if (!url.equals("")) {
- state = ScannerState.DTDAfterDoctypePublicId;
- return finishToken(offset, TokenType.DTDDoctypePublicId);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterDoctypeSYSTEM:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- state = ScannerState.DTDWithinDoctype;
- url = stream.advanceIfRegExp(URL_VALUE_REGEX);
- if (!url.equals("")) {
- return finishToken(offset, TokenType.DTDDoctypeSystemId);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterDoctypePublicId:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- state = ScannerState.DTDWithinDoctype;
- url = stream.advanceIfRegExp(URL_VALUE_REGEX); // scan the System Identifier URL
- if (!url.equals("")) {
- return finishToken(offset, TokenType.DTDDoctypeSystemId);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDWithinContent:
- if (!isDTDFile && (stream.advanceIfChar(_CSB) || stream.peekChar() == _RAN)) { // ] || >
- state = ScannerState.DTDWithinDoctype;
- isInsideDTDContent = false;
- return finishToken(offset, TokenType.DTDEndInternalSubset);
- }
- boolean startsWithLessThanBracket = false;
- if (stream.advanceIfChar(_LAN)) { // <
- startsWithLessThanBracket = true;
- if (!stream.eos() && stream.peekChar() == _EXL) { // !
- isDeclCompleted = false;
- if (stream.advanceIfChars(_EXL, _EVL, _LVL, _EVL, _MVL, _EVL, _NVL, _TVL)) { // !ELEMENT
- state = ScannerState.DTDWithinElement;
- return finishToken(offset, TokenType.DTDStartElement);
- } else if (stream.advanceIfChars(_EXL, _AVL, _TVL, _TVL, _LVL, _IVL, _SVL, _TVL)) { // !ATTLIST
- isInitialAttlistDeclCompleted = false;
- state = ScannerState.DTDWithinAttlist;
- return finishToken(offset, TokenType.DTDStartAttlist);
- } else if (stream.advanceIfChars(_EXL, _EVL, _NVL, _TVL, _IVL, _TVL, _YVL)) { // !ENTITY
- state = ScannerState.DTDWithinEntity;
- return finishToken(offset, TokenType.DTDStartEntity);
- } else if (stream.advanceIfChars(_EXL, _NVL, _OVL, _TVL, _AVL, _TVL, _IVL, _OVL, _NVL)) { // !NOTATION
- state = ScannerState.DTDWithinNotation;
- return finishToken(offset, TokenType.DTDStartNotation);
- } else if (stream.advanceIfChars(_EXL, _MIN, _MIN)) { // !-- (for comment)
- state = ScannerState.WithinComment;
- return finishToken(offset, TokenType.StartCommentTag);
- }
- }
- }
- if(isDTDFile) {
- if(startsWithLessThanBracket) {
- if (stream.advanceIfChar(_QMA)) { // ?
- state = ScannerState.PrologOrPI;
- return finishToken(offset, TokenType.StartPrologOrPI);
- }
- if(stream.advanceUntilCharOrNewTag(_RAN)){ // >
- if(stream.peekChar() == _RAN) {
- stream.advance(1); //consume '>'
- }
- }
- }
- else {
- stream.advanceUntilAnyOfChars(_LAN); // <
- }
- } else {
- stream.advanceUntilAnyOfChars(_RAN, _LAN, _CSB); // > || < || ]
- if(startsWithLessThanBracket && stream.peekChar() == _RAN) {
- stream.advance(1); //consume '>'
- }
- }
- return finishToken(offset, TokenType.Content);
-
-
-
- case DTDUnrecognizedParameters:
-
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if(stream.advanceIfChar(_RAN)) { // >
- state = isInsideDTDContent ? ScannerState.DTDWithinContent : ScannerState.WithinContent;
- tempToken = isInsideDTDContent ? TokenType.DTDEndTag : TokenType.EndTagClose;
- return finishToken(offset, tempToken);
- }
-
- if(stream.peekChar() == _LAN) { // <
- state = isInsideDTDContent ? ScannerState.DTDWithinContent : ScannerState.WithinContent;
- return internalScan();
- }
-
- if(stream.peekChar() == _CSB && isInsideDTDContent) { // ]
- state = ScannerState.DTDWithinDoctype;
- return internalScan();
- }
-
- //If in DOCTYPE this will skip over the whole internal subset
- if(!isInsideDTDContent) {
- stream.advanceUntilAnyOfChars(_OSB, _RAN, _LAN); // [ | < | >
- if(stream.peekChar() == _OSB) {
- stream.advance(1);
- stream.advanceUntilCharUsingStack(_CSB);// ]
-
- }
- }
-
- if(stream.advanceUntilCharOrNewTag(_RAN)) { // >
- if(stream.peekChar() == _LAN) { // <
- state = isInsideDTDContent ? ScannerState.DTDWithinContent : ScannerState.DTDWithinDoctype;
- }
- }
- return finishToken(offset, TokenType.DTDUnrecognizedParameters);
-
-
- case DTDWithinElement:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- if(isDeclCompleted == true) {
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
- }
-
- if (!stream.advanceIfRegExp(Constants.ELEMENT_NAME_REGEX).equals("")) {
- state = ScannerState.DTDElementAfterName;
- return finishToken(offset, TokenType.DTDElementDeclName);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDElementAfterName:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (stream.advanceIfChar(_ORB)) { // (
- nbBraceOpened = 1;
- state = ScannerState.DTDElementWithinContent;
- return finishToken(offset, TokenType.DTDStartElementContent);
- }
-
- if (!stream.advanceIfRegExpGroup1(DTD_ELEMENT_CATEGORY).equals("")) {
- isDeclCompleted = true;
- state = ScannerState.DTDWithinElement;
- return finishToken(offset, TokenType.DTDElementCategory);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDElementWithinContent: //
-
- if(stream.advanceIfChar(_CRB)) { // )
- isDeclCompleted = true;
- state = ScannerState.DTDWithinElement;
- stream.advanceIfAnyOfChars(_QMA, _AST, _PLS); // ? | * | +
- return finishToken(offset, TokenType.DTDEndElementContent);
- }
-
- while(nbBraceOpened > 0) {
- int c = stream.peekChar();
-
- if(c == _ORB) { // (
- nbBraceOpened++;
- }
- else if(c == _CRB) { // )
- nbBraceOpened--;
- if(nbBraceOpened == 0) {
- return finishToken(offset, TokenType.DTDElementContent);
- }
- }
- else if(c == _RAN) { // >
- state = ScannerState.DTDWithinElement;
- return finishToken(offset, TokenType.DTDElementContent);
- }
- else if(c == _LAN) { // <
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDElementContent);
- }
- else if(c == -1) {
- return finishToken(offset, TokenType.DTDElementContent);
- }
- stream.advance(1);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDWithinAttlist:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- if(isDeclCompleted == true) {
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
- }
-
- if (isInitialAttlistDeclCompleted == false && !stream.advanceIfRegExp(Constants.ELEMENT_NAME_REGEX).equals("")) {
- state = ScannerState.DTDAfterAttlistElementName;
- return finishToken(offset, TokenType.DTDAttlistElementName);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterAttlistElementName:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (!stream.advanceIfRegExp(Constants.ATTRIBUTE_NAME_REGEX).equals("")) {
- state = ScannerState.DTDAfterAttlistAttributeName;
- return finishToken(offset, TokenType.DTDAttlistAttributeName);
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterAttlistAttributeName:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (!stream.advanceIfRegExpGroup1(Constants.DTD_ATTLIST_ATTRIBUTE_TYPE).equals("")) {
- state = ScannerState.DTDAfterAttlistAttributeType;
- return finishToken(offset, TokenType.DTDAttlistAttributeType);
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterAttlistAttributeType:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (!stream.advanceIfRegExpGroup1(Constants.DTD_ATTLIST_ATTRIBUTE_VALUE).equals("")) {
- isInitialAttlistDeclCompleted = true; //we completed the initial attribute declaration
- isDeclCompleted = true;
- state = ScannerState.DTDAfterAttlistElementName;
- return finishToken(offset, TokenType.DTDAttlistAttributeValue);
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDWithinEntity:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- if(isDeclCompleted == true) {
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
- }
-
- if (!stream.advanceIfRegExp(Constants.ELEMENT_NAME_REGEX).equals("")) {
- state = ScannerState.DTDAfterEntityName;
- return finishToken(offset, TokenType.DTDEntityName);
- }
-
- if (stream.advanceIfChar(_PCT)) { // %
- return finishToken(offset, TokenType.DTDEntityPercent);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterEntityName:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (!stream.advanceIfRegExp(Constants.DTD_ENTITY_VALUE).equals("")) {
- isDeclCompleted = true;
- state = ScannerState.DTDWithinEntity;
- return finishToken(offset, TokenType.DTDEntityValue);
- }
-
- lastDoctypeKind = doctypeKind(); // eg: PUBLIC || SYSTEM, will advance the stream if either of these
- if (lastDoctypeKind.equals(DocumentTypeKind.PUBLIC.name())) {
- state = ScannerState.DTDAfterEntityPUBLIC;
- return finishToken(offset, TokenType.DTDEntityKindPUBLIC);
- } else if (lastDoctypeKind.equals(DocumentTypeKind.SYSTEM.name())) {
- state = ScannerState.DTDAfterEntitySYSTEM;
- return finishToken(offset, TokenType.DTDEntityKindSYSTEM);
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterEntityPUBLIC:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (!stream.advanceIfRegExp(URL_VALUE_REGEX).equals("")) {
- state = ScannerState.DTDAfterEntitySYSTEM;
- return finishToken(offset, TokenType.DTDEntityPublicId);
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterEntitySYSTEM:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if (!stream.advanceIfRegExp(URL_VALUE_REGEX).equals("")) {
- isDeclCompleted = true;
- state = ScannerState.DTDWithinEntity;
- return finishToken(offset, TokenType.DTDEntitySystemId);
- }
-
- if (stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDWithinNotation:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- if(stream.advanceIfChar(_RAN)) { // >
- state = ScannerState.DTDWithinContent;
- return finishToken(offset, TokenType.DTDEndTag);
- }
-
- if(isDeclCompleted == true) {
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
- }
-
- if (!stream.advanceIfRegExp(ELEMENT_NAME_REGEX).equals("")) {
- state = ScannerState.DTDAfterNotationName;
- return finishToken(offset, TokenType.DTDNotationName);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterNotationName:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- lastDoctypeKind = doctypeKind(); // eg: PUBLIC || SYSTEM, will advance the stream if either of these
- if (lastDoctypeKind.equals(DocumentTypeKind.PUBLIC.name())) {
- state = ScannerState.DTDAfterNotationPUBLIC;
- return finishToken(offset, TokenType.DTDNotationKindPUBLIC);
- } else if (lastDoctypeKind.equals(DocumentTypeKind.SYSTEM.name())) {
- state = ScannerState.DTDAfterNotationSYSTEM;
- return finishToken(offset, TokenType.DTDNotationKindSYSTEM);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterNotationPUBLIC:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
- url = stream.advanceIfRegExp(URL_VALUE_REGEX);
- if (!url.equals("")) {
- isDeclCompleted = true;
- state = ScannerState.DTDAfterNotationPublicId;
- return finishToken(offset, TokenType.DTDNotationPublicId);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterNotationSYSTEM:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- state = ScannerState.DTDWithinNotation;
- url = stream.advanceIfRegExp(URL_VALUE_REGEX);
- if (!url.equals("")) {
- isDeclCompleted = true;
- state = ScannerState.DTDAfterNotationName;
- return finishToken(offset, TokenType.DTDNotationSystemId);
- }
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- case DTDAfterNotationPublicId:
- if (stream.skipWhitespace()) {
- return finishToken(offset, TokenType.Whitespace);
- }
-
- state = ScannerState.DTDAfterNotationName;
- url = stream.advanceIfRegExp(URL_VALUE_REGEX); // scan the System Identifier URL
- if (!url.equals("")) {
- isDeclCompleted = true;
- return finishToken(offset, TokenType.DTDNotationSystemId);
- }
-
- state = ScannerState.DTDUnrecognizedParameters;
- return internalScan();
-
- default:
- }
-
-
- stream.advance(1);
- state = isInsideDTDContent ? ScannerState.DTDWithinContent : ScannerState.WithinContent;
- return finishToken(offset, TokenType.Unknown, errorMessage);
- }
-
- private String localize(String string, String string2) {
- return string;
- }
-
- private ScannerState getWithinContentState() {
- if (isDTDFile) {
- return ScannerState.DTDWithinContent;
- }
- return ScannerState.WithinContent;
- }
-
- public int getLastNonWhitespaceOffset() {
- return stream.getLastNonWhitespaceOffset();
- }
-
- @Override
- public TokenType getTokenType() {
- return tokenType;
- }
-
- @Override
- /**
- * Starting offset position of the current token
- *
- * @return Starting offset position of the current token
- */
- public int getTokenOffset() {
- return tokenOffset;
- }
-
- @Override
- public int getTokenLength() {
- return stream.pos() - tokenOffset;
- }
-
- @Override
- /**
- * Ending offset position of the current token
- *
- * @return Ending offset position of the current token
- */
- public int getTokenEnd() {
- return stream.pos();
- }
-
- @Override
- public String getTokenText() {
- return stream.getSource().substring(tokenOffset, stream.pos());
- }
-
- @Override
- public boolean isTokenTextBlank() {
- return StringUtils.isWhitespace(stream.getSource(), tokenOffset, stream.pos());
- }
-
- @Override
- public ScannerState getScannerState() {
- return state;
- }
-
- @Override
- public String getTokenError() {
- return tokenError;
- }
-
- public String getTokenTextFromOffset(int offset) {
- return stream.getSource().substring(offset, stream.pos());
- }
-
- public static Scanner createScanner(String input) {
- return createScanner(input, false);
- }
-
- public static Scanner createScanner(String input, boolean isDTD) {
- return createScanner(input, 0, isDTD);
- }
-
- public static Scanner createScanner(String input, int initialOffset) {
- return createScanner(input, initialOffset, false);
- }
-
- public static Scanner createScanner(String input, int initialOffset, boolean isDTDFile) {
- return createScanner(input, initialOffset,
- isDTDFile ? ScannerState.DTDWithinContent : ScannerState.WithinContent, isDTDFile);
- }
-
- public static Scanner createScanner(String input, int initialOffset, ScannerState initialState) {
- return new XMLScanner(input, initialOffset, initialState, false);
- }
-
- public static Scanner createScanner(String input, int initialOffset, ScannerState initialState, boolean isDTDFile) {
- return new XMLScanner(input, initialOffset, initialState, isDTDFile);
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/CatalogCatalogEntry.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/CatalogCatalogEntry.java
deleted file mode 100644
index b8de9afa3..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/CatalogCatalogEntry.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*******************************************************************************
-* 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
-*
-* Contributors:
-* Red Hat Inc. - initial API and implementation
-*******************************************************************************/
-package org.eclipse.lemminx.extensions.catalog;
-
-import java.nio.file.Paths;
-
-import org.eclipse.lemminx.dom.DOMAttr;
-import org.eclipse.lemminx.dom.DOMElement;
-import org.eclipse.lemminx.dom.DOMRange;
-import org.eclipse.lemminx.utils.StringUtils;
-import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
-
-/**
- * Represents a catalog entry that uses the "catalog" attribute to reference an external document
- */
-public class CatalogCatalogEntry extends CatalogEntry {
-
- public CatalogCatalogEntry(@NonNull String baseURI, DOMElement entryElement) {
- super(baseURI, entryElement);
- }
-
- @Override
- public DOMRange getLinkRange() {
- DOMAttr catalogAttr = CatalogUtils.getCatalogEntryCatalog(getEntryElement());
- if (catalogAttr == null) {
- return null;
- }
- return catalogAttr.getNodeAttrValue();
- }
-
- @Override
- public String getResolvedURI() {
- DOMAttr catalogAttr = CatalogUtils.getCatalogEntryCatalog(getEntryElement());
- if (catalogAttr == null) {
- return null;
- }
- String lastSegment = catalogAttr.getValue();
- if (StringUtils.isBlank(lastSegment)) {
- return null;
- }
- return Paths.get(getBaseURI(), lastSegment).toString();
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/CatalogEntry.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/CatalogEntry.java
deleted file mode 100644
index 1bc737072..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/CatalogEntry.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*******************************************************************************
-* 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
-*
-* Contributors:
-* Red Hat Inc. - initial API and implementation
-*******************************************************************************/
-package org.eclipse.lemminx.extensions.catalog;
-
-import org.eclipse.lemminx.dom.DOMElement;
-import org.eclipse.lemminx.dom.DOMRange;
-
-/**
- * Represents a catalog entry that references an external document
- */
-public abstract class CatalogEntry {
-
- private final String baseURI;
- private final DOMElement entryElement;
-
- /**
- *
- * @param baseURI 's xml:base + 's xml:base (if in a
- * )
- * @param entryElement the element that corresponds with this catalog entry
- */
- protected CatalogEntry(String baseURI, DOMElement entryElement) {
- this.baseURI = baseURI;
- this.entryElement = entryElement;
- }
-
- /**
- * Returns the base URI for this catalog entry
- *
- * @return the base URI for this catalog entry
- */
- public String getBaseURI() {
- return baseURI;
- }
-
- /**
- * Returns the element that corresponds with this catalog entry
- *
- * @return the element that corresponds with this catalog entry
- */
- protected DOMElement getEntryElement() {
- return entryElement;
- }
-
- /**
- * Returns the range in the document where the link to an external document is,
- * or null if this catalog entry does not refer to an external document
- *
- * @return the range in the document where the link to an external document is
- */
- public abstract DOMRange getLinkRange();
-
- /**
- * Returns the URI for the document that this catalog entry references, or null
- * if this catalog entry does not refer to an external document
- *
- * @return the URI for the document that this catalog entry references
- */
- public abstract String getResolvedURI();
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/CatalogUtils.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/CatalogUtils.java
deleted file mode 100644
index 73c23bb5e..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/CatalogUtils.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*******************************************************************************
-* 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
-*
-* Contributors:
-* Red Hat Inc. - initial API and implementation
-*******************************************************************************/
-
-package org.eclipse.lemminx.extensions.catalog;
-
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.lemminx.dom.DOMAttr;
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.dom.DOMElement;
-import org.eclipse.lemminx.dom.DOMNode;
-import org.eclipse.lemminx.utils.DOMUtils;
-import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
-
-/**
- * Utility functions for working with XML catalog documents
- */
-public class CatalogUtils {
-
- /**
- * The catalog entries that have a 'uri' attribute
- */
- private static final Collection HAS_URI_ATTRIBUTE = Arrays.asList("public", "system", "uri", "systemSuffix",
- "uriSuffix");
-
- /**
- * The catalog entries that have a 'catalog' attribute
- */
- private static final Collection HAS_CATALOG_ATTRIBUTE = Arrays.asList("delegatePublic", "delegateSystem",
- "delegateUri", "nextCatalog");
-
- private static final String XML_BASE_ATTRIBUTE = "xml:base";
-
- private static final String CATALOG_ENTITY_NAME = "catalog";
-
- private static final String GROUP_ENTITY_NAME = "group";
-
- private static final String URI_ATTRIBUTE_NAME = "uri";
-
- private static final String CATALOG_ATTRIBUTE_NAME = "catalog";
-
- /**
- * Returns a list of all the catalog entries in the given document, or an empty
- * list if the document is not a catalog.
- *
- * @return a list of all the catalog entries in the given document, or an empty
- * list if the document is not a catalog.
- */
- public static List getCatalogEntries(DOMDocument document) {
- if (!DOMUtils.isCatalog(document)) {
- return Collections.emptyList();
- }
- for (DOMNode n : document.getChildren()) {
- if (n.isElement() && CATALOG_ENTITY_NAME.equals(n.getNodeName())) {
- return collectCatalogEntries((DOMElement) n);
- }
- }
- return Collections.emptyList();
- }
-
- /**
- * Returns the uri attribute node of the given catalog entry or null if there is
- * no uri attribute
- *
- * @param element The catalog entry to get the uri attribute of
- * @return the uri attribute node of the given catalog entry or null if there is
- * no uri attribute
- */
- public static DOMAttr getCatalogEntryURI(DOMElement element) {
- return element.getAttributeNode(URI_ATTRIBUTE_NAME);
- }
-
- /**
- * Returns the catalog attribute node of the given catalog entry or null if
- * there is no catalog attribute
- *
- * @param element The catalog entry to get the catalog attribute of
- * @return the catalog attribute node of the given catalog entry or null if
- * there is no catalog attribute
- */
- public static DOMAttr getCatalogEntryCatalog(DOMElement element) {
- return element.getAttributeNode(CATALOG_ATTRIBUTE_NAME);
- }
-
- /**
- * Returns true if this element is a catalog entry that is required to have the
- * 'uri' attribute and false otherwise
- *
- * @param element The element to check
- * @return true if this element is an catalog entry that is required to have the
- * 'uri' attribute and false otherwise
- */
- private static boolean isCatalogEntryWithURI(DOMElement element) {
- return HAS_URI_ATTRIBUTE.contains(element.getNodeName());
- }
-
- /**
- * Returns true if this element is a catalog entry that is required to have the
- * 'catalog' attribute and false otherwise
- *
- * @param element The element to check
- * @return true if this element is an catalog entry that is required to have the
- * 'catalog' attribute and false otherwise
- */
- private static boolean isCatalogEntryWithCatalog(DOMElement element) {
- return HAS_CATALOG_ATTRIBUTE.contains(element.getNodeName());
- }
-
- /**
- * Returns true if the given element is a group element and false otherwise
- *
- * @param element The element to check
- * @return true if the given element is a group element and false otherwise
- */
- private static boolean isGroupCatalogEntry(DOMElement element) {
- return GROUP_ENTITY_NAME.equals(element.getNodeName());
- }
-
- /**
- * Get a list of all catalog entry elements that are in the given catalog
- *
- * @param catalog the catalog element to collect the entries for
- * @return A list of all the catalog entities in this catalog
- */
- private static List collectCatalogEntries(@NonNull DOMElement catalog) {
- List entries = new ArrayList<>();
- String baseURI = catalog.getAttribute(XML_BASE_ATTRIBUTE);
- baseURI = baseURI == null ? "" : baseURI;
- for (DOMNode node : catalog.getChildren()) {
- if (node.isElement()) {
- DOMElement element = (DOMElement) node;
- CatalogEntry catalogEntry = createCatalogEntry(baseURI, element);
- if (catalogEntry != null) {
- entries.add(catalogEntry);
- } else if (isGroupCatalogEntry(element)) {
- entries.addAll(collectGroupEntries(element, baseURI));
- }
- }
- }
- return entries;
- }
-
- /**
- * Get a list of all catalog entry elements that are in the given group
- *
- * @param group the group element to collect the entries for
- * @param baseURI the baseURI of the catalog
- * @return A list of all the catalog entities in this group
- */
- private static List collectGroupEntries(DOMElement group, @NonNull String baseURI) {
- List entries = new ArrayList<>();
- String groupSegment = group.getAttribute(XML_BASE_ATTRIBUTE);
- if (groupSegment != null) {
- baseURI = Paths.get(baseURI, groupSegment).toString();
- }
- for (DOMNode node : group.getChildren()) {
- if (node.isElement()) {
- DOMElement element = (DOMElement) node;
- CatalogEntry catalogEntry = createCatalogEntry(baseURI, element);
- if (catalogEntry != null) {
- entries.add(catalogEntry);
- }
- }
- }
- return entries;
- }
-
- /**
- * Returns a catalog entry for the given element and null if a catalog entry
- * can't be made
- *
- * @param baseURI the base URI of the catalog entry
- * @param element the element to turn into a catalog entry
- * @return a catalog entry for the given element and null if a catalog entry
- * can't be made
- */
- private static CatalogEntry createCatalogEntry(@NonNull String baseURI, DOMElement element) {
- if (isCatalogEntryWithURI(element)) {
- return new URICatalogEntry(baseURI, element);
- } else if (isCatalogEntryWithCatalog(element)) {
- return new CatalogCatalogEntry(baseURI, element);
- }
- return null;
- }
-
-}
\ No newline at end of file
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/URICatalogEntry.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/URICatalogEntry.java
deleted file mode 100644
index ae699318d..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/URICatalogEntry.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*******************************************************************************
-* 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
-*
-* Contributors:
-* Red Hat Inc. - initial API and implementation
-*******************************************************************************/
-package org.eclipse.lemminx.extensions.catalog;
-
-import java.nio.file.InvalidPathException;
-import java.nio.file.Paths;
-
-import org.eclipse.lemminx.dom.DOMAttr;
-import org.eclipse.lemminx.dom.DOMElement;
-import org.eclipse.lemminx.dom.DOMRange;
-import org.eclipse.lemminx.utils.StringUtils;
-import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
-
-/**
- * Represents a catalog entry that uses the "uri" attribute to reference an external document
- */
-public class URICatalogEntry extends CatalogEntry {
-
- public URICatalogEntry(@NonNull String baseURI, DOMElement entryElement) {
- super(baseURI, entryElement);
- }
-
- @Override
- public DOMRange getLinkRange() {
- DOMAttr uriAttr = CatalogUtils.getCatalogEntryURI(getEntryElement());
- if (uriAttr == null) {
- return null;
- }
- return uriAttr.getNodeAttrValue();
- }
-
- @Override
- public String getResolvedURI() {
- DOMAttr uriAttr = CatalogUtils.getCatalogEntryURI(getEntryElement());
- if (uriAttr == null) {
- return null;
- }
- String lastSegment = uriAttr.getValue();
- if (StringUtils.isBlank(lastSegment)) {
- return null;
- }
- try {
- return Paths.get(getBaseURI(), lastSegment).toString();
- } catch (InvalidPathException e) {
- // See issue #977
- return null;
- }
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogDocumentLinkParticipant.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogDocumentLinkParticipant.java
deleted file mode 100644
index 217ccc431..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogDocumentLinkParticipant.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*******************************************************************************
-* 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
-*
-* Contributors:
-* Red Hat Inc. - initial API and implementation
-*******************************************************************************/
-
-package org.eclipse.lemminx.extensions.catalog;
-
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.xerces.impl.XMLEntityManager;
-import org.apache.xerces.util.URI.MalformedURIException;
-import org.eclipse.lemminx.commons.BadLocationException;
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.services.extensions.IDocumentLinkParticipant;
-import org.eclipse.lemminx.utils.FilesUtils;
-import org.eclipse.lemminx.utils.StringUtils;
-import org.eclipse.lemminx.utils.XMLPositionUtility;
-import org.eclipse.lsp4j.DocumentLink;
-
-/**
- * Document links that are specific to catalogs
- */
-public class XMLCatalogDocumentLinkParticipant implements IDocumentLinkParticipant {
-
- private static Logger LOGGER = Logger.getLogger(XMLCatalogDocumentLinkParticipant.class.getName());
-
- @Override
- public void findDocumentLinks(DOMDocument document, List links) {
- for (CatalogEntry catalogEntry : CatalogUtils.getCatalogEntries(document)) {
- DocumentLink docLink = createDocumentLinkFromCatalogEntry(document, catalogEntry);
- if (docLink != null) {
- links.add(docLink);
- }
- }
- }
-
- /**
- * Return a DocumentLink for the given CatalogEntry or null if this fails
- *
- * @param document The document that the attribute belongs to
- * @param catalogEntry The CatalogEntry that should be turned into a
- * DocumentLink
- * @return a document link that links the CatalogEntry to the external document
- * it references or null otherwise
- */
- private static DocumentLink createDocumentLinkFromCatalogEntry(DOMDocument document, CatalogEntry catalogEntry) {
- try {
- String path = getResolvedLocation(FilesUtils.removeFileScheme(document.getDocumentURI()),
- catalogEntry.getResolvedURI());
- if (path != null && catalogEntry.getLinkRange() != null) {
- return XMLPositionUtility.createDocumentLink(catalogEntry.getLinkRange(), path, true);
- }
- } catch (BadLocationException e) {
- LOGGER.log(Level.SEVERE, "Creation of document link failed", e);
- }
- return null;
- }
-
- /**
- * Returns the expanded system location
- *
- * @return the expanded system location
- */
- private static String getResolvedLocation(String documentURI, String location) {
- if (StringUtils.isBlank(location)) {
- return null;
- }
- try {
- return XMLEntityManager.expandSystemId(location, documentURI, false);
- } catch (MalformedURIException e) {
- return location;
- }
- }
-
-}
\ No newline at end of file
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogPlugin.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogPlugin.java
deleted file mode 100644
index 6455cf0b3..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogPlugin.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.catalog;
-
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.eclipse.lemminx.client.InvalidPathWarner;
-import org.eclipse.lemminx.client.PathFeature;
-import org.eclipse.lemminx.extensions.contentmodel.settings.ContentModelSettings;
-import org.eclipse.lemminx.services.IXMLNotificationService;
-import org.eclipse.lemminx.services.extensions.IDocumentLinkParticipant;
-import org.eclipse.lemminx.services.extensions.IXMLExtension;
-import org.eclipse.lemminx.services.extensions.XMLExtensionsRegistry;
-import org.eclipse.lemminx.services.extensions.save.ISaveContext;
-import org.eclipse.lemminx.utils.FilesUtils;
-import org.eclipse.lsp4j.InitializeParams;
-
-/**
- * XMl Catalog plugin.
- */
-public class XMLCatalogPlugin implements IXMLExtension {
-
- private XMLCatalogURIResolverExtension uiResolver;
- private final IDocumentLinkParticipant documentLinkParticipant;
-
- private InvalidPathWarner pathWarner;
-
- public XMLCatalogPlugin() {
- documentLinkParticipant = new XMLCatalogDocumentLinkParticipant();
- }
-
- @Override
- public void doSave(ISaveContext context) {
- Object initializationOptionsSettings = context.getSettings();
- ContentModelSettings cmSettings = ContentModelSettings.getContentModelXMLSettings(initializationOptionsSettings);
- if (cmSettings == null) {
- return;
- }
- validateCatalogPaths(cmSettings);
- }
-
- @Override
- public void start(InitializeParams params, XMLExtensionsRegistry registry) {
- uiResolver = new XMLCatalogURIResolverExtension(registry);
- registry.getResolverExtensionManager().registerResolver(uiResolver);
- IXMLNotificationService notificationService = registry.getNotificationService();
- if (notificationService != null) {
- this.pathWarner = new InvalidPathWarner(notificationService);
- }
- registry.registerDocumentLinkParticipant(documentLinkParticipant);
- }
-
- @Override
- public void stop(XMLExtensionsRegistry registry) {
- registry.getResolverExtensionManager().unregisterResolver(uiResolver);
- }
-
- private void validateCatalogPaths(ContentModelSettings cmSettings) {
- if (this.pathWarner == null) {
- return; // happen when notification service is not available
- }
- String[] catalogs = cmSettings.getCatalogs();
- Set invalidCatalogs = Arrays.stream(catalogs).filter(c -> {
- return Files.notExists(FilesUtils.getPath(c));
- }).collect(Collectors.toSet());
-
- if (invalidCatalogs.size() > 0) {
- this.pathWarner.onInvalidFilePath(invalidCatalogs, PathFeature.CATALOGS);
- } else {
- this.pathWarner.evictKey(PathFeature.CATALOGS);
- }
- }
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogURIResolverExtension.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogURIResolverExtension.java
deleted file mode 100644
index 88961a4b9..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/catalog/XMLCatalogURIResolverExtension.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.catalog;
-
-import java.io.IOException;
-
-import org.apache.xerces.xni.XMLResourceIdentifier;
-import org.apache.xerces.xni.XNIException;
-import org.apache.xerces.xni.parser.XMLInputSource;
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.services.extensions.XMLExtensionsRegistry;
-import org.eclipse.lemminx.uriresolver.CacheResourcesManager;
-import org.eclipse.lemminx.uriresolver.CacheResourcesManager.ResourceToDeploy;
-import org.eclipse.lemminx.uriresolver.URIResolverExtension;
-
-/**
- * Resolve the XML Schema of XML/Catalog
- *
- */
-public class XMLCatalogURIResolverExtension implements URIResolverExtension {
-
- /**
- * The XML Catalog namespace URI (=
- * http://www.oasis-open.org/committees/entity/release/1.1/catalog.xsd)
- */
- private static final String CATALOG_NAMESPACE_URI = "urn:oasis:names:tc:entity:xmlns:xml:catalog"; //$NON-NLS-1$
-
- private static final String CATALOG_SYSTEM = "http://www.oasis-open.org/committees/entity/release/1.1/catalog.xsd";
-
- private static final ResourceToDeploy CATALOG_RESOURCE = new ResourceToDeploy(CATALOG_SYSTEM,
- "schemas/catalog/catalog-1.1.xsd");
- private final XMLExtensionsRegistry extensionsRegistry;
-
- @Override
- public String getName() {
- return "embedded catalog.xsd";
- }
-
- public XMLCatalogURIResolverExtension(XMLExtensionsRegistry extensionsRegistry) {
- this.extensionsRegistry = extensionsRegistry;
- }
-
- @Override
- public String resolve(String baseLocation, String publicId, String systemId) {
- if (!CATALOG_NAMESPACE_URI.equals(publicId)) {
- return null;
- }
- if (hasDTDorXMLSchema(baseLocation)) {
- return null;
- }
- try {
- return CacheResourcesManager.getResourceCachePath(CATALOG_RESOURCE).toFile().toURI().toString();
- } catch (Exception e) {
- // Do nothing?
- }
- return CATALOG_SYSTEM;
- }
-
- @Override
- public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) throws XNIException, IOException {
- if (hasDTDorXMLSchema(resourceIdentifier.getBaseSystemId())) {
- return null;
- }
- String publicId = resourceIdentifier.getNamespace();
- if (CATALOG_NAMESPACE_URI.equals(publicId)) {
- String baseLocation = resourceIdentifier.getBaseSystemId();
- String catalogFilePath = resolve(baseLocation, publicId, null);
- if (catalogFilePath != null) {
- return new XMLInputSource(publicId, catalogFilePath, catalogFilePath);
- }
- }
- return null;
- }
-
- private boolean hasDTDorXMLSchema(String uri) {
- DOMDocument document = extensionsRegistry.getDocumentProvider().getDocument(uri);
- if (document == null) {
- return false;
- }
- return document.hasDTD() || document.hasSchemaLocation() || document.hasNoNamespaceSchemaLocation();
- }
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/ContentModelPlugin.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/ContentModelPlugin.java
deleted file mode 100644
index e1bf8336a..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/ContentModelPlugin.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.contentmodel;
-
-import java.util.Objects;
-
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.extensions.contentmodel.commands.AssociateGrammarCommand;
-import org.eclipse.lemminx.extensions.contentmodel.commands.CheckBoundGrammarCommand;
-import org.eclipse.lemminx.extensions.contentmodel.commands.CheckFilePatternCommand;
-import org.eclipse.lemminx.extensions.contentmodel.commands.XMLValidationAllFilesCommand;
-import org.eclipse.lemminx.extensions.contentmodel.commands.XMLValidationFileCommand;
-import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
-import org.eclipse.lemminx.extensions.contentmodel.participants.ContentModelCodeActionParticipant;
-import org.eclipse.lemminx.extensions.contentmodel.participants.ContentModelCodeLensParticipant;
-import org.eclipse.lemminx.extensions.contentmodel.participants.ContentModelCompletionParticipant;
-import org.eclipse.lemminx.extensions.contentmodel.participants.ContentModelDocumentLinkParticipant;
-import org.eclipse.lemminx.extensions.contentmodel.participants.ContentModelHoverParticipant;
-import org.eclipse.lemminx.extensions.contentmodel.participants.ContentModelSymbolsProviderParticipant;
-import org.eclipse.lemminx.extensions.contentmodel.participants.ContentModelTypeDefinitionParticipant;
-import org.eclipse.lemminx.extensions.contentmodel.participants.DocumentTelemetryParticipant;
-import org.eclipse.lemminx.extensions.contentmodel.participants.diagnostics.ContentModelDiagnosticsParticipant;
-import org.eclipse.lemminx.extensions.contentmodel.settings.ContentModelSettings;
-import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationSettings;
-import org.eclipse.lemminx.services.IXMLDocumentProvider;
-import org.eclipse.lemminx.services.IXMLValidationService;
-import org.eclipse.lemminx.services.extensions.ICodeActionParticipant;
-import org.eclipse.lemminx.services.extensions.ICompletionParticipant;
-import org.eclipse.lemminx.services.extensions.IDocumentLinkParticipant;
-import org.eclipse.lemminx.services.extensions.IHoverParticipant;
-import org.eclipse.lemminx.services.extensions.ITypeDefinitionParticipant;
-import org.eclipse.lemminx.services.extensions.IXMLExtension;
-import org.eclipse.lemminx.services.extensions.XMLExtensionsRegistry;
-import org.eclipse.lemminx.services.extensions.codelens.ICodeLensParticipant;
-import org.eclipse.lemminx.services.extensions.commands.IXMLCommandService;
-import org.eclipse.lemminx.services.extensions.diagnostics.IDiagnosticsParticipant;
-import org.eclipse.lemminx.services.extensions.save.ISaveContext;
-import org.eclipse.lemminx.uriresolver.URIResolverExtensionManager;
-import org.eclipse.lemminx.utils.DOMUtils;
-import org.eclipse.lsp4j.InitializeParams;
-
-/**
- * Content model plugin extension to provide:
- *
- *
- *
completion based on XML Schema, DTD...
- *
hover based on XML Schema
- *
diagnostics based on on XML Schema, DTD...
- *
- */
-public class ContentModelPlugin implements IXMLExtension {
-
- private final ICompletionParticipant completionParticipant;
-
- private final IHoverParticipant hoverParticipant;
-
- private final IDiagnosticsParticipant diagnosticsParticipant;
-
- private final ICodeActionParticipant codeActionParticipant;
-
- private IDocumentLinkParticipant documentLinkParticipant;
-
- private final ITypeDefinitionParticipant typeDefinitionParticipant;
-
- private ContentModelSymbolsProviderParticipant symbolsProviderParticipant;
-
- private ICodeLensParticipant codeLensParticipant;
-
- ContentModelManager contentModelManager;
-
- private ContentModelSettings cmSettings;
-
- private XMLValidationSettings currentValidationSettings;
-
- private DocumentTelemetryParticipant documentTelemetryParticipant;
-
- public ContentModelPlugin() {
- completionParticipant = new ContentModelCompletionParticipant();
- hoverParticipant = new ContentModelHoverParticipant();
- diagnosticsParticipant = new ContentModelDiagnosticsParticipant(this);
- codeActionParticipant = new ContentModelCodeActionParticipant();
- typeDefinitionParticipant = new ContentModelTypeDefinitionParticipant();
- }
-
- @Override
- public void doSave(ISaveContext context) {
- if (context.getType() == ISaveContext.SaveContextType.DOCUMENT) {
- // The save is done for a given XML file
- String documentURI = context.getUri();
- DOMDocument document = context.getDocument(documentURI);
- if (document != null && DOMUtils.isCatalog(document)) {
- // the XML document which has changed is a XML catalog.
- // 1) refresh catalogs
- contentModelManager.refreshCatalogs();
- }
- // 2) Validate all opened XML files except the catalog which have changed
- context.collectDocumentToValidate(d -> {
- DOMDocument xml = context.getDocument(d.getDocumentURI());
- xml.resetGrammar();
- return !documentURI.equals(d.getDocumentURI());
- });
- } else {
- // Settings
- updateSettings(context);
- }
- }
-
- private void updateSettings(ISaveContext saveContext) {
- Object initializationOptionsSettings = saveContext.getSettings();
- cmSettings = ContentModelSettings.getContentModelXMLSettings(initializationOptionsSettings);
- if (cmSettings != null) {
- updateSettings(cmSettings, saveContext);
- } else {
- currentValidationSettings = null;
- }
- }
-
- private void updateSettings(ContentModelSettings settings, ISaveContext context) {
- if (settings.getCatalogs() != null) {
- // Update XML catalog settings
- boolean catalogPathsChanged = contentModelManager.setCatalogs(settings.getCatalogs());
- if (catalogPathsChanged) {
- // Validate all opened XML files
- context.collectDocumentToValidate(d -> {
- DOMDocument xml = context.getDocument(d.getDocumentURI());
- if (xml == null) {
- return false;
- }
- xml.resetGrammar();
- return true;
- });
- }
- }
- if (settings.getFileAssociations() != null) {
- // Update XML file associations
- boolean fileAssociationsChanged = contentModelManager.setFileAssociations(settings.getFileAssociations());
- if (fileAssociationsChanged) {
- // Validate all opened XML files
- context.collectDocumentToValidate(d -> {
- DOMDocument xml = context.getDocument(d.getDocumentURI());
- xml.resetGrammar();
- return true;
- });
- }
- }
- // Update use cache, only if it is set in the settings.
- Boolean useCache = settings.isUseCache();
- if (useCache != null) {
- contentModelManager.setUseCache(useCache);
- }
- // Update symbols
- boolean showReferencedGrammars = settings.isShowReferencedGrammars();
- symbolsProviderParticipant.setEnabled(showReferencedGrammars);
- // Track if validation settings has changed
- XMLValidationSettings oldValidationSettings = currentValidationSettings;
- currentValidationSettings = cmSettings.getValidation();
- if (oldValidationSettings != null && !Objects.equals(oldValidationSettings, currentValidationSettings)) {
- context.collectDocumentToValidate(d -> true);
- }
- }
-
- @Override
- public void start(InitializeParams params, XMLExtensionsRegistry registry) {
- URIResolverExtensionManager resolverManager = registry.getComponent(URIResolverExtensionManager.class);
- contentModelManager = new ContentModelManager(resolverManager);
- registry.registerComponent(contentModelManager);
- if (params != null) {
- contentModelManager.setRootURI(params.getRootUri());
- }
- documentLinkParticipant = new ContentModelDocumentLinkParticipant(resolverManager);
- registry.registerCompletionParticipant(completionParticipant);
- registry.registerHoverParticipant(hoverParticipant);
- registry.registerDiagnosticsParticipant(diagnosticsParticipant);
- registry.registerCodeActionParticipant(codeActionParticipant);
- registry.registerDocumentLinkParticipant(documentLinkParticipant);
- registry.registerTypeDefinitionParticipant(typeDefinitionParticipant);
- symbolsProviderParticipant = new ContentModelSymbolsProviderParticipant(contentModelManager);
- registry.registerSymbolsProviderParticipant(symbolsProviderParticipant);
- codeLensParticipant = new ContentModelCodeLensParticipant(contentModelManager);
- registry.registerCodeLensParticipant(codeLensParticipant);
- documentTelemetryParticipant = new DocumentTelemetryParticipant(registry.getTelemetryManager(), contentModelManager);
- registry.registerDocumentLifecycleParticipant(documentTelemetryParticipant);
-
- // Register custom commands to re-validate XML files
- IXMLCommandService commandService = registry.getCommandService();
- if (commandService != null) {
- IXMLValidationService validationService = registry.getValidationService();
- IXMLDocumentProvider documentProvider = registry.getDocumentProvider();
- commandService.registerCommand(XMLValidationFileCommand.COMMAND_ID,
- new XMLValidationFileCommand(contentModelManager, documentProvider, validationService));
- commandService.registerCommand(XMLValidationAllFilesCommand.COMMAND_ID,
- new XMLValidationAllFilesCommand(contentModelManager, documentProvider, validationService));
- commandService.registerCommand(AssociateGrammarCommand.COMMAND_ID,
- new AssociateGrammarCommand(documentProvider));
- commandService.registerCommand(CheckBoundGrammarCommand.COMMAND_ID,
- new CheckBoundGrammarCommand(documentProvider));
- commandService.registerCommand(CheckFilePatternCommand.COMMAND_ID,
- new CheckFilePatternCommand());
- }
- }
-
- @Override
- public void stop(XMLExtensionsRegistry registry) {
- registry.unregisterCompletionParticipant(completionParticipant);
- registry.unregisterHoverParticipant(hoverParticipant);
- registry.unregisterDiagnosticsParticipant(diagnosticsParticipant);
- registry.unregisterCodeActionParticipant(codeActionParticipant);
- registry.unregisterDocumentLinkParticipant(documentLinkParticipant);
- registry.unregisterTypeDefinitionParticipant(typeDefinitionParticipant);
- registry.unregisterSymbolsProviderParticipant(symbolsProviderParticipant);
- registry.unregisterCodeLensParticipant(codeLensParticipant);
- registry.unregisterDocumentLifecycleParticipant(documentTelemetryParticipant);
-
- // Un-register custom commands to re-validate XML files
- IXMLCommandService commandService = registry.getCommandService();
- if (commandService != null) {
- commandService.unregisterCommand(XMLValidationFileCommand.COMMAND_ID);
- commandService.unregisterCommand(XMLValidationAllFilesCommand.COMMAND_ID);
- commandService.unregisterCommand(AssociateGrammarCommand.COMMAND_ID);
- commandService.unregisterCommand(CheckBoundGrammarCommand.COMMAND_ID);
- commandService.unregisterCommand(CheckFilePatternCommand.COMMAND_ID);
- }
- }
-
- public ContentModelSettings getContentModelSettings() {
- return cmSettings;
- }
-
- public ContentModelManager getContentModelManager() {
- return contentModelManager;
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/AssociateGrammarCommand.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/AssociateGrammarCommand.java
deleted file mode 100644
index 1def77348..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/AssociateGrammarCommand.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*******************************************************************************
-* Copyright (c) 2021 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.contentmodel.commands;
-
-import static org.eclipse.lemminx.extensions.xsd.utils.XSDUtils.TARGET_NAMESPACE_ATTR;
-
-import java.net.URL;
-import java.nio.file.Path;
-import java.text.MessageFormat;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.NoGrammarConstraintsCodeAction;
-import org.eclipse.lemminx.services.IXMLDocumentProvider;
-import org.eclipse.lemminx.services.extensions.commands.AbstractDOMDocumentCommandHandler;
-import org.eclipse.lemminx.services.extensions.commands.ArgumentsUtils;
-import org.eclipse.lemminx.settings.SharedSettings;
-import org.eclipse.lemminx.utils.DOMUtils;
-import org.eclipse.lemminx.utils.FilesUtils;
-import org.eclipse.lemminx.utils.StringUtils;
-import org.eclipse.lsp4j.ExecuteCommandParams;
-import org.eclipse.lsp4j.jsonrpc.CancelChecker;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * XML Command "xml.associate.grammar.insert" to associate a grammar to a given
- * DOM document.
- *
- * The command parameters {@link ExecuteCommandParams} must be filled with 3
- * parameters:
- *
- *
- *
document URI (String) : the DOM document file URI to bind with a grammar.
- *
- *
grammar URI (String) : the XSD, DTD file URI to bind with the DOM
- * document.
- *
binding type (String) : which can takes values "standard", "xml-model" to
- * know which binding type must be inserted in the DOM document.
- *
- *
- * @author Angelo ZERR
- *
- */
-public class AssociateGrammarCommand extends AbstractDOMDocumentCommandHandler {
-
- public static final String COMMAND_ID = "xml.associate.grammar.insert";
-
- public AssociateGrammarCommand(IXMLDocumentProvider documentProvider) {
- super(documentProvider);
- }
-
- public enum GrammarBindingType {
-
- STANDARD("standard"), // xsi:schemaLocation, xsi:noNamespaceSchemaLocation, DOCTYPE
- XML_MODEL("xml-model"); // xml-model processing instruction
-
- private String name;
-
- private GrammarBindingType(String name) {
- this.name = name != null ? name : name();
- }
-
- public String getName() {
- return name;
- }
- }
-
- @SuppressWarnings({ "serial" })
- public static class UnknownBindingTypeException extends Exception {
-
- private final static String MESSAGE = "Unknown binding type ''{0}''. Allowed values are " + //
- Stream.of(GrammarBindingType.values()) //
- .map(GrammarBindingType::getName) //
- .collect(Collectors.joining(", ", "[", "]"));
-
- public UnknownBindingTypeException(String bindingType) {
- super(MessageFormat.format(MESSAGE, bindingType));
- }
-
- }
-
- @Override
- protected Object executeCommand(DOMDocument document, ExecuteCommandParams params, SharedSettings sharedSettings,
- CancelChecker cancelChecker) throws Exception {
- String documentURI = document.getDocumentURI();
- String fullPathGrammarURI = ArgumentsUtils.getArgAt(params, 1, String.class);
- String bindingType = ArgumentsUtils.getArgAt(params, 2, String.class);
- String grammarURI = getRelativeURI(fullPathGrammarURI, documentURI);
- boolean isXSD = DOMUtils.isXSD(fullPathGrammarURI);
-
- if (GrammarBindingType.STANDARD.getName().equals(bindingType)) {
- if (isXSD) {
- // XSD file
- // Check if XSD to bind declares a target namespace
- String targetNamespace = getTargetNamespace(fullPathGrammarURI);
- if (StringUtils.isEmpty(targetNamespace)) {
- // Insert inside ->
- // xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance"
- // xsi:noNamespaceSchemaLocation=\"xsd/tag.xsd\"
- return NoGrammarConstraintsCodeAction.createXSINoNamespaceSchemaLocationEdit(grammarURI, document);
- }
- // Insert inside ->
- // xmlns="team_namespace"
- // xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- // xsi:schemaLocation="team_namespace xsd/team.xsd"
- return NoGrammarConstraintsCodeAction.createXSISchemaLocationEdit(grammarURI, targetNamespace,
- document);
- } else {
- // DTD file
- // Insert before ->
- return NoGrammarConstraintsCodeAction.createDocTypeEdit(grammarURI, document, sharedSettings);
- }
- } else if (GrammarBindingType.XML_MODEL.getName().equals(bindingType)) {
- String targetNamespace = isXSD ? getTargetNamespace(fullPathGrammarURI) : null;
- // Insert before ->
- return NoGrammarConstraintsCodeAction.createXmlModelEdit(grammarURI, targetNamespace, document,
- sharedSettings);
- }
- throw new UnknownBindingTypeException(bindingType);
- }
-
- private static String getRelativeURI(String fullPathGrammarURI, String documentURI) {
- try {
- Path grammarPath = FilesUtils.getPath(fullPathGrammarURI);
- Path documentPath = FilesUtils.getPath(documentURI);
- Path relativePath = documentPath.getParent().relativize(grammarPath);
- return relativePath.toString().replaceAll("\\\\", "/");
- } catch (Exception e) {
- return fullPathGrammarURI;
- }
- }
-
- private static String getTargetNamespace(String xsdURI) {
- TargetNamespaceHandler handler = new TargetNamespaceHandler();
- try {
- SAXParserFactory factory = DOMUtils.newSAXParserFactory();
- SAXParser saxParser = factory.newSAXParser();
- saxParser.parse(new URL(xsdURI).openStream(), handler);
- } catch (Exception e) {
-
- }
- return handler.getTargetNamespace();
- }
-
- /**
- * SAX handler which extract the targetNamespace attribute from the xs:schema
- * root tag element and null otherwise.
- *
- */
- private static class TargetNamespaceHandler extends DefaultHandler {
-
- private String targetNamespace;
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attributes)
- throws SAXException {
- super.startElement(uri, localName, qName, attributes);
- this.targetNamespace = attributes.getValue(TARGET_NAMESPACE_ATTR);
- throw new SAXException();
- }
-
- public String getTargetNamespace() {
- return targetNamespace;
- }
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/CheckBoundGrammarCommand.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/CheckBoundGrammarCommand.java
deleted file mode 100644
index 32dae57c6..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/CheckBoundGrammarCommand.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*******************************************************************************
-* Copyright (c) 2021 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.contentmodel.commands;
-
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.dom.DOMElement;
-import org.eclipse.lemminx.services.IXMLDocumentProvider;
-import org.eclipse.lemminx.services.extensions.commands.AbstractDOMDocumentCommandHandler;
-import org.eclipse.lemminx.settings.SharedSettings;
-import org.eclipse.lsp4j.ExecuteCommandParams;
-import org.eclipse.lsp4j.jsonrpc.CancelChecker;
-
-/**
- * XML Command "xml.check.bound.grammar" to verify if an XML document already
- * has a bound grammar/schema, opened from the command palette.
- *
- */
-public class CheckBoundGrammarCommand extends AbstractDOMDocumentCommandHandler {
-
- public static final String COMMAND_ID = "xml.check.bound.grammar";
-
- public CheckBoundGrammarCommand(IXMLDocumentProvider documentProvider) {
- super(documentProvider);
- }
-
- @Override
- protected Object executeCommand(DOMDocument document, ExecuteCommandParams params, SharedSettings sharedSettings,
- CancelChecker cancelChecker) throws Exception {
- // Check if the document has a bound grammar.
- return canBindWithGrammar(document);
- }
-
- /**
- * Returns true if the given DOM document can be bound with a given grammar and
- * false otherwise.
- *
- * @param document the DOM document.
- *
- * @return true if the given DOM document can be bound with a given grammar and
- * false otherwise.
- */
- public static boolean canBindWithGrammar(DOMDocument document) {
- DOMElement documentElement = document.getDocumentElement();
- if (documentElement == null) {
- return false;
- }
- return !document.hasGrammar();
- }
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/CheckFilePatternCommand.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/CheckFilePatternCommand.java
deleted file mode 100644
index 13a67b789..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/CheckFilePatternCommand.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
-* Copyright (c) 2021 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.contentmodel.commands;
-
-import org.eclipse.lemminx.services.extensions.commands.ArgumentsUtils;
-import org.eclipse.lemminx.services.extensions.commands.IXMLCommandService.IDelegateCommandHandler;
-import org.eclipse.lemminx.settings.PathPatternMatcher;
-import org.eclipse.lemminx.settings.SharedSettings;
-import org.eclipse.lsp4j.ExecuteCommandParams;
-import org.eclipse.lsp4j.jsonrpc.CancelChecker;
-
-/**
- * XML Command "xml.check.file.pattern" whose first argument is a file pattern,
- * and whose second argument is some file URI. The command returns true when
- * the given pattern matches against the given file URI and false otherwise.
- */
-public class CheckFilePatternCommand implements IDelegateCommandHandler {
-
- public static final String COMMAND_ID = "xml.check.file.pattern";
-
- @Override
- public Object executeCommand(ExecuteCommandParams params, SharedSettings sharedSettings,
- CancelChecker cancelChecker) throws Exception {
- String pattern = ArgumentsUtils.getArgAt(params, 0, String.class);
- String currentUri = ArgumentsUtils.getArgAt(params, 1, String.class);
- PathPatternMatcher matcher = new PathPatternMatcher();
- matcher.setPattern(pattern);
- return matcher.matches(currentUri);
- }
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/XMLValidationAllFilesCommand.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/XMLValidationAllFilesCommand.java
deleted file mode 100644
index b5a7e694d..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/XMLValidationAllFilesCommand.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
-* 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.contentmodel.commands;
-
-import java.util.Collection;
-
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
-import org.eclipse.lemminx.services.IXMLDocumentProvider;
-import org.eclipse.lemminx.services.IXMLValidationService;
-import org.eclipse.lemminx.services.extensions.commands.IXMLCommandService.IDelegateCommandHandler;
-import org.eclipse.lemminx.settings.SharedSettings;
-import org.eclipse.lsp4j.ExecuteCommandParams;
-import org.eclipse.lsp4j.jsonrpc.CancelChecker;
-
-/**
- * XML Command "xml.validation.all.files" to revalidate all opened XML files
- * which means:
- *
- *
- *
clear the Xerces grammar pool (used by the Xerces validation) and the
- * content model documents cache (used by the XML completion/hover based on the
- * grammar)
- *
trigger the validation for the all opened XML files
- *
- *
- * @author Angelo ZERR
- *
- */
-public class XMLValidationAllFilesCommand implements IDelegateCommandHandler {
-
- public static final String COMMAND_ID = "xml.validation.all.files";
-
- private final ContentModelManager contentModelManager;
-
- private final IXMLDocumentProvider documentProvider;
-
- private final IXMLValidationService validationService;
-
- public XMLValidationAllFilesCommand(ContentModelManager contentModelManager, IXMLDocumentProvider documentProvider,
- IXMLValidationService validationService) {
- this.contentModelManager = contentModelManager;
- this.documentProvider = documentProvider;
- this.validationService = validationService;
- }
-
- @Override
- public Object executeCommand(ExecuteCommandParams params, SharedSettings sharedSettings,
- CancelChecker cancelChecker) throws Exception {
- // 1. clear the Xerces grammar pool
- // (used by the Xerces validation) and the content model documents cache (used
- // by the XML completion/hover based on the grammar)
- contentModelManager.evictCache();
- // 2. trigger the validation for the all opened XML files
- Collection all = documentProvider.getAllDocuments();
- for (DOMDocument document : all) {
- validationService.validate(document);
- }
- return null;
- }
-
-}
\ No newline at end of file
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/XMLValidationFileCommand.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/XMLValidationFileCommand.java
deleted file mode 100644
index 3c9b07e1b..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/commands/XMLValidationFileCommand.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
-* 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.contentmodel.commands;
-
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
-import org.eclipse.lemminx.services.IXMLDocumentProvider;
-import org.eclipse.lemminx.services.IXMLValidationService;
-import org.eclipse.lemminx.services.extensions.commands.AbstractDOMDocumentCommandHandler;
-import org.eclipse.lemminx.settings.SharedSettings;
-import org.eclipse.lsp4j.ExecuteCommandParams;
-import org.eclipse.lsp4j.jsonrpc.CancelChecker;
-
-/**
- * XML Command "xml.validation.current.file" to revalidate a give XML file which
- * means:
- *
- *
- *
remove the referenced grammar in the XML file from the Xerces grammar
- * pool (used by the Xerces validation) and the content model documents cache
- * (used by the XML completion/hover based on the grammar)
- *
trigger the validation for the given XML file
- *
- *
- * @author Angelo ZERR
- *
- */
-public class XMLValidationFileCommand extends AbstractDOMDocumentCommandHandler {
-
- public static final String COMMAND_ID = "xml.validation.current.file";
-
- private final ContentModelManager contentModelManager;
-
- private final IXMLValidationService validationService;
-
- public XMLValidationFileCommand(ContentModelManager contentModelManager, IXMLDocumentProvider documentProvider,
- IXMLValidationService validationService) {
- super(documentProvider);
- this.contentModelManager = contentModelManager;
- this.validationService = validationService;
- }
-
- @Override
- protected Object executeCommand(DOMDocument document, ExecuteCommandParams params, SharedSettings sharedSettings,
- CancelChecker cancelChecker) throws Exception {
- // 1. remove the referenced grammar in the XML file from the Xerces grammar pool
- // (used by the Xerces validation) and the content model documents cache (used
- // by the XML completion/hover based on the grammar)
- contentModelManager.evictCacheFor(document);
- // 2. trigger the validation for the given XML file
- validationService.validate(document);
- return null;
- }
-
-}
\ No newline at end of file
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/CMAttributeDeclaration.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/CMAttributeDeclaration.java
deleted file mode 100644
index 56a322083..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/CMAttributeDeclaration.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.contentmodel.model;
-
-import java.util.Collection;
-
-import org.eclipse.lemminx.services.extensions.ISharedSettingsRequest;
-
-/**
- * Content model element which abstracts attribute declaration from a given
- * grammar (XML Schema, DTD).
- */
-public interface CMAttributeDeclaration {
-
- /**
- * Returns the declared element name.
- *
- * @return the declared element name.
- */
- String getName();
-
- String getDefaultValue();
-
- Collection getEnumerationValues();
-
- /**
- * Returns formatted documentation of the declared
- * attribute according to settings defined in request
- *
- * @param request the request that contains settings
- * @return formatted documentation of the declared
- * attribute according to settings defined in request
- */
- String getAttributeNameDocumentation(ISharedSettingsRequest request);
-
- /**
- * Returns formatted documentation about value,
- * according to settings defined in request
- *
- * @param value the attribute value to find documentation for
- * @param request the request containing settings
- * @return formatted documentation about value,
- * according to settings defined in request
- */
- String getAttributeValueDocumentation(String value, ISharedSettingsRequest request);
-
- /**
- * Returns true if the attribute is required and false otherwise.
- *
- * @return true if the attribute is required and false otherwise.
- */
- boolean isRequired();
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/CMDocument.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/CMDocument.java
deleted file mode 100644
index f514d134e..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/CMDocument.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.contentmodel.model;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.lemminx.dom.DOMElement;
-import org.eclipse.lemminx.dom.DOMNode;
-import org.eclipse.lsp4j.LocationLink;
-import org.w3c.dom.Entity;
-
-/**
- * Content model document which abstracts element declaration from a given
- * grammar (XML Schema, DTD).
- */
-public interface CMDocument {
-
- /**
- * Returns true if the model document defines the given namespace and false
- * otherwise.
- *
- * @param namespaceURI
- * @return true if the model document defines the given namespace and false
- * otherwise.
- */
- boolean hasNamespace(String namespaceURI);
-
- /**
- * Returns the elements declaration of the model document root.
- *
- * @return the elements declaration of the model document root.
- */
- Collection getElements();
-
- /**
- * Returns the declared element which matches the given XML element and null
- * otherwise.
- *
- * @param element the XML element
- * @return the declared element which matches the given XML element and null
- * otherwise.
- */
- default CMElementDeclaration findCMElement(DOMElement element) {
- return findCMElement(element, element.getNamespaceURI());
- }
-
- /**
- * Returns the declared element which matches the given XML element and null
- * otherwise.
- *
- * @param element the XML element
- * @param namespace the given namespace
- * @return the declared element which matches the given XML element and null
- * otherwise.
- */
- CMElementDeclaration findCMElement(DOMElement element, String namespace);
-
- default CMAttributeDeclaration findCMAttribute(DOMElement element, String attributeName) {
- CMElementDeclaration elementDeclaration = findCMElement(element);
- return elementDeclaration != null ? elementDeclaration.findCMAttribute(attributeName) : null;
- }
-
- /**
- * Returns the location of the type definition of the given node.
- *
- * @param node the node
- * @return the location of the type definition of the given node.
- */
- LocationLink findTypeLocation(DOMNode node);
-
- /**
- * Returns true if the content model document is dirty and false otherwise.
- *
- * @return true if the content model document is dirty and false otherwise.
- */
- boolean isDirty();
-
- /**
- * Returns list of declared entities.
- *
- * @return list of declared entities.
- */
- default List getEntities() {
- return Collections.emptyList();
- }
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/CMElementDeclaration.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/CMElementDeclaration.java
deleted file mode 100644
index 91df3937e..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/CMElementDeclaration.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.contentmodel.model;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-
-import org.eclipse.lemminx.dom.DOMElement;
-import org.eclipse.lemminx.services.extensions.ISharedSettingsRequest;
-
-/**
- * Content model element which abstracts element declaration from a given
- * grammar (XML Schema, DTD).
- */
-public interface CMElementDeclaration {
-
- public static final Collection ANY_ELEMENT_DECLARATIONS = Collections
- .unmodifiableCollection(Arrays.asList());
-
- /**
- * Returns the declared element name.
- *
- * @return the declared element name.
- */
- String getName();
-
- /**
- * Returns the target namespace and null otherwise.
- *
- * @return the target namespace and null otherwise.
- */
- String getNamespace();
-
- /**
- * Returns the declared element name with the given prefix.
- *
- * @return the declared element name with the given prefix.
- */
- default String getName(String prefix) {
- String name = getName();
- if (prefix == null || prefix.isEmpty()) {
- return name;
- }
- return prefix + ":" + name;
- }
-
- /**
- * Returns the attributes of this declared element.
- *
- * @return the attributes element of this declared element.
- */
- Collection getAttributes();
-
- /**
- * Returns the children declared element of this declared element.
- *
- * @return the children declared element of this declared element.
- */
- Collection getElements();
-
- /**
- * Returns the possible declared elements at the given offset of the given
- * parent element.
- *
- * @param parentElement the parent element
- * @param offset the offset
- * @return the possible declared elements at the given offset of the given
- * parent element.
- */
- Collection getPossibleElements(DOMElement parentElement, int offset);
-
- /**
- * Returns the declared element which matches the given XML tag name / namespace
- * and null otherwise.
- *
- * @param tag
- * @param namespace
- * @return the declared element which matches the given XML tag name / namespace
- * and null otherwise.
- */
- CMElementDeclaration findCMElement(String tag, String namespace);
-
- /**
- * Returns the declared attribute which match the given name and null otherwise.
- *
- * @param attributeName
- * @return the declared attribute which match the given name and null otherwise.
- */
- CMAttributeDeclaration findCMAttribute(String attributeName);
-
- /**
- * Returns formatted documentation of the declared element, according to
- * settings defined in request.
- *
- * @param request the request containing settings
- * @return formatted documentation of the declared element, according to
- * settings defined in request.
- */
- String getDocumentation(ISharedSettingsRequest request);
-
- /**
- * Returns true if the element cannot contains element children or text content
- * and false otherwise.
- *
- * @return true if the element cannot contains element children or text content
- * and false otherwise.
- */
- boolean isEmpty();
-
- /**
- * Return the enumeration values.
- *
- * @return the enumeration values.
- */
- Collection getEnumerationValues();
-
- /**
- * Returns the documentation for the given enumeration value and null otherwise.
- *
- * @param value the enumeration value.
- * @param request the shared settings.
- *
- * @return the documentation for the given enumeration value and null otherwise.
- */
- String getTextDocumentation(String value, ISharedSettingsRequest request);
-
- /**
- * Returns the owner document URI where the element is declared.
- *
- * @return the owner document URI where the element is declared.
- */
- String getDocumentURI();
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/ContentModelManager.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/ContentModelManager.java
deleted file mode 100644
index 02ebc0f59..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/ContentModelManager.java
+++ /dev/null
@@ -1,477 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.contentmodel.model;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.xerces.xni.grammars.XMLGrammarPool;
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.dom.DOMElement;
-import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelProvider.Identifier;
-import org.eclipse.lemminx.extensions.contentmodel.participants.diagnostics.LSPXMLGrammarPool;
-import org.eclipse.lemminx.extensions.contentmodel.settings.XMLFileAssociation;
-import org.eclipse.lemminx.extensions.contentmodel.uriresolver.XMLCacheResolverExtension;
-import org.eclipse.lemminx.extensions.contentmodel.uriresolver.XMLCatalogResolverExtension;
-import org.eclipse.lemminx.extensions.contentmodel.uriresolver.XMLFileAssociationResolverExtension;
-import org.eclipse.lemminx.uriresolver.CacheResourceDownloadingException;
-import org.eclipse.lemminx.uriresolver.CacheResourcesManager;
-import org.eclipse.lemminx.uriresolver.ResolvedURIInfo;
-import org.eclipse.lemminx.uriresolver.URIResolverExtensionManager;
-import org.eclipse.lemminx.utils.FilesUtils;
-import org.eclipse.lemminx.utils.StringUtils;
-import org.eclipse.lemminx.utils.URIUtils;
-
-/**
- * Content model manager used to load XML Schema, DTD.
- *
- */
-public class ContentModelManager {
-
- private final Map cmDocumentCache;
-
- private final URIResolverExtensionManager resolverManager;
- private final List modelProviders;
-
- private final XMLCacheResolverExtension cacheResolverExtension;
- private final XMLCatalogResolverExtension catalogResolverExtension;
- private final XMLFileAssociationResolverExtension fileAssociationResolver;
- private final XMLGrammarPool grammarPool;
-
- public ContentModelManager(URIResolverExtensionManager resolverManager) {
- this.resolverManager = resolverManager;
- modelProviders = new ArrayList<>();
- cmDocumentCache = Collections.synchronizedMap(new HashMap<>());
- fileAssociationResolver = new XMLFileAssociationResolverExtension();
- resolverManager.registerResolver(fileAssociationResolver);
- catalogResolverExtension = new XMLCatalogResolverExtension();
- resolverManager.registerResolver(catalogResolverExtension);
- cacheResolverExtension = new XMLCacheResolverExtension();
- resolverManager.registerResolver(cacheResolverExtension);
- grammarPool = new LSPXMLGrammarPool();
- // Use cache by default
- setUseCache(true);
- }
-
- /**
- * Returns the owner document of the declared element which matches the given
- * XML element and null otherwise.
- *
- * @param element the XML element
- *
- * @return the owner document of the declared element which matches the given
- * XML element and null otherwise.
- */
- public Collection findCMDocument(DOMElement element) {
- return findCMDocument(element.getOwnerDocument(), element.getNamespaceURI());
- }
-
- /**
- * Returns the owner document of the declared element which matches the given
- * XML element and null otherwise.
- *
- * @param element the XML element
- *
- * @return the owner document of the declared element which matches the given
- * XML element and null otherwise.
- */
- public Collection findCMDocument(DOMElement element, String namespaceURI) {
- return findCMDocument(element.getOwnerDocument(), namespaceURI);
- }
-
- public Collection findCMDocument(DOMDocument xmlDocument, String namespaceURI) {
- return findCMDocument(xmlDocument, namespaceURI, true);
- }
-
- /**
- * Returns the declared documents which match the given DOM document.
- *
- * @param xmlDocument the DOM document.
- * @param namespaceURI the namespace URI
- * @return the declared documents which match the given DOM document.
- */
- public Collection findCMDocument(DOMDocument xmlDocument, String namespaceURI, boolean withInternal) {
- if (namespaceURI == null) {
- // This case comes from when an element has no namespace and XML Schema defines
- // elementFormDefault="unqualified"
- // --> we use the namespace from the DOM document
-
- // ex: XSD:
- //
- // --> here template has a null namespace and the DOM document has
- // "urn:reports/itops" namespace
- // --> we use urn:reports/itops as namespace to get the DOM Document
- namespaceURI = xmlDocument.getNamespaceURI();
- }
- Collection documents = new ArrayList<>();
- for (ContentModelProvider modelProvider : modelProviders) {
- // internal grammar
- if (withInternal) {
- CMDocument internalCMDocument = modelProvider.createInternalCMDocument(xmlDocument);
- if (internalCMDocument != null) {
- documents.add(internalCMDocument);
- }
- }
- // external grammar
- if (modelProvider.adaptFor(xmlDocument, false)) {
- // The content model provider can collect the system ids
- // ex for identifiers = modelProvider.getIdentifiers(xmlDocument, namespaceURI);
- for (Identifier identifier : identifiers) {
- String systemId = identifier.getSystemId();
- String publicId = identifier.getPublicId() != null ? identifier.getPublicId() : namespaceURI;
- // get the content model document from the current system id
- CMDocument cmDocument = findCMDocument(xmlDocument.getDocumentURI(), publicId, systemId,
- modelProvider);
- if (cmDocument != null) {
- documents.add(cmDocument);
- }
- }
- }
- }
- if (documents.isEmpty()) {
- CMDocument cmDocument = findCMDocument(xmlDocument.getDocumentURI(), namespaceURI, null, null);
- if (cmDocument != null) {
- documents.add(cmDocument);
- }
- }
- return documents;
- }
-
- /**
- * Returns true if the given document is linked to the given grammar URI (XML
- * Schema, DTD) and false otherwise.
- *
- * @param document the DOM document
- * @param grammarURI the grammar URI
- * @return true if the given document is linked to the given grammar URI (XML
- * Schema, DTD) and false otherwise.
- */
- public boolean dependsOnGrammar(DOMDocument document, String grammarURI) {
- if (StringUtils.isEmpty(grammarURI)) {
- return false;
- }
- for (ContentModelProvider modelProvider : modelProviders) {
- if (modelProvider.adaptFor(document, false)) {
- Collection identifiers = modelProvider.getIdentifiers(document, document.getNamespaceURI());
- for (Identifier identifier : identifiers) {
- String publicId = identifier.getPublicId();
- String systemId = identifier.getSystemId();
- String key = resolverManager.resolve(document.getDocumentURI(), publicId, systemId);
- if (grammarURI.equals(key)) {
- return true;
- }
- }
- }
- }
- String key = resolverManager.resolve(document.getDocumentURI(), null, null);
- return grammarURI.equals(key);
- }
-
- /**
- * Returns informations about all referenced grammar (XSD, DTD) from the given
- * DOM document.
- *
- *
- * In other words, it gives information about
- *
- *
- *
which XSD, DTD files are bound to the DOM document.
- *
which binding strategies are used (catalog, file association,
- * xsi:schemaLocation, xsi:noNamespaceSchemaLocation, DOCTYPE).
- *
the cache file path (for remote grammar with http://)
- *
- *
- *
- * @param document the DOM document.
- *
- * @return informations about all referenced grammar (XSD, DTD) from the given
- * DOM document.
- */
- public Set getReferencedGrammarInfos(DOMDocument document) {
- Set referencedGrammarInfos = new LinkedHashSet<>();
- for (ContentModelProvider modelProvider : modelProviders) {
- if (modelProvider.adaptFor(document, false)) {
- Collection identifiers = modelProvider.getIdentifiers(document, null);
- for (Identifier identifier : identifiers) {
- String publicId = identifier.getPublicId();
- String systemId = identifier.getSystemId();
- fillReferencedGrammarInfo(document, publicId, systemId, identifier, referencedGrammarInfos);
- }
- }
- }
- fillReferencedGrammarInfo(document, document.getNamespaceURI(), null, null, referencedGrammarInfos);
- return referencedGrammarInfos;
- }
-
- private void fillReferencedGrammarInfo(DOMDocument document, String publicId, String systemId,
- Identifier identifier, Set referencedGrammarInfos) {
- ResolvedURIInfo resolvedURIInfo = resolverManager.resolveInfo(document.getDocumentURI(), publicId, systemId);
- if (resolvedURIInfo != null) {
- GrammarCacheInfo grammarCacheInfo = null;
- String cachedResolvedUri = null;
- boolean downloading = false;
- Exception cacheError = null;
- String resolvedUri = resolvedURIInfo.getResolvedURI();
- if (cacheResolverExtension.canUseCache(resolvedUri)) {
- // The DTD/XML Schema comes from http://, ftp:// etc and cache manager is
- // activated
- // Try to load the DTD/XML Schema with the cache manager
- try {
- Path file = cacheResolverExtension.getCachedResource(resolvedUri);
- if (file != null) {
- cachedResolvedUri = file.toUri().toString();
- }
- } catch (CacheResourceDownloadingException e) {
- // the DTD/XML Schema is downloading
- downloading = true;
- } catch (Exception e) {
- // other error like network which is not available
- cacheError = e;
- } finally {
- if (cachedResolvedUri == null) {
- try {
- cachedResolvedUri = CacheResourcesManager.getResourceCachePath(resolvedUri).toUri()
- .toString();
- } catch (IOException e) {
- // should never occur
- }
- }
- }
- grammarCacheInfo = new GrammarCacheInfo(cachedResolvedUri, downloading, cacheError);
- }
- if (identifier == null) {
- identifier = new Identifier(publicId, systemId, null, null);
- }
- referencedGrammarInfos.add(new ReferencedGrammarInfo(resolvedURIInfo, grammarCacheInfo, identifier));
- }
- }
-
- /**
- * Returns the content model document loaded by the given uri and null
- * otherwise.
- *
- * @param publicId the public identifier.
- * @param systemId the expanded system identifier.
- * @param modelProvider
- * @return the content model document loaded by the given uri and null
- * otherwise.
- */
- private CMDocument findCMDocument(String uri, String publicId, String systemId,
- ContentModelProvider modelProvider) {
- // Resolve the XML Schema/DTD uri (file, http, etc)
- String resolvedUri = resolverManager.resolve(uri, publicId, systemId);
- if (resolvedUri == null) {
- return null;
- }
- // the XML Schema, DTD can be resolved
- if (modelProvider == null) {
- // the model provider cannot be get with standard mean (xsi:schemaLocation,
- // xsi:noNamespaceSchemaLocation, doctype)
- // try to get it by using extension (ex: .xsd, .dtd)
- modelProvider = getModelProviderByURI(resolvedUri);
- }
- if (modelProvider == null) {
- return null;
- }
- // Try to get the document from the cache
- CMDocument cmDocument = getCMDocumentFromCache(resolvedUri);
- if (cmDocument != null) {
- return cmDocument;
- }
- if (cacheResolverExtension.canUseCache(resolvedUri)) {
- // The DTD/XML Schema comes from http://, ftp:// etc and cache manager is
- // activated
- // Try to load the DTD/XML Schema with the cache manager
- try {
- Path file = cacheResolverExtension.getCachedResource(resolvedUri);
- if (file != null) {
- cmDocument = modelProvider.createCMDocument(file.toUri().toString());
- }
- } catch (CacheResourceDownloadingException e) {
- // the DTD/XML Schema is downloading
- return null;
- } catch (Exception e) {
- // other error like network which is not available
- cmDocument = modelProvider.createCMDocument(resolvedUri);
- }
- } else {
- cmDocument = modelProvider.createCMDocument(resolvedUri);
- }
- // Cache the document
- if (cmDocument != null) {
- cache(resolvedUri, cmDocument);
- }
- return cmDocument;
- }
-
- private CMDocument getCMDocumentFromCache(String key) {
- CMDocument document = null;
- synchronized (cmDocumentCache) {
- document = cmDocumentCache.get(key);
- if (document != null && document.isDirty()) {
- cmDocumentCache.remove(key);
- return null;
- }
- }
- return document;
- }
-
- private void cache(String key, CMDocument cmDocument) {
- synchronized (cmDocumentCache) {
- cmDocumentCache.put(key, cmDocument);
- }
- }
-
- /**
- * Returns the model provider by the given uri and null otherwise.
- *
- * @param uri the grammar URI
- *
- * @return the model provider by the given uri and null otherwise.
- */
- public ContentModelProvider getModelProviderByURI(String uri) {
- for (ContentModelProvider modelProvider : modelProviders) {
- if (modelProvider.adaptFor(uri)) {
- return modelProvider;
- }
- }
- return null;
- }
-
- /**
- * Set up XML catalogs.
- *
- * @param catalogs list of XML catalog files.
- * @return true if catalogs changed and false otherwise
- */
- public boolean setCatalogs(String[] catalogs) {
- return catalogResolverExtension.setCatalogs(catalogs);
- }
-
- /**
- * Refresh the XML catalogs.
- */
- public void refreshCatalogs() {
- catalogResolverExtension.refreshCatalogs();
- }
-
- /**
- * Set file associations.
- *
- * @param fileAssociations
- * @return true if file associations changed and false otherwise
- */
- public boolean setFileAssociations(XMLFileAssociation[] fileAssociations) {
- return this.fileAssociationResolver.setFileAssociations(fileAssociations);
- }
-
- public void setRootURI(String rootUri) {
- rootUri = URIUtils.sanitizingUri(rootUri);
- fileAssociationResolver.setRootUri(rootUri);
- catalogResolverExtension.setRootUri(rootUri);
- }
-
- public void setUseCache(boolean useCache) {
- cacheResolverExtension.setUseCache(useCache);
- if (!useCache) {
- grammarPool.clear();
- }
- }
-
- /**
- * Remove the referenced grammar from the given document and clear the Xerces
- * grammar cache which stores the XSD, DTD grammar.
- *
- * @param document the DOM document
- *
- * @throws IOException if the delete of grammar file cannot be done.
- */
- public void evictCacheFor(DOMDocument document) throws IOException {
- // Get the referenced grammars
- Set referencedGrammarInfos = getReferencedGrammarInfos(document);
- if (referencedGrammarInfos.isEmpty()) {
- return;
- }
- // Loop for each referenced grammars and deleted the XSD, DTD file if it is in
- // the lemminx cache.
- int nbDeletedFiles = 0;
- try {
- for (ReferencedGrammarInfo referencedGrammarInfo : referencedGrammarInfos) {
- if (referencedGrammarInfo.isInCache()) {
- // Delete XSD/DTD file
- String resolvedURI = referencedGrammarInfo.getGrammarCacheInfo().getCachedResolvedUri();
- Files.deleteIfExists(FilesUtils.getPath(resolvedURI));
- // remove the XSD/DTD content model document from the cache.
- cmDocumentCache.remove(resolvedURI);
- nbDeletedFiles++;
- }
- // TODO : get XSD, DTD dependencies from the current referenced grammar to
- // delete the file too.
- }
- } finally {
- if (nbDeletedFiles > 0) {
- // TODO : clear only the DTD, XSD which has been deleted from the cache.
- grammarPool.clear();
- }
- }
- }
-
- /**
- * Remove the cache directory (.lemminx/cache) if it exists and clear the Xerces
- * grammar cache which stores the XSD, DTD grammars.
- *
- * @throws IOException if the delete of directory (.lemminx/cache) cannot be
- * done.
- */
- public void evictCache() throws IOException {
- try {
- cacheResolverExtension.evictCache();
- } finally {
- // clear Xerces cache
- grammarPool.clear();
- // clear the XSD/DTD content model documents.
- cmDocumentCache.clear();
- }
-
- }
-
- public void registerModelProvider(ContentModelProvider modelProvider) {
- modelProviders.add(modelProvider);
- }
-
- public void unregisterModelProvider(ContentModelProvider modelProvider) {
- modelProviders.remove(modelProvider);
- }
-
- public XMLGrammarPool getGrammarPool() {
- return cacheResolverExtension.isUseCache() ? grammarPool : null;
- }
-
-}
\ No newline at end of file
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/ContentModelProvider.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/ContentModelProvider.java
deleted file mode 100644
index d2d945085..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/ContentModelProvider.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.contentmodel.model;
-
-import java.util.Collection;
-
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.dom.DOMRange;
-
-/**
- * Content model provider API.
- *
- */
-public interface ContentModelProvider {
-
- public class Identifier {
-
- private final String publicId;
-
- private final String systemId;
-
- private final DOMRange range;
-
- private final String kind;
-
- public Identifier(String publicId, String systemId, DOMRange range, String kind) {
- this.publicId = publicId;
- this.systemId = systemId;
- this.range = range;
- this.kind = kind;
- }
-
- public String getPublicId() {
- return publicId;
- }
-
- public String getSystemId() {
- return systemId;
- }
-
- public DOMRange getRange() {
- return range;
- }
-
- public String getKind() {
- return kind;
- }
-
- }
-
- /**
- * Returns the content model provider by using standard association
- * (xsi:schemaLocation, xsi:noNamespaceSchemaLocation, doctype) and null
- * otherwise.
- *
- * @param document
- * @param internal
- * @return the content model provider by using standard association
- * (xsi:schemaLocation, xsi:noNamespaceSchemaLocation, doctype) and null
- * otherwise.
- */
- boolean adaptFor(DOMDocument document, boolean internal);
-
- boolean adaptFor(String uri);
-
- Collection getIdentifiers(DOMDocument xmlDocument, String namespaceURI);
-
- CMDocument createCMDocument(String key);
-
- CMDocument createInternalCMDocument(DOMDocument xmlDocument);
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/FilesChangedTracker.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/FilesChangedTracker.java
deleted file mode 100644
index b331dad9d..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/FilesChangedTracker.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*******************************************************************************
-* Copyright (c) 2019 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.contentmodel.model;
-
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.attribute.FileTime;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * File changed tracker.
- *
- * @author Angelo ZERR
- *
- */
-public class FilesChangedTracker {
-
- private static final Logger LOGGER = Logger.getLogger(FilesChangedTracker.class.getName());
-
- private static class FileChangedTracker {
-
- private final Path file;
- private FileTime lastModified;
-
- public FileChangedTracker(Path file) {
- this.file = file;
- if (Files.exists(file)) {
- try {
- lastModified = Files.getLastModifiedTime(file);
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, "Get last modified time failed", e);
- }
- }
- }
-
- public boolean isDirty() {
- try {
- if (!Files.exists(file)) {
- // This case occurs when user delete the XML Schema / DTD file
- return true;
- }
- FileTime currentLastModified = Files.getLastModifiedTime(file);
- if (!currentLastModified.equals(lastModified)) {
- lastModified = currentLastModified;
- return true;
- }
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, "Get last modified time failed", e);
- return true;
- }
- return false;
- }
-
- }
-
- private final List files;
-
- public FilesChangedTracker() {
- files = new ArrayList<>();
- }
-
- /**
- * Add file URI to track
- *
- * @param fileURI
- */
- public void addFileURI(String fileURI) {
- try {
- addFileURI(new URI(fileURI));
- } catch (URISyntaxException e) {
- LOGGER.log(Level.SEVERE, "Add file URI to track failed", e);
- }
- }
-
- /**
- * Add file URI to track
- *
- * @param fileURI
- */
- public void addFileURI(URI fileURI) {
- files.add(new FileChangedTracker(Paths.get(fileURI)));
- }
-
- /**
- * Returns true if one file has changed and false otherwise.
- *
- * @return true if one file has changed and false otherwise.
- */
- public boolean isDirty() {
- for (FileChangedTracker dirtyFile : files) {
- if (dirtyFile.isDirty()) {
- return true;
- }
- }
- return false;
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/GrammarCacheInfo.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/GrammarCacheInfo.java
deleted file mode 100644
index 054662a6f..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/GrammarCacheInfo.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*******************************************************************************
-* 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.contentmodel.model;
-
-/**
- * Grammar cache information.
- */
-public class GrammarCacheInfo {
-
- private final String cachedResolvedUri;
- private final boolean downloading;
- private final Exception cacheError;
-
- public GrammarCacheInfo(String cachedResolvedUri, boolean downloading, Exception cacheError) {
- super();
- this.cachedResolvedUri = cachedResolvedUri;
- this.downloading = downloading;
- this.cacheError = cacheError;
- }
-
- /**
- * Returns the file path cache.
- *
- * @return the file path cache.
- */
- public String getCachedResolvedUri() {
- return cachedResolvedUri;
- }
-
- /**
- * Returns true if the grammar is downloading and false otherwise.
- *
- * @return true if the grammar is downloading and false otherwise.
- */
- public boolean isDownloading() {
- return downloading;
- }
-
- /**
- * Returns the error while downloading and null otherwise.
- *
- * @return the error while downloading and null otherwise.
- */
- public Exception getCacheError() {
- return cacheError;
- }
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/ReferencedGrammarInfo.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/ReferencedGrammarInfo.java
deleted file mode 100644
index 4ae33c28a..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/model/ReferencedGrammarInfo.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*******************************************************************************
-* 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.contentmodel.model;
-
-import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelProvider.Identifier;
-import org.eclipse.lemminx.uriresolver.ResolvedURIInfo;
-import org.eclipse.lemminx.uriresolver.URIResolverExtension;
-
-/**
- * Class which holds a referenced grammar information.
- *
- *
- * In other words, it gives information about
- *
- *
- *
which XSD, DTD file is bound to the DOM document.
- *
which binding strategies is used (catalog, file association,
- * xsi:schemaLocation, xsi:noNamespaceSchemaLocation, DOCTYPE).
- *
the cache file path (for remote grammar with http://)
- *
- *
- */
-public class ReferencedGrammarInfo {
-
- private final ResolvedURIInfo resolvedURIInfo;
- private final GrammarCacheInfo grammarCacheInfo;
-
- private final Identifier identifier;
-
- public ReferencedGrammarInfo(ResolvedURIInfo resolvedURIInfo, GrammarCacheInfo grammarCacheInfo,
- Identifier identifier) {
- this.resolvedURIInfo = resolvedURIInfo;
- this.grammarCacheInfo = grammarCacheInfo;
- this.identifier = identifier;
- }
-
- /**
- * Returns the resolved URI information (the result of the resolve and the
- * resolution strategy (ex : catalog, file association, etc)).
- *
- * @return the resolved URI information (the result of the resolve and the
- * resolution strategy
- */
- public ResolvedURIInfo getResolvedURIInfo() {
- return resolvedURIInfo;
- }
-
- /**
- * Returns the grammar cache information and null otherwise. (grammar is not a
- * remote grammar with http://)
- *
- * @return the grammar cache information and null otherwise.
- */
- public GrammarCacheInfo getGrammarCacheInfo() {
- return grammarCacheInfo;
- }
-
- /**
- * Returns the identifier (xml-model, xsi:schemaLocation,
- * xsi:noNamespaceSchemaLocation, DOCTYPE) and null otherwise.
- *
- * @return the identifier (xml-model, xsi:schemaLocation,
- * xsi:noNamespaceSchemaLocation, DOCTYPE) and null otherwise.
- */
- public Identifier getIdentifier() {
- return identifier;
- }
-
- /**
- * Returns true if the grammar is in the .lemminx cache and false otherwise.
- *
- * @return true if the grammar is in the .lemminx cache and false otherwise.
- */
- public boolean isInCache() {
- return grammarCacheInfo != null;
- }
-
- /**
- * Returns the system or public identifier URI and null otherwise.
- *
- * @return the system or public identifier URI and null otherwise.
- */
- public String getIdentifierURI() {
- if (identifier == null) {
- return null;
- }
- String publicId = identifier.getPublicId();
- String systemId = identifier.getSystemId();
- return publicId != null ? publicId : systemId;
- }
-
- /**
- * Returns the binding kind and null otherwise. Binding kind can have values:
- *
- *
- *
xsi:schemaLocation
- *
xsi:noNamespaceSchemaLocation
- *
doctype
- *
xml-model
- *
- *
- * @return the binding kind and null otherwise.
- */
- public String getBindingKind() {
- return identifier != null ? identifier.getKind() : null;
- }
-
- /**
- * Returns the resolver which is used to resolve the identifier URI and null
- * otherwise. Resolved by can have values:
- *
- *
- *
catalog
- *
file association
- *
embedded catalog.xsd
- *
embedded xml.xsd
- *
embedded xslt.xsd
- *
- *
- * @return the resolver which is used to resolve the identifier URI and null
- * otherwise.
- */
- public String getResolvedBy() {
- String resolvedBy = resolvedURIInfo != null ? resolvedURIInfo.getResolverName() : null;
- return URIResolverExtension.DEFAULT.equals(resolvedBy) ? null : resolvedBy;
- }
-
- /**
- * Returns the binding kind and resolved by label.
- *
- * @param info the referenced grammar information.
- *
- * @return the binding kind and resolved by label.
- */
- public static String getBindingKindAndResolvedBy(ReferencedGrammarInfo info) {
- StringBuilder bindingName = new StringBuilder();
- String bindingKind = info.getBindingKind();
- boolean hasKind = bindingKind != null;
- if (hasKind) {
- bindingName.append(bindingKind);
- }
- String resolverBy = info.getResolvedBy();
- if (resolverBy != null) {
- if (bindingName.length() > 0) {
- bindingName.append(" ");
- }
- bindingName.append("with ");
- bindingName.append(resolverBy);
- }
- return bindingName.toString();
- }
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/AggregateRelatedInfoFinder.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/AggregateRelatedInfoFinder.java
deleted file mode 100644
index c44e05a30..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/AggregateRelatedInfoFinder.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*******************************************************************************
-* Copyright (c) 2021 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
-*
-* Contributors:
-* Red Hat Inc. - initial API and implementation
-*******************************************************************************/
-package org.eclipse.lemminx.extensions.contentmodel.participants;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lsp4j.DiagnosticRelatedInformation;
-
-/**
- * Finds related info for any error code
- */
-public class AggregateRelatedInfoFinder implements IRelatedInfoFinder {
-
- private static IRelatedInfoFinder[] RELATED_INFO_FINDERS = {
- new XMLSyntaxRelatedInfoFinder()
- };
-
- private static AggregateRelatedInfoFinder INSTANCE = null;
-
- private AggregateRelatedInfoFinder() {}
-
- public static AggregateRelatedInfoFinder getInstance() {
- if (INSTANCE == null) {
- INSTANCE = new AggregateRelatedInfoFinder();
- }
- return INSTANCE;
- }
-
- @Override
- public List findRelatedInformation(
- int offset,
- String errorKey,
- DOMDocument document) {
- List relatedInfo = new ArrayList<>();
- for (IRelatedInfoFinder relatedInfoFinder : RELATED_INFO_FINDERS) {
- relatedInfo.addAll(relatedInfoFinder.findRelatedInformation(
- offset,
- errorKey,
- document
- ));
- }
- return relatedInfo;
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelCodeActionParticipant.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelCodeActionParticipant.java
deleted file mode 100644
index 72a25397e..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelCodeActionParticipant.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Copyright (c) 2018 Angelo ZERR
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.contentmodel.participants;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.extensions.xsd.participants.XSDErrorCode;
-import org.eclipse.lemminx.services.extensions.ICodeActionParticipant;
-import org.eclipse.lemminx.services.extensions.IComponentProvider;
-import org.eclipse.lemminx.settings.SharedSettings;
-import org.eclipse.lsp4j.CodeAction;
-import org.eclipse.lsp4j.Diagnostic;
-import org.eclipse.lsp4j.Range;
-
-/**
- * Extension to support XML code actions based on content model (XML Schema
- * completion, etc)
- */
-public class ContentModelCodeActionParticipant implements ICodeActionParticipant {
-
- private final Map codeActionParticipants;
-
- public ContentModelCodeActionParticipant() {
- codeActionParticipants = new HashMap<>();
- }
-
- @Override
- public void doCodeAction(Diagnostic diagnostic, Range range, DOMDocument document, List codeActions,
- SharedSettings sharedSettings, IComponentProvider componentProvider) {
- if (diagnostic == null || diagnostic.getCode() == null || !diagnostic.getCode().isLeft()) {
- return;
- }
- registerCodeActionsIfNeeded(sharedSettings);
- ICodeActionParticipant participant = codeActionParticipants.get(diagnostic.getCode().getLeft());
- if (participant != null) {
- participant.doCodeAction(diagnostic, range, document, codeActions, sharedSettings, componentProvider);
- }
- }
-
- /**
- * Register code action if needed.
- *
- * @param sharedSettings the shared settings.
- */
- private void registerCodeActionsIfNeeded(SharedSettings sharedSettings) {
- if (codeActionParticipants.isEmpty()) {
- synchronized (codeActionParticipants) {
- if (!codeActionParticipants.isEmpty()) {
- return;
- }
- XMLSyntaxErrorCode.registerCodeActionParticipants(codeActionParticipants, sharedSettings);
- DTDErrorCode.registerCodeActionParticipants(codeActionParticipants, sharedSettings);
- XMLSchemaErrorCode.registerCodeActionParticipants(codeActionParticipants, sharedSettings);
- XSDErrorCode.registerCodeActionParticipants(codeActionParticipants);
- }
- }
- }
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelCodeLensParticipant.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelCodeLensParticipant.java
deleted file mode 100644
index 384428a3a..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelCodeLensParticipant.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*******************************************************************************
-* Copyright (c) 2021 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.contentmodel.participants;
-
-import static org.eclipse.lemminx.client.ClientCommands.OPEN_BINDING_WIZARD;
-import static org.eclipse.lemminx.client.ClientCommands.OPEN_URI;
-import static org.eclipse.lemminx.extensions.contentmodel.commands.CheckBoundGrammarCommand.canBindWithGrammar;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.lemminx.client.CodeLensKind;
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.dom.DOMRange;
-import org.eclipse.lemminx.extensions.contentmodel.commands.AssociateGrammarCommand;
-import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
-import org.eclipse.lemminx.extensions.contentmodel.model.ReferencedGrammarInfo;
-import org.eclipse.lemminx.services.extensions.codelens.ICodeLensParticipant;
-import org.eclipse.lemminx.services.extensions.codelens.ICodeLensRequest;
-import org.eclipse.lemminx.utils.DOMUtils;
-import org.eclipse.lemminx.utils.StringUtils;
-import org.eclipse.lemminx.utils.XMLPositionUtility;
-import org.eclipse.lsp4j.CodeLens;
-import org.eclipse.lsp4j.Command;
-import org.eclipse.lsp4j.Range;
-import org.eclipse.lsp4j.TextDocumentEdit;
-import org.eclipse.lsp4j.jsonrpc.CancelChecker;
-
-/**
- * At first this participant is enabled only when LSP client can support the
- * client command "xml.open.binding.wizard" to open the wizard to bind a XML to
- * a grammar/schema.
- *
- * In this case, when XML file is not associated to a grammar/schema (DTD, XSD),
- * this class generates [Bind to grammar/schema...] CodeLens on the root of the
- * DOM Document:
- *
- * On client side, click on this Codelens should open a wizard:
- *
- *
- *
page1 : display a combo to select the binding type ("standard",
- * "xml-model").
- *
page2: open a file dialog to select the grammar/schema (XSD/DTD) to
- * bind.
- *
the finish wizard should consume the "xml.associate.grammar.insert"
- * command {@link AssociateGrammarCommand} to generate the proper syntax for
- * binding with following parameters:
- *
- *
the document uri.
- *
the selected grammar/schema file uri.
- *
the binding type.
- *
- * In other words the "xml.associate.grammar.insert" returns the
- * {@link TextDocumentEdit} which must be applied on the LSP client side.
- *
- *
- */
-public class ContentModelCodeLensParticipant implements ICodeLensParticipant {
-
- private final ContentModelManager contentModelManager;
-
- public ContentModelCodeLensParticipant(ContentModelManager contentModelManager) {
- this.contentModelManager = contentModelManager;
- }
-
- @Override
- public void doCodeLens(ICodeLensRequest request, List lenses, CancelChecker cancelChecker) {
- // List of referenced schema/grammar
- createReferencedGrammarLenses(request, lenses);
- // "Bind to grammar/schema..."
- createBindToGrammarSchemaLenses(request, lenses);
- }
-
- private void createReferencedGrammarLenses(ICodeLensRequest request, List lenses) {
- DOMDocument document = request.getDocument();
- if (!document.hasGrammar()) {
- return;
- }
-
- // The DOM document is bound with a schema/grammar, display the referenced
- // grammars as Codelens.
- boolean canSupportOpenUri = canSupportOpenUri(request);
- Range range = XMLPositionUtility.createRange((DOMRange) document.getFirstChild());
- range.setEnd(range.getStart());
- Set referencedGrammarInfos = contentModelManager.getReferencedGrammarInfos(document);
- for (ReferencedGrammarInfo info : referencedGrammarInfos) {
- lenses.add(createReferencedGrammarLens(info, range, canSupportOpenUri));
- }
- }
-
- private static boolean canSupportOpenUri(ICodeLensRequest request) {
- return request.isSupportedByClient(CodeLensKind.OpenUri);
- }
-
- private CodeLens createReferencedGrammarLens(ReferencedGrammarInfo info, Range range, boolean canSupportOpenUri) {
- String uri = info.getIdentifierURI();
- StringBuilder title = new StringBuilder(uri != null ? uri : "");
- String bindingKind = ReferencedGrammarInfo.getBindingKindAndResolvedBy(info);
- if (!StringUtils.isEmpty(bindingKind)) {
- title.append(" (");
- title.append(bindingKind);
- title.append(")");
- }
-
- String grammarURI = info.isInCache() ? info.getGrammarCacheInfo().getCachedResolvedUri() : null;
- if (grammarURI == null) {
- grammarURI = info.getResolvedURIInfo().getResolvedURI();
- }
- Command command = new Command(title.toString(), canSupportOpenUri ? OPEN_URI : "",
- canSupportOpenUri ? Arrays.asList(grammarURI) : null);
- return new CodeLens(range, command, null);
- }
-
- private static void createBindToGrammarSchemaLenses(ICodeLensRequest request, List lenses) {
- if (!canSupportAssociation(request)) {
- return;
- }
-
- // The LSP client can support Association, when DOM document is not bound to a
- // grammar, [Bind to grammar/schema...] CodeLens appears:
-
- // [Bind to grammar/schema...]
- //
-
- DOMDocument document = request.getDocument();
- if (!canBindWithGrammar(document)) {
- return;
- }
- String documentURI = document.getDocumentURI();
- Range range = XMLPositionUtility.selectRootStartTag(document);
-
- lenses.add(createAssociateLens(documentURI, "Bind to grammar/schema...", range));
- }
-
- private static boolean canSupportAssociation(ICodeLensRequest request) {
- if (!request.isSupportedByClient(CodeLensKind.Association)) {
- return false;
- }
- String uri = request.getDocument().getDocumentURI();
- return !DOMUtils.isXSD(uri) && !DOMUtils.isDTD(uri);
- }
-
- private static CodeLens createAssociateLens(String documentURI, String title, Range range) {
- Command command = new Command(title, OPEN_BINDING_WIZARD, Arrays.asList(documentURI));
- return new CodeLens(range, command, null);
- }
-
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelCompletionParticipant.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelCompletionParticipant.java
deleted file mode 100644
index c1d6f715c..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelCompletionParticipant.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/**
- * Copyright (c) 2018-2020 Angelo ZERR
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.contentmodel.participants;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.eclipse.lemminx.commons.BadLocationException;
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.dom.DOMElement;
-import org.eclipse.lemminx.dom.DOMNode;
-import org.eclipse.lemminx.extensions.contentmodel.model.CMAttributeDeclaration;
-import org.eclipse.lemminx.extensions.contentmodel.model.CMDocument;
-import org.eclipse.lemminx.extensions.contentmodel.model.CMElementDeclaration;
-import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
-import org.eclipse.lemminx.extensions.contentmodel.utils.XMLGenerator;
-import org.eclipse.lemminx.services.AttributeCompletionItem;
-import org.eclipse.lemminx.services.extensions.CompletionParticipantAdapter;
-import org.eclipse.lemminx.services.extensions.ICompletionRequest;
-import org.eclipse.lemminx.services.extensions.ICompletionResponse;
-import org.eclipse.lemminx.uriresolver.CacheResourceDownloadingException;
-import org.eclipse.lemminx.utils.StringUtils;
-import org.eclipse.lsp4j.CompletionItem;
-import org.eclipse.lsp4j.CompletionItemKind;
-import org.eclipse.lsp4j.InsertTextFormat;
-import org.eclipse.lsp4j.MarkupContent;
-import org.eclipse.lsp4j.Position;
-import org.eclipse.lsp4j.Range;
-import org.eclipse.lsp4j.TextEdit;
-import org.eclipse.lsp4j.jsonrpc.CancelChecker;
-import org.eclipse.lsp4j.jsonrpc.messages.Either;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Extension to support XML completion based on content model (XML Schema
- * completion, etc)
- */
-public class ContentModelCompletionParticipant extends CompletionParticipantAdapter {
-
- @Override
- public void onTagOpen(ICompletionRequest request, ICompletionResponse response, CancelChecker cancelChecker) throws Exception {
- try {
- DOMDocument document = request.getXMLDocument();
- ContentModelManager contentModelManager = request.getComponent(ContentModelManager.class);
- DOMElement parentElement = request.getParentElement();
- if (parentElement == null) {
- // XML is empty, in case of XML file associations, a XML Schema/DTD can be bound
- // check if it's root element (in the case of XML file associations, the link to
- // XML Schema is done with pattern and not with XML root element)
- Collection cmDocuments = contentModelManager.findCMDocument(document, null);
- for (CMDocument cmDocument : cmDocuments) {
- fillWithChildrenElementDeclaration(null, null, cmDocument.getElements(), null, false, request,
- response);
- }
- return;
- }
- // Try to retrieve XML Schema/DTD element declaration for the parent element
- // where completion was triggered.
- Collection cmRootDocuments = contentModelManager.findCMDocument(parentElement,
- parentElement.getNamespaceURI());
-
- String defaultPrefix = null;
- for (CMDocument cmDocument : cmRootDocuments) {
- CMElementDeclaration cmElement = cmDocument.findCMElement(parentElement,
- parentElement.getNamespaceURI());
- if (cmElement != null) {
- defaultPrefix = parentElement.getPrefix();
- fillWithPossibleElementDeclaration(parentElement, cmElement, defaultPrefix, contentModelManager,
- request, response);
- }
- }
- if (parentElement.isDocumentElement()) {
- // completion on root document element
- Collection prefixes = parentElement.getAllPrefixes();
- for (String prefix : prefixes) {
- if (defaultPrefix != null && prefix.equals(defaultPrefix)) {
- continue;
- }
- String namespaceURI = parentElement.getNamespaceURI(prefix);
- if (!hasNamespace(namespaceURI, cmRootDocuments)) {
- // The model document root doesn't define the namespace, try to load the
- // external model document (XML Schema, DTD)
- Collection cmDocuments = contentModelManager.findCMDocument(parentElement,
- namespaceURI);
- for (CMDocument cmDocument : cmDocuments) {
- fillWithChildrenElementDeclaration(parentElement, null, cmDocument.getElements(), prefix,
- true, request, response);
- }
- }
- }
- }
- } catch (CacheResourceDownloadingException e) {
- // XML Schema, DTD is loading, ignore this error
- }
- }
-
- private boolean hasNamespace(String namespaceURI, Collection cmRootDocuments) {
- if (cmRootDocuments.isEmpty()) {
- return false;
- }
- for (CMDocument cmDocument : cmRootDocuments) {
- if (cmDocument.hasNamespace(namespaceURI)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Fill with possible element declarations.
- *
- * @param parentElement the parent DOM element
- * @param cmElement the content model element declaration
- * @param defaultPrefix
- * @param contentModelManager
- * @param request
- * @param response
- * @throws BadLocationException
- */
- private static void fillWithPossibleElementDeclaration(DOMElement parentElement, CMElementDeclaration cmElement,
- String defaultPrefix, ContentModelManager contentModelManager, ICompletionRequest request,
- ICompletionResponse response) throws BadLocationException {
- // Get possible elements
- Collection possibleElements = cmElement.getPossibleElements(parentElement,
- request.getOffset());
- boolean isAny = CMElementDeclaration.ANY_ELEMENT_DECLARATIONS.equals(possibleElements);
- Collection cmDocuments = null;
- if (isAny) {
- // It's a xs:any, get the XML Schema/DTD document to retrieve the all elements
- // declarations
- cmDocuments = contentModelManager.findCMDocument(parentElement);
- }
- fillWithChildrenElementDeclaration(parentElement, cmDocuments, possibleElements, defaultPrefix, false, request,
- response);
- }
-
- /**
- * Fill with children element declarations
- *
- * @param element
- * @param cmDocument
- * @param cmElements
- * @param defaultPrefix
- * @param forceUseOfPrefix
- * @param request
- * @param response
- * @throws BadLocationException
- */
- private static void fillWithChildrenElementDeclaration(DOMElement element, Collection cmDocuments,
- Collection cmElements, String defaultPrefix, boolean forceUseOfPrefix,
- ICompletionRequest request, ICompletionResponse response) throws BadLocationException {
- XMLGenerator generator = request.getXMLGenerator();
- if (cmDocuments != null) {
- // xs:any case
- Set tags = new HashSet<>();
-
- // Fill with all element declarations from the XML Schema/DTD document
- Set processedElements = new HashSet<>();
- for (CMDocument cmDocument : cmDocuments) {
- Collection elements = cmDocument.getElements();
- fillCompletionItem(elements, element, defaultPrefix, forceUseOfPrefix, request, response, generator,
- tags, processedElements);
- }
- // Fill with all element tags from the DOM document
- Document document = element.getOwnerDocument();
- NodeList list = document.getChildNodes();
- addTagName(list, tags, request, response);
- } else {
- for (CMElementDeclaration child : cmElements) {
- addCompletionItem(child, element, defaultPrefix, forceUseOfPrefix, request, response, generator, null);
- }
- }
- }
-
- private static void fillCompletionItem(Collection elements, DOMElement element,
- String defaultPrefix, boolean forceUseOfPrefix, ICompletionRequest request, ICompletionResponse response,
- XMLGenerator generator, Set tags, Set processedElements) {
- for (CMElementDeclaration child : elements) {
- if (!processedElements.contains(child)) {
- processedElements.add(child);
- addCompletionItem(child, element, defaultPrefix, forceUseOfPrefix, request, response, generator, tags);
- fillCompletionItem(child.getElements(), element, defaultPrefix, forceUseOfPrefix, request, response,
- generator, tags, processedElements);
- }
- }
- }
-
- /**
- * Add completion item with all tag names of the node list.
- *
- * @param list
- * @param tags
- * @param request
- * @param response
- */
- private static void addTagName(NodeList list, Set tags, ICompletionRequest request,
- ICompletionResponse response) {
- for (int i = 0; i < list.getLength(); i++) {
- Node node = list.item(i);
- if (Node.ELEMENT_NODE == node.getNodeType()) {
- DOMElement elt = (DOMElement) node;
- if (elt.hasTagName()) {
- String tagName = elt.getTagName();
- if (!tags.contains(tagName)) {
- CompletionItem item = new CompletionItem(tagName);
- item.setKind(CompletionItemKind.Property);
- item.setFilterText(request.getFilterForStartTagName(tagName));
- String xml = elt.getOwnerDocument().getText().substring(elt.getStart(), elt.getEnd());
- item.setTextEdit(Either.forLeft(new TextEdit(request.getReplaceRange(), xml)));
- response.addCompletionItem(item);
- tags.add(item.getLabel());
- }
- }
- addTagName(elt.getChildNodes(), tags, request, response);
- }
- }
- }
-
- private static void addCompletionItem(CMElementDeclaration elementDeclaration, DOMElement parentElement,
- String defaultPrefix, boolean forceUseOfPrefix, ICompletionRequest request, ICompletionResponse response,
- XMLGenerator generator, Set tags) {
- String prefix = forceUseOfPrefix ? defaultPrefix
- : (parentElement != null ? parentElement.getPrefix(elementDeclaration.getNamespace()) : null);
- String label = elementDeclaration.getName(prefix);
- if (tags != null) {
- if (tags.contains(label)) {
- return;
- } else {
- tags.add(label);
- }
- }
-
- CompletionItem item = new CompletionItem(label);
- item.setFilterText(request.getFilterForStartTagName(label));
- item.setKind(CompletionItemKind.Property);
- MarkupContent documentation = XMLGenerator.createMarkupContent(elementDeclaration, request);
- item.setDocumentation(documentation);
- String xml = generator.generate(elementDeclaration, prefix,
- isGenerateEndTag(request.getNode(), request.getOffset(), label));
- item.setTextEdit(Either.forLeft(new TextEdit(request.getReplaceRange(), xml)));
- item.setInsertTextFormat(InsertTextFormat.Snippet);
- response.addCompletionItem(item, true);
- }
-
- private static boolean isGenerateEndTag(DOMNode node, int offset, String tagName) {
- if (node == null) {
- return true;
- }
- return node.getOrphanEndElement(offset, tagName) == null;
- }
-
- @Override
- public void onAttributeName(boolean generateValue, ICompletionRequest request, ICompletionResponse response, CancelChecker cancelChecker)
- throws Exception {
- // otherwise, manage completion based on XML Schema, DTD.
- DOMElement parentElement = request.getNode().isElement() ? (DOMElement) request.getNode() : null;
- if (parentElement == null) {
- return;
- }
- try {
- Range fullRange = request.getReplaceRange();
- boolean canSupportSnippet = request.isCompletionSnippetsSupported();
- ContentModelManager contentModelManager = request.getComponent(ContentModelManager.class);
- // Completion on attribute name based on
- // - internal grammar (ex: DOCTYPE with subset)
- // - external grammar (ex : DOCTYPE SYSTEM, xs:schemaLocation, etc)
- Collection cmDocuments = contentModelManager.findCMDocument(parentElement);
- for (CMDocument cmDocument : cmDocuments) {
- CMElementDeclaration cmElement = cmDocument.findCMElement(parentElement,
- parentElement.getNamespaceURI());
- if (cmElement != null) {
- fillAttributesWithCMAttributeDeclarations(parentElement, fullRange, cmElement, canSupportSnippet,
- generateValue, request, response);
- }
- }
- } catch (CacheResourceDownloadingException e) {
- // XML Schema, DTD is loading, ignore this error
- }
- }
-
- private void fillAttributesWithCMAttributeDeclarations(DOMElement parentElement, Range fullRange,
- CMElementDeclaration cmElement, boolean canSupportSnippet, boolean generateValue,
- ICompletionRequest request, ICompletionResponse response) {
-
- Collection attributes = cmElement.getAttributes();
- if (attributes == null) {
- return;
- }
- for (CMAttributeDeclaration cmAttribute : attributes) {
- String attrName = cmAttribute.getName();
- if (!parentElement.hasAttribute(attrName)) {
- CompletionItem item = new AttributeCompletionItem(attrName, canSupportSnippet, fullRange, generateValue,
- cmAttribute.getDefaultValue(), cmAttribute.getEnumerationValues(), request.getSharedSettings());
- MarkupContent documentation = XMLGenerator.createMarkupContent(cmAttribute, cmElement, request);
- item.setDocumentation(documentation);
- response.addCompletionAttribute(item);
- }
- }
- }
-
- @Override
- public void onAttributeValue(String valuePrefix, ICompletionRequest request, ICompletionResponse response, CancelChecker cancelChecker)
- throws Exception {
- DOMElement parentElement = request.getNode().isElement() ? (DOMElement) request.getNode() : null;
- if (parentElement == null) {
- return;
- }
- try {
- ContentModelManager contentModelManager = request.getComponent(ContentModelManager.class);
- // Completion on attribute value based on
- // - internal grammar (ex: DOCTYPE with subset)
- // - external grammar (ex : DOCTYPE SYSTEM, xs:schemaLocation, etc)
- Collection cmDocuments = contentModelManager.findCMDocument(parentElement);
- for (CMDocument cmDocument : cmDocuments) {
- CMElementDeclaration cmElement = cmDocument.findCMElement(parentElement,
- parentElement.getNamespaceURI());
- if (cmElement != null) {
- fillAttributeValuesWithCMAttributeDeclarations(cmElement, request, response);
- }
- }
- } catch (CacheResourceDownloadingException e) {
- // XML Schema, DTD is loading, ignore this error
- }
- }
-
- private void fillAttributeValuesWithCMAttributeDeclarations(CMElementDeclaration cmElement,
- ICompletionRequest request, ICompletionResponse response) {
- String attributeName = request.getCurrentAttributeName();
- CMAttributeDeclaration cmAttribute = cmElement.findCMAttribute(attributeName);
- if (cmAttribute != null) {
- Range fullRange = request.getReplaceRange();
- cmAttribute.getEnumerationValues().forEach(value -> {
- CompletionItem item = new CompletionItem();
- item.setLabel(value);
- String insertText = request.getInsertAttrValue(value);
- item.setLabel(value);
- item.setKind(CompletionItemKind.Value);
- item.setFilterText(insertText);
- item.setTextEdit(Either.forLeft(new TextEdit(fullRange, insertText)));
- MarkupContent documentation = XMLGenerator.createMarkupContent(cmAttribute, value, cmElement, request);
- item.setDocumentation(documentation);
- response.addCompletionItem(item);
- });
- }
- }
-
- @Override
- public void onXMLContent(ICompletionRequest request, ICompletionResponse response, CancelChecker cancelChecker) throws Exception {
- try {
- ContentModelManager contentModelManager = request.getComponent(ContentModelManager.class);
- DOMElement parentElement = request.getParentElement();
- if (parentElement != null) {
- Collection cmDocuments = contentModelManager.findCMDocument(parentElement);
- for (CMDocument cmDocument : cmDocuments) {
- CMElementDeclaration cmElement = cmDocument.findCMElement(parentElement,
- parentElement.getNamespaceURI());
- Collection values = cmElement != null ? cmElement.getEnumerationValues()
- : Collections.emptyList();
- if (!values.isEmpty()) {
- // Completion for xs:enumeration inside Element Text node
- DOMDocument document = parentElement.getOwnerDocument();
- int startOffset = parentElement.getStartTagCloseOffset() + 1;
- Position start = parentElement.getOwnerDocument().positionAt(startOffset);
- Position end = request.getPosition();
- int endOffset = parentElement.getEndTagOpenOffset();
- if (endOffset > 0) {
- end = document.positionAt(endOffset);
- }
- int completionOffset = request.getOffset();
- String tokenStart = StringUtils.getWhitespaces(document.getText(), startOffset,
- completionOffset);
- Range fullRange = new Range(start, end);
- values.forEach(value -> {
- CompletionItem item = new CompletionItem();
- item.setLabel(value);
- String insertText = value;
- item.setLabel(value);
- item.setKind(CompletionItemKind.Value);
- item.setFilterText(tokenStart + insertText);
- item.setTextEdit(Either.forLeft(new TextEdit(fullRange, insertText)));
- MarkupContent documentation = XMLGenerator.createMarkupContent(cmElement, value, request);
- item.setDocumentation(documentation);
- response.addCompletionItem(item);
- });
- }
- }
- }
- } catch (CacheResourceDownloadingException e) {
- // XML Schema, DTD is loading, ignore this error
- }
- }
-}
diff --git a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelDocumentLinkParticipant.java b/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelDocumentLinkParticipant.java
deleted file mode 100644
index 0ce9f069c..000000000
--- a/lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/ContentModelDocumentLinkParticipant.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * Copyright (c) 2018-2020 Angelo ZERR
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v2.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v20.html
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- * Angelo Zerr - initial API and implementation
- */
-package org.eclipse.lemminx.extensions.contentmodel.participants;
-
-import static org.eclipse.lemminx.utils.XMLPositionUtility.createDocumentLink;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.eclipse.lemminx.commons.BadLocationException;
-import org.eclipse.lemminx.dom.DOMDocument;
-import org.eclipse.lemminx.dom.DOMDocumentType;
-import org.eclipse.lemminx.dom.DOMRange;
-import org.eclipse.lemminx.dom.NoNamespaceSchemaLocation;
-import org.eclipse.lemminx.dom.SchemaLocation;
-import org.eclipse.lemminx.dom.SchemaLocationHint;
-import org.eclipse.lemminx.dom.XMLModel;
-import org.eclipse.lemminx.services.extensions.IDocumentLinkParticipant;
-import org.eclipse.lemminx.uriresolver.URIResolverExtensionManager;
-import org.eclipse.lsp4j.DocumentLink;
-
-/**
- * Document link for :
- *
- *