first steps to create symbols for XML-defined beans

This commit is contained in:
Martin Lippert
2019-01-15 12:08:04 +01:00
parent 9ab5cd6c8d
commit 9806e95cf2
5 changed files with 143 additions and 27 deletions

View File

@@ -10,11 +10,13 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.xml.stream.XMLEventReader;
@@ -27,6 +29,7 @@ import javax.xml.stream.events.XMLEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.util.UriUtil;
/**
* @author Martin Lippert
@@ -36,9 +39,11 @@ public class SpringIndexerXML implements SpringIndexer {
private static final Logger log = LoggerFactory.getLogger(SpringIndexerJava.class);
private final SymbolHandler handler;
private final Map<String, SpringIndexerXMLNamespaceHandler> namespaceHandler;
public SpringIndexerXML(SymbolHandler handler) {
public SpringIndexerXML(SymbolHandler handler, Map<String, SpringIndexerXMLNamespaceHandler> namespaceHandler) {
this.handler = handler;
this.namespaceHandler = namespaceHandler;
}
@Override
@@ -68,11 +73,11 @@ public class SpringIndexerXML implements SpringIndexer {
private void scanProject(IJavaProject project, String[] files) {
for (String file : files) {
scanFile(file);
scanFile(project, file);
}
}
private void scanFile(String file) {
private void scanFile(IJavaProject project, String file) {
System.out.println("XML parsing for: " + file);
@@ -82,27 +87,36 @@ public class SpringIndexerXML implements SpringIndexer {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLEventReader eventReader = inputFactory.createXMLEventReader(xmlInputStream);
while(eventReader.hasNext()){
XMLEvent event = eventReader.nextEvent();
switch (event.getEventType()) {
case XMLEvent.START_ELEMENT:
StartElement startElement = event.asStartElement();
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
switch (event.getEventType()) {
System.out.print("<"+startElement.getName().toString()+">");
break;
case XMLEvent.CHARACTERS:
Characters characters = event.asCharacters();
System.out.print(characters.getData());
break;
case XMLEvent.END_ELEMENT:
EndElement endElement = event.asEndElement();
System.out.println("</"+endElement.getName().toString()+">");
break;
default:
//do nothing
break;
}
}
case XMLEvent.START_ELEMENT:
StartElement startElement = event.asStartElement();
String namespaceURI = startElement.getName().getNamespaceURI();
if (namespaceURI != null && this.namespaceHandler.containsKey(namespaceURI)) {
SpringIndexerXMLNamespaceHandler namespaceHandler = this.namespaceHandler.get(namespaceURI);
String docURI = UriUtil.toUri(new File(file)).toString();
namespaceHandler.processStartElement(project, docURI, startElement, this.handler);
}
break;
case XMLEvent.CHARACTERS:
Characters characters = event.asCharacters();
System.out.print(characters.getData());
break;
case XMLEvent.END_ELEMENT:
EndElement endElement = event.asEndElement();
System.out.println("</" + endElement.getName().toString() + ">");
break;
default:
// do nothing
break;
}
}
}
catch (Exception e) {
log.error("error parsing XML file: ", e);

View File

@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2019 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.utils;
import javax.xml.stream.events.StartElement;
import org.springframework.ide.vscode.commons.java.IJavaProject;
/**
* @author Martin Lippert
*/
public interface SpringIndexerXMLNamespaceHandler {
void processStartElement(IJavaProject project, String docURI, StartElement startElement, SymbolHandler handler);
}

View File

@@ -0,0 +1,73 @@
/*******************************************************************************
* Copyright (c) 2019 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.utils;
import java.util.Iterator;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.SymbolKind;
import org.springframework.ide.vscode.boot.java.handlers.EnhancedSymbolInformation;
import org.springframework.ide.vscode.commons.java.IJavaProject;
/**
* @author Martin Lippert
*/
public class SpringIndexerXMLNamespaceHandlerBeans implements SpringIndexerXMLNamespaceHandler {
@Override
public void processStartElement(IJavaProject project, String docURI, StartElement startElement, SymbolHandler handler) {
String localPart = startElement.getName().getLocalPart();
if (localPart != null && "bean".equals(localPart)) {
createBeanSymbol(project, docURI, startElement, handler);
}
}
private void createBeanSymbol(IJavaProject project, String docURI, StartElement startElement, SymbolHandler handler) {
String beanID = null;
String beanClass = null;
Iterator<?> attributes = startElement.getAttributes();
while (attributes.hasNext()) {
Attribute attribute = (Attribute) attributes.next();
String name = attribute.getName().getLocalPart();
if (name != null && name.equals("id")) {
beanID = attribute.getValue();
}
else if (name != null && name.equals("class")) {
String value = attribute.getValue();
beanClass = value.substring(value.lastIndexOf(".") + 1);
}
}
if (beanID != null && beanClass != null) {
Range range = new Range();
range.setStart(new Position(startElement.getLocation().getLineNumber(), startElement.getLocation().getColumnNumber()));
range.setEnd(new Position(startElement.getLocation().getLineNumber(), startElement.getLocation().getColumnNumber() + 1));
Location location = new Location();
location.setUri(docURI);
location.setRange(range);
SymbolInformation symbol = new SymbolInformation("@+ '" + beanID + "' " + beanClass, SymbolKind.Interface, new Location(docURI, range));
EnhancedSymbolInformation fullSymbol = new EnhancedSymbolInformation(symbol, null);
handler.addSymbol(project, docURI, fullSymbol);
}
}
}

View File

@@ -15,8 +15,10 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@@ -120,7 +122,10 @@ public class SpringSymbolIndex {
}
};
// this.indexer = new SpringIndexer[] {new SpringIndexerJava(handler, specificProviders), new SpringIndexerXML(handler) };
// Map<String, SpringIndexerXMLNamespaceHandler> namespaceHandler = new HashMap<>();
// namespaceHandler.put("http://www.springframework.org/schema/beans", new SpringIndexerXMLNamespaceHandlerBeans());
// SpringIndexerXML springIndexerXML = new SpringIndexerXML(handler, namespaceHandler);
// this.indexer = new SpringIndexer[] {new SpringIndexerJava(handler, specificProviders), springIndexerXML };
this.indexer = new SpringIndexer[] {new SpringIndexerJava(handler, specificProviders)};
this.updateQueue = Executors.newSingleThreadExecutor();

View File

@@ -72,9 +72,9 @@ public class SpringIndexerXMLProjectTest {
// assertEquals(3, allSymbols.size());
//
// String docUri = directory.toPath().resolve("config/simple-spring-config.xml").toUri().toString();
// assertTrue(containsSymbol(allSymbols, "@+ 'transactionManager' DataSourceTransactionManager", docUri, 6, 8, 7, 46));
// assertTrue(containsSymbol(allSymbols, "@+ 'jdbcTemplate' JdbcTemplate", docUri, 11, 1, 11, 28));
// assertTrue(containsSymbol(allSymbols, "@+ 'namedParameterJdbcTemplate' NamedParameterJdbcTemplate", docUri, 11, 1, 11, 28));
// assertTrue(containsSymbol(allSymbols, "@+ 'transactionManager' DataSourceTransactionManager", docUri, 7, 143, 7, 144));
// assertTrue(containsSymbol(allSymbols, "@+ 'jdbcTemplate' JdbcTemplate", docUri, 9, 84, 9, 85));
// assertTrue(containsSymbol(allSymbols, "@+ 'namedParameterJdbcTemplate' NamedParameterJdbcTemplate", docUri, 14, 91, 14, 92));
}
private boolean containsSymbol(List<? extends SymbolInformation> symbols, String name, String uri, int startLine, int startCHaracter, int endLine, int endCharacter) {