Skip to content

Commit

Permalink
Report grammar identifier to didOpen telemetry events.
Browse files Browse the repository at this point in the history
- Fixes #1105
- Do not report local grammars
- When exactly 1 grammar reference exists per file, simply send the
  relevant values (not a list of size 1). Otherwise, send the values as
  a list

Signed-off-by: Roland Grunberg <[email protected]>
  • Loading branch information
rgrunber authored and angelozerr committed Aug 27, 2021
1 parent d9ba63a commit a3058b7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
1 change: 1 addition & 0 deletions USAGE_DATA.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ When telemetry events are enabled, the following information is emitted when the
* When a document is opened :
* The file extension (eg. `xml`, `xsd`, `dtd`)
* The associated grammar types (eg. `none`, `doctype`, `xml-model`, `xsi:schemaLocation`, `xsi:noNamespaceSchemaLocation`)
* The grammar identifiers for an XML document (eg. `http://maven.apache.org/xsd/maven-4.0.0.xsd`)
* The resolver used to resolve the grammar identifier (eg. `catalog`, `file association`, `embedded catalog.xsd`, `embedded xml.xsd`, `embedded xslt.xsd`)
* Note: Does NOT include the `JAVA_HOME` environment variable for privacy reasons

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
*******************************************************************************/
package org.eclipse.lemminx.telemetry;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand All @@ -20,11 +22,14 @@
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager;
import org.eclipse.lemminx.extensions.contentmodel.model.ReferencedGrammarInfo;
import org.eclipse.lemminx.utils.DOMUtils;
import org.eclipse.lemminx.utils.URIUtils;

public class DocumentTelemetryInfo {

private static final String DOC_PROP_EXT = "file.extension";
private static final String DOC_PROP_RESOLVER = "file.resolver";
private static final String DOC_PROP_IDENTIFIER = "file.identifier";
private static final String DOC_PROP_GRAMMAR_NONE = "file.grammar.none";
private static final String DOC_PROP_GRAMMAR_DOCTYPE = "file.grammar.doctype";
private static final String DOC_PROP_GRAMMAR_XMLMODEL = "file.grammar.xmlmodel";
Expand All @@ -35,20 +40,23 @@ public static Map<String, Object> getDocumentTelemetryInfo (DOMDocument doc, Con
String uri = doc.getDocumentURI();
int index = uri.lastIndexOf('.');
String fileExtension = uri.substring(index + 1, uri.length()).toLowerCase();
boolean isXML = !DOMUtils.isXSD(doc) && !DOMUtils.isDTD(uri);
Set<ReferencedGrammarInfo> referencedGrammarInfos = manager.getReferencedGrammarInfos(doc);
HashMap<String, Object> props = new HashMap<>();
props.put(DOC_PROP_EXT, fileExtension);

if (referencedGrammarInfos.isEmpty()) {
if ("xml".equals(fileExtension)) {
if (isXML) {
props.put(DOC_PROP_GRAMMAR_NONE, true);
}
} else {
List<String> resolvers = new ArrayList<String>();
List<String> identifiers = new ArrayList<String>();
for (ReferencedGrammarInfo info : referencedGrammarInfos) {
String kind = info.getBindingKind() == null ? "none" : info.getBindingKind();
String resolver = info.getResolvedBy();
if ("xml".equals(fileExtension)) {
String identifier = info.getIdentifierURI();
if (isXML) {
switch (kind) {
case "none":
props.put(DOC_PROP_GRAMMAR_NONE, true);
Expand All @@ -67,10 +75,32 @@ public static Map<String, Object> getDocumentTelemetryInfo (DOMDocument doc, Con
break;
}
}
if (identifier != null) {
try {
// non-local identifiers only
if (new URI(identifier).getScheme() != null && !URIUtils.isFileResource(identifier)) {
int limit = Math.min(identifier.length(), 200); // 200 char limit
identifiers.add(identifier.substring(0, limit));
}
} catch (URISyntaxException e) {
// continue
}
}
resolvers.add(resolver == null ? "default" : resolver);
}

props.put(DOC_PROP_RESOLVER, resolvers);
if (resolvers.size() == 1) {
props.put(DOC_PROP_RESOLVER, resolvers.iterator().next());
} else {
props.put(DOC_PROP_RESOLVER, resolvers);
}
if (!identifiers.isEmpty()) {
if (identifiers.size() == 1) {
props.put(DOC_PROP_IDENTIFIER, identifiers.iterator().next());
} else {
props.put(DOC_PROP_IDENTIFIER, identifiers);
}
}
}
return props;
}
Expand Down

0 comments on commit a3058b7

Please sign in to comment.