getValuesNow(IJavaProject javaProject, String query) {
+ return this.getValues(javaProject, query)
+ .take(CachingValueProvider.TIMEOUT)
+ .collectList()
+ .block();
+ }
}
/**
diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/StsValueHint.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/StsValueHint.java
new file mode 100644
index 000000000..8ab138fb6
--- /dev/null
+++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/StsValueHint.java
@@ -0,0 +1,154 @@
+package org.springframework.ide.vscode.boot.properties.metadata.types;
+
+import static org.springframework.ide.vscode.boot.properties.util.DeprecationUtil.*;
+
+import javax.inject.Provider;
+
+import org.springframework.boot.configurationmetadata.Deprecation;
+import org.springframework.boot.configurationmetadata.ValueHint;
+import org.springframework.ide.vscode.boot.properties.util.DeprecationUtil;
+import org.springframework.ide.vscode.java.IJavaElement;
+import org.springframework.ide.vscode.java.IJavaProject;
+import org.springframework.ide.vscode.java.IType;
+import org.springframework.ide.vscode.util.Assert;
+import org.springframework.ide.vscode.util.HtmlSnippet;
+import org.springframework.ide.vscode.util.Log;
+import org.springframework.ide.vscode.util.StringUtil;
+
+/**
+ * Sts version of {@link ValueHint} contains similar data, but accomoates
+ * a html snippet to be computed lazyly for the description.
+ *
+ * This is meant to support using data pulled from JavaDoc in enums as description.
+ * This data is a html snippet, whereas the data derived from spring-boot metadata is
+ * just plain text.
+ *
+ * @author Kris De Volder
+ */
+public class StsValueHint {
+
+ private static final HtmlSnippet EMPTY_DESCRIPTION = HtmlSnippet.italic("No description");
+
+ private static final Provider EMPTY_DESCRIPTION_PROVIDER = () -> EMPTY_DESCRIPTION;
+
+ private final String value;
+ private final Provider description;
+ private final Deprecation deprecation;
+
+ /**
+ * Create a hint with a textual description.
+ *
+ * This constructor is private. Use one of the provided
+ * static 'create' methods instead.
+ */
+ private StsValueHint(String value, Provider description, Deprecation deprecation) {
+ this.value = value==null?"null":value.toString();
+ Assert.isLegal(!this.value.startsWith("StsValueHint"));
+ this.description = description;
+ this.deprecation = deprecation;
+ }
+
+ /**
+ * Creates a hint out of an IJavaElement.
+ */
+ public static StsValueHint create(String value, IJavaElement javaElement) {
+ return new StsValueHint(value, javaDocSnippet(javaElement), DeprecationUtil.extract(javaElement)) {
+ @Override
+ public IJavaElement getJavaElement() {
+ return javaElement;
+ }
+ };
+ }
+
+ public static StsValueHint create(String value) {
+ return new StsValueHint(value, EMPTY_DESCRIPTION_PROVIDER, null);
+ }
+
+ public static StsValueHint create(ValueHint hint) {
+ return new StsValueHint(""+hint.getValue(), textSnippet(hint.getDescription()), null);
+ }
+
+ public static StsValueHint className(String fqName, TypeUtil typeUtil) {
+ try {
+ IJavaProject jp = typeUtil.getJavaProject();
+ if (jp!=null) {
+ IType type = jp.findType(fqName);
+ if (type!=null) {
+ return create(type);
+ }
+ }
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ return null;
+ }
+
+ public static StsValueHint create(IType klass) {
+ return new StsValueHint(klass.getFullyQualifiedName(), javaDocSnippet(klass), DeprecationUtil.extract(klass)) {
+ @Override
+ public IJavaElement getJavaElement() {
+ return klass;
+ }
+ };
+ }
+
+ /**
+ * Create a html snippet from a text snippet.
+ */
+ private static Provider textSnippet(String description) {
+ if (StringUtil.hasText(description)) {
+ return () -> HtmlSnippet.text(description);
+ }
+ return EMPTY_DESCRIPTION_PROVIDER;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public HtmlSnippet getDescription() {
+ return description.get();
+ }
+ public Provider getDescriptionProvider() {
+ return description;
+ }
+
+ public static Provider javaDocSnippet(IJavaElement je) {
+ return () -> {
+ try {
+ HtmlSnippet jdoc = je.getJavaDoc();
+ if (jdoc!=null) {
+ return jdoc;
+ }
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ return EMPTY_DESCRIPTION;
+ };
+ }
+
+ @Override
+ public String toString() {
+ return "StsValueHint("+value+")";
+ }
+
+ public Deprecation getDeprecation() {
+ return deprecation;
+ }
+
+ public IJavaElement getJavaElement() {
+ return null;
+ }
+
+ public StsValueHint prefixWith(String prefix) {
+ StsValueHint it = this;
+ return new StsValueHint(prefix+getValue(), description, deprecation) {
+ @Override
+ public IJavaElement getJavaElement() {
+ return it.getJavaElement();
+ }
+ };
+ }
+
+
+}
diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/Type.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/Type.java
new file mode 100644
index 000000000..377ade78a
--- /dev/null
+++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/Type.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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.properties.metadata.types;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.ide.vscode.java.IType;
+import org.springframework.ide.vscode.util.ArrayUtils;
+import org.springframework.ide.vscode.util.Assert;
+import org.springframework.ide.vscode.util.Log;
+import org.springframework.ide.vscode.util.StringUtil;
+import org.springframework.ide.vscode.yaml.schema.YType;
+
+/**
+ * @author Kris De Volder
+ */
+public class Type implements YType {
+
+ private final String erasure;
+ private final Type[] params;
+
+ public Type(String erasure, Type[] params) {
+ this.erasure = erasure;
+ this.params = params;
+ }
+
+
+ public boolean isGeneric() {
+ return params!=null;
+ }
+
+ public String getErasure() {
+ return erasure;
+ }
+ public Type[] getParams() {
+ return params;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ toString(buf);
+ return buf.toString();
+ }
+
+ private void toString(StringBuilder buf) {
+ buf.append(getErasure());
+ if (isGeneric()) {
+ buf.append("<");
+ boolean first = true;
+ for (Type param : getParams()) {
+ if (!first) {
+ buf.append(",");
+ }
+ param.toString(buf);
+ first = false;
+ }
+ buf.append(">");
+ }
+ }
+
+ /**
+ * Attempt to convert given typeSignature to a corresponding Type object.
+ *
+ * Not all valid typeSig have a representation as a Type object. This may
+ * return null if no corresponding representation can be constructed.
+ */
+ public static Type fromSignature(String typeSig, IType context) {
+ //TODO: does this work correctly with nested types (i.e like Map$Entry)
+ Type type = TYPE_FROM_SIG.get(typeSig);
+ if (type!=null) {
+ return type;
+ }
+ int kind = Signature.getTypeSignatureKind(typeSig);
+ //Essentially, Type object only able to represent class types with with generic parameters
+ // as long as these generic parameters are fully concrete (i.e. do not contain unbound type
+ // variables. For now only support the simplest case (no generics) and bail out returning null if we
+ // see something we don't understand.
+ if (kind==Signature.CLASS_TYPE_SIGNATURE) {
+ boolean shouldResolve = typeSig.charAt(0)==Signature.C_UNRESOLVED;
+ String erasure = Signature.getTypeErasure(typeSig);
+ String pkg = Signature.getSignatureQualifier(erasure);
+ String nam = Signature.getSignatureSimpleName(erasure);
+ String[] params = Signature.getTypeParameters(typeSig);
+ String[] args = Signature.getTypeArguments(typeSig);
+ if (shouldResolve) {
+ erasure = tryToResolve(qualifiedName(pkg, nam), context);
+ } else {
+ erasure = qualifiedName(pkg, nam);
+ }
+ if (ArrayUtils.hasElements(params)) {
+ //TODO: handle this case
+ return null;
+ } else if (ArrayUtils.hasElements(args)) {
+ Type[] argTypes = new Type[args.length];
+ for (int i = 0; i < argTypes.length; i++) {
+ argTypes[i] = fromSignature(args[i], context);
+ }
+ return new Type(erasure, argTypes);
+ } else {
+ return new Type(erasure, null);
+ }
+ } else if (kind==Signature.ARRAY_TYPE_SIGNATURE) {
+ Type elementType = fromSignature(Signature.getElementType(typeSig), context);
+ if (elementType!=null) {
+ int arrayCount = Signature.getArrayCount(typeSig);
+ return elementType.asArray(arrayCount);
+ }
+ }
+ return null;
+ }
+
+ public Type asArray(int arrayCount) {
+ Assert.isLegal(arrayCount>0);
+ StringBuilder arrayErasure = new StringBuilder(erasure);
+ for (int i = 0; i < arrayCount; i++) {
+ arrayErasure.append("[]");
+ }
+ return new Type(arrayErasure.toString(), params);
+ }
+
+ private static String qualifiedName(String pkg, String nam) {
+ if (StringUtil.hasText(pkg)) {
+ return pkg + "." + nam;
+ } else {
+ return nam;
+ }
+ }
+
+ private static String tryToResolve(String typeName, IType context) {
+ try {
+ String[][] resolved = context.resolveType(typeName);
+ if (ArrayUtils.hasElements(resolved)) {
+ String pkg = resolved[0][0];
+ String nam = resolved[0][1];
+ if (StringUtil.hasText(pkg)) {
+ return pkg+"."+nam;
+ } else {
+ //No . in front of default package
+ return nam;
+ }
+ }
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ return typeName;
+ }
+
+ //////////////////////////////////////////////////
+
+ /**
+ * Map of some known / common type signatures and their corresponding 'Type' representation.
+ * Note that springboot metadata 'normalizes' all primitive types to their corresponding box
+ * types. So we do the same here.
+ */
+ private static final Map TYPE_FROM_SIG = new HashMap();
+ static {
+ sig2type("B", Byte.class);
+ sig2type("C", Character.class);
+ sig2type("D", Double.class);
+ sig2type("F", Float.class);
+ sig2type("I", Integer.class);
+ sig2type("J", Long.class);
+ sig2type("S", Short.class);
+ sig2type("V", Void.class);
+ sig2type("Z", Boolean.class);
+ }
+ private static void sig2type(String sig, Class> cls) {
+ TYPE_FROM_SIG.put(sig, TypeParser.parse(cls.getName()));
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((erasure == null) ? 0 : erasure.hashCode());
+ result = prime * result + Arrays.hashCode(params);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Type other = (Type) obj;
+ if (erasure == null) {
+ if (other.erasure != null)
+ return false;
+ } else if (!erasure.equals(other.erasure))
+ return false;
+ if (!Arrays.equals(params, other.params))
+ return false;
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypeParser.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypeParser.java
new file mode 100644
index 000000000..d2b2bd744
--- /dev/null
+++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypeParser.java
@@ -0,0 +1,134 @@
+package org.springframework.ide.vscode.boot.properties.metadata.types;
+
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+import org.springframework.ide.vscode.util.StringUtil;
+
+/**
+ * Converts types in notation used by spring properties metadata into a 'Structured' form
+ *
+ * @author Kris De Volder
+ */
+public class TypeParser {
+
+ private static final String DELIM = "<>,";
+
+ /**
+ * Wrapper around StringTokenizer that manages a single lookahead token.
+ * So it can implement 'peekToken()' method.
+ */
+ private static class Tokener {
+ private String lookahead;
+ private StringTokenizer tokens;
+ public Tokener(String input) {
+ this.tokens = new StringTokenizer(input, DELIM, true);
+ }
+
+ /**
+ * Fetch next token. Returns null if there are no more tokens.
+ */
+ public String nextToken() {
+ if (lookahead!=null) {
+ try {
+ return lookahead;
+ } finally {
+ lookahead = null;
+ }
+ } else if (tokens.hasMoreTokens()) {
+ return tokens.nextToken();
+ }
+ return null;
+ }
+ /**
+ * Fetch the next token without consuming it.
+ * Returns null if there are no more tokens.
+ */
+ public String peekToken() {
+ if (lookahead!=null) {
+ return lookahead;
+ } else if (tokens.hasMoreTokens()) {
+ lookahead = tokens.nextToken();
+ return lookahead;
+ }
+ return null;
+ }
+ }
+
+ private Tokener input;
+
+ private TypeParser(String input) {
+ this.input = new Tokener(input);
+ }
+
+ public static Type parse(String str) {
+ if (StringUtil.hasText(str)) {
+ return new TypeParser(str).parseType();
+ }
+ return null;
+ }
+
+ private Type parseType() {
+ String ident = input.nextToken();
+ String token = input.peekToken();
+ if ("<".equals(token)) {
+ ArrayList params = parseParams();
+ return new Type(ident, params.toArray(new Type[params.size()]));
+ } else {
+ return new Type(ident, null);
+ }
+ }
+
+ private ArrayList parseParams() {
+ skip("<");
+ try {
+ return parseParamList(new ArrayList());
+ } finally {
+ skip(">");
+ }
+ }
+
+ private ArrayList parseParamList(ArrayList params) {
+ //parse params separate by ",'
+ String tok = input.peekToken();
+ if (isIdent(tok)) {
+ params.add(parseType());
+ if (skip(",")) {
+ return parseParamList(params);
+ }
+ }
+ return params;
+ }
+
+ /**
+ * Skip an expected token, or do nothing if the next token is
+ * something unexpected.
+ * @return whether token was skipped.
+ */
+ private boolean skip(String expected) {
+ String t = input.peekToken();
+ if (expected.equals(t)) {
+ input.nextToken();
+ return true;
+ }
+ return false;
+ }
+
+ public boolean isIdent(String token) {
+ return token!=null && !isSeparator(token);
+ }
+
+ private boolean isSeparator(String token) {
+ if (token!=null && token.length()==1) {
+ int len = DELIM.length();
+ char c = token.charAt(0);
+ for (int i = 0; i < len; i++) {
+ if (DELIM.charAt(i)==c) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypeUtil.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypeUtil.java
new file mode 100644
index 000000000..a66b3ff85
--- /dev/null
+++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypeUtil.java
@@ -0,0 +1,976 @@
+package org.springframework.ide.vscode.boot.properties.metadata.types;
+
+import static org.springframework.ide.vscode.util.ArrayUtils.firstElement;
+import static org.springframework.ide.vscode.util.ArrayUtils.lastElement;
+
+import java.lang.reflect.Field;
+import java.net.InetAddress;
+import java.nio.charset.Charset;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import javax.inject.Provider;
+
+import org.springframework.boot.configurationmetadata.Deprecation;
+import org.springframework.ide.vscode.boot.properties.metadata.ValueProviderRegistry.ValueProviderStrategy;
+import org.springframework.ide.vscode.boot.properties.util.DeprecationUtil;
+import org.springframework.ide.vscode.java.Flags;
+import org.springframework.ide.vscode.java.IField;
+import org.springframework.ide.vscode.java.IJavaElement;
+import org.springframework.ide.vscode.java.IJavaProject;
+import org.springframework.ide.vscode.java.IMethod;
+import org.springframework.ide.vscode.java.IType;
+import org.springframework.ide.vscode.util.AlwaysFailingParser;
+import org.springframework.ide.vscode.util.ArrayUtils;
+import org.springframework.ide.vscode.util.Assert;
+import org.springframework.ide.vscode.util.CollectionUtil;
+import org.springframework.ide.vscode.util.EnumValueParser;
+import org.springframework.ide.vscode.util.HtmlSnippet;
+import org.springframework.ide.vscode.util.LazyProvider;
+import org.springframework.ide.vscode.util.Log;
+import org.springframework.ide.vscode.util.StringUtil;
+import org.springframework.ide.vscode.util.ValueParser;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.net.MediaType;
+
+import reactor.core.publisher.Flux;
+
+/**
+ * Utilities to work with types represented as Strings as returned by
+ * Spring config metadata apis.
+ *
+ * @author Kris De Volder
+ */
+public class TypeUtil {
+
+ private static abstract class RadixableParser implements ValueParser {
+ protected abstract Object parse(String str, int radix);
+
+ @Override
+ public Object parse(String str) {
+ if (str.startsWith("0")) {
+ if (str.startsWith("0x")||str.startsWith("0X")) {
+ return parse(str.substring(2), 16);
+ } else if (str.startsWith("0b") || str.startsWith("0B")) {
+ return parse(str.substring(2), 2);
+ } else {
+ return parse(str, 8);
+ }
+ }
+ return parse(str, 10);
+ }
+
+ }
+
+ private static final Object OBJECT_TYPE_NAME = Object.class.getName();
+ private static final String STRING_TYPE_NAME = String.class.getName();
+ private static final String INET_ADDRESS_TYPE_NAME = InetAddress.class.getName();
+ private static final String CLASS_TYPE_NAME = Class.class.getName();
+
+ public enum BeanPropertyNameMode {
+ HYPHENATED(true,false), //bean property name in hyphenated form. E.g 'some-property-name'
+ CAMEL_CASE(false,true), //bean property name in camelCase. E.g. 'somePropertyName'
+ ALIASED(true,true); //use both as aliases of one another.
+
+ private final boolean includesHyphenated;
+ private final boolean includesCamelCase;
+
+ BeanPropertyNameMode(boolean hyphenated, boolean camelCase) {
+ this.includesCamelCase = camelCase;
+ this.includesHyphenated = hyphenated;
+ }
+
+ public boolean includesHyphenated() {
+ return includesHyphenated;
+ }
+
+ public boolean includesCamelCase() {
+ return includesCamelCase;
+ }
+ }
+
+ public enum EnumCaseMode {
+ LOWER_CASE, //convert enum names to lower case
+ ORIGNAL, //keep orignal enum name
+ ALIASED //use both lower-cased and original names as aliases of one another
+ }
+
+ private IJavaProject javaProject;
+
+ public TypeUtil(IJavaProject jp) {
+ //Note javaProject is allowed to be null, but only in unit testing context
+ // (This is so some tests can be run without an explicit jp needing to be created)
+ this.javaProject = jp;
+ }
+
+
+ private static final Map PRIMITIVE_TYPE_NAMES = new HashMap<>();
+ private static final Map PRIMITIVE_TO_BOX_TYPE = new HashMap<>();
+ static {
+ PRIMITIVE_TYPE_NAMES.put("java.lang.Boolean", "boolean");
+
+ PRIMITIVE_TYPE_NAMES.put("java.lang.Byte", "byte");
+ PRIMITIVE_TYPE_NAMES.put("java.lang.Short", "short");
+ PRIMITIVE_TYPE_NAMES.put("java.lang.Integer","int");
+ PRIMITIVE_TYPE_NAMES.put("java.lang.Long", "long");
+
+ PRIMITIVE_TYPE_NAMES.put("java.lang.Double", "double");
+ PRIMITIVE_TYPE_NAMES.put("java.lang.Float", "float");
+
+ PRIMITIVE_TYPE_NAMES.put("java.lang.Character", "char");
+
+ for (Entry e : PRIMITIVE_TYPE_NAMES.entrySet()) {
+ PRIMITIVE_TO_BOX_TYPE.put(e.getValue(), new Type(e.getKey(), null));
+ }
+ }
+
+ public static final Type INTEGER_TYPE = new Type("java.lang.Integer", null);
+
+ private static final Set ASSIGNABLE_TYPES = new HashSet<>(Arrays.asList(
+ "java.lang.Boolean",
+ "java.lang.String",
+ "java.lang.Short",
+ "java.lang.Integer",
+ "java.lang.Long",
+ "java.lang.Double",
+ "java.lang.Float",
+ "java.lang.Character",
+ "java.lang.Byte",
+ INET_ADDRESS_TYPE_NAME,
+ CLASS_TYPE_NAME,
+ "java.lang.String[]"
+ ));
+
+ private static final Set ATOMIC_TYPES = new HashSet<>(PRIMITIVE_TYPE_NAMES.keySet());
+ static {
+ ATOMIC_TYPES.add(INET_ADDRESS_TYPE_NAME);
+ ATOMIC_TYPES.add(STRING_TYPE_NAME);
+ ATOMIC_TYPES.add(CLASS_TYPE_NAME);
+ }
+
+ private static final Map TYPE_VALUES = new HashMap<>();
+ static {
+ TYPE_VALUES.put("java.lang.Boolean", new String[] { "true", "false" });
+ }
+
+ private static final Map VALUE_PARSERS = new HashMap<>();
+ static {
+ VALUE_PARSERS.put(Byte.class.getName(), new RadixableParser() {
+ public Object parse(String str, int radix) {
+ return Byte.parseByte(str, radix);
+ }
+ });
+ VALUE_PARSERS.put(Integer.class.getName(), new RadixableParser() {
+ public Object parse(String str, int radix) {
+ return Integer.parseInt(str, radix);
+ }
+ });
+ VALUE_PARSERS.put(Long.class.getName(), new RadixableParser() {
+ public Object parse(String str, int radix) {
+ return Long.parseLong(str, radix);
+ }
+ });
+ VALUE_PARSERS.put(Short.class.getName(), new RadixableParser() {
+ public Object parse(String str, int radix) {
+ return Short.parseShort(str, radix);
+ }
+ });
+ VALUE_PARSERS.put(Double.class.getName(), new ValueParser() {
+ public Object parse(String str) {
+ return Double.parseDouble(str);
+ }
+ });
+ VALUE_PARSERS.put(Float.class.getName(), new ValueParser() {
+ public Object parse(String str) {
+ return Float.parseFloat(str);
+ }
+ });
+ VALUE_PARSERS.put(Boolean.class.getName(), new ValueParser() {
+ public Object parse(String str) {
+ //The 'more obvious' implementation is too liberal and accepts anything as okay.
+ //return Boolean.parseBoolean(str);
+ str = str.toLowerCase();
+ if (str.equals("true")) {
+ return true;
+ } else if (str.equals("false")) {
+ return false;
+ }
+ throw new IllegalArgumentException("Value should be 'true' or 'false'");
+ }
+ });
+ }
+
+ public ValueParser getValueParser(Type type) {
+ ValueParser simpleParser = VALUE_PARSERS.get(type.getErasure());
+ if (simpleParser!=null) {
+ return simpleParser;
+ }
+ Collection enumValues = getAllowedValues(type, EnumCaseMode.ALIASED);
+ if (enumValues!=null) {
+ //Note, technically if 'enumValues is empty array' this means something different
+ // from when it is null. An empty array means a type that has no values, so
+ // assigning anything to it is an error.
+ return new EnumValueParser(niceTypeName(type), getBareValues(enumValues));
+ }
+ if (isMap(type)) {
+ //Trying to parse map types from scalars is not possible. Thus we
+ // provide a parser that allows throws
+ return new AlwaysFailingParser(niceTypeName(type));
+ }
+ return null;
+ }
+
+ private String[] getBareValues(Collection hints) {
+ if (hints!=null) {
+ String[] values = new String[hints.size()];
+ int i = 0;
+ for (StsValueHint h : hints) {
+ values[i++] = h.getValue();
+ }
+ return values;
+ }
+ return null;
+ }
+
+ /**
+ * @return An array of allowed values for a given type. If an array is returned then
+ * *only* values in the array are valid and using any other value constitutes an error.
+ * This may return null if allowedValues list is unknown or the type is not characterizable
+ * as a simple enumaration of allowed values.
+ * @param caseMode determines whether Enum values are returned in 'lower case form', 'orignal form',
+ * or 'aliased' (meaning both forms are returned).
+ */
+ public Collection getAllowedValues(Type enumType, EnumCaseMode caseMode) {
+ if (enumType!=null) {
+ try {
+ String[] values = TYPE_VALUES.get(enumType.getErasure());
+ if (values!=null) {
+ if (caseMode==EnumCaseMode.ALIASED) {
+ ImmutableSet.Builder aliased = ImmutableSet.builder();
+ aliased.add(values);
+ for (int i = 0; i < values.length; i++) {
+ aliased.add(values[i].toUpperCase());
+ }
+ return aliased.build().stream().map(StsValueHint::create).collect(Collectors.toList());
+ } else {
+ return Arrays.stream(values).map(StsValueHint::create).collect(Collectors.toList());
+ }
+ }
+ IType type = findType(enumType.getErasure());
+ if (type!=null && type.isEnum()) {
+ IField[] fields = type.getFields();
+
+ if (fields!=null) {
+ ImmutableList.Builder enums = ImmutableList.builder();
+ boolean addOriginal = caseMode==EnumCaseMode.ORIGNAL||caseMode==EnumCaseMode.ALIASED;
+ boolean addLowerCased = caseMode==EnumCaseMode.LOWER_CASE||caseMode==EnumCaseMode.ALIASED;
+ for (int i = 0; i < fields.length; i++) {
+ IField f = fields[i];
+ Provider jdoc = StsValueHint.javaDocSnippet(f);
+ if (f.isEnumConstant()) {
+ String rawName = f.getElementName();
+ if (addOriginal) {
+ enums.add(StsValueHint.create(rawName, f));
+ }
+ if (addLowerCased) {
+ enums.add(StsValueHint.create(StringUtil.upperCaseToHyphens(rawName), f));
+ }
+ }
+ }
+ return enums.build();
+ }
+ }
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ }
+ return null;
+ }
+
+ public String niceTypeName(Type _type) {
+ StringBuilder buf = new StringBuilder();
+ niceTypeName(_type, buf);
+ return buf.toString();
+ }
+
+ public void niceTypeName(Type type, StringBuilder buf) {
+ if (type==null) {
+ buf.append("null");
+ return;
+ }
+ String typeStr = type.getErasure();
+ String primTypeName = PRIMITIVE_TYPE_NAMES.get(typeStr);
+ if (primTypeName!=null) {
+ buf.append(primTypeName);
+ } else if (typeStr.startsWith("java.lang.")) {
+ buf.append(typeStr.substring("java.lang.".length()));
+ } else if (typeStr.startsWith("java.util.")) {
+ buf.append(typeStr.substring("java.util.".length()));
+ } else {
+ buf.append(typeStr);
+ }
+ if (isEnum(type)) {
+ Collection values = getAllowedValues(type, EnumCaseMode.ORIGNAL);
+ if (values!=null && !values.isEmpty()) {
+ buf.append("[");
+ int i = 0;
+ for (StsValueHint hint : values) {
+ if (i>0) {
+ buf.append(", ");
+ }
+ buf.append(hint.getValue());
+ i++;
+ if (i>=4) {
+ break;
+ }
+ }
+ if (i0) {
+ buf.append(", ");
+ }
+ niceTypeName(params[i], buf);
+ }
+ buf.append(">");
+ }
+ }
+
+
+ /**
+ * @return true if it is reasonable to navigate given type with '.' notation. This returns true
+ * by default except for some specific cases we assume are not 'dotable' such as Primitive types
+ * and String
+ */
+ public boolean isDotable(Type type) {
+ String typeName = type.getErasure();
+ if (typeName.equals("java.lang.Object")) {
+ //special case. Treat as 'non dotable' type. This mainly for stuff like logging.level
+ // declared as Map so it would 'eat' the dots into the key.
+ // also it makes sense to treat Object as 'non-dotable' since we cannot determine properties
+ // for such an abstract type (as Object itself has no setters).
+ return false;
+ }
+ return !isAtomic(type);
+ }
+
+ public static boolean isObject(Type type) {
+ return type!=null && OBJECT_TYPE_NAME.equals(type.getErasure());
+ }
+
+ public static boolean isString(Type type) {
+ return type!=null && STRING_TYPE_NAME.equals(type.getErasure());
+ }
+
+ public boolean isAtomic(Type type) {
+ if (type!=null) {
+ String typeName = type.getErasure();
+ return ATOMIC_TYPES.contains(typeName) || isEnum(type);
+ }
+ return false;
+ }
+
+ /**
+ * Check if it is valid to
+ * use the notation []= in property file
+ * for properties of this type.
+ */
+ public static boolean isBracketable(Type type) {
+ //Note array types where once not considered 'Bracketable'
+ //see: STS-4031
+
+ //However...
+ //Seems that in Boot 1.3 arrays are now 'Bracketable' and funcion much equivalnt to list (even including 'autogrowing' them).
+ //This is actually more logical too.
+ //So '[' notation in props file can be used for either list or arrays (at leats in recent versions of boot).
+ return isArray(type) || isList(type);
+ }
+
+ public static boolean isList(Type type) {
+ //Note: to be really correct we should use JDT infrastructure to resolve
+ //type in project classpath instead of using Java reflection.
+ //However, use reflection here is okay assuming types we care about
+ //are part of JRE standard libraries. Using eclipse 'type hirearchy' would
+ //also potentialy be very slow.
+ if (type!=null) {
+ String erasure = type.getErasure();
+ try {
+ Class> erasureClass = Class.forName(erasure);
+ return List.class.isAssignableFrom(erasureClass);
+ } catch (Exception e) {
+ //type not resolveable assume its not 'array like'
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if type can be treated / represented as a sequence node in .yml file
+ */
+ public static boolean isSequencable(Type type) {
+ return isList(type) || isArray(type);
+ }
+
+ public static boolean isArray(Type type) {
+ return type!=null && type.getErasure().endsWith("[]");
+ }
+
+ public static boolean isMap(Type type) {
+ //Note: to be really correct we should use JDT infrastructure to resolve
+ //type in project classpath instead of using Java reflection.
+ //However, use reflection here is okay assuming types we care about
+ //are part of JRE standard libraries. Using eclipse 'type hirearchy' would
+ //also potentialy be very slow.
+ if (type!=null) {
+ String erasure = type.getErasure();
+ try {
+ Class> erasureClass = Class.forName(erasure);
+ return Map.class.isAssignableFrom(erasureClass);
+ } catch (Exception e) {
+ //type not resolveable
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get domain type for a map or list generic type.
+ */
+ public static Type getDomainType(Type type) {
+ if (isArray(type)) {
+ return getArrayDomainType(type);
+ } else {
+ return lastElement(type.getParams());
+ }
+ }
+
+ private static Type getArrayDomainType(Type type) {
+ if (type!=null) {
+ String fullName = type.getErasure();
+ Assert.isLegal(fullName.endsWith("[]"));
+ String elName = fullName.substring(0, fullName.length()-2);
+ return normalizePrimitiveType(new Type(elName, null));
+ }
+ return null;
+ }
+
+ /**
+ * Convert a type which is a 'primitive' type like 'int', 'long' etc. to its
+ * corresponding 'Boxed' type. If the type isn't a primitive type then
+ * just return it unchanged.
+ */
+ private static Type normalizePrimitiveType(Type type) {
+ if (type!=null) {
+ String name = type.getErasure();
+ Type boxType = PRIMITIVE_TO_BOX_TYPE.get(name);
+ if (boxType!=null) {
+ return boxType;
+ }
+ }
+ return type;
+ }
+
+ public Type getKeyType(Type mapOrArrayType) {
+ if (isSequencable(mapOrArrayType)) {
+ return INTEGER_TYPE;
+ } else {
+ //assumed to be a map
+ return firstElement(mapOrArrayType.getParams());
+ }
+ }
+
+ public boolean isAssignableType(Type type) {
+ return ASSIGNABLE_TYPES.contains(type.getErasure())
+ || isEnum(type)
+ || isAssignableList(type);
+ }
+
+ private boolean isAssignableList(Type type) {
+ //TODO: isBracketable means 'isList' right now, but this may not be
+ // the case in the future.
+ if (isBracketable(type)) {
+ Type domainType = getDomainType(type);
+ return isAtomic(domainType);
+ }
+ return false;
+ }
+
+ public boolean isEnum(Type type) {
+ try {
+ IType eclipseType = findType(type.getErasure());
+ if (eclipseType!=null) {
+ return eclipseType.isEnum();
+ }
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ return false;
+ }
+
+ private IType findType(String typeName) {
+ try {
+ if (javaProject!=null) {
+ return javaProject.findType(typeName);
+ }
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ return null;
+ }
+
+ private IType findType(Type beanType) {
+ return findType(beanType.getErasure());
+ }
+
+ private static final String[] NO_PARAMS = new String[0];
+ private static final Map VALUE_HINTERS = new HashMap<>();
+ static {
+ valueHints("java.nio.charset.Charset", new LazyProvider() {
+ @Override
+ protected String[] compute() {
+ Set charsets = Charset.availableCharsets().keySet();
+ return charsets.toArray(new String[charsets.size()]);
+ }
+ });
+ valueHints("java.util.Locale", new LazyProvider() {
+ @Override
+ protected String[] compute() {
+ Locale[] locales = SimpleDateFormat.getAvailableLocales();
+ String[] names = new String[locales.length];
+ for (int i = 0; i < names.length; i++) {
+ names[i] = locales[i].toString();
+ }
+ return names;
+ }
+ });
+ valueHints("org.springframework.util.MimeType", new LazyProvider() {
+ @Override
+ protected String[] compute() {
+ try {
+ Field f = MediaType.class.getDeclaredField("KNOWN_TYPES");
+ f.setAccessible(true);
+ @SuppressWarnings("unchecked")
+ Map map = (Map) f.get(null);
+ TreeSet mediaTypes = new TreeSet<>();
+ for (MediaType m : map.keySet()) {
+ mediaTypes.add(m.toString());
+ }
+ return mediaTypes.toArray(new String[mediaTypes.size()]);
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ return null;
+ }
+ });
+// valueHints("org.springframework.core.io.Resource", new ResourceHintProvider());
+ }
+
+ /**
+ * Determine properties that are setable on object of given type.
+ *
+ * Note that this may return both null or an empty list, but they mean
+ * different things. Null means that the properties on the object are not known,
+ * and therefore reconciling should not check property validity. On the other hand
+ * returning an empty list means that there are no properties. In this case,
+ * accessing properties is invalid and reconciler should show an error message
+ * for any property access.
+ *
+ * @return A list of known properties or null if the list of properties is unknown.
+ */
+ public List getProperties(Type type, EnumCaseMode enumMode, BeanPropertyNameMode beanMode) {
+ if (type==null) {
+ return null;
+ }
+ if (!isDotable(type)) {
+ //If dot navigation is not valid then really this is just like saying the type has no properties.
+ return Collections.emptyList();
+ }
+ if (isMap(type)) {
+ Type keyType = getKeyType(type);
+ if (keyType!=null) {
+ Collection keyHints = getAllowedValues(keyType, enumMode);
+ if (CollectionUtil.hasElements(keyHints)) {
+ Type valueType = getDomainType(type);
+ ArrayList properties = new ArrayList<>(keyHints.size());
+ for (StsValueHint hint : keyHints) {
+ String propName = hint.getValue();
+ properties.add(new TypedProperty(propName, valueType, hint.getDescriptionProvider(), hint.getDeprecation()));
+ }
+ return properties;
+ }
+ }
+ } else {
+ String typename = type.getErasure();
+ IType eclipseType = findType(typename);
+
+ //TODO: handle type parameters.
+ if (eclipseType!=null) {
+ List getters = getGetterMethods(eclipseType);
+ //TODO: getters inherited from super classes?
+ if (getters!=null && !getters.isEmpty()) {
+ ArrayList properties = new ArrayList<>(getters.size());
+ for (IMethod m : getters) {
+ Deprecation deprecation = DeprecationUtil.extract(m);
+ Type propType = null;
+ try {
+ propType = Type.fromSignature(m.getReturnType(), eclipseType);
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ if (beanMode.includesHyphenated()) {
+ properties.add(new TypedProperty(getterOrSetterNameToProperty(m.getElementName()), propType, deprecation));
+ }
+ if (beanMode.includesCamelCase()) {
+ properties.add(new TypedProperty(getterOrSetterNameToCamelName(m.getElementName()), propType, deprecation));
+ }
+ }
+ return properties;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Registers a strategy for providing value hints with a given typeName.
+ */
+ public static void valueHints(String typeName, ValueProviderStrategy provider) {
+ Assert.isLegal(!VALUE_HINTERS.containsKey(typeName)); //Only one value hinter per type is supported at the moment
+ ATOMIC_TYPES.add(typeName); //valueHints typically implies that the type should be treated as atomic as well.
+ ASSIGNABLE_TYPES.add(typeName); //valueHints typically implies that the type should be treated as atomic as well.
+ VALUE_HINTERS.put(typeName, provider);
+ }
+
+ /**
+ * Registers a strategy for providing value hints with a given typeName.
+ */
+ public static void valueHints(String typeName, Provider provider) {
+ valueHints(typeName, new ValueProviderStrategy() {
+ @Override
+ public Flux getValues(IJavaProject javaProject, String query) {
+ String[] values = provider.get();
+ if (ArrayUtils.hasElements(values)) {
+ return Flux.fromArray(values)
+ .map(StsValueHint::create);
+ }
+ return Flux.empty();
+ }
+ });
+ }
+
+ private String getterOrSetterNameToProperty(String name) {
+ String camelName = getterOrSetterNameToCamelName(name);
+ return StringUtil.camelCaseToHyphens(camelName);
+ }
+
+ public String getterOrSetterNameToCamelName(String name) {
+ Assert.isLegal(name.startsWith("set") || name.startsWith("get") || name.startsWith("is"));
+ int prefixLen = name.startsWith("is") ? 2 : 3;
+ String camelName = Character.toLowerCase(name.charAt(prefixLen)) + name.substring(prefixLen+1);
+ return camelName;
+ }
+
+ private List getGetterMethods(IType eclipseType) {
+ try {
+ if (eclipseType!=null && eclipseType.isClass()) {
+ IMethod[] allMethods = eclipseType.getMethods();
+ if (ArrayUtils.hasElements(allMethods)) {
+ ArrayList getters = new ArrayList<>();
+ for (IMethod m : allMethods) {
+ if (!isStatic(m) && isPublic(m)) {
+ String mname = m.getElementName();
+ if (
+ (mname.startsWith("get") && mname.length()>=4) ||
+ (mname.startsWith("is") && mname.length()>=3)
+ ) {
+ //Need at least x chars or the property name will be empty.
+ String sig = m.getSignature();
+ int numParams = Signature.getParameterCount(sig);
+ if (numParams==0) {
+ getters.add(m);
+ }
+ }
+ }
+ }
+ return getters;
+ }
+ }
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ return null;
+ }
+
+// private List getSetterMethods(IType eclipseType) {
+// try {
+// if (eclipseType!=null && eclipseType.isClass()) {
+// IMethod[] allMethods = eclipseType.getMethods();
+// if (ArrayUtils.hasElements(allMethods)) {
+// ArrayList setters = new ArrayList();
+// for (IMethod m : allMethods) {
+// String mname = m.getElementName();
+// if (mname.startsWith("set") && mname.length()>=4) {
+// //Need at least 4 chars or the property name will be empty.
+// String sig = m.getSignature();
+// int numParams = Signature.getParameterCount(sig);
+// if (numParams==1) {
+// setters.add(m);
+// }
+// }
+// }
+// return setters;
+// }
+// }
+// } catch (Exception e) {
+// BootActivator.log(e);
+// }
+// return null;
+// }
+
+ private boolean isStatic(IMethod m) {
+ try {
+ return Flags.isStatic(m.getFlags());
+ } catch (Exception e) {
+ //Couldn't determine if it was public or not... let's assume it was NOT
+ // (will result in potentially more CA completions)
+ Log.log(e);
+ return false;
+ }
+ }
+
+ private boolean isPublic(IMethod m) {
+ try {
+ return m.getDeclaringType().isInterface()
+ || Flags.isPublic(m.getFlags());
+ } catch (Exception e) {
+ //Couldn't determine if it was public or not... let's assume it WAS
+ // (will result in potentially more CA completions)
+ Log.log(e);
+ return true;
+ }
+ }
+
+ public Map getPropertiesMap(Type type, EnumCaseMode enumMode, BeanPropertyNameMode beanMode) {
+ //TODO: optimize, produce directly as a map instead of
+ // first creating list and then coverting it.
+ List list = getProperties(type, enumMode, beanMode);
+ if (list!=null) {
+ Map map = new HashMap<>();
+ for (TypedProperty p : list) {
+ map.put(p.getName(), p);
+ }
+ return map;
+ }
+ return null;
+ }
+
+ /**
+ * Maybe ne null in some contexts. In such context functionality will be limited because
+ * types can not be resolved.
+ */
+ public IJavaProject getJavaProject() {
+ return javaProject;
+ }
+
+ public IField getField(Type beanType, String propName) {
+ IType type = findType(beanType);
+ return getExactField(type, propName);
+ }
+
+ protected IField getExactField(IType type, String fieldName) {
+ IField f = type.getField(StringUtil.hyphensToCamelCase(fieldName, false));
+ if (f!=null && f.exists()) {
+ return f;
+ }
+ return null;
+ }
+
+ public IField getEnumConstant(Type enumType, String propName) {
+ IType type = findType(enumType);
+ //1: if propname is already spelled exactly...
+ IField f = getExactField(type, propName);
+ if (f!=null) return f;
+
+ //2: most likely enum constant is upper-case form of propname
+ String fieldName = StringUtil.hyphensToUpperCase(propName);
+ return getExactField(type, fieldName);
+ }
+
+
+ public IMethod getSetter(Type beanType, String propName) {
+ try {
+ String setterName = "set" + StringUtil.hyphensToCamelCase(propName, true);
+ IType type = findType(beanType);
+ for (IMethod m : type.getMethods()) {
+ if (setterName.equals(m.getElementName())) {
+ return m;
+ }
+ }
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ return null;
+ }
+
+ public IJavaElement getGetter(Type beanType, String propName) {
+ String getterName = "get" + StringUtil.hyphensToCamelCase(propName, true);
+ IType type = findType(beanType);
+
+ IMethod m = type.getMethod(getterName, NO_PARAMS);
+ if (m.exists()) {
+ return m;
+ }
+ return null;
+ }
+
+ public static String deprecatedPropertyMessage(String name, String contextType, String replace, String reason) {
+ StringBuilder msg = new StringBuilder("Property '"+name+"'");
+ if (StringUtil.hasText(contextType)) {
+ msg.append(" of type '"+contextType+"'");
+ }
+ boolean hasReplace = StringUtil.hasText(replace);
+ boolean hasReason = StringUtil.hasText(reason);
+ if (!hasReplace && !hasReason) {
+ msg.append(" is Deprecated!");
+ } else {
+ msg.append(" is Deprecated: ");
+ if (hasReplace) {
+ msg.append("Use '"+ replace +"' instead.");
+ if (hasReason) {
+ msg.append(" Reason: ");
+ }
+ }
+ if (hasReason) {
+ msg.append(reason);
+ }
+ }
+ return msg.toString();
+ }
+
+ public Collection getHintValues(Type type, String query, EnumCaseMode enumCaseMode) {
+ if (type!=null) {
+ Collection allowed = getAllowedValues(type, enumCaseMode);
+ if (allowed!=null) {
+ return allowed;
+ }
+ ValueProviderStrategy valueHinter = VALUE_HINTERS.get(type.getErasure());
+ if (valueHinter!=null) {
+ return valueHinter.getValuesNow(javaProject, query);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Determine the dimensionality of a collection-like type (i.e. a Map or List). The dimensionality
+ * is essentialy how many succesive 'indexing' operations need to be applied before reasing the actual elements.
+ *
+ * For examle:
+ * List -> 1
+ * List> -> 2
+ * List>> -> 2
+ * Map<*,List> -> 2
+ */
+ public static int getDimensionality(Type type) {
+ int dim = 0;
+ while (isSequencable(type) || isMap(type)) {
+ dim++;
+ type = getDomainType(type);
+ }
+ return dim;
+ }
+
+ public static boolean isClass(Type type) {
+ if (type!=null) {
+ return CLASS_TYPE_NAME.equals(type.getErasure());
+ }
+ return false;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // Addapting our interface so it is compatible with YTypeUtil
+ //
+ // This allows our types to be used by the more generic stuff from the 'editor.support' plugin.
+ //
+ // Note, it may be possible to avoid having these 'adaptor' methods by making YTypeUtil a paramerized
+ // type. I.e something like "interface YTypeUtil.
+ // Paramterizations like that tend to propagate fire and wide in the code and make for complicated
+ // signatures. For now using these bredging methods is simpler if perhaps a bit more error prone.
+
+// @Override
+// public boolean isAtomic(YType type) {
+// return isAtomic((Type)type);
+// }
+//
+// @Override
+// public boolean isMap(YType type) {
+// return isMap((Type)type);
+// }
+//
+// @Override
+// public boolean isSequencable(YType type) {
+// return isSequencable((Type)type);
+// }
+//
+// @Override
+// public YType getDomainType(YType type) {
+// return getDomainType((Type)type);
+// }
+//
+// @Override
+// public String[] getHintValues(YType type) {
+// return getAllowedValues((Type) type, EnumCaseMode.ALIASED);
+// }
+//
+// @SuppressWarnings("unchecked")
+// @Override
+// public List getProperties(YType type) {
+// //Dirty hack, passing this through a raw type to bypass the java type system
+// //complaining the List is not compatible with List
+// //This dirty and 'illegal' conversion is okay because the list is only used for reading.
+// @SuppressWarnings("rawtypes")
+// List props = getProperties((Type)type, EnumCaseMode.ALIASED, BeanPropertyNameMode.ALIASED);
+// return Collections.unmodifiableList(props);
+// }
+//
+// @SuppressWarnings("unchecked")
+// @Override
+// public Map getPropertiesMap(YType type) {
+// //Dirty hack, see comment in getProperties(YType)
+// @SuppressWarnings("rawtypes")
+// Map map = getPropertiesMap((Type)type, EnumCaseMode.ALIASED, BeanPropertyNameMode.ALIASED);
+// return Collections.unmodifiableMap(map);
+// }
+//
+// @Override
+// public String niceTypeName(YType type) {
+// return niceTypeName((Type)type);
+// }
+//
+// @Override
+// public YType getKeyType(YType type) {
+// return getKeyType((Type)type);
+// }
+
+}
\ No newline at end of file
diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypeUtilProvider.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypeUtilProvider.java
new file mode 100644
index 000000000..f1c2a4bd0
--- /dev/null
+++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypeUtilProvider.java
@@ -0,0 +1,8 @@
+package org.springframework.ide.vscode.boot.properties.metadata.types;
+
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+
+@FunctionalInterface
+public interface TypeUtilProvider {
+ TypeUtil getTypeUtil(IDocument doc);
+}
diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypedProperty.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypedProperty.java
new file mode 100644
index 000000000..69356bda3
--- /dev/null
+++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/TypedProperty.java
@@ -0,0 +1,97 @@
+package org.springframework.ide.vscode.boot.properties.metadata.types;
+
+import javax.inject.Provider;
+
+import org.springframework.boot.configurationmetadata.Deprecation;
+import org.springframework.ide.vscode.util.HtmlSnippet;
+import org.springframework.ide.vscode.yaml.schema.YTypedProperty;
+import org.springframework.ide.vscode.yaml.util.DescriptionProviders;
+
+/**
+ * Represents a property on a Type that can be accessed by name.
+ *
+ * @author Kris De Volder
+ */
+public class TypedProperty implements YTypedProperty {
+
+ /**
+ * The name of the property
+ */
+ private final String name;
+
+ /**
+ * The type of value associated with the property.
+ */
+ private final Type type;
+
+ /**
+ * Provides a description for this property.
+ */
+ private final Provider descriptionProvider;
+
+ private final Deprecation deprecation;
+
+ public TypedProperty(String name, Type type, Deprecation deprecation) {
+ this(name, type, DescriptionProviders.NO_DESCRIPTION, deprecation);
+ }
+
+ public TypedProperty(String name, Type type, Provider descriptionProvider, Deprecation deprecation) {
+ this.name = name;
+ this.type = type;
+ this.descriptionProvider = descriptionProvider;
+ this.deprecation = deprecation;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ @Override
+ public String toString() {
+ return name + "::" + type;
+ }
+
+ @Override
+ public HtmlSnippet getDescription() {
+ //TODO: real implementation that somehow gets this from somewhere (i.e. the JavaDoc)
+ // Note that presently the application.yml and application.properties editor do not actually
+ // use this description provider but produce hover infos in a different way (so this is only
+ // used in Schema-based content assist, reconciling and hovering.
+ //So in that sense putting a good implementation here is kind of pointless right now.
+ //More refactoring needs to be done to also make use of this.
+ return descriptionProvider.get();
+ }
+
+ public static Type typeOf(TypedProperty typedProperty) {
+ if (typedProperty!=null) {
+ return typedProperty.getType();
+ }
+ return null;
+ }
+
+ public boolean isDeprecated() {
+ return deprecation!=null;
+ }
+
+ public String getDeprecationReplacement() {
+ if (deprecation!=null) {
+ return deprecation.getReplacement();
+ }
+ return null;
+ }
+
+ public String getDeprecationReason() {
+ if (deprecation!=null) {
+ return deprecation.getReason();
+ }
+ return null;
+ }
+
+ public Deprecation getDeprecation() {
+ return deprecation;
+ }
+}
diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/util/DeprecationUtil.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/util/DeprecationUtil.java
new file mode 100644
index 000000000..4f9e336d1
--- /dev/null
+++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/util/DeprecationUtil.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.properties.util;
+
+import org.springframework.boot.configurationmetadata.Deprecation;
+import org.springframework.ide.vscode.java.IAnnotatable;
+import org.springframework.ide.vscode.java.IAnnotation;
+import org.springframework.ide.vscode.java.IJavaElement;
+import org.springframework.ide.vscode.java.IMemberValuePair;
+import org.springframework.ide.vscode.util.Log;
+
+import com.google.common.collect.ImmutableSet;
+
+public class DeprecationUtil {
+
+ private static final ImmutableSet DEPRECATED_ANOT_NAMES = ImmutableSet.of(
+ "org.springframework.boot.context.properties.DeprecatedConfigurationProperty",
+ "DeprecatedConfigurationProperty",
+ "java.lang.Deprecated",
+ "Deprecated"
+ );
+
+ /**
+ * Extract {@link Deprecation} info from annotations on a {@link IJavaElement}
+ */
+ public static Deprecation extract(IJavaElement je) {
+ if (je instanceof IAnnotatable) {
+ return extract((IAnnotatable)je);
+ }
+ return null;
+ }
+
+ /**
+ * Extract {@link Deprecation} info from annotations on a {@link IJavaElement}
+ */
+ private static Deprecation extract(IAnnotatable m) {
+ try {
+ for (IAnnotation a : m.getAnnotations()) {
+ if (DEPRECATED_ANOT_NAMES.contains(a.getElementName())) {
+ Deprecation d = new Deprecation();
+ for (IMemberValuePair pair : a.getMemberValuePairs()) {
+ String name = pair.getMemberName();
+ if (name.equals("reason")) {
+ d.setReason((String) pair.getValue());
+ } else if (name.equals("replacement")) {
+ d.setReplacement((String) pair.getValue());
+ }
+ }
+ return d;
+ }
+ }
+ } catch (Exception e) {
+ Log.log(e);
+ }
+ return null;
+ }
+
+
+}
diff --git a/vscode-extensions/commons/commons-java/.classpath b/vscode-extensions/commons/commons-java/.classpath
new file mode 100644
index 000000000..fae1a2b37
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/.classpath
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vscode-extensions/commons/commons-java/.project b/vscode-extensions/commons/commons-java/.project
new file mode 100644
index 000000000..bca620960
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/.project
@@ -0,0 +1,23 @@
+
+
+ commons-java
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/vscode-extensions/commons/commons-java/.settings/org.eclipse.jdt.core.prefs b/vscode-extensions/commons/commons-java/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..714351aec
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,5 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/vscode-extensions/commons/commons-java/.settings/org.eclipse.m2e.core.prefs b/vscode-extensions/commons/commons-java/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 000000000..f897a7f1c
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/vscode-extensions/commons/commons-java/pom.xml b/vscode-extensions/commons/commons-java/pom.xml
new file mode 100644
index 000000000..4bac01ea8
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/pom.xml
@@ -0,0 +1,22 @@
+
+ 4.0.0
+ commons-java
+ commons-java
+ Common code related to 'accessing Java knowledge'
+
+
+ org.springframework.ide.vscode
+ commons-parent
+ 0.0.1-SNAPSHOT
+ ../pom.xml
+
+
+
+
+ org.springframework.ide.vscode
+ commons-util
+ ${project.version}
+
+
+
\ No newline at end of file
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/Signature.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/Signature.java
new file mode 100644
index 000000000..e5959cfc2
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/boot/properties/metadata/types/Signature.java
@@ -0,0 +1,195 @@
+package org.springframework.ide.vscode.boot.properties.metadata.types;
+
+public class Signature {
+
+ //These are the bits of JDTs 'Signature' class. Only we copied the method decls
+ // of stuff we actually use
+
+ //TODO: For performamce reason, JDT probably works with String or even naked char[] instead
+ // of wrapping these in a proper 'TypeSignature' or 'MethodSignature' object. But probably we should
+ // do the proper wrapping and abstract out a interface for these types. A 'client'
+ // using 'Java knowledge' should not have to directly be dealing with the JVM method and
+ // type signature strings.
+
+ /**
+ * Kind constant for a class type signature.
+ * @see #getTypeSignatureKind(String)
+ * @since 3.0
+ */
+ public static final int CLASS_TYPE_SIGNATURE = 1;
+
+ /**
+ * Kind constant for an array type signature.
+ * @see #getTypeSignatureKind(String)
+ * @since 3.0
+ */
+ public static final int ARRAY_TYPE_SIGNATURE = 4;
+
+ /**
+ * Character constant indicating the start of an unresolved, named type in a
+ * signature. Value is 'Q'.
+ */
+ public static final char C_UNRESOLVED = 'Q';
+ //TODO: unless we use JDT to work with suource-types we probably don't see these?
+
+ /**
+ * Returns the kind of type signature encoded by the given string.
+ *
+ * @param typeSignature the type signature string
+ * @return the kind of type signature; one of the kind constants:
+ * {@link #ARRAY_TYPE_SIGNATURE}, {@link #CLASS_TYPE_SIGNATURE},
+ * {@link #BASE_TYPE_SIGNATURE}, or {@link #TYPE_VARIABLE_SIGNATURE},
+ * or (since 3.1) {@link #WILDCARD_TYPE_SIGNATURE} or {@link #CAPTURE_TYPE_SIGNATURE}
+ * or (since 3.7) {@link #INTERSECTION_TYPE_SIGNATURE}
+ * @exception IllegalArgumentException if this is not a type signature
+ * @since 3.0
+ */
+ public static int getTypeSignatureKind(String typeSignature) {
+ return getTypeSignatureKind(typeSignature.toCharArray());
+ }
+
+ /**
+ * Returns the kind of type signature encoded by the given string.
+ *
+ * @param typeSignature the type signature string
+ * @return the kind of type signature; one of the kind constants:
+ * {@link #ARRAY_TYPE_SIGNATURE}, {@link #CLASS_TYPE_SIGNATURE},
+ * {@link #BASE_TYPE_SIGNATURE}, or {@link #TYPE_VARIABLE_SIGNATURE},
+ * or (since 3.1) {@link #WILDCARD_TYPE_SIGNATURE} or {@link #CAPTURE_TYPE_SIGNATURE},
+ * or (since 3.7) {@link #INTERSECTION_TYPE_SIGNATURE}
+ * @exception IllegalArgumentException if this is not a type signature
+ * @since 3.0
+ */
+ public static int getTypeSignatureKind(char[] typeSignature) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Extracts the type erasure signature from the given parameterized type signature.
+ * Returns the given type signature if it is not parameterized.
+ *
+ * @param parameterizedTypeSignature the parameterized type signature
+ * @return the signature of the type erasure
+ * @exception IllegalArgumentException if the signature is syntactically
+ * incorrect
+ *
+ * @since 3.1
+ */
+ public static String getTypeErasure(String parameterizedTypeSignature) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Returns package fragment of a type signature. The package fragment separator must be '.'
+ * and the type fragment separator must be '$'.
+ *
+ * For example:
+ *
+ *
+ * getSignatureQualifier("Ljava.util.Map$Entry") -> "java.util"
+ *
+ *
+ *
+ *
+ * @param typeSignature the type signature
+ * @return the package fragment (separators are '.')
+ * @since 3.1
+ */
+ public static String getSignatureQualifier(String typeSignature) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Returns type fragment of a type signature. The package fragment separator must be '.'
+ * and the type fragment separator must be '$'.
+ *
+ * For example:
+ *
+ *
+ * getSignatureSimpleName("Ljava.util.Map$Entry") -> "Map.Entry"
+ *
+ *
+ *
+ *
+ * @param typeSignature the type signature
+ * @return the type fragment (separators are '.')
+ * @since 3.1
+ */
+ public static String getSignatureSimpleName(String typeSignature) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Extracts the type parameter signatures from the given method or type signature.
+ * The method or type signature is expected to be dot-based.
+ *
+ * @param methodOrTypeSignature the method or type signature
+ * @return the list of type parameter signatures
+ * @exception IllegalArgumentException if the signature is syntactically
+ * incorrect
+ *
+ * @since 3.1
+ */
+ public static String[] getTypeParameters(String methodOrTypeSignature) throws IllegalArgumentException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Extracts the type argument signatures from the given type signature.
+ * Returns an empty array if the type signature is not a parameterized type signature.
+ *
+ * @param parameterizedTypeSignature the parameterized type signature
+ * @return the signatures of the type arguments
+ * @exception IllegalArgumentException if the signature is syntactically incorrect
+ *
+ * @since 3.1
+ */
+ public static String[] getTypeArguments(String parameterizedTypeSignature) throws IllegalArgumentException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Returns the type signature without any array nesting.
+ *
+ * For example:
+ *
+ *
+ * getElementType("[[I") --> "I".
+ *
+ *
+ *
+ *
+ * @param typeSignature the type signature
+ * @return the type signature without arrays
+ * @exception IllegalArgumentException if the signature is not syntactically
+ * correct
+ */
+ public static String getElementType(String typeSignature) throws IllegalArgumentException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Returns the array count (array nesting depth) of the given type signature.
+ *
+ * @param typeSignature the type signature
+ * @return the array nesting depth, or 0 if not an array
+ * @exception IllegalArgumentException if the signature is not syntactically
+ * correct
+ */
+ public static int getArrayCount(String typeSignature) throws IllegalArgumentException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Returns the number of parameter types in the given method signature.
+ *
+ * @param methodSignature the method signature
+ * @return the number of parameters
+ * @exception IllegalArgumentException if the signature is not syntactically
+ * correct
+ */
+ public static int getParameterCount(String methodSignature) throws IllegalArgumentException {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/ClassFileConstants.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/ClassFileConstants.java
new file mode 100644
index 000000000..78412793e
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/ClassFileConstants.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Jesper S Moller - Contributions for
+ * Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
+ * Bug 406982 - [1.8][compiler] Generation of MethodParameters Attribute in classfile
+ * Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
+ * Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
+ *******************************************************************************/
+package org.springframework.ide.vscode.java;
+
+public interface ClassFileConstants {
+
+ int AccDefault = 0;
+ /*
+ * Modifiers
+ */
+ int AccPublic = 0x0001;
+ int AccPrivate = 0x0002;
+ int AccProtected = 0x0004;
+ int AccStatic = 0x0008;
+ int AccFinal = 0x0010;
+ int AccSynchronized = 0x0020;
+ int AccVolatile = 0x0040;
+ int AccBridge = 0x0040;
+ int AccTransient = 0x0080;
+ int AccVarargs = 0x0080;
+ int AccNative = 0x0100;
+ int AccInterface = 0x0200;
+ int AccAbstract = 0x0400;
+ int AccStrictfp = 0x0800;
+ int AccSynthetic = 0x1000;
+ int AccAnnotation = 0x2000;
+ int AccEnum = 0x4000;
+
+ /**
+ * From classfile version 52 (compliance 1.8 up), meaning that a formal parameter is mandated
+ * by a language specification, so all compilers for the language must emit it.
+ */
+ int AccMandated = 0x8000;
+
+
+ /**
+ * Other VM flags.
+ */
+ int AccSuper = 0x0020;
+
+// /**
+// * Extra flags for types and members attributes (not from the JVMS, should have been defined in ExtraCompilerModifiers).
+// */
+// int AccAnnotationDefault = ASTNode.Bit18; // indicate presence of an attribute "DefaultValue" (annotation method)
+// int AccDeprecated = ASTNode.Bit21; // indicate presence of an attribute "Deprecated"
+
+ int Utf8Tag = 1;
+ int IntegerTag = 3;
+ int FloatTag = 4;
+ int LongTag = 5;
+ int DoubleTag = 6;
+ int ClassTag = 7;
+ int StringTag = 8;
+ int FieldRefTag = 9;
+ int MethodRefTag = 10;
+ int InterfaceMethodRefTag = 11;
+ int NameAndTypeTag = 12;
+ int MethodHandleTag = 15;
+ int MethodTypeTag = 16;
+ int InvokeDynamicTag = 18;
+
+ int ConstantMethodRefFixedSize = 5;
+ int ConstantClassFixedSize = 3;
+ int ConstantDoubleFixedSize = 9;
+ int ConstantFieldRefFixedSize = 5;
+ int ConstantFloatFixedSize = 5;
+ int ConstantIntegerFixedSize = 5;
+ int ConstantInterfaceMethodRefFixedSize = 5;
+ int ConstantLongFixedSize = 9;
+ int ConstantStringFixedSize = 3;
+ int ConstantUtf8FixedSize = 3;
+ int ConstantNameAndTypeFixedSize = 5;
+ int ConstantMethodHandleFixedSize = 4;
+ int ConstantMethodTypeFixedSize = 3;
+ int ConstantInvokeDynamicFixedSize = 5;
+
+ // JVMS 4.4.8
+ int MethodHandleRefKindGetField = 1;
+ int MethodHandleRefKindGetStatic = 2;
+ int MethodHandleRefKindPutField = 3;
+ int MethodHandleRefKindPutStatic = 4;
+ int MethodHandleRefKindInvokeVirtual = 5;
+ int MethodHandleRefKindInvokeStatic = 6;
+ int MethodHandleRefKindInvokeSpecial = 7;
+ int MethodHandleRefKindNewInvokeSpecial = 8;
+ int MethodHandleRefKindInvokeInterface = 9;
+
+ int MAJOR_VERSION_1_1 = 45;
+ int MAJOR_VERSION_1_2 = 46;
+ int MAJOR_VERSION_1_3 = 47;
+ int MAJOR_VERSION_1_4 = 48;
+ int MAJOR_VERSION_1_5 = 49;
+ int MAJOR_VERSION_1_6 = 50;
+ int MAJOR_VERSION_1_7 = 51;
+ int MAJOR_VERSION_1_8 = 52;
+ int MAJOR_VERSION_1_9 = 53; // This might change
+
+ int MINOR_VERSION_0 = 0;
+ int MINOR_VERSION_1 = 1;
+ int MINOR_VERSION_2 = 2;
+ int MINOR_VERSION_3 = 3;
+ int MINOR_VERSION_4 = 4;
+
+ // JDK 1.1 -> 1.9, comparable value allowing to check both major/minor version at once 1.4.1 > 1.4.0
+ // 16 unsigned bits for major, then 16 bits for minor
+ long JDK1_1 = ((long)ClassFileConstants.MAJOR_VERSION_1_1 << 16) + ClassFileConstants.MINOR_VERSION_3; // 1.1. is 45.3
+ long JDK1_2 = ((long)ClassFileConstants.MAJOR_VERSION_1_2 << 16) + ClassFileConstants.MINOR_VERSION_0;
+ long JDK1_3 = ((long)ClassFileConstants.MAJOR_VERSION_1_3 << 16) + ClassFileConstants.MINOR_VERSION_0;
+ long JDK1_4 = ((long)ClassFileConstants.MAJOR_VERSION_1_4 << 16) + ClassFileConstants.MINOR_VERSION_0;
+ long JDK1_5 = ((long)ClassFileConstants.MAJOR_VERSION_1_5 << 16) + ClassFileConstants.MINOR_VERSION_0;
+ long JDK1_6 = ((long)ClassFileConstants.MAJOR_VERSION_1_6 << 16) + ClassFileConstants.MINOR_VERSION_0;
+ long JDK1_7 = ((long)ClassFileConstants.MAJOR_VERSION_1_7 << 16) + ClassFileConstants.MINOR_VERSION_0;
+ long JDK1_8 = ((long)ClassFileConstants.MAJOR_VERSION_1_8 << 16) + ClassFileConstants.MINOR_VERSION_0;
+ long JDK1_9 = ((long)ClassFileConstants.MAJOR_VERSION_1_9 << 16) + ClassFileConstants.MINOR_VERSION_0;
+
+ /*
+ * cldc1.1 is 45.3, but we modify it to be different from JDK1_1.
+ * In the code gen, we will generate the same target value as JDK1_1
+ */
+ long CLDC_1_1 = ((long)ClassFileConstants.MAJOR_VERSION_1_1 << 16) + ClassFileConstants.MINOR_VERSION_4;
+
+ // jdk level used to denote future releases: optional behavior is not enabled for now, but may become so. In order to enable these,
+ // search for references to this constant, and change it to one of the official JDT constants above.
+ long JDK_DEFERRED = Long.MAX_VALUE;
+
+ int INT_ARRAY = 10;
+ int BYTE_ARRAY = 8;
+ int BOOLEAN_ARRAY = 4;
+ int SHORT_ARRAY = 9;
+ int CHAR_ARRAY = 5;
+ int LONG_ARRAY = 11;
+ int FLOAT_ARRAY = 6;
+ int DOUBLE_ARRAY = 7;
+
+ // Debug attributes
+ int ATTR_SOURCE = 0x1; // SourceFileAttribute
+ int ATTR_LINES = 0x2; // LineNumberAttribute
+ int ATTR_VARS = 0x4; // LocalVariableTableAttribute
+ int ATTR_STACK_MAP_TABLE = 0x8; // Stack map table attribute
+ int ATTR_STACK_MAP = 0x10; // Stack map attribute: cldc
+ int ATTR_TYPE_ANNOTATION = 0x20; // type annotation attribute (jsr 308)
+ int ATTR_METHOD_PARAMETERS = 0x40; // method parameters attribute (jep 118)
+
+ // See java.lang.invoke.LambdaMetafactory constants - option bitflags when calling altMetaFactory()
+ int FLAG_SERIALIZABLE = 0x01;
+ int FLAG_MARKERS = 0x02;
+ int FLAG_BRIDGES = 0x04;
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/Flags.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/Flags.java
new file mode 100644
index 000000000..486e59f3e
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/Flags.java
@@ -0,0 +1,473 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * IBM Corporation - added constant AccDefault
+ * IBM Corporation - added constants AccBridge and AccVarargs for J2SE 1.5
+ *******************************************************************************/
+package org.springframework.ide.vscode.java;
+
+/**
+ * Utility class for decoding modifier flags in Java elements.
+ *
+ * This class provides static methods only.
+ *
+ *
+ * Note that the numeric values of these flags match the ones for class files
+ * as described in the Java Virtual Machine Specification (except for
+ * {@link #AccDeprecated}, {@link #AccAnnotationDefault}, and {@link #AccDefaultMethod}).
+ *
+ *
+ * The AST class Modifier provides
+ * similar functionality as this class, only in the
+ * org.eclipse.jdt.core.dom package.
+ *
+ *
+ * @see IMember#getFlags()
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class Flags {
+
+ /**
+ * Constant representing the absence of any flag.
+ * @since 3.0
+ */
+ public static final int AccDefault = ClassFileConstants.AccDefault;
+ /**
+ * Public access flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccPublic = ClassFileConstants.AccPublic;
+ /**
+ * Private access flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccPrivate = ClassFileConstants.AccPrivate;
+ /**
+ * Protected access flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccProtected = ClassFileConstants.AccProtected;
+ /**
+ * Static access flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccStatic = ClassFileConstants.AccStatic;
+ /**
+ * Final access flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccFinal = ClassFileConstants.AccFinal;
+ /**
+ * Synchronized access flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccSynchronized = ClassFileConstants.AccSynchronized;
+ /**
+ * Volatile property flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccVolatile = ClassFileConstants.AccVolatile;
+ /**
+ * Transient property flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccTransient = ClassFileConstants.AccTransient;
+ /**
+ * Native property flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccNative = ClassFileConstants.AccNative;
+ /**
+ * Interface property flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccInterface = ClassFileConstants.AccInterface;
+ /**
+ * Abstract property flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccAbstract = ClassFileConstants.AccAbstract;
+ /**
+ * Strictfp property flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccStrictfp = ClassFileConstants.AccStrictfp;
+ /**
+ * Super property flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccSuper = ClassFileConstants.AccSuper;
+ /**
+ * Synthetic property flag. See The Java Virtual Machine Specification for more details.
+ * @since 2.0
+ */
+ public static final int AccSynthetic = ClassFileConstants.AccSynthetic;
+
+// /**
+// * Deprecated property flag.
+// *
+// * Note that this flag's value is internal and is not defined in the
+// * Virtual Machine specification.
+// *
+// * @since 2.0
+// */
+// public static final int AccDeprecated = ClassFileConstants.AccDeprecated;
+
+ /**
+ * Bridge method property flag (added in J2SE 1.5). Used to flag a compiler-generated
+ * bridge methods.
+ * See The Java Virtual Machine Specification for more details.
+ * @since 3.0
+ */
+ public static final int AccBridge = ClassFileConstants.AccBridge;
+
+ /**
+ * Varargs method property flag (added in J2SE 1.5).
+ * Used to flag variable arity method declarations.
+ * See The Java Virtual Machine Specification for more details.
+ * @since 3.0
+ */
+ public static final int AccVarargs = ClassFileConstants.AccVarargs;
+
+ /**
+ * Enum property flag (added in J2SE 1.5).
+ * See The Java Virtual Machine Specification for more details.
+ * @since 3.0
+ */
+ public static final int AccEnum = ClassFileConstants.AccEnum;
+
+ /**
+ * Annotation property flag (added in J2SE 1.5).
+ * See The Java Virtual Machine Specification for more details.
+ * @since 3.0
+ */
+ public static final int AccAnnotation = ClassFileConstants.AccAnnotation;
+
+// /**
+// * Default method property flag.
+// *
+// * Note that this flag's value is internal and is not defined in the
+// * Virtual Machine specification.
+// *
+// * @since 3.10
+// */
+// public static final int AccDefaultMethod = ExtraCompilerModifiers.AccDefaultMethod;
+//
+// /**
+// * Annotation method default property flag.
+// * Used to flag annotation type methods that declare a default value.
+// *
+// * Note that this flag's value is internal and is not defined in the
+// * Virtual Machine specification.
+// *
+// * @since 3.10
+// */
+// public static final int AccAnnotationDefault = ClassFileConstants.AccAnnotationDefault;
+
+ /**
+ * Not instantiable.
+ */
+ private Flags() {
+ // Not instantiable
+ }
+ /**
+ * Returns whether the given integer includes the abstract modifier.
+ *
+ * @param flags the flags
+ * @return true if the abstract modifier is included
+ */
+ public static boolean isAbstract(int flags) {
+ return (flags & AccAbstract) != 0;
+ }
+// /**
+// * Returns whether the given integer includes the indication that the
+// * element is deprecated (@deprecated tag in Javadoc comment).
+// *
+// * @param flags the flags
+// * @return true if the element is marked as deprecated
+// */
+// public static boolean isDeprecated(int flags) {
+// return (flags & AccDeprecated) != 0;
+// }
+
+ /**
+ * Returns whether the given integer includes the final modifier.
+ *
+ * @param flags the flags
+ * @return true if the final modifier is included
+ */
+ public static boolean isFinal(int flags) {
+ return (flags & AccFinal) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the interface modifier.
+ *
+ * @param flags the flags
+ * @return true if the interface modifier is included
+ * @since 2.0
+ */
+ public static boolean isInterface(int flags) {
+ return (flags & AccInterface) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the native modifier.
+ *
+ * @param flags the flags
+ * @return true if the native modifier is included
+ */
+ public static boolean isNative(int flags) {
+ return (flags & AccNative) != 0;
+ }
+ /**
+ * Returns whether the given integer does not include one of the
+ * public, private, or protected flags.
+ *
+ * @param flags the flags
+ * @return true if no visibility flag is set
+ * @since 3.2
+ */
+ public static boolean isPackageDefault(int flags) {
+ return (flags & (AccPublic | AccPrivate | AccProtected)) == 0;
+ }
+ /**
+ * Returns whether the given integer includes the private modifier.
+ *
+ * @param flags the flags
+ * @return true if the private modifier is included
+ */
+ public static boolean isPrivate(int flags) {
+ return (flags & AccPrivate) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the protected modifier.
+ *
+ * @param flags the flags
+ * @return true if the protected modifier is included
+ */
+ public static boolean isProtected(int flags) {
+ return (flags & AccProtected) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the public modifier.
+ *
+ * @param flags the flags
+ * @return true if the public modifier is included
+ */
+ public static boolean isPublic(int flags) {
+ return (flags & AccPublic) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the static modifier.
+ *
+ * @param flags the flags
+ * @return true if the static modifier is included
+ */
+ public static boolean isStatic(int flags) {
+ return (flags & AccStatic) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the super modifier.
+ *
+ * @param flags the flags
+ * @return true if the super modifier is included
+ * @since 3.2
+ */
+ public static boolean isSuper(int flags) {
+ return (flags & AccSuper) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the strictfp modifier.
+ *
+ * @param flags the flags
+ * @return true if the strictfp modifier is included
+ */
+ public static boolean isStrictfp(int flags) {
+ return (flags & AccStrictfp) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the synchronized modifier.
+ *
+ * @param flags the flags
+ * @return true if the synchronized modifier is included
+ */
+ public static boolean isSynchronized(int flags) {
+ return (flags & AccSynchronized) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the indication that the
+ * element is synthetic.
+ *
+ * @param flags the flags
+ * @return true if the element is marked synthetic
+ */
+ public static boolean isSynthetic(int flags) {
+ return (flags & AccSynthetic) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the transient modifier.
+ *
+ * @param flags the flags
+ * @return true if the transient modifier is included
+ */
+ public static boolean isTransient(int flags) {
+ return (flags & AccTransient) != 0;
+ }
+ /**
+ * Returns whether the given integer includes the volatile modifier.
+ *
+ * @param flags the flags
+ * @return true if the volatile modifier is included
+ */
+ public static boolean isVolatile(int flags) {
+ return (flags & AccVolatile) != 0;
+ }
+
+ /**
+ * Returns whether the given integer has the AccBridge
+ * bit set.
+ *
+ * @param flags the flags
+ * @return true if the AccBridge flag is included
+ * @see #AccBridge
+ * @since 3.0
+ */
+ public static boolean isBridge(int flags) {
+ return (flags & AccBridge) != 0;
+ }
+
+ /**
+ * Returns whether the given integer has the AccVarargs
+ * bit set.
+ *
+ * @param flags the flags
+ * @return true if the AccVarargs flag is included
+ * @see #AccVarargs
+ * @since 3.0
+ */
+ public static boolean isVarargs(int flags) {
+ return (flags & AccVarargs) != 0;
+ }
+
+ /**
+ * Returns whether the given integer has the AccEnum
+ * bit set.
+ *
+ * @param flags the flags
+ * @return true if the AccEnum flag is included
+ * @see #AccEnum
+ * @since 3.0
+ */
+ public static boolean isEnum(int flags) {
+ return (flags & AccEnum) != 0;
+ }
+
+ /**
+ * Returns whether the given integer has the AccAnnotation
+ * bit set.
+ *
+ * @param flags the flags
+ * @return true if the AccAnnotation flag is included
+ * @see #AccAnnotation
+ * @since 3.0
+ */
+ public static boolean isAnnotation(int flags) {
+ return (flags & AccAnnotation) != 0;
+ }
+
+// /**
+// * Returns whether the given integer has the AccDefaultMethod
+// * bit set. Note that this flag represents the usage of the 'default' keyword
+// * on a method and should not be confused with the 'package' access visibility (which used to be called 'default access').
+// *
+// * @return true if the AccDefaultMethod flag is included
+// * @see #AccDefaultMethod
+// * @since 3.10
+// */
+// public static boolean isDefaultMethod(int flags) {
+// return (flags & AccDefaultMethod) != 0;
+// }
+
+// /**
+// * Returns whether the given integer has the AccAnnnotationDefault
+// * bit set.
+// *
+// * @return true if the AccAnnotationDefault flag is included
+// * @see #AccAnnotationDefault
+// * @since 3.10
+// */
+// public static boolean isAnnnotationDefault(int flags) {
+// return (flags & AccAnnotationDefault) != 0;
+// }
+
+ /**
+ * Returns a standard string describing the given modifier flags.
+ * Only modifier flags are included in the output; deprecated,
+ * synthetic, bridge, etc. flags are ignored.
+ *
+ * The flags are output in the following order:
+ *
public protected private
+ * abstract default static final synchronized native strictfp transient volatile
+ *
+ * This order is consistent with the recommendations in JLS8 ("*Modifier:" rules in chapters 8 and 9).
+ *
+ *
+ * Note that the flags of a method can include the AccVarargs flag that has no standard description. Since the AccVarargs flag has the same value as
+ * the AccTransient flag (valid for fields only), attempting to get the description of method modifiers with the AccVarargs flag set would result in an
+ * unexpected description. Clients should ensure that the AccVarargs is not included in the flags of a method as follows:
+ *
+ * IMethod method = ...
+ * int flags = method.getFlags() & ~Flags.AccVarargs;
+ * return Flags.toString(flags);
+ *
+ *
+ *
+ * Examples results:
+ *
+ * "public static final"
+ * "private native"
+ *
+ *
+ *
+ * @param flags the flags
+ * @return the standard string representation of the given flags
+ */
+ public static String toString(int flags) {
+ StringBuffer sb = new StringBuffer();
+
+ if (isPublic(flags))
+ sb.append("public "); //$NON-NLS-1$
+ if (isProtected(flags))
+ sb.append("protected "); //$NON-NLS-1$
+ if (isPrivate(flags))
+ sb.append("private "); //$NON-NLS-1$
+ if (isAbstract(flags))
+ sb.append("abstract "); //$NON-NLS-1$
+// if (isDefaultMethod(flags))
+// sb.append("default "); //$NON-NLS-1$
+ if (isStatic(flags))
+ sb.append("static "); //$NON-NLS-1$
+ if (isFinal(flags))
+ sb.append("final "); //$NON-NLS-1$
+ if (isSynchronized(flags))
+ sb.append("synchronized "); //$NON-NLS-1$
+ if (isNative(flags))
+ sb.append("native "); //$NON-NLS-1$
+ if (isStrictfp(flags))
+ sb.append("strictfp "); //$NON-NLS-1$
+ if (isTransient(flags))
+ sb.append("transient "); //$NON-NLS-1$
+ if (isVolatile(flags))
+ sb.append("volatile "); //$NON-NLS-1$
+ int len = sb.length();
+ if (len == 0)
+ return ""; //$NON-NLS-1$
+ sb.setLength(len - 1);
+ return sb.toString();
+ }
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IAnnotatable.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IAnnotatable.java
new file mode 100644
index 000000000..23d21283d
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IAnnotatable.java
@@ -0,0 +1,7 @@
+package org.springframework.ide.vscode.java;
+
+public interface IAnnotatable extends IJavaElement {
+
+ IAnnotation[] getAnnotations();
+
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IAnnotation.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IAnnotation.java
new file mode 100644
index 000000000..60bdbb772
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IAnnotation.java
@@ -0,0 +1,15 @@
+package org.springframework.ide.vscode.java;
+
+public interface IAnnotation extends IJavaElement {
+
+ /**
+ * Returns the member-value pairs of this annotation. Returns an empty
+ * array if this annotation is a marker annotation. Returns a size-1 array if this
+ * annotation is a single member annotation. In this case, the member
+ * name is always "value".
+ *
+ * @return the member-value pairs of this annotation
+ */
+ IMemberValuePair[] getMemberValuePairs();
+
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IField.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IField.java
new file mode 100644
index 000000000..84b6110f3
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IField.java
@@ -0,0 +1,5 @@
+package org.springframework.ide.vscode.java;
+
+public interface IField extends IMember {
+ boolean isEnumConstant();
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IJavaElement.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IJavaElement.java
new file mode 100644
index 000000000..04aec7bf2
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IJavaElement.java
@@ -0,0 +1,9 @@
+package org.springframework.ide.vscode.java;
+
+import org.springframework.ide.vscode.util.HtmlSnippet;
+
+public interface IJavaElement {
+ String getElementName();
+ HtmlSnippet getJavaDoc();
+ boolean exists();
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IJavaProject.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IJavaProject.java
new file mode 100644
index 000000000..fd02c0b71
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IJavaProject.java
@@ -0,0 +1,8 @@
+package org.springframework.ide.vscode.java;
+
+import java.nio.file.Path;
+
+public interface IJavaProject extends IJavaElement {
+ IType findType(String fqName);
+ Path getPath();
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IMember.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IMember.java
new file mode 100644
index 000000000..dd0860515
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IMember.java
@@ -0,0 +1,35 @@
+package org.springframework.ide.vscode.java;
+
+public interface IMember extends IJavaElement, IAnnotatable {
+
+ /**
+ * Returns the modifier flags for this member. The flags can be examined using class
+ * Flags.
+ *
+ * For {@linkplain #isBinary() binary} members, flags from the class file
+ * as well as derived flags {@link Flags#AccAnnotationDefault} and {@link Flags#AccDefaultMethod} are included.
+ *
+ *
+ * For source members, only flags as indicated in the source are returned. Thus if an interface
+ * defines a method void myMethod();, the flags don't include the
+ * 'public' flag. Source flags include {@link Flags#AccAnnotationDefault} as well.
+ *
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ * exception occurs while accessing its corresponding resource.
+ * @return the modifier flags for this member
+ * @see Flags
+ */
+ int getFlags();
+
+ /**
+ * Returns the type in which this member is declared, or null
+ * if this member is not declared in a type (for example, a top-level type).
+ * This is a handle-only method.
+ *
+ * @return the type in which this member is declared, or null
+ * if this member is not declared in a type (for example, a top-level type)
+ */
+ IType getDeclaringType();
+
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IMemberValuePair.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IMemberValuePair.java
new file mode 100644
index 000000000..fdd7b4030
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IMemberValuePair.java
@@ -0,0 +1,28 @@
+package org.springframework.ide.vscode.java;
+
+public interface IMemberValuePair {
+
+ /**
+ * Returns the member's name of this member-value pair.
+ *
+ * @return the member's name of this member-value pair.
+ */
+ String getMemberName();
+
+ /**
+ * Returns the value of this member-value pair. The type of this value
+ * is function of this member-value pair's {@link #getValueKind() value kind}. It is an
+ * instance of {@link Object}[] if the value is an array.
+ *
+ * If the value kind is {@link #K_UNKNOWN} and the value is not an array, then the
+ * value is null.
+ * If the value kind is {@link #K_UNKNOWN} and the value is an array, then the
+ * value is an array containing {@link Object}s and/or nulls for
+ * unknown elements.
+ * See {@link #K_UNKNOWN} for more details.
+ *
+ * @return the value of this member-value pair.
+ */
+ Object getValue();
+
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IMethod.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IMethod.java
new file mode 100644
index 000000000..758898feb
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IMethod.java
@@ -0,0 +1,49 @@
+package org.springframework.ide.vscode.java;
+
+import org.springframework.ide.vscode.boot.properties.metadata.types.Signature;
+
+public interface IMethod extends IMember {
+
+ /**
+ * Returns the type signature of the return value of this method.
+ * For constructors, this returns the signature for void.
+ *
+ * For example, a source method declared as public String getName()
+ * would return "QString;".
+ *
+ *
+ * The type signature may be either unresolved (for source types)
+ * or resolved (for binary types), and either basic (for basic types)
+ * or rich (for parameterized types). See {@link Signature} for details.
+ *
+ *
+ * @exception JavaModelException if this element does not exist or if an
+ * exception occurs while accessing its corresponding resource.
+ * @return the type signature of the return value of this method, void for constructors
+ * @see Signature
+ */
+ String getReturnType();
+
+ /**
+ * Returns the signature of this method. This includes the signatures for the
+ * parameter types and return type, but does not include the method name,
+ * exception types, or type parameters.
+ *
+ * For example, a source method declared as public void foo(String text, int length)
+ * would return "(QString;I)V".
+ *
+ *
+ * The type signatures embedded in the method signature may be either unresolved
+ * (for source types) or resolved (for binary types), and either basic (for
+ * basic types) or rich (for parameterized types). See {@link Signature} for
+ * details.
+ *
+ *
+ * @return the signature of this method
+ * @exception JavaModelException if this element does not exist or if an
+ * exception occurs while accessing its corresponding resource.
+ * @see Signature
+ */
+ String getSignature();
+
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IType.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IType.java
new file mode 100644
index 000000000..a1c821262
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/java/IType.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * IBM Corporation - added J2SE 1.5 support
+ * Stephan Herrmann - Contribution for
+ * Bug 463533 - Signature.getSignatureSimpleName() returns different results for resolved and unresolved extends
+ *******************************************************************************/
+package org.springframework.ide.vscode.java;
+
+/**
+ * Replaces eclipse JDT IType.
+ */
+public interface IType extends IMember {
+
+ boolean isClass();
+ boolean isEnum();
+ boolean isInterface();
+
+ /**
+ * Returns the fully qualified name of this type,
+ * including qualification for any containing types and packages.
+ * This is the name of the package, followed by '.',
+ * followed by the type-qualified name.
+ *
+ * Note: The enclosing type separator used in the type-qualified
+ * name is '$', not '.'.
+ *
+ * This method is fully equivalent to getFullyQualifiedName('$').
+ * This is a handle-only method.
+ *
+ * @see IType#getTypeQualifiedName()
+ * @see IType#getFullyQualifiedName(char)
+ * @return the fully qualified name of this type
+ */
+ String getFullyQualifiedName();
+
+ /**
+ * Returns the field with the specified name
+ * in this type (for example, "bar").
+ * This is a handle-only method. The field may or may not exist.
+ *
+ * @param name the given name
+ * @return the field with the specified name in this type
+ */
+ IField getField(String name);
+
+ /**
+ * Returns the fields declared by this type in the order in which they appear
+ * in the source or class file. For binary types, this includes synthetic fields.
+ *
+ * @return the fields declared by this type
+ */
+ IField[] getFields();
+
+ /**
+ * Returns the method with the specified name and parameter types
+ * in this type (for example, "foo", {"I", "QString;"}).
+ * To get the handle for a constructor, the name specified must be the
+ * simple name of the enclosing type.
+ * This is a handle-only method. The method may or may not be present.
+ *
+ * The type signatures may be either unresolved (for source types)
+ * or resolved (for binary types), and either basic (for basic types)
+ * or rich (for parameterized types). See {@link Signature} for details.
+ * Note that the parameter type signatures for binary methods are expected
+ * to be dot-based.
+ *
+ *
+ * @param name the given name
+ * @param parameterTypeSignatures the given parameter types
+ * @return the method with the specified name and parameter types in this type
+ */
+ IMethod getMethod(String name, String[] parameterTypeSignatures);
+
+ /**
+ * Returns the methods and constructors declared by this type.
+ * For binary types, this may include the special <clinit> method
+ * and synthetic methods.
+ *
+ * The results are listed in the order in which they appear in the source or class file.
+ *
+ *
+ * @return the methods and constructors declared by this type
+ */
+ IMethod[] getMethods();
+
+ /**
+ * Resolves the given type name within the context of this type (depending on the type hierarchy
+ * and its imports).
+ *
+ * Multiple answers might be found in case there are ambiguous matches.
+ *
+ *
+ * Each matching type name is decomposed as an array of two strings, the first denoting the package
+ * name (dot-separated) and the second being the type name. The package name is empty if it is the
+ * default package. The type name is the type qualified name using a '.' enclosing type separator.
+ *
+ *
+ * Returns null if unable to find any matching type.
+ *
+ *
+ * For example, resolution of "Object" would typically return
+ * {{"java.lang", "Object"}}. Another resolution that returns
+ * {{"", "X.Inner"}} represents the inner type Inner defined in type X in the
+ * default package.
+ *
+ *
+ * @param typeName the given type name
+ * @return the resolved type names or null if unable to find any matching type
+ * @see #getTypeQualifiedName(char)
+ */
+ String[][] resolveType(String typeName);
+
+}
diff --git a/vscode-extensions/commons/commons-language-server/pom.xml b/vscode-extensions/commons/commons-language-server/pom.xml
index 0376556b6..2c47c1de6 100644
--- a/vscode-extensions/commons/commons-language-server/pom.xml
+++ b/vscode-extensions/commons/commons-language-server/pom.xml
@@ -12,30 +12,16 @@
../pom.xml
-
-
-
- oss-sonatype
- oss-sonatype
- https://oss.sonatype.org/content/repositories/snapshots/
-
- true
-
-
-
-
org.springframework.ide.vscode
commons-util
${project.version}
-
org.springframework.ide.vscode
- language-server-test-harness
+ commons-java
${project.version}
- test
@@ -79,5 +65,15 @@
jackson-datatype-jdk8
${jackson-2-version}
+
+
+
+ org.springframework.ide.vscode
+ language-server-test-harness
+ ${project.version}
+ test
+
+
+
diff --git a/vscode-extensions/commons/commons-language-server/pom.xml~ b/vscode-extensions/commons/commons-language-server/pom.xml~
deleted file mode 100644
index 9d6330f2c..000000000
--- a/vscode-extensions/commons/commons-language-server/pom.xml~
+++ /dev/null
@@ -1,83 +0,0 @@
-
- 4.0.0
- language-server-commons
- language-server-commons
- Shared utilities for building vscode language servers in Java
-
-
- org.springframework.ide.vscode
- commons-parent
- 0.0.1-SNAPSHOT
- ../pom.xml
-
-
-
-
-
- oss-sonatype
- oss-sonatype
- https://oss.sonatype.org/content/repositories/snapshots/
-
- true
-
-
-
-
-
-
- org.springframework.ide.vscode
- commons-util
- ${project.version}
-
-
-
- org.springframework.ide.vscode
- language-server-test-harness
- ${project.version}
- test
-
-
-
- io.typefox.lsapi
- io.typefox.lsapi
- ${lsapi-version}
-
-
- io.typefox.lsapi
- io.typefox.lsapi.services
- ${lsapi-version}
-
-
- io.typefox.lsapi
- io.typefox.lsapi.annotations
- ${lsapi-version}
-
-
-
- com.fasterxml.jackson.core
- jackson-core
- ${jackson-2-version}
-
-
- com.fasterxml.jackson.core
- jackson-annotations
- ${jackson-2-version}
-
-
- com.fasterxml.jackson.core
- jackson-databind
- ${jackson-2-version}
-
-
- com.fasterxml.jackson.datatype
- jackson-datatype-jsr310
- ${jackson-2-version}
-
-
- com.fasterxml.jackson.datatype
- jackson-datatype-jdk8
- ${jackson-2-version}
-
-
-
\ No newline at end of file
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/DocumentEdits.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/DocumentEdits.java
similarity index 96%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/DocumentEdits.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/DocumentEdits.java
index adb277986..79540717e 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/DocumentEdits.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/DocumentEdits.java
@@ -8,15 +8,15 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
-package org.springframework.ide.vscode.commons.completion;
+package org.springframework.ide.vscode.commons.languageserver.completion;
import java.util.ArrayList;
+import org.springframework.ide.vscode.commons.languageserver.util.BadLocationException;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.IRegion;
+import org.springframework.ide.vscode.commons.languageserver.util.Region;
import org.springframework.ide.vscode.util.Assert;
-import org.springframework.ide.vscode.util.BadLocationException;
-import org.springframework.ide.vscode.util.IDocument;
-import org.springframework.ide.vscode.util.IRegion;
-import org.springframework.ide.vscode.util.Region;
import io.typefox.lsapi.TextEdit;
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/ICompletionEngine.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/ICompletionEngine.java
similarity index 82%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/ICompletionEngine.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/ICompletionEngine.java
index 2cadc73d5..d838e238f 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/ICompletionEngine.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/ICompletionEngine.java
@@ -8,11 +8,11 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
-package org.springframework.ide.vscode.commons.completion;
+package org.springframework.ide.vscode.commons.languageserver.completion;
import java.util.Collection;
-import org.springframework.ide.vscode.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
/**
* @author Kris De Volder
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/ICompletionProposal.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/ICompletionProposal.java
similarity index 81%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/ICompletionProposal.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/ICompletionProposal.java
index 60e9273b1..aa0f7e919 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/ICompletionProposal.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/ICompletionProposal.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.commons.completion;
+package org.springframework.ide.vscode.commons.languageserver.completion;
import io.typefox.lsapi.CompletionItemKind;
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/ProposalApplier.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/ProposalApplier.java
similarity index 83%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/ProposalApplier.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/ProposalApplier.java
index 9a6b35425..85c20831e 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/completion/ProposalApplier.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/ProposalApplier.java
@@ -8,10 +8,10 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
-package org.springframework.ide.vscode.commons.completion;
+package org.springframework.ide.vscode.commons.languageserver.completion;
-import org.springframework.ide.vscode.util.IDocument;
-import org.springframework.ide.vscode.util.IRegion;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.IRegion;
/**
* Interface that represents the methods that one needs to implement in order
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/DefaultJavaProjectFinder.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/DefaultJavaProjectFinder.java
new file mode 100644
index 000000000..e8e7339aa
--- /dev/null
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/DefaultJavaProjectFinder.java
@@ -0,0 +1,92 @@
+package org.springframework.ide.vscode.commons.languageserver.java;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.java.IJavaProject;
+import org.springframework.ide.vscode.java.IType;
+import org.springframework.ide.vscode.util.HtmlSnippet;
+import org.springframework.ide.vscode.util.StringUtil;
+
+public class DefaultJavaProjectFinder implements JavaProjectFinder {
+
+ private final String CLASSPATH_FILE_NAME;
+
+ public DefaultJavaProjectFinder(String classpathFileName) {
+ this.CLASSPATH_FILE_NAME = classpathFileName;
+ }
+
+ private File findClasspathFile(File file) {
+ if (file!=null && file.exists()) {
+ File cpFile = new File(file, CLASSPATH_FILE_NAME);
+ if (cpFile.isFile()) {
+ return cpFile;
+ } else {
+ return findClasspathFile(file.getParentFile());
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public IJavaProject find(IDocument d) {
+ String uriStr = d.getUri();
+ if (StringUtil.hasText(uriStr)) {
+ try {
+ URI uri = new URI(uriStr);
+ //TODO: This only work with File uri. Should it work with others too?
+ File file = new File(uri).getAbsoluteFile();
+ File cpFile = findClasspathFile(file);
+ if (cpFile!=null) {
+ return new JavaProjectWithClasspathFile(cpFile);
+ }
+ } catch (URISyntaxException | IllegalArgumentException e) {
+ //garbage data. Ignore it.
+ }
+ }
+ return null;
+ };
+
+ private static class JavaProjectWithClasspathFile implements IJavaProject {
+
+ private File cpFile;
+
+ public JavaProjectWithClasspathFile(File cpFile) {
+ this.cpFile = cpFile;
+ }
+
+ @Override
+ public String getElementName() {
+ return cpFile.getParentFile().getName();
+ }
+
+ @Override
+ public HtmlSnippet getJavaDoc() {
+ return null;
+ }
+
+ @Override
+ public boolean exists() {
+ return cpFile.exists();
+ }
+
+ @Override
+ public IType findType(String fqName) {
+ //TODO: implement
+ return null;
+ }
+
+ @Override
+ public Path getPath() {
+ return cpFile.getParentFile().toPath();
+ }
+
+ @Override
+ public String toString() {
+ return "JavaProjectWithClasspathFile("+cpFile+")";
+ }
+ }
+}
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java
new file mode 100644
index 000000000..40e27e65a
--- /dev/null
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java
@@ -0,0 +1,10 @@
+package org.springframework.ide.vscode.commons.languageserver.java;
+
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.java.IJavaProject;
+
+@FunctionalInterface
+public interface JavaProjectFinder {
+ JavaProjectFinder DEFAULT = new DefaultJavaProjectFinder("classpath.txt");
+ IJavaProject find(IDocument doc);
+}
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/ProblemFixer.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/ProblemFixer.java
new file mode 100644
index 000000000..e5cf4b2a4
--- /dev/null
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/ProblemFixer.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.commons.languageserver.quickfix;
+
+import java.util.List;
+
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
+
+/**
+ * Represents a strategy for computing potential quickfixes for a given problem.
+ *
+ * @author Kris De Volder
+ */
+@FunctionalInterface
+public interface ProblemFixer {
+
+ /**
+ * Implementor can inspect the problem and quickfix context provided as parameters.
+ *
+ * If the problem is deemed fixable, the strategy can contribute one or more fixes by
+ * adding them to the list of proposals (provided as third parameter).
+ */
+ void contributeFixes(
+ QuickfixContext context, ReconcileProblem problem,
+ List proposals
+ );
+
+}
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/QuickfixContext.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/QuickfixContext.java
new file mode 100644
index 000000000..cf62d2ae0
--- /dev/null
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/quickfix/QuickfixContext.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 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.commons.languageserver.quickfix;
+
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+
+/**
+ * Provides access to additional context info and objects that quickfixes might
+ * need in order to be able to apply themselves.
+ *
+ * @author Kris De Volder
+ */
+public interface QuickfixContext {
+// IProject getProject();
+// IPreferenceStore getWorkspacePreferences();
+// IPreferenceStore getProjectPreferences();
+// IJavaProject getJavaProject();
+// UserInteractions getUI();
+ IDocument getDocument();
+}
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/BadWordReconcileEngine.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/BadWordReconcileEngine.java
new file mode 100644
index 000000000..cccb9494b
--- /dev/null
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/BadWordReconcileEngine.java
@@ -0,0 +1,67 @@
+package org.springframework.ide.vscode.commons.languageserver.reconcile;
+
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+
+/**
+ * A fake reconcule engine which is not useful except for quickly testing
+ * whether stuff is wired up correctly to the editor.
+ */
+public class BadWordReconcileEngine implements IReconcileEngine {
+
+ static enum BWProblemType implements ProblemType {
+ VERY_BAD_WORD,
+ BAD_WORD;
+
+ @Override
+ public ProblemSeverity getDefaultSeverity() {
+ if (this==VERY_BAD_WORD) {
+ return ProblemSeverity.ERROR;
+ } else {
+ return ProblemSeverity.WARNING;
+ }
+ }
+
+ @Override
+ public String getCode() {
+ return this.name();
+ }
+ }
+
+ private final String[] BADWORDS = {
+ "bar", "foo"
+ };
+
+ public BadWordReconcileEngine() {
+ }
+
+ @Override
+ public void reconcile(IDocument doc, IProblemCollector problemCollector) {
+ String text = doc.get();
+ System.out.println(">>>> reconciling for bad words ==========");
+ System.out.println(text);
+ System.out.println("<<<< reconciling for bad words ==========");
+
+ problemCollector.beginCollecting();
+ try {
+ for (String badword : BADWORDS) {
+ int pos = 0;
+ while (pos>=0 && pos < text.length()) {
+ int badPos = text.indexOf(badword, pos);
+ if (badPos>=0) {
+ if (badword.equals(BADWORDS[0])) {
+ problemCollector.accept(new ReconcileProblemImpl(BWProblemType.VERY_BAD_WORD, "'"+badword+"' is a VERY bad word", badPos, badword.length()));
+ } else {
+ problemCollector.accept(new ReconcileProblemImpl(BWProblemType.BAD_WORD, "'"+badword+"' is a bad word", badPos, badword.length()));
+ }
+ pos = badPos+1;
+ } else {
+ pos = badPos;
+ }
+ }
+ }
+ } finally {
+ problemCollector.endCollecting();
+ }
+ }
+
+}
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/IProblemCollector.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/IProblemCollector.java
similarity index 92%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/IProblemCollector.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/IProblemCollector.java
index 773f72b6d..6ac511745 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/IProblemCollector.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/IProblemCollector.java
@@ -8,7 +8,7 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
-package org.springframework.ide.vscode.commons.reconcile;
+package org.springframework.ide.vscode.commons.languageserver.reconcile;
public interface IProblemCollector {
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/IReconcileEngine.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/IReconcileEngine.java
similarity index 80%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/IReconcileEngine.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/IReconcileEngine.java
index ef9257a4b..381074245 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/IReconcileEngine.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/IReconcileEngine.java
@@ -8,9 +8,9 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
-package org.springframework.ide.vscode.commons.reconcile;
+package org.springframework.ide.vscode.commons.languageserver.reconcile;
-import org.springframework.ide.vscode.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
public interface IReconcileEngine {
public void reconcile(IDocument doc, IProblemCollector problemCollector);
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ProblemSeverity.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ProblemSeverity.java
similarity index 56%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ProblemSeverity.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ProblemSeverity.java
index d215237eb..71dd16335 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ProblemSeverity.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ProblemSeverity.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.commons.reconcile;
+package org.springframework.ide.vscode.commons.languageserver.reconcile;
/**
* @author Kris De Volder
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ProblemType.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ProblemType.java
similarity index 87%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ProblemType.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ProblemType.java
index 45a6fdbe8..489ec4d65 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ProblemType.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ProblemType.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.commons.reconcile;
+package org.springframework.ide.vscode.commons.languageserver.reconcile;
/**
* Besides the methods below, the only hard requirement for a 'problem type' is
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ReconcileProblem.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ReconcileProblem.java
similarity index 78%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ReconcileProblem.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ReconcileProblem.java
index ee3d61b6e..066f9b127 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ReconcileProblem.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ReconcileProblem.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.commons.reconcile;
+package org.springframework.ide.vscode.commons.languageserver.reconcile;
/**
* Minamal interface that objects representing a reconciler problem must
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ReconcileProblemImpl.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ReconcileProblemImpl.java
similarity index 91%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ReconcileProblemImpl.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ReconcileProblemImpl.java
index f83d4468b..e7ff94aac 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/reconcile/ReconcileProblemImpl.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/reconcile/ReconcileProblemImpl.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.commons.reconcile;
+package org.springframework.ide.vscode.commons.languageserver.reconcile;
/**
* An implementation of {@link ReconcileProblem} that is just a simple data object.
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/BadLocationException.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/BadLocationException.java
similarity index 81%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/BadLocationException.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/BadLocationException.java
index f38145483..8c330fb23 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/BadLocationException.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/BadLocationException.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
/**
* Replacement for Eclipse's BadLocationException (so as ot make porting code easier)
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/CompletionHandler.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CompletionHandler.java
similarity index 80%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/CompletionHandler.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CompletionHandler.java
index 166764a0b..39e4d127a 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/CompletionHandler.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CompletionHandler.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import java.util.concurrent.CompletableFuture;
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/CompletionResolveHandler.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CompletionResolveHandler.java
similarity index 76%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/CompletionResolveHandler.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CompletionResolveHandler.java
index 73d9d011a..50d0ef3d9 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/CompletionResolveHandler.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/CompletionResolveHandler.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import java.util.concurrent.CompletableFuture;
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/DocumentUtil.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/DocumentUtil.java
similarity index 78%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/DocumentUtil.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/DocumentUtil.java
index 7a0eeb983..fb9a6cd5b 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/DocumentUtil.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/DocumentUtil.java
@@ -1,7 +1,11 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
+
+import org.springframework.ide.vscode.util.Assert;
public class DocumentUtil {
+ //TODO: this stuff belongs in IDocument and its implementation, not here. This class should be removed.
+
/**
* Fetch text between two offsets. Doesn't throw BadLocationException.
* If either one or both of the offsets points outside the
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/IDocument.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/IDocument.java
similarity index 85%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/IDocument.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/IDocument.java
index 0d9367a67..b61707841 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/IDocument.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/IDocument.java
@@ -1,7 +1,8 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
public interface IDocument {
+ String getUri();
String get();
IRegion getLineInformationOfOffset(int offset);
int getLength();
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/IRegion.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/IRegion.java
similarity index 67%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/IRegion.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/IRegion.java
index 7eb255818..50eac8284 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/IRegion.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/IRegion.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
/**
* Mimicks eclipse IRegion (i.e. a region is a offset + length).
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/JSON.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/JSON.java
similarity index 96%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/JSON.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/JSON.java
index 32df4f379..f42f0c036 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/JSON.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/JSON.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import java.io.IOException;
import java.nio.file.Path;
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/ListenerList.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ListenerList.java
similarity index 83%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/ListenerList.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ListenerList.java
index a8bb01e51..ac9a11fe8 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/ListenerList.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ListenerList.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import java.util.ArrayList;
import java.util.List;
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/LoggingFormat.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/LoggingFormat.java
similarity index 96%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/LoggingFormat.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/LoggingFormat.java
index 29bbff43e..6464c05f7 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/LoggingFormat.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/LoggingFormat.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import java.io.IOException;
import java.io.PrintWriter;
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/PrefixFinder.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/PrefixFinder.java
similarity index 94%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/PrefixFinder.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/PrefixFinder.java
index 18b29753b..0b2c5dd54 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/PrefixFinder.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/PrefixFinder.java
@@ -8,7 +8,7 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
public abstract class PrefixFinder {
public String getPrefix(IDocument doc, int offset, int lowerBound) {
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/Region.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/Region.java
similarity index 93%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/Region.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/Region.java
index 2889ae76f..620e71c16 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/Region.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/Region.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
/**
* Trivial implementation of {@link IRegion}
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/Settings.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/Settings.java
similarity index 92%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/Settings.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/Settings.java
index 7ff3458ee..0c978a4a1 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/Settings.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/Settings.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import java.util.Map;
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/ShowMessageException.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ShowMessageException.java
similarity index 93%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/ShowMessageException.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ShowMessageException.java
index 585c0271a..d87572564 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/ShowMessageException.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ShowMessageException.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import io.typefox.lsapi.MessageParams;
import io.typefox.lsapi.impl.MessageParamsImpl;
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/SimpleLanguageServer.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java
similarity index 64%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/SimpleLanguageServer.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java
index 2db20cf38..72b011d1a 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/SimpleLanguageServer.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleLanguageServer.java
@@ -1,17 +1,26 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
+
+import io.typefox.lsapi.DiagnosticSeverity;
import io.typefox.lsapi.InitializeParams;
import io.typefox.lsapi.InitializeResult;
import io.typefox.lsapi.MessageParams;
import io.typefox.lsapi.MessageType;
import io.typefox.lsapi.ShowMessageRequestParams;
+import io.typefox.lsapi.impl.DiagnosticImpl;
import io.typefox.lsapi.impl.InitializeResultImpl;
import io.typefox.lsapi.impl.MessageParamsImpl;
import io.typefox.lsapi.impl.ServerCapabilitiesImpl;
@@ -134,5 +143,54 @@ public abstract class SimpleLanguageServer implements LanguageServer {
//TODO: not sure what this is for exactly. We just stub it and do nothing for now.
}
+ /**
+ * Convenience method. Subclasses can call this to use a {@link IReconcileEngine} ported
+ * from old STS codebase to validate a given {@link TextDocument} and publish Diagnostics.
+ */
+ protected void validateWith(TextDocument doc, IReconcileEngine engine) {
+ SimpleTextDocumentService documents = getTextDocumentService();
+ IProblemCollector problems = new IProblemCollector() {
+
+ private List diagnostics = new ArrayList<>();
+
+ @Override
+ public void endCollecting() {
+ documents.publishDiagnostics(doc, diagnostics);
+ }
+
+ @Override
+ public void beginCollecting() {
+ diagnostics.clear();
+ }
+
+ @Override
+ public void accept(ReconcileProblem problem) {
+ DiagnosticSeverity severity = getDiagnosticSeverity(problem);
+ if (severity!=null) {
+ DiagnosticImpl d = new DiagnosticImpl();
+ d.setCode(problem.getCode());
+ d.setMessage(problem.getMessage());
+ d.setRange(doc.toRange(problem.getOffset(), problem.getLength()));
+ d.setSeverity(severity);
+ diagnostics.add(d);
+ }
+ }
+
+ private DiagnosticSeverity getDiagnosticSeverity(ReconcileProblem problem) {
+ ProblemSeverity severity = problem.getType().getDefaultSeverity();
+ switch (severity) {
+ case ERROR:
+ return DiagnosticSeverity.Error;
+ case WARNING:
+ return DiagnosticSeverity.Warning;
+ case IGNORE:
+ return null;
+ default:
+ throw new IllegalStateException("Bug! Missing switch case?");
+ }
+ }
+ };
+ engine.reconcile(doc, problems);
+ }
}
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/SimpleTextDocumentService.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java
similarity index 97%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/SimpleTextDocumentService.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java
index 50317b2ea..e4519b924 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/SimpleTextDocumentService.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import java.util.ArrayList;
import java.util.Collection;
@@ -10,6 +10,9 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.logging.Logger;
+import org.springframework.ide.vscode.util.Assert;
+import org.springframework.ide.vscode.util.Futures;
+
import io.typefox.lsapi.CodeActionParams;
import io.typefox.lsapi.CodeLens;
import io.typefox.lsapi.CodeLensParams;
@@ -44,16 +47,16 @@ import io.typefox.lsapi.impl.PublishDiagnosticsParamsImpl;
import io.typefox.lsapi.services.TextDocumentService;
public class SimpleTextDocumentService implements TextDocumentService {
-
+
private static final Logger LOG = Logger.getLogger(SimpleTextDocumentService.class.getName());
-
+
private Consumer publishDiagnostics = (p) -> {};
-
+
private Map documents = new HashMap<>();
private ListenerList documentChangeListeners = new ListenerList<>();
private CompletionHandler completionHandler = null;
private CompletionResolveHandler completionResolveHandler = null;
-
+
public synchronized void onCompletion(CompletionHandler h) {
Assert.isNull("A completion handler is already set, multiple handlers not supported yet", completionHandler);
this.completionHandler = h;
@@ -85,7 +88,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
}
}
}
-
+
@Override
public void didOpen(DidOpenTextDocumentParams params) {
//LOG.info("didOpen: "+params);
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/SimpleWorkspaceService.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleWorkspaceService.java
similarity index 93%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/SimpleWorkspaceService.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleWorkspaceService.java
index d0df372c6..2de8347a8 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/SimpleWorkspaceService.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleWorkspaceService.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@@ -11,7 +11,7 @@ import io.typefox.lsapi.WorkspaceSymbolParams;
import io.typefox.lsapi.services.WorkspaceService;
public class SimpleWorkspaceService implements WorkspaceService {
-
+
private ListenerList configurationListeners = new ListenerList<>();
@Override
@@ -34,5 +34,5 @@ public class SimpleWorkspaceService implements WorkspaceService {
public void onDidChangeConfiguraton(Consumer l) {
configurationListeners.add(l);
}
-
+
}
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/TextDocument.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/TextDocument.java
similarity index 98%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/TextDocument.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/TextDocument.java
index f6c9cc397..5eaea2f9d 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/TextDocument.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/TextDocument.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import java.util.ArrayList;
import java.util.List;
diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/TextDocumentContentChange.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/TextDocumentContentChange.java
similarity index 87%
rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/TextDocumentContentChange.java
rename to vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/TextDocumentContentChange.java
index ca82c08ef..f63515f55 100644
--- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/util/TextDocumentContentChange.java
+++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/TextDocumentContentChange.java
@@ -1,4 +1,4 @@
-package org.springframework.ide.vscode.util;
+package org.springframework.ide.vscode.commons.languageserver.util;
import io.typefox.lsapi.TextDocumentContentChangeEvent;
diff --git a/vscode-extensions/commons/commons-language-server/src/test/java/org/springframework/ide/vscode/commons/completion/DocumentEditsTest.java b/vscode-extensions/commons/commons-language-server/src/test/java/org/springframework/ide/vscode/commons/completion/DocumentEditsTest.java
index 843a9a33a..f7dd424b3 100644
--- a/vscode-extensions/commons/commons-language-server/src/test/java/org/springframework/ide/vscode/commons/completion/DocumentEditsTest.java
+++ b/vscode-extensions/commons/commons-language-server/src/test/java/org/springframework/ide/vscode/commons/completion/DocumentEditsTest.java
@@ -15,11 +15,12 @@ import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
+import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.IRegion;
+import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
import org.springframework.ide.vscode.testharness.Editor;
import org.springframework.ide.vscode.testharness.LanguageServerHarness;
-import org.springframework.ide.vscode.util.IDocument;
-import org.springframework.ide.vscode.util.IRegion;
-import org.springframework.ide.vscode.util.TextDocument;
/**
* @author Kris De Volder
*/
diff --git a/vscode-extensions/commons/commons-util/pom.xml b/vscode-extensions/commons/commons-util/pom.xml
index 904cf2425..0617ac842 100644
--- a/vscode-extensions/commons/commons-util/pom.xml
+++ b/vscode-extensions/commons/commons-util/pom.xml
@@ -10,4 +10,17 @@
../pom.xml
+
+
+ com.google.guava
+ guava
+ 18.0
+
+
+ javax.inject
+ javax.inject
+ 1
+
+
+
diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/util/CollectionUtil.java b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/AlwaysFailingParser.java
similarity index 50%
rename from vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/util/CollectionUtil.java
rename to vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/AlwaysFailingParser.java
index 02a32792f..cee2ae16a 100644
--- a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/util/CollectionUtil.java
+++ b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/AlwaysFailingParser.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2015 Pivotal, Inc.
+ * Copyright (c) 2014-2015 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
@@ -8,17 +8,25 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
-package org.springframework.ide.vscode.boot.properties.util;
-
-import java.util.Collection;
+package org.springframework.ide.vscode.util;
/**
+ * Parser that always fails, regardless of the input. Used for types who's value cannot be
+ * expressed as a 'scalar' string value.
+ *
* @author Kris De Volder
*/
-public class CollectionUtil {
+public class AlwaysFailingParser implements ValueParser {
- public static boolean hasElements(Collection c) {
- return c!=null && !c.isEmpty();
+ private String typeName;
+
+ public AlwaysFailingParser(String typeName) {
+ this.typeName = typeName;
+ }
+
+ @Override
+ public Object parse(String str) {
+ throw new IllegalArgumentException("'"+str+"' is not valid for type '"+typeName+"'");
}
}
diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/util/ArrayUtils.java b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/ArrayUtils.java
similarity index 95%
rename from vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/util/ArrayUtils.java
rename to vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/ArrayUtils.java
index b445b2aaa..e34e39f63 100644
--- a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/boot/properties/util/ArrayUtils.java
+++ b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/ArrayUtils.java
@@ -8,7 +8,7 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
-package org.springframework.ide.vscode.boot.properties.util;
+package org.springframework.ide.vscode.util;
import java.lang.reflect.Array;
import java.util.ArrayList;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/EnumValueParser.java b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/EnumValueParser.java
similarity index 96%
rename from vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/EnumValueParser.java
rename to vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/EnumValueParser.java
index 1c373754b..ee1cc76ab 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/EnumValueParser.java
+++ b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/EnumValueParser.java
@@ -8,7 +8,7 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
-package org.springframework.ide.vscode.yaml.util;
+package org.springframework.ide.vscode.util;
import java.util.Collection;
import java.util.Set;
diff --git a/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/HtmlBuffer.java b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/HtmlBuffer.java
new file mode 100644
index 000000000..8ac3f5a07
--- /dev/null
+++ b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/HtmlBuffer.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2014-2016 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.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+/**
+ * Helper class to make it a little easier to create simple html page.
+ *
+ * @author Kris De Volder
+ */
+public class HtmlBuffer {
+
+ private StringBuffer buffer = new StringBuffer();
+ private boolean epilogAdded = false; //to ensure only added once.
+
+ public HtmlBuffer() {
+ this.buffer = new StringBuffer();
+ }
+
+ /**
+ * Append text, applies escaping to the text as needed.
+ */
+ public void text(String text) {
+ raw(convertToHTMLContent(text));
+ }
+
+ /**
+ * Append 'raw' text. Doesn't apply any escaping.
+ */
+ public void raw(String rawText) {
+ if (epilogAdded) {
+ throw new IllegalStateException("Can not append more text after epilog was added");
+ }
+ buffer.append(rawText);
+ }
+
+ /**
+ * Append text, applies urlencoding to the text.
+ */
+ public void url(String string) {
+ try {
+ raw(URLEncoder.encode(string, "utf8"));
+ } catch (UnsupportedEncodingException e) {
+ Log.log(e);
+ }
+ }
+
+
+ public String toString() {
+ if (!epilogAdded && buffer.length()>0) {
+ epilogAdded = true;
+ addPrologAndEpilog();
+ }
+ return buffer.toString();
+ }
+
+ protected void addPrologAndEpilog() {
+// HTMLPrinter.insertPageProlog(buffer, 0, getCSSStyles());
+// HTMLPrinter.addPageEpilog(buffer);
+ }
+
+// /**
+// * Note: copied from org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal.getCSSStyles()
+// * Returns the style information for displaying HTML (Javadoc) content.
+// *
+// * @return the CSS styles
+// * @since 3.3
+// */
+// public static String getCSSStyles() {
+// if (fgCSSStyles == null) {
+// Bundle bundle= Platform.getBundle(JavaPlugin.getPluginId());
+// URL url= bundle.getEntry("/JavadocHoverStyleSheet.css"); //$NON-NLS-1$
+// if (url != null) {
+// BufferedReader reader= null;
+// try {
+// url= FileLocator.toFileURL(url);
+// reader= new BufferedReader(new InputStreamReader(url.openStream()));
+// StringBuffer buffer= new StringBuffer(200);
+// String line= reader.readLine();
+// while (line != null) {
+// buffer.append(line);
+// buffer.append('\n');
+// line= reader.readLine();
+// }
+// fgCSSStyles= buffer.toString();
+// } catch (IOException ex) {
+// JavaPlugin.log(ex);
+// } finally {
+// try {
+// if (reader != null)
+// reader.close();
+// } catch (IOException e) {
+// }
+// }
+//
+// }
+// }
+// String css= fgCSSStyles;
+// if (css != null) {
+// FontData fontData= JFaceResources.getFontRegistry().getFontData(PreferenceConstants.APPEARANCE_JAVADOC_FONT)[0];
+// css= HTMLPrinter.convertTopLevelFont(css, fontData);
+// }
+// return css;
+// }
+
+ public void hline() {
+ raw("
");
+ }
+
+ public void p(String string) {
+ raw("");
+ text(string);
+ raw("
");
+ }
+
+ public void snippet(HtmlSnippet snippet) {
+ snippet.render(this);
+ }
+
+ public void bold(String string) {
+ raw("");
+ text(string);
+ raw("");
+ }
+
+ /**
+ * Escapes reserved HTML characters in the given string.
+ *
+ * Warning: Does not preserve whitespace.
+ *
+ * @param content the input string
+ * @return the string with escaped characters
+ */
+ public static String convertToHTMLContent(String content) {
+ content= replace(content, '&', "&"); //$NON-NLS-1$
+ content= replace(content, '"', """); //$NON-NLS-1$
+ content= replace(content, '<', "<"); //$NON-NLS-1$
+ return replace(content, '>', ">"); //$NON-NLS-1$
+ }
+
+ private static String replace(String text, char c, String s) {
+
+ int previous= 0;
+ int current= text.indexOf(c, previous);
+
+ if (current == -1)
+ return text;
+
+ StringBuffer buffer= new StringBuffer();
+ while (current > -1) {
+ buffer.append(text.substring(previous, current));
+ buffer.append(s);
+ previous= current + 1;
+ current= text.indexOf(c, previous);
+ }
+ buffer.append(text.substring(previous));
+
+ return buffer.toString();
+ }
+
+}
diff --git a/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/HtmlSnippet.java b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/HtmlSnippet.java
new file mode 100644
index 000000000..6c10308e5
--- /dev/null
+++ b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/HtmlSnippet.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.util;
+
+/**
+ * A snippet that can be rendered into html.
+ *
+ * @author Kris De Volder
+ */
+public abstract class HtmlSnippet {
+ public abstract void render(HtmlBuffer html);
+
+ public String toHtml() {
+ HtmlBuffer buf = new HtmlBuffer();
+ render(buf);
+ return buf.toString();
+ }
+
+ // Create snippets:
+
+ public static HtmlSnippet text(final String text) {
+ return new HtmlSnippet() {
+ @Override
+ public void render(HtmlBuffer html) {
+ html.text(text);
+ }
+ };
+ }
+
+ public static HtmlSnippet raw(final String rawHtml) {
+ return new HtmlSnippet() {
+ @Override
+ public void render(HtmlBuffer html) {
+ html.raw(rawHtml);
+ }
+ };
+ }
+
+ public static HtmlSnippet italic(String text) {
+ return italic(text(text));
+ }
+
+ public static HtmlSnippet italic(final HtmlSnippet wrappee) {
+ return new HtmlSnippet() {
+ @Override
+ public void render(HtmlBuffer html) {
+ html.raw("");
+ wrappee.render(html);
+ html.raw("");
+ }
+ };
+ }
+
+ // add more as needed ...
+}
diff --git a/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/LazyProvider.java b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/LazyProvider.java
new file mode 100644
index 000000000..a77fcc6c3
--- /dev/null
+++ b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/LazyProvider.java
@@ -0,0 +1,26 @@
+package org.springframework.ide.vscode.util;
+
+import javax.inject.Provider;
+
+/**
+ * An abstract class implementing {@link Provider}. The provided value
+ * is computed on demand and cached once computed.
+ *
+ * Subclass must implement the compute method.
+ */
+public abstract class LazyProvider implements Provider {
+
+ private boolean computed = false;
+ private T cached = null;
+
+ @Override
+ public synchronized final T get() {
+ if (!computed) {
+ cached = compute();
+ }
+ return cached;
+ }
+
+ protected abstract T compute();
+
+}
diff --git a/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/Log.java b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/Log.java
new file mode 100644
index 000000000..c5119fe30
--- /dev/null
+++ b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/Log.java
@@ -0,0 +1,20 @@
+package org.springframework.ide.vscode.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Deprecated, this class is here to make porting old STS code easier. Code should
+ * avoid using this as much as possible and replaces calls to this by using Slf4J loggers
+ * directly.
+ */
+@Deprecated
+public class Log {
+
+ final static Logger logger = LoggerFactory.getLogger(Log.class);
+
+ public static void log(Throwable e) {
+ logger.error("Error", e);
+ }
+
+}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/ValueParser.java b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/ValueParser.java
similarity index 94%
rename from vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/ValueParser.java
rename to vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/ValueParser.java
index 262052002..50806b806 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/ValueParser.java
+++ b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/util/ValueParser.java
@@ -8,7 +8,7 @@
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
-package org.springframework.ide.vscode.yaml.util;
+package org.springframework.ide.vscode.util;
/**
* A ValueParser provides the means to Strings into some kind of
diff --git a/vscode-extensions/commons/commons-yaml/pom.xml b/vscode-extensions/commons/commons-yaml/pom.xml
index d7443a099..f28900823 100644
--- a/vscode-extensions/commons/commons-yaml/pom.xml
+++ b/vscode-extensions/commons/commons-yaml/pom.xml
@@ -26,12 +26,7 @@
org.yaml
snakeyaml
- 1.17
-
-
- org.yaml
- snakeyaml
- 1.17
+ ${yaml-version}
javax.inject
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/ast/YamlASTProvider.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/ast/YamlASTProvider.java
index 43088c28d..abe0be822 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/ast/YamlASTProvider.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/ast/YamlASTProvider.java
@@ -1,6 +1,6 @@
package org.springframework.ide.vscode.yaml.ast;
-import org.springframework.ide.vscode.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
@FunctionalInterface
public interface YamlASTProvider {
diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/YamlParser.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/ast/YamlParser.java
similarity index 58%
rename from vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/YamlParser.java
rename to vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/ast/YamlParser.java
index 5a8454f68..fc4111372 100644
--- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/YamlParser.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/ast/YamlParser.java
@@ -1,10 +1,8 @@
-package org.springframework.ide.vscode.cloudfoundry.manifest.editor;
+package org.springframework.ide.vscode.yaml.ast;
import java.io.StringReader;
-import org.springframework.ide.vscode.util.IDocument;
-import org.springframework.ide.vscode.yaml.ast.YamlASTProvider;
-import org.springframework.ide.vscode.yaml.ast.YamlFileAST;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.yaml.snakeyaml.Yaml;
public class YamlParser implements YamlASTProvider {
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/AbstractYamlAssistContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/AbstractYamlAssistContext.java
index 3c8899d80..020e6e46a 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/AbstractYamlAssistContext.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/AbstractYamlAssistContext.java
@@ -10,7 +10,7 @@
*******************************************************************************/
package org.springframework.ide.vscode.yaml.completion;
-import org.springframework.ide.vscode.util.PrefixFinder;
+import org.springframework.ide.vscode.commons.languageserver.util.PrefixFinder;
import org.springframework.ide.vscode.yaml.path.YamlPath;
import org.springframework.ide.vscode.yaml.structure.YamlDocument;
import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SDocNode;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/CompletionFactory.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/CompletionFactory.java
index bd629d431..92a34505b 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/CompletionFactory.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/CompletionFactory.java
@@ -1,8 +1,8 @@
package org.springframework.ide.vscode.yaml.completion;
-import org.springframework.ide.vscode.commons.completion.DocumentEdits;
-import org.springframework.ide.vscode.commons.completion.ICompletionProposal;
-import org.springframework.ide.vscode.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.yaml.schema.YType;
import org.springframework.ide.vscode.yaml.schema.YTypeUtil;
import org.springframework.ide.vscode.yaml.schema.YTypedProperty;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/DefaultCompletionFactory.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/DefaultCompletionFactory.java
index ad2222161..bcf1705b4 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/DefaultCompletionFactory.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/DefaultCompletionFactory.java
@@ -2,9 +2,9 @@ package org.springframework.ide.vscode.yaml.completion;
import java.util.Comparator;
-import org.springframework.ide.vscode.commons.completion.DocumentEdits;
-import org.springframework.ide.vscode.commons.completion.ICompletionProposal;
-import org.springframework.ide.vscode.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.yaml.schema.YType;
import org.springframework.ide.vscode.yaml.schema.YTypeUtil;
import org.springframework.ide.vscode.yaml.schema.YTypedProperty;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/TopLevelAssistContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/TopLevelAssistContext.java
index 35b8d9b6c..503ffdf64 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/TopLevelAssistContext.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/TopLevelAssistContext.java
@@ -13,7 +13,7 @@ package org.springframework.ide.vscode.yaml.completion;
import java.util.Collection;
import java.util.Collections;
-import org.springframework.ide.vscode.commons.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.yaml.path.YamlPathSegment;
import org.springframework.ide.vscode.yaml.structure.YamlDocument;
import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SNode;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YTypeAssistContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YTypeAssistContext.java
index 521fdbe8d..5e42c2bef 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YTypeAssistContext.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YTypeAssistContext.java
@@ -20,8 +20,8 @@ import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.ide.vscode.commons.completion.DocumentEdits;
-import org.springframework.ide.vscode.commons.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.util.CollectionUtil;
import org.springframework.ide.vscode.util.FuzzyMatcher;
import org.springframework.ide.vscode.yaml.path.YamlPath;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlAssistContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlAssistContext.java
index f23550e75..9f3c2ee5d 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlAssistContext.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlAssistContext.java
@@ -12,7 +12,7 @@ package org.springframework.ide.vscode.yaml.completion;
import java.util.Collection;
-import org.springframework.ide.vscode.commons.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.yaml.path.YamlNavigable;
import org.springframework.ide.vscode.yaml.structure.YamlDocument;
import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SNode;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlCompletionEngine.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlCompletionEngine.java
index 88484ef68..bb3d77551 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlCompletionEngine.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlCompletionEngine.java
@@ -15,10 +15,10 @@ import java.util.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.ide.vscode.commons.completion.ICompletionEngine;
-import org.springframework.ide.vscode.commons.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.util.Assert;
-import org.springframework.ide.vscode.util.IDocument;
import org.springframework.ide.vscode.yaml.path.YamlPath;
import org.springframework.ide.vscode.yaml.structure.YamlDocument;
import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SKeyNode;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlPathEdits.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlPathEdits.java
index 60bb4e483..341356e1b 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlPathEdits.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/completion/YamlPathEdits.java
@@ -10,9 +10,9 @@
*******************************************************************************/
package org.springframework.ide.vscode.yaml.completion;
-import org.springframework.ide.vscode.commons.completion.DocumentEdits;
+import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
+import org.springframework.ide.vscode.commons.languageserver.util.IRegion;
import org.springframework.ide.vscode.util.Assert;
-import org.springframework.ide.vscode.util.IRegion;
import org.springframework.ide.vscode.yaml.path.YamlPath;
import org.springframework.ide.vscode.yaml.path.YamlPathSegment;
import org.springframework.ide.vscode.yaml.path.YamlPathSegment.YamlPathSegmentType;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/SchemaBasedYamlASTReconciler.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/SchemaBasedYamlASTReconciler.java
index 7ea5f5ad0..8ae578f3d 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/SchemaBasedYamlASTReconciler.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/SchemaBasedYamlASTReconciler.java
@@ -4,16 +4,16 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import org.springframework.ide.vscode.commons.reconcile.IProblemCollector;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
import org.springframework.ide.vscode.util.ExceptionUtil;
import org.springframework.ide.vscode.util.StringUtil;
+import org.springframework.ide.vscode.util.ValueParser;
import org.springframework.ide.vscode.yaml.ast.NodeUtil;
import org.springframework.ide.vscode.yaml.ast.YamlFileAST;
import org.springframework.ide.vscode.yaml.schema.YType;
import org.springframework.ide.vscode.yaml.schema.YTypeUtil;
import org.springframework.ide.vscode.yaml.schema.YTypedProperty;
import org.springframework.ide.vscode.yaml.schema.YamlSchema;
-import org.springframework.ide.vscode.yaml.util.ValueParser;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeTuple;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlReconcileEngine.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlReconcileEngine.java
index 792953ca1..51f9bb980 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlReconcileEngine.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlReconcileEngine.java
@@ -2,10 +2,10 @@ package org.springframework.ide.vscode.yaml.reconcile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.ide.vscode.commons.reconcile.IProblemCollector;
-import org.springframework.ide.vscode.commons.reconcile.IReconcileEngine;
-import org.springframework.ide.vscode.commons.reconcile.ReconcileProblem;
-import org.springframework.ide.vscode.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.yaml.ast.YamlASTProvider;
import org.springframework.ide.vscode.yaml.ast.YamlFileAST;
import org.yaml.snakeyaml.error.Mark;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlSchemaBasedReconcileEngine.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlSchemaBasedReconcileEngine.java
index 2ec6a0887..76fbea103 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlSchemaBasedReconcileEngine.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlSchemaBasedReconcileEngine.java
@@ -1,8 +1,8 @@
package org.springframework.ide.vscode.yaml.reconcile;
-import org.springframework.ide.vscode.commons.reconcile.IProblemCollector;
-import org.springframework.ide.vscode.commons.reconcile.ReconcileProblem;
-import org.springframework.ide.vscode.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.yaml.ast.YamlASTProvider;
import org.springframework.ide.vscode.yaml.schema.YamlSchema;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlSchemaProblems.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlSchemaProblems.java
index 7808d9425..dd95c339a 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlSchemaProblems.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/YamlSchemaProblems.java
@@ -1,9 +1,9 @@
package org.springframework.ide.vscode.yaml.reconcile;
-import org.springframework.ide.vscode.commons.reconcile.ProblemSeverity;
-import org.springframework.ide.vscode.commons.reconcile.ProblemType;
-import org.springframework.ide.vscode.commons.reconcile.ReconcileProblem;
-import org.springframework.ide.vscode.commons.reconcile.ReconcileProblemImpl;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
import org.yaml.snakeyaml.nodes.Node;
/**
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypeFactory.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypeFactory.java
index d9421c6db..a8ff3e14d 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypeFactory.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypeFactory.java
@@ -21,10 +21,10 @@ import java.util.Set;
import javax.inject.Provider;
-import org.springframework.ide.vscode.yaml.util.Description;
+import org.springframework.ide.vscode.util.EnumValueParser;
+import org.springframework.ide.vscode.util.HtmlSnippet;
+import org.springframework.ide.vscode.util.ValueParser;
import org.springframework.ide.vscode.yaml.util.DescriptionProviders;
-import org.springframework.ide.vscode.yaml.util.EnumValueParser;
-import org.springframework.ide.vscode.yaml.util.ValueParser;
/**
* Static utility method for creating YType objects representing either
@@ -193,7 +193,7 @@ public class YTypeFactory {
propertyList.add(p);
}
- public void addProperty(String name, YType type, Provider description) {
+ public void addProperty(String name, YType type, Provider description) {
YTypedPropertyImpl prop;
addProperty(prop = new YTypedPropertyImpl(name, type));
prop.setDescriptionProvider(description);
@@ -314,7 +314,7 @@ public class YTypeFactory {
final private String name;
final private YType type;
- private Provider descriptionProvider = DescriptionProviders.NO_DESCRIPTION;
+ private Provider descriptionProvider = DescriptionProviders.NO_DESCRIPTION;
private YTypedPropertyImpl(String name, YType type) {
this.name = name;
@@ -337,11 +337,11 @@ public class YTypeFactory {
}
@Override
- public Description getDescription() {
+ public HtmlSnippet getDescription() {
return descriptionProvider.get();
}
- public void setDescriptionProvider(Provider descriptionProvider) {
+ public void setDescriptionProvider(Provider descriptionProvider) {
this.descriptionProvider = descriptionProvider;
}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypeUtil.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypeUtil.java
index a78d47cdc..1b922cce1 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypeUtil.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypeUtil.java
@@ -13,7 +13,7 @@ package org.springframework.ide.vscode.yaml.schema;
import java.util.List;
import java.util.Map;
-import org.springframework.ide.vscode.yaml.util.ValueParser;
+import org.springframework.ide.vscode.util.ValueParser;
/**
* An implementation of YTypeUtil provides implementations of various
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypedProperty.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypedProperty.java
index bbc64e41b..e8ffb0650 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypedProperty.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/schema/YTypedProperty.java
@@ -10,7 +10,7 @@
*******************************************************************************/
package org.springframework.ide.vscode.yaml.schema;
-import org.springframework.ide.vscode.yaml.util.Description;
+import org.springframework.ide.vscode.util.HtmlSnippet;
/**
* @author Kris De Volder
@@ -18,5 +18,5 @@ import org.springframework.ide.vscode.yaml.util.Description;
public interface YTypedProperty {
String getName();
YType getType();
- Description getDescription();
+ HtmlSnippet getDescription();
}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/structure/YamlDocument.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/structure/YamlDocument.java
index 2b7104d84..7ce9c0d20 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/structure/YamlDocument.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/structure/YamlDocument.java
@@ -10,10 +10,10 @@
*******************************************************************************/
package org.springframework.ide.vscode.yaml.structure;
-import org.springframework.ide.vscode.util.BadLocationException;
-import org.springframework.ide.vscode.util.DocumentUtil;
-import org.springframework.ide.vscode.util.IDocument;
-import org.springframework.ide.vscode.util.IRegion;
+import org.springframework.ide.vscode.commons.languageserver.util.BadLocationException;
+import org.springframework.ide.vscode.commons.languageserver.util.DocumentUtil;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.IRegion;
import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SRootNode;
/**
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/structure/YamlStructureParser.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/structure/YamlStructureParser.java
index d78d63ba7..666f94fb8 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/structure/YamlStructureParser.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/structure/YamlStructureParser.java
@@ -10,9 +10,9 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.springframework.ide.vscode.commons.languageserver.util.IRegion;
import org.springframework.ide.vscode.util.Assert;
import org.springframework.ide.vscode.util.CollectionUtil;
-import org.springframework.ide.vscode.util.IRegion;
import org.springframework.ide.vscode.util.StringUtil;
import org.springframework.ide.vscode.yaml.path.KeyAliases;
import org.springframework.ide.vscode.yaml.path.YamlNavigable;
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/Description.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/Description.java
deleted file mode 100644
index 3caa74646..000000000
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/Description.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.springframework.ide.vscode.yaml.util;
-
-public abstract class Description {
-
- public abstract void renderAsText(StringBuilder buf);
-
- public void renderAsHtml(StringBuilder buf) {
- throw new UnsupportedOperationException("Rendering as html not supported");
- }
-
- public static Description text(String text) {
- return new Description() {
- @Override
- public void renderAsText(StringBuilder buf) {
- buf.append(text);
- }
- };
- }
-
- public static Description italic(Description d) {
- //Not really supported, we just ignore italic and display as is
- return d;
- }
-
- public String toText() {
- StringBuilder buf = new StringBuilder();
- renderAsText(buf);
- return buf.toString();
- }
-
-}
diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/DescriptionProviders.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/DescriptionProviders.java
index 09e1816be..30168713b 100644
--- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/DescriptionProviders.java
+++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/yaml/util/DescriptionProviders.java
@@ -16,8 +16,9 @@ import javax.inject.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.ide.vscode.util.HtmlSnippet;
-import static org.springframework.ide.vscode.yaml.util.Description.*;
+import static org.springframework.ide.vscode.util.HtmlSnippet.*;
/**
* Static methods and convenience constants for creating some 'description providers'.
@@ -28,33 +29,33 @@ public class DescriptionProviders {
final static Logger logger = LoggerFactory.getLogger(DescriptionProviders.class);
- public static final Provider NO_DESCRIPTION = () -> italic(text("no description"));
+ public static final Provider NO_DESCRIPTION = () -> italic(text("no description"));
- public static Provider snippet(final Description snippet) {
- return new Provider() {
+ public static Provider snippet(final HtmlSnippet snippet) {
+ return new Provider() {
@Override
public String toString() {
return snippet.toString();
}
@Override
- public Description get() {
+ public HtmlSnippet get() {
return snippet;
}
};
}
- public static Provider fromClasspath(final Class> klass, final String resourcePath) {
- return new Provider() {
+ public static Provider fromClasspath(final Class> klass, final String resourcePath) {
+ return new Provider() {
@Override
public String toString() {
return "DescriptionFromClassPth(class="+klass.getSimpleName()+", "+resourcePath+")";
}
@Override
- public Description get() {
+ public HtmlSnippet get() {
try {
InputStream stream = klass.getResourceAsStream(resourcePath);
if (stream!=null) {
- return Description.text(IOUtil.toString(stream));
+ return HtmlSnippet.text(IOUtil.toString(stream));
}
} catch (Exception e) {
logger.error("Error", e);;
diff --git a/vscode-extensions/commons/commons-yaml/src/test/java/org/springframework/ide/vscode/yaml/structure/YamlStructureParserTest.java b/vscode-extensions/commons/commons-yaml/src/test/java/org/springframework/ide/vscode/yaml/structure/YamlStructureParserTest.java
index 12a1789eb..5ac7a2b12 100644
--- a/vscode-extensions/commons/commons-yaml/src/test/java/org/springframework/ide/vscode/yaml/structure/YamlStructureParserTest.java
+++ b/vscode-extensions/commons/commons-yaml/src/test/java/org/springframework/ide/vscode/yaml/structure/YamlStructureParserTest.java
@@ -21,7 +21,7 @@ import java.util.ArrayList;
import java.util.regex.Pattern;
import org.junit.Test;
-import org.springframework.ide.vscode.util.TextDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
import org.springframework.ide.vscode.yaml.path.YamlPath;
import org.springframework.ide.vscode.yaml.path.YamlPathSegment;
import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SChildBearingNode;
diff --git a/vscode-extensions/commons/language-server-test-harness/pom.xml b/vscode-extensions/commons/language-server-test-harness/pom.xml
index 8e33e6f6b..76b81e7c5 100644
--- a/vscode-extensions/commons/language-server-test-harness/pom.xml
+++ b/vscode-extensions/commons/language-server-test-harness/pom.xml
@@ -29,6 +29,11 @@
io.typefox.lsapi.annotations
${lsapi-version}
+
+ org.springframework.ide.vscode
+ commons-java
+ ${project.version}
+
junit
junit
diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/IType.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/IType.java
deleted file mode 100644
index 6ed7f2d34..000000000
--- a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/IType.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package org.springframework.ide.vscode.testharness;
-
-/**
- * Replaces eclipse JDT IType. Maybe we keep this maybe not, if keep, it should move to some
- * other place, not stay here in the testharness.
- */
-public interface IType {
-
-}
diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TestProject.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TestProject.java
deleted file mode 100644
index 1c06ceb61..000000000
--- a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TestProject.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.springframework.ide.vscode.testharness;
-
-import java.nio.file.Path;
-
-public interface TestProject {
-
- Path getPath();
-
- IType findType(String string);
-
-}
diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TestProjectHarness.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TestProjectHarness.java
new file mode 100644
index 000000000..4593ca46f
--- /dev/null
+++ b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/testharness/TestProjectHarness.java
@@ -0,0 +1,66 @@
+package org.springframework.ide.vscode.testharness;
+
+import static org.junit.Assert.assertTrue;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.springframework.ide.vscode.java.IJavaProject;
+import org.springframework.ide.vscode.java.IType;
+import org.springframework.ide.vscode.util.ExternalCommand;
+import org.springframework.ide.vscode.util.ExternalProcess;
+import org.springframework.ide.vscode.util.HtmlSnippet;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+
+/**
+ * Class meant to be used in writing tests that require test projects to be populated
+ * from some data on the classpath.
+ */
+public class TestProjectHarness {
+
+ public Cache cache = CacheBuilder.newBuilder().build();
+
+ public IJavaProject get(String name) throws Exception {
+ Path testProjectPath = Paths.get(TestProjectHarness.class.getResource("/demo-1").toURI());
+ assertTrue(Files.exists(testProjectPath));
+ if (!Files.exists(testProjectPath.resolve("classpath.txt"))) {
+ testProjectPath.resolve("mvnw").toFile().setExecutable(true);
+ ExternalProcess process = new ExternalProcess(testProjectPath.toFile(), new ExternalCommand("./mvnw", "clean", "package"), true);
+ if (process.getExitValue() != 0) {
+ throw new RuntimeException("Failed to build test project");
+ }
+ }
+ return new IJavaProject() {
+
+ @Override
+ public HtmlSnippet getJavaDoc() {
+ return null;
+ }
+
+ @Override
+ public String getElementName() {
+ return name;
+ }
+
+ @Override
+ public boolean exists() {
+ return true;
+ }
+
+ @Override
+ public Path getPath() {
+ return testProjectPath;
+ }
+
+ @Override
+ public IType findType(String string) {
+ //throw new UnsupportedOperationException("Not yet implemented");
+ return null;
+ }
+ };
+ }
+
+}
diff --git a/vscode-extensions/commons/pom.xml b/vscode-extensions/commons/pom.xml
index e41b048b6..5892de458 100644
--- a/vscode-extensions/commons/pom.xml
+++ b/vscode-extensions/commons/pom.xml
@@ -14,11 +14,13 @@
language-server-test-harness
commons-yaml
commons-util
+ commons-java
java-properties
application-properties-metadata
+ 1.17
4.11
3.5.2
1.7.21
diff --git a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/ApplicationPropertiesLanguageServer.java b/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/ApplicationPropertiesLanguageServer.java
index 304e3085a..dcefcbab6 100644
--- a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/ApplicationPropertiesLanguageServer.java
+++ b/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/ApplicationPropertiesLanguageServer.java
@@ -12,12 +12,12 @@ package org.springframework.ide.vscode.boot.properties;
import java.util.stream.Collectors;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
+import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
import org.springframework.ide.vscode.properties.antlr.parser.AntlrParser;
import org.springframework.ide.vscode.properties.parser.ParseResults;
import org.springframework.ide.vscode.properties.parser.Parser;
-import org.springframework.ide.vscode.util.SimpleLanguageServer;
-import org.springframework.ide.vscode.util.SimpleTextDocumentService;
-import org.springframework.ide.vscode.util.TextDocument;
import io.typefox.lsapi.Diagnostic;
import io.typefox.lsapi.DiagnosticSeverity;
diff --git a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/Main.java b/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/Main.java
index 4aee322ca..01b658605 100644
--- a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/Main.java
+++ b/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/boot/properties/Main.java
@@ -20,7 +20,7 @@ import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.springframework.ide.vscode.util.LoggingFormat;
+import org.springframework.ide.vscode.commons.languageserver.util.LoggingFormat;
import io.typefox.lsapi.services.json.LoggingJsonAdapter;
diff --git a/vscode-extensions/vscode-application-yaml/pom.xml b/vscode-extensions/vscode-application-yaml/pom.xml
index 65011bbe7..fbff35022 100644
--- a/vscode-extensions/vscode-application-yaml/pom.xml
+++ b/vscode-extensions/vscode-application-yaml/pom.xml
@@ -46,6 +46,12 @@
commons-language-server
${project.version}
+
+
+ org.springframework.ide.vscode
+ commons-java
+ ${project.version}
+
org.springframework.ide.vscode
@@ -53,6 +59,11 @@
${project.version}
+
+ org.springframework.ide.vscode
+ commons-yaml
+ ${project.version}
+
org.yaml
snakeyaml
diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/ApplicationYamlLanguageServer.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/ApplicationYamlLanguageServer.java
index 1172e25e7..88889cd53 100644
--- a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/ApplicationYamlLanguageServer.java
+++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/ApplicationYamlLanguageServer.java
@@ -1,45 +1,46 @@
package org.springframework.ide.vscode.yaml;
-import java.io.StringReader;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
+import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertyIndexProvider;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypeUtilProvider;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
+import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
import org.springframework.ide.vscode.util.Futures;
-import org.springframework.ide.vscode.util.SimpleLanguageServer;
-import org.springframework.ide.vscode.util.SimpleTextDocumentService;
-import org.springframework.ide.vscode.util.TextDocument;
+import org.springframework.ide.vscode.yaml.ast.YamlASTProvider;
+import org.springframework.ide.vscode.yaml.ast.YamlParser;
+import org.springframework.ide.vscode.yaml.reconcile.ApplicationYamlReconcileEngine;
import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.error.MarkedYAMLException;
-import org.yaml.snakeyaml.error.YAMLException;
-import org.yaml.snakeyaml.nodes.Node;
-
-import com.google.common.collect.ImmutableList;
import io.typefox.lsapi.CompletionItem;
import io.typefox.lsapi.CompletionItemKind;
import io.typefox.lsapi.CompletionList;
-import io.typefox.lsapi.DiagnosticSeverity;
import io.typefox.lsapi.TextDocumentSyncKind;
import io.typefox.lsapi.impl.CompletionItemImpl;
import io.typefox.lsapi.impl.CompletionListImpl;
import io.typefox.lsapi.impl.CompletionOptionsImpl;
-import io.typefox.lsapi.impl.DiagnosticImpl;
-import io.typefox.lsapi.impl.PositionImpl;
-import io.typefox.lsapi.impl.RangeImpl;
import io.typefox.lsapi.impl.ServerCapabilitiesImpl;
public class ApplicationYamlLanguageServer extends SimpleLanguageServer {
private Yaml yaml = new Yaml();
+ private YamlASTProvider parser = new YamlParser(yaml);
+ private SpringPropertyIndexProvider indexProvider;
+ private TypeUtilProvider typeUtilProvider;
- public ApplicationYamlLanguageServer() {
+ public ApplicationYamlLanguageServer(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider) {
+ this.indexProvider = indexProvider;
+ this.typeUtilProvider = typeUtilProvider;
SimpleTextDocumentService documents = getTextDocumentService();
// SimpleWorkspaceService workspace = getWorkspaceService();
+ IReconcileEngine reconcileEngine = getReconcileEngine();
documents.onDidChangeContent(params -> {
TextDocument doc = params.getDocument();
- validateDocument(documents, doc);
+ validateWith(doc, reconcileEngine);
});
// workspace.onDidChangeConfiguraton(settings -> {
@@ -103,54 +104,8 @@ public class ApplicationYamlLanguageServer extends SimpleLanguageServer {
});
}
- private void validateDocument(SimpleTextDocumentService documents, TextDocument doc) {
- List diagnostics = reconcile(documents, doc);
- documents.publishDiagnostics(doc, diagnostics);
- }
-
- protected List reconcile(SimpleTextDocumentService documents, TextDocument doc) {
- try {
- Iterator asts = yaml.composeAll(new StringReader(doc.getText())).iterator();
- while (asts.hasNext()) {
- asts.next();
- }
- return ImmutableList.of();
- } catch (YAMLException e) {
- return ImmutableList.of(parseError(e));
- }
- }
-
- private DiagnosticImpl parseError(YAMLException e) {
- DiagnosticImpl d = new DiagnosticImpl();
- d.setMessage(getMessage(e));
- d.setRange(getRange(e));
- d.setSeverity(DiagnosticSeverity.Error);
- d.setCode(ErrorCodes.YAML_SYNTAX_ERROR);
- d.setSource("yaml");
- return d;
- }
-
- private String getMessage(YAMLException e) {
- if (e instanceof MarkedYAMLException) {
- return ((MarkedYAMLException) e).getProblem();
- }
- return e.getMessage();
- }
-
- private RangeImpl getRange(YAMLException _e) {
- if (_e instanceof MarkedYAMLException) {
- MarkedYAMLException e = (MarkedYAMLException) _e;
-
- PositionImpl start = new PositionImpl();
- start.setLine(e.getProblemMark().getLine());
- start.setCharacter(e.getProblemMark().getColumn());
-
- RangeImpl rng = new RangeImpl();
- rng.setStart(start);
- rng.setEnd(start);
- return rng;
- }
- return null;
+ protected IReconcileEngine getReconcileEngine() {
+ return new ApplicationYamlReconcileEngine(parser, indexProvider, typeUtilProvider);
}
@Override
diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/ApplicationYamlProblems.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/ApplicationYamlProblems.java
new file mode 100644
index 000000000..652fe71a2
--- /dev/null
+++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/ApplicationYamlProblems.java
@@ -0,0 +1,43 @@
+package org.springframework.ide.vscode.yaml;
+
+import static org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity.ERROR;
+
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
+
+public class ApplicationYamlProblems {
+
+ public static enum Type implements ProblemType {
+
+ YAML_SYNTAX_ERROR;
+
+ Type() {
+ this(ERROR);
+ }
+
+ Type(ProblemSeverity defaultSeverity) {
+ this.severity = defaultSeverity;
+ }
+
+ private final ProblemSeverity severity;
+
+ @Override
+ public ProblemSeverity getDefaultSeverity() {
+ return severity;
+ }
+
+ @Override
+ public String getCode() {
+ return name();
+ }
+
+ }
+
+ public static final String YAML_SYNTAX_ERROR = "YAML_SYNTAX_ERROR";
+
+ public static ReconcileProblem problem(Type type, String msg, int offset, int len) {
+ return new ReconcileProblemImpl(type, msg, offset, len);
+ }
+}
diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/DefaultSpringPropertyIndexProvider.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/DefaultSpringPropertyIndexProvider.java
new file mode 100644
index 000000000..a001c9443
--- /dev/null
+++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/DefaultSpringPropertyIndexProvider.java
@@ -0,0 +1,31 @@
+package org.springframework.ide.vscode.yaml;
+
+import java.nio.file.Path;
+
+import org.springframework.ide.vscode.boot.properties.metadata.PropertyInfo;
+import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertiesIndexManager;
+import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertyIndexProvider;
+import org.springframework.ide.vscode.boot.properties.metadata.ValueProviderRegistry;
+import org.springframework.ide.vscode.boot.properties.util.FuzzyMap;
+import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.java.IJavaProject;
+
+public class DefaultSpringPropertyIndexProvider implements SpringPropertyIndexProvider {
+
+ private JavaProjectFinder javaProjectFinder = JavaProjectFinder.DEFAULT;
+ private SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager(ValueProviderRegistry.getDefault());
+
+ @Override
+ public FuzzyMap getIndex(IDocument doc) {
+ IJavaProject jp = javaProjectFinder.find(doc);
+ if (jp!=null) {
+ Path projectFolder = jp.getPath();
+ if (projectFolder!=null) {
+ return indexManager.get(projectFolder);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/ErrorCodes.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/ErrorCodes.java
deleted file mode 100644
index fce1b8d27..000000000
--- a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/ErrorCodes.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package org.springframework.ide.vscode.yaml;
-
-public class ErrorCodes {
- public static final String YAML_SYNTAX_ERROR = "YAML_SYNTAX_ERROR";
-}
diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/Main.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/Main.java
index 90a575fd1..4c92da780 100644
--- a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/Main.java
+++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/Main.java
@@ -6,11 +6,14 @@ import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
-import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.springframework.ide.vscode.util.LoggingFormat;
+import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertyIndexProvider;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypeUtil;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypeUtilProvider;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.LoggingFormat;
import io.typefox.lsapi.services.json.LoggingJsonAdapter;
@@ -79,7 +82,14 @@ public class Main {
* When the request stream is closed, wait for 5s for all outstanding responses to compute, then return.
*/
public static void run(Connection connection) {
- ApplicationYamlLanguageServer server = new ApplicationYamlLanguageServer();
+ //TODO: proper TypeUtilProvider and IndexProvider that somehow determine classpath that should be
+ // in effect for given IDocument and provide TypeUtil or SpringPropertyIndex parsed from that classpath.
+ // Note that the provider is responsible for doing some kind of sensible caching so that indexes are not
+ // rebuilt every time the index is being used.
+ SpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider();
+ TypeUtil typeUtil = new TypeUtil(null);
+ TypeUtilProvider typeUtilProvider = (IDocument doc) -> typeUtil;
+ ApplicationYamlLanguageServer server = new ApplicationYamlLanguageServer(indexProvider, typeUtilProvider);
LoggingJsonAdapter jsonServer = new LoggingJsonAdapter(server);
jsonServer.setMessageLog(new PrintWriter(System.out));
diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/quickfix/ReplaceDeprecatedYamlQuickfix.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/quickfix/ReplaceDeprecatedYamlQuickfix.java
new file mode 100644
index 000000000..5e60c2e4b
--- /dev/null
+++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/quickfix/ReplaceDeprecatedYamlQuickfix.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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.yaml.quickfix;
+
+import java.awt.Image;
+import java.awt.Point;
+
+import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.completion.ProposalApplier;
+import org.springframework.ide.vscode.commons.languageserver.quickfix.ProblemFixer;
+import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixContext;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.util.Log;
+import org.springframework.ide.vscode.yaml.completion.YamlPathEdits;
+import org.springframework.ide.vscode.yaml.path.YamlPath;
+import org.springframework.ide.vscode.yaml.reconcile.SpringPropertyProblem;
+import org.springframework.ide.vscode.yaml.structure.YamlDocument;
+import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SChildBearingNode;
+import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SDocNode;
+import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SKeyNode;
+import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SNode;
+import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SNodeType;
+import org.springframework.ide.vscode.yaml.structure.YamlStructureProvider;
+
+import io.typefox.lsapi.CompletionItemKind;
+
+@SuppressWarnings("restriction")
+public class ReplaceDeprecatedYamlQuickfix implements ICompletionProposal {
+
+ public static ProblemFixer FIXER = (context, problem, proposals) -> {
+ throw new UnsupportedOperationException("Not yet implemented");
+// PropertyInfo metadata = problem.getMetadata();
+// if (metadata!=null) {
+// String replacement = metadata.getDeprecationReplacement();
+// if (replacement!=null) {
+// //No need to check problem type... we only attach this fixer to problems of applicable type.
+// proposals.add(new ReplaceDeprecatedYamlQuickfix(context, problem));
+// }
+// }
+ };
+
+ @Override
+ public ICompletionProposal deemphasize() {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+ @Override
+ public String getLabel() {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+ @Override
+ public CompletionItemKind getKind() {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+ @Override
+ public DocumentEdits getTextEdit() {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+// private final QuickfixContext context;
+// private final SpringPropertyProblem problem;
+//
+// private LazyProposalApplier applier = new LazyProposalApplier() {
+// protected ProposalApplier create() throws Exception {
+// String newName = problem.getMetadata().getDeprecationReplacement();
+// String oldName = problem.getPropertyName();
+// YamlPath newPath = YamlPath.fromProperty(newName);
+// YamlPath oldPath = YamlPath.fromProperty(oldName);
+// YamlPath prefix = newPath.commonPrefix(oldPath);
+// if (prefix.size()==newPath.size()-1 && newPath.size()==oldPath.size()) {
+// //only the last segment has changed. We can do a simple 'in-place' replace
+// // of just the change segment.
+// DocumentEdits edits = new DocumentEdits(context.getDocument());
+// edits.replace(problem.getOffset(), problem.getEnd(), newPath.getLastSegment().toPropString());
+// return edits;
+// }
+// YamlDocument doc = new YamlDocument(context.getDocument(), YamlStructureProvider.DEFAULT);
+// SNode problemNode = doc.getStructure().find(problem.getOffset());
+// if (problemNode.getNodeType()==SNodeType.KEY) {
+// SKeyNode problemKey = (SKeyNode) problemNode;
+// if (problemKey.isInKey(problem.getOffset())) {
+// YamlPathEdits edits = new YamlPathEdits(doc);
+//// print(doc, edits);
+// String valueText = problemKey.getValueWithRelativeIndent();
+// edits.deleteNode(problemKey);
+// int maxParentDeletions = oldPath.size() - prefix.size() - 1; // don't delete bits of the common prefix!
+// SChildBearingNode parent = problemNode.getParent();
+// while (maxParentDeletions>0 && parent!=null && parent.getChildren().size()==1) {
+// edits.deleteNode(parent);
+// parent = parent.getParent();
+// maxParentDeletions--;
+// }
+//// print(doc, edits);
+// SDocNode docRoot = problemNode.getDocNode(); //edits should stay within the same 'document' for yaml file that has multiple documents inside of it.
+// edits.createPath(docRoot, YamlPath.fromProperty(newName), valueText);
+//// print(doc, edits);
+// return edits;
+// }
+// }
+// //Not sure what to do... case not covered... so do nothing but tell the user.
+// context.getUI().error("Yaml file too complex",
+// "Sorry, but the yaml file is too complex for this quickfix. " +
+// "Please make the change manually."
+// );
+// return ProposalApplier.NULL;
+// }
+//
+//// private void print(YamlDocument doc, YamlPathEdits edits) throws Exception {
+//// Document workingCopy = new Document(doc.getDocument().get());
+//// edits.apply(workingCopy);
+//// System.out.println("==============");
+//// System.out.println(workingCopy.get());
+//// System.out.println("==============");
+//// }
+// };
+//
+// public ReplaceDeprecatedYamlQuickfix(QuickfixContext context, SpringPropertyProblem problem) {
+// this.context = context;
+// this.problem = problem;
+// }
+//
+// @Override
+// public void apply(IDocument doc) {
+// try {
+// applier.apply(doc);
+// } catch (Exception e) {
+// Log.log(e);
+// }
+// }
+//
+// private String getReplacementProperty() {
+// return problem.getMetadata().getDeprecationReplacement();
+// }
+//
+// @Override
+// public Point getSelection(IDocument doc) {
+// try {
+// return applier.getSelection(doc);
+// } catch (Exception e) {
+// Log.log(e);
+// return null;
+// }
+// }
+//
+// @Override
+// public String getAdditionalProposalInfo() {
+// return null;
+// }
+//
+// @Override
+// public String getDisplayString() {
+// return "Change to '"+getReplacementProperty()+"'";
+// }
+//
+// @Override
+// public Image getImage() {
+// return JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+// }
+//
+// @Override
+// public IContextInformation getContextInformation() {
+// return null;
+// }
+
+}
diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/ApplicationYamlASTReconciler.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/ApplicationYamlASTReconciler.java
new file mode 100644
index 000000000..a34f6213d
--- /dev/null
+++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/ApplicationYamlASTReconciler.java
@@ -0,0 +1,379 @@
+package org.springframework.ide.vscode.yaml.reconcile;
+
+import static org.springframework.ide.vscode.yaml.ast.NodeUtil.asScalar;
+import static org.springframework.ide.vscode.yaml.ast.YamlFileAST.getChildren;
+import static org.springframework.ide.vscode.yaml.reconcile.SpringPropertiesProblemType.YAML_DEPRECATED;
+import static org.springframework.ide.vscode.yaml.reconcile.SpringPropertiesProblemType.YAML_DUPLICATE_KEY;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.springframework.ide.vscode.boot.properties.metadata.IndexNavigator;
+import org.springframework.ide.vscode.boot.properties.metadata.PropertyInfo;
+import org.springframework.ide.vscode.boot.properties.metadata.types.Type;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypeParser;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypeUtil;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypeUtil.BeanPropertyNameMode;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypeUtil.EnumCaseMode;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypedProperty;
+import org.springframework.ide.vscode.util.StringUtil;
+import org.springframework.ide.vscode.util.ValueParser;
+import org.springframework.ide.vscode.yaml.ast.NodeRef;
+import org.springframework.ide.vscode.yaml.ast.NodeRef.Kind;
+import org.springframework.ide.vscode.yaml.ast.NodeRef.TupleValueRef;
+import org.springframework.ide.vscode.yaml.ast.NodeUtil;
+import org.springframework.ide.vscode.yaml.ast.YamlFileAST;
+import org.springframework.ide.vscode.yaml.quickfix.ReplaceDeprecatedYamlQuickfix;
+import org.yaml.snakeyaml.nodes.MappingNode;
+import org.yaml.snakeyaml.nodes.Node;
+import org.yaml.snakeyaml.nodes.NodeId;
+import org.yaml.snakeyaml.nodes.NodeTuple;
+import org.yaml.snakeyaml.nodes.ScalarNode;
+import org.yaml.snakeyaml.nodes.SequenceNode;
+
+/**
+ * @author Kris De Volder
+ */
+public class ApplicationYamlASTReconciler implements YamlASTReconciler {
+
+ private final IProblemCollector problems;
+ private final TypeUtil typeUtil;
+ private final IndexNavigator nav;
+
+ public ApplicationYamlASTReconciler(IProblemCollector problems, IndexNavigator nav, TypeUtil typeUtil) {
+ this.problems = problems;
+ this.typeUtil = typeUtil;
+ this.nav = nav;
+ }
+
+ @Override
+ public void reconcile(YamlFileAST ast) {
+ reconcile(ast, nav);
+ }
+
+ protected void reconcile(YamlFileAST ast, IndexNavigator nav) {
+ List nodes = ast.getNodes();
+ if (nodes!=null && !nodes.isEmpty()) {
+ for (Node node : nodes) {
+ reconcile(node, nav);
+ }
+ }
+ }
+
+ protected void reconcile(Node node, IndexNavigator nav) {
+ switch (node.getNodeId()) {
+ case mapping:
+ checkForDuplicateKeys((MappingNode)node);
+ for (NodeTuple entry : ((MappingNode)node).getValue()) {
+ reconcile(entry, nav);
+ }
+ break;
+ case scalar:
+ if (!isIgnoreScalarAssignmentTo(nav.getPrefix())) {
+ expectMapping(node);
+ }
+ break;
+ default:
+ expectMapping(node);
+ break;
+ }
+ }
+
+ private void checkForDuplicateKeys(MappingNode node) {
+ Set duplicateKeys = new HashSet<>();
+ Set seenKeys = new HashSet<>();
+ for (NodeTuple entry : node.getValue()) {
+ String key = asScalar(entry.getKeyNode());
+ if (key!=null) {
+ if (!seenKeys.add(key)) {
+ duplicateKeys.add(key);
+ }
+ }
+ }
+ if (!duplicateKeys.isEmpty()) {
+ for (NodeTuple entry : node.getValue()) {
+ Node keyNode = entry.getKeyNode();
+ String key = asScalar(keyNode);
+ if (key!=null && duplicateKeys.contains(key)) {
+ problems.accept(problem(YAML_DUPLICATE_KEY, keyNode, "Duplicate key '"+key+"'"));
+ }
+ }
+ }
+ }
+
+ protected boolean isIgnoreScalarAssignmentTo(String propName) {
+ //See https://issuetracker.springsource.com/browse/STS-4144
+ return propName!=null && propName.equals("spring.profiles");
+ }
+
+ private void reconcile(NodeTuple entry, IndexNavigator nav) {
+ Node keyNode = entry.getKeyNode();
+ String key = asScalar(keyNode);
+ if (key==null) {
+ expectScalar(keyNode);
+ } else {
+ IndexNavigator subNav = nav.selectSubProperty(key);
+ PropertyInfo match = subNav.getExactMatch();
+ PropertyInfo extension = subNav.getExtensionCandidate();
+ if (match==null && extension==null) {
+ //nothing found for this key. Maybe user is using camelCase variation of the key?
+ String keyAlias = StringUtil.camelCaseToHyphens(key);
+ IndexNavigator subNavAlias = nav.selectSubProperty(keyAlias);
+ match = subNavAlias.getExactMatch();
+ extension = subNavAlias.getExtensionCandidate();
+ if (match!=null || extension!=null) {
+ //Got something for the alias, so use that instead.
+ //Note: do not swap for alias unless we actually found something.
+ // This gives more logical errors (in terms of user's key, not its canonical alias)
+ subNav = subNavAlias;
+ }
+ }
+ if (match!=null && extension!=null) {
+ //This is an odd situation, the current prefix lands on a propery
+ //but there are also other properties that have it as a prefix.
+ //This ambiguity is hard to deal with and we choose not to do so for now
+ return;
+ } else if (match!=null) {
+ Type type = TypeParser.parse(match.getType());
+ if (match.isDeprecated()) {
+ deprecatedProperty(match, keyNode);
+ }
+ reconcile(entry.getValueNode(), type);
+ } else if (extension!=null) {
+ //We don't really care about the extension only about the fact that it
+ // exists and so it is meaningful to continue checking...
+ Node valueNode = entry.getValueNode();
+ reconcile(valueNode, subNav);
+ } else {
+ //both are null, this means there's no valid property with the current prefix
+ //whether exact or extending it with further navigation
+ unkownProperty(keyNode, subNav.getPrefix(), entry);
+ }
+ }
+ }
+
+ /**
+ * Reconcile a node given the type that we expect the node to be.
+ */
+ private void reconcile(Node node, Type type) {
+ if (type!=null) {
+ switch (node.getNodeId()) {
+ case scalar:
+ reconcile((ScalarNode)node, type);
+ break;
+ case sequence:
+ reconcile((SequenceNode)node, type);
+ break;
+ case mapping:
+ reconcile((MappingNode)node, type);
+ break;
+ case anchor:
+ //TODO: what should we do with anchor nodes
+ break;
+ default:
+ throw new IllegalStateException("Missing switch case");
+ }
+ }
+ }
+
+ private void reconcile(MappingNode mapping, Type type) {
+ checkForDuplicateKeys(mapping);
+ if (typeUtil.isAtomic(type)) {
+ expectTypeFoundMapping(type, mapping);
+ } else if (TypeUtil.isMap(type) || TypeUtil.isSequencable(type)) {
+ Type keyType = typeUtil.getKeyType(type);
+ Type valueType = TypeUtil.getDomainType(type);
+ if (keyType!=null) {
+ for (NodeTuple entry : mapping.getValue()) {
+ reconcile(entry.getKeyNode(), keyType);
+ }
+ }
+ if (valueType!=null) {
+ for (NodeTuple entry : mapping.getValue()) {
+ Node value = entry.getValueNode();
+ Type nestedValueType = valueType;
+ if (value.getNodeId()==NodeId.mapping) {
+ //Some special cases to handle here!!
+ // See https://issuetracker.springsource.com/browse/STS-4254
+ // See https://issuetracker.springsource.com/browse/STS-4335
+ if (TypeUtil.isObject(valueType)) {
+ nestedValueType = type;
+ } else if (TypeUtil.isString(keyType) && typeUtil.isAtomic(valueType)) {
+ nestedValueType = type;
+ }
+ }
+ reconcile(entry.getValueNode(), nestedValueType);
+ }
+ }
+ } else {
+ // Neither atomic, map or sequence-like => bean-like
+ Map props = typeUtil.getPropertiesMap(type, EnumCaseMode.ALIASED, BeanPropertyNameMode.ALIASED);
+ if (props!=null) {
+ for (NodeTuple entry : mapping.getValue()) {
+ Node keyNode = entry.getKeyNode();
+ String key = NodeUtil.asScalar(keyNode);
+ if (key==null) {
+ expectBeanPropertyName(keyNode, type);
+ } else {
+ if (!props.containsKey(key)) {
+ unknownBeanProperty(keyNode, type, key);
+ } else {
+ Node valNode = entry.getValueNode();
+ TypedProperty typedProperty = props.get(key);
+ if (typedProperty!=null) {
+ if (typedProperty.isDeprecated()) {
+ deprecatedProperty(type, typedProperty, keyNode);
+ }
+ reconcile(valNode, typedProperty.getType());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void reconcile(SequenceNode seq, Type type) {
+ if (typeUtil.isAtomic(type)) {
+ expectTypeFoundSequence(type, seq);
+ } else if (TypeUtil.isSequencable(type)) {
+ Type domainType = TypeUtil.getDomainType(type);
+ if (domainType!=null) {
+ for (Node element : seq.getValue()) {
+ reconcile(element, domainType);
+ }
+ }
+ } else {
+ expectTypeFoundSequence(type, seq);
+ }
+ }
+
+
+ private void reconcile(ScalarNode scalar, Type type) {
+ String stringValue = scalar.getValue();
+ if (!stringValue.contains("${")) { //don't check anything with ${} expressions in it as we
+ // don't know its actual value
+ ValueParser valueParser = typeUtil.getValueParser(type);
+ if (valueParser!=null) {
+ // Tag tag = scalar.getTag(); //use the tag? Actually, boot tolerates String values
+ // even if integeger etc are expected. It has its ways of parsing the String to the
+ // expected type
+ try {
+ valueParser.parse(stringValue);
+ } catch (Exception e) {
+ //Couldn't parse
+ valueTypeMismatch(type, scalar);
+ }
+ }
+ }
+ }
+
+ private void expectTypeFoundMapping(Type type, MappingNode node) {
+ expectType(SpringPropertiesProblemType.YAML_EXPECT_TYPE_FOUND_MAPPING, type, node);
+ }
+
+ private void expectTypeFoundSequence(Type type, SequenceNode seq) {
+ expectType(SpringPropertiesProblemType.YAML_EXPECT_TYPE_FOUND_SEQUENCE, type, seq);
+ }
+
+ private void valueTypeMismatch(Type type, ScalarNode scalar) {
+ expectType(SpringPropertiesProblemType.YAML_VALUE_TYPE_MISMATCH, type, scalar);
+ }
+
+ private void unkownProperty(Node node, String name, NodeTuple entry) {
+ SpringPropertyProblem p = problem(SpringPropertiesProblemType.YAML_UNKNOWN_PROPERTY, node, "Unknown property '"+name+"'");
+ p.setPropertyName(extendForQuickfix(StringUtil.camelCaseToHyphens(name), entry.getValueNode()));
+ problems.accept(p);
+ }
+
+ private String extendForQuickfix(String name, Node node) {
+ if (node!=null) {
+ TupleValueRef child = getFirstTupleValue(getChildren(node));
+ if (child!=null) {
+ String extra = NodeUtil.asScalar(child.getKey());
+ if (extra!=null) {
+ return extendForQuickfix(name + "." + StringUtil.camelCaseToHyphens(extra),
+ child.get());
+ }
+ }
+ }
+ //couldn't extend name any further
+ return name;
+ }
+
+ private TupleValueRef getFirstTupleValue(List> children) {
+ for (NodeRef> nodeRef : children) {
+ if (nodeRef.getKind()==Kind.VAL) {
+ return (TupleValueRef) nodeRef;
+ }
+ }
+ return null;
+ }
+
+ private void expectScalar(Node node) {
+ problems.accept(problem(SpringPropertiesProblemType.YAML_EXPECT_SCALAR, node, "Expecting a 'Scalar' node but got "+describe(node)));
+ }
+
+ protected void expectMapping(Node node) {
+ problems.accept(problem(SpringPropertiesProblemType.YAML_EXPECT_MAPPING, node, "Expecting a 'Mapping' node but got "+describe(node)));
+ }
+
+ private void expectBeanPropertyName(Node keyNode, Type type) {
+ problems.accept(problem(SpringPropertiesProblemType.YAML_EXPECT_BEAN_PROPERTY_NAME, keyNode, "Expecting a bean-property name for object of type '"+typeUtil.niceTypeName(type)+"' "
+ + "but got "+describe(keyNode)));
+ }
+
+ private void unknownBeanProperty(Node keyNode, Type type, String name) {
+ problems.accept(problem(SpringPropertiesProblemType.YAML_INVALID_BEAN_PROPERTY, keyNode, "Unknown property '"+name+"' for type '"+typeUtil.niceTypeName(type)+"'"));
+ }
+
+ private void expectType(SpringPropertiesProblemType problemType, Type type, Node node) {
+ problems.accept(problem(problemType, node, "Expecting a '"+typeUtil.niceTypeName(type)+"' but got "+describe(node)));
+ }
+
+ private void deprecatedProperty(PropertyInfo property, Node keyNode) {
+ SpringPropertyProblem problem = deprecatedPropertyProblem(property.getId(), null, keyNode,
+ property.getDeprecationReplacement(), property.getDeprecationReason());
+ problem.setMetadata(property);
+ problem.setProblemFixer(ReplaceDeprecatedYamlQuickfix.FIXER);
+ problems.accept(problem);
+ }
+
+ private void deprecatedProperty(Type contextType, TypedProperty property, Node keyNode) {
+ SpringPropertyProblem problem = deprecatedPropertyProblem(property.getName(), typeUtil.niceTypeName(contextType),
+ keyNode, property.getDeprecationReplacement(), property.getDeprecationReason());
+ problems.accept(problem);
+ }
+
+ protected SpringPropertyProblem deprecatedPropertyProblem(String name, String contextType, Node keyNode,
+ String replace, String reason) {
+ SpringPropertyProblem problem = problem(YAML_DEPRECATED, keyNode, TypeUtil.deprecatedPropertyMessage(name, contextType, replace, reason));
+ problem.setPropertyName(name);
+ return problem;
+ }
+
+ protected SpringPropertyProblem problem(SpringPropertiesProblemType type, Node node, String msg) {
+ int start = node.getStartMark().getIndex();
+ int end = node.getEndMark().getIndex();
+ return SpringPropertyProblem.problem(type, msg, start, end-start);
+ }
+
+ private String describe(Node node) {
+ switch (node.getNodeId()) {
+ case scalar:
+ return "'"+((ScalarNode)node).getValue()+"'";
+ case mapping:
+ return "a 'Mapping' node";
+ case sequence:
+ return "a 'Sequence' node";
+ case anchor:
+ return "a 'Anchor' node";
+ default:
+ throw new IllegalStateException("Missing switch case");
+ }
+ }
+
+}
diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/ApplicationYamlReconcileEngine.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/ApplicationYamlReconcileEngine.java
new file mode 100644
index 000000000..3d7ee2dbf
--- /dev/null
+++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/ApplicationYamlReconcileEngine.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2015, 2016 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.yaml.reconcile;
+
+import static org.springframework.ide.vscode.yaml.ApplicationYamlProblems.Type.YAML_SYNTAX_ERROR;
+
+import org.springframework.ide.vscode.boot.properties.metadata.IndexNavigator;
+import org.springframework.ide.vscode.boot.properties.metadata.PropertyInfo;
+import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertyIndexProvider;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypeUtilProvider;
+import org.springframework.ide.vscode.boot.properties.util.FuzzyMap;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.yaml.ApplicationYamlProblems;
+import org.springframework.ide.vscode.yaml.ast.YamlASTProvider;
+
+public class ApplicationYamlReconcileEngine extends YamlReconcileEngine {
+
+ private SpringPropertyIndexProvider indexProvider;
+ private TypeUtilProvider typeUtilProvider;
+
+ public ApplicationYamlReconcileEngine(YamlASTProvider astProvider, SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider) {
+ super(astProvider);
+ this.indexProvider = indexProvider;
+ this.typeUtilProvider = typeUtilProvider;
+ }
+
+ protected YamlASTReconciler getASTReconciler(IDocument doc, IProblemCollector problemCollector) {
+ FuzzyMap index = indexProvider.getIndex(doc);
+ if (index!=null && !index.isEmpty()) {
+ IndexNavigator nav = IndexNavigator.with(index);
+ return new ApplicationYamlASTReconciler(problemCollector, nav, typeUtilProvider.getTypeUtil(doc));
+ }
+ return null;
+ }
+
+ @Override
+ protected ReconcileProblem syntaxError(String msg, int offset, int len) {
+ return ApplicationYamlProblems.problem(YAML_SYNTAX_ERROR, msg, offset, len);
+ }
+
+}
diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/SpringPropertiesProblemType.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/SpringPropertiesProblemType.java
new file mode 100644
index 000000000..57fa02036
--- /dev/null
+++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/SpringPropertiesProblemType.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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.yaml.reconcile;
+
+import static org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity.*;
+
+import java.util.ArrayList;
+
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
+
+/**
+ * @author Kris De Volder
+ */
+public enum SpringPropertiesProblemType implements ProblemType {
+
+ // Naming:
+ // YAML_* for all problems in .yml files.
+ // PROP_* for all problems in .properties files.
+ // All enum values must start with one or the other (or some stuff will break!).
+
+// PROP_INVALID_BEAN_NAVIGATION("Accessing a 'bean property' in a type that doesn't have properties (e.g. like String or Integer)"),
+// PROP_INVALID_INDEXED_NAVIGATION("Accessing a property using [] in a type that doesn't support that"),
+// PROP_EXPECTED_DOT_OR_LBRACK("Unexpected character found where a '.' or '[' was expected"),
+// PROP_NO_MATCHING_RBRACK("Found a '[' but no matching ']'"),
+// PROP_NON_INTEGER_IN_BRACKETS("Use of [..] navigation with non-integer value"),
+// PROP_VALUE_TYPE_MISMATCH("Expecting a value of a certain type, but value doesn't parse as such"),
+// PROP_INVALID_BEAN_PROPERTY("Accessing a named property in a type that doesn't provide a property accessor with that name"),
+// PROP_UNKNOWN_PROPERTY(WARNING, "Property-key not found in any configuration metadata on the project's classpath"),
+// PROP_DEPRECATED(WARNING, "Property is marked as Deprecated"),
+// PROP_DUPLICATE_KEY("Multiple assignments to the same property value"),
+
+ YAML_SYNTAX_ERROR("Error parsing the input using snakeyaml"),
+ YAML_UNKNOWN_PROPERTY(WARNING, "Property-key not found in the configuration metadata on the project's classpath"),
+ YAML_VALUE_TYPE_MISMATCH("Expecting a value of a certain type, but value doesn't parse as such"),
+ YAML_EXPECT_SCALAR("Expecting a 'scalar' value but found something more complex."),
+ YAML_EXPECT_TYPE_FOUND_SEQUENCE("Found a 'sequence' node where a non 'list-like' type is expected"),
+ YAML_EXPECT_TYPE_FOUND_MAPPING("Found a 'mapping' node where a type that can't be treated as a 'property map' is expected"),
+ YAML_EXPECT_MAPPING("Expecting a 'mapping' node but found something else"),
+ YAML_EXPECT_BEAN_PROPERTY_NAME("Expecting a 'bean property' name but found something more complex"),
+ YAML_INVALID_BEAN_PROPERTY("Accessing a named property in a type that doesn't provide a property accessor with that name"),
+ YAML_DEPRECATED(WARNING, "Property is marked as Deprecated"),
+ YAML_DUPLICATE_KEY("A mapping node contains multiple entries for the same key");
+
+ private final ProblemSeverity defaultSeverity;
+ private String description;
+ private String label;
+
+ private SpringPropertiesProblemType(ProblemSeverity defaultSeverity, String description, String label) {
+ this.description = description;
+ this.defaultSeverity = defaultSeverity;
+ this.label = label;
+ }
+
+ private SpringPropertiesProblemType(ProblemSeverity defaultSeverity, String description) {
+ this(defaultSeverity, description, null);
+ }
+
+ private SpringPropertiesProblemType(String description) {
+ this(ERROR, description);
+ }
+
+ public ProblemSeverity getDefaultSeverity() {
+ return defaultSeverity;
+ }
+
+
+ public static SpringPropertiesProblemType[] forProperties() {
+ return withPrefix("PROP_");
+ }
+
+
+ private static SpringPropertiesProblemType[] withPrefix(String prefix) {
+ SpringPropertiesProblemType[] allValues = values();
+ ArrayList values = new ArrayList(allValues.length);
+ for (SpringPropertiesProblemType v : allValues) {
+ if (v.toString().startsWith(prefix)) {
+ values.add(v);
+ }
+ }
+ return values.toArray(new SpringPropertiesProblemType[values.size()]);
+ }
+
+ public String getLabel() {
+ if (label==null) {
+ label = createDefaultLabel();
+ }
+ return label;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ private String createDefaultLabel() {
+ String label = this.toString().substring(5).toLowerCase().replace('_', ' ');
+ return Character.toUpperCase(label.charAt(0)) + label.substring(1);
+ }
+
+ @Override
+ public String getCode() {
+ return name();
+ }
+
+// TODO: obsolete? We should simply keep the problemtype implementations for yaml / props editor totally separate
+// public static final SpringPropertiesProblemType[] FOR_YAML = FOR(EditorType.YAML);
+// public static final SpringPropertiesProblemType[] FOR_PROPERTIES = FOR(EditorType.PROP);
+// public static SpringPropertiesProblemType[] FOR(EditorType et) {
+// return withPrefix(et.getProblemTypePrefix());
+// }
+// public EditorType getEditorType() {
+// String string = this.toString();
+// for (EditorType et : EditorType.values()) {
+// String prefix = et.getProblemTypePrefix();
+// if (string.startsWith(prefix)) {
+// return et;
+// }
+// }
+// throw new IllegalStateException("Bug: unknown editor type for "+this);
+// }
+}
diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/SpringPropertyProblem.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/SpringPropertyProblem.java
new file mode 100644
index 000000000..53ac32be7
--- /dev/null
+++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/yaml/reconcile/SpringPropertyProblem.java
@@ -0,0 +1,34 @@
+package org.springframework.ide.vscode.yaml.reconcile;
+
+import org.springframework.ide.vscode.boot.properties.metadata.PropertyInfo;
+import org.springframework.ide.vscode.commons.languageserver.quickfix.ProblemFixer;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
+
+public class SpringPropertyProblem extends ReconcileProblemImpl {
+
+ private PropertyInfo property = null;
+ private ProblemFixer fixer;
+ private String propertyName;
+
+ public SpringPropertyProblem(ProblemType type, String msg, int offset, int len) {
+ super(type, msg, offset, len);
+ }
+
+ public static SpringPropertyProblem problem(SpringPropertiesProblemType type, String msg, int offset, int len) {
+ return new SpringPropertyProblem(type, msg, offset, len);
+ }
+
+ public void setMetadata(PropertyInfo property) {
+ this.property = property;
+ }
+
+ public void setProblemFixer(ProblemFixer fixer) {
+ this.fixer = fixer;
+ }
+
+ public void setPropertyName(String name) {
+ propertyName = name;
+ }
+
+}
diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/AbstractPropsEditorTest.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/AbstractPropsEditorTest.java
index 0a07aab79..69e34e137 100644
--- a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/AbstractPropsEditorTest.java
+++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/AbstractPropsEditorTest.java
@@ -11,9 +11,13 @@ import java.util.Set;
import org.junit.Before;
import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertyIndexProvider;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypeUtil;
+import org.springframework.ide.vscode.boot.properties.metadata.types.TypeUtilProvider;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
+import org.springframework.ide.vscode.java.IJavaProject;
import org.springframework.ide.vscode.testharness.Editor;
import org.springframework.ide.vscode.testharness.LanguageServerHarness;
-import org.springframework.ide.vscode.testharness.TestProject;
import org.springframework.ide.vscode.yaml.PropertyIndexHarness.ItemConfigurer;
import io.typefox.lsapi.CompletionItem;
@@ -22,7 +26,16 @@ public class AbstractPropsEditorTest {
private PropertyIndexHarness md;
private LanguageServerHarness harness;
-
+ private IJavaProject testProject;
+ private TypeUtil typeUtil;
+
+ private TypeUtilProvider typeUtilProvider = (IDocument doc) -> {
+ if (typeUtil==null) {
+ typeUtil = new TypeUtil(testProject);
+ }
+ return typeUtil;
+ };
+
public Editor newEditor(String contents) throws Exception {
return harness.newEditor(contents);
}
@@ -30,10 +43,14 @@ public class AbstractPropsEditorTest {
@Before
public void setup() throws Exception {
md = new PropertyIndexHarness();
- harness = new LanguageServerHarness(ApplicationYamlLanguageServer::new);
+ harness = new LanguageServerHarness(this::newLanguageServer);
harness.intialize(null);
}
+ private SimpleLanguageServer newLanguageServer() {
+ return new ApplicationYamlLanguageServer(md.getIndexProvider(), typeUtilProvider);
+ }
+
public ItemConfigurer data(String id, String type, Object deflt, String description, String... sources) {
return md.data(id, type, deflt, description, sources);
}
@@ -42,13 +59,15 @@ public class AbstractPropsEditorTest {
md.defaultTestData();
}
- public TestProject createPredefinedMavenProject(String string) {
+ public IJavaProject createPredefinedMavenProject(String string) {
notImplemented();
return null;
}
- public void useProject(TestProject p) {
- notImplemented(); //only tests that don't require project context / classpath work for now
+ public void useProject(IJavaProject p) throws Exception {
+ md.useProject(p);
+ this.testProject = p;
+ this.typeUtil = null;
}
/**
diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java
index e031a657c..62fa611a5 100644
--- a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java
+++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlEditorTest.java
@@ -20,9 +20,8 @@ import org.junit.Ignore;
import org.junit.Test;
import org.springframework.ide.vscode.boot.properties.metadata.CachingValueProvider;
import org.springframework.ide.vscode.boot.properties.metadata.PropertyInfo;
+import org.springframework.ide.vscode.java.IJavaProject;
import org.springframework.ide.vscode.testharness.Editor;
-import org.springframework.ide.vscode.testharness.LanguageServerHarness;
-import org.springframework.ide.vscode.testharness.TestProject;
import org.springframework.ide.vscode.util.StringUtil;
import io.typefox.lsapi.CompletionItem;
@@ -40,9 +39,6 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
////////////////////////////////////////////////////////////////////////////////////////
@Test public void linterRunsOnDocumentOpenAndChange() throws Exception {
- LanguageServerHarness harness = new LanguageServerHarness(ApplicationYamlLanguageServer::new);
- harness.intialize(null);
-
Editor editor = newEditor(
"somemap: val\n"+
"- sequence"
@@ -110,7 +106,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
@Ignore @Test public void testHoverInfoForEnumValueInMapKey() throws Exception {
Editor editor;
- TestProject project = createPredefinedMavenProject("boot13");
+ IJavaProject project = createPredefinedMavenProject("boot13");
useProject(project);
//This test will fail if source jars haven't been downloaded.
@@ -142,7 +138,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
}
@Ignore @Test public void testHoverInfoForEnumValueInMapKeyCompletion() throws Exception {
- TestProject project = createPredefinedMavenProject("boot13");
+ IJavaProject project = createPredefinedMavenProject("boot13");
useProject(project);
//This test will fail if source jars haven't been downloaded.
@@ -226,7 +222,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
@Ignore @Test public void testHyperlinkTargets() throws Exception {
System.out.println(">>> testHyperlinkTargets");
- TestProject p = createPredefinedMavenProject("demo");
+ IJavaProject p = createPredefinedMavenProject("demo");
useProject(p);
Editor editor = newEditor(
@@ -252,7 +248,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
System.out.println("<<< testHyperlinkTargets");
}
- @Test @Ignore public void testReconcile() throws Exception {
+ @Test public void testReconcile() throws Exception {
defaultTestData();
Editor editor = newEditor(
"server:\n" +
@@ -266,6 +262,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
" no: \n" +
" good: true\n"
);
+ System.out.println(editor);
editor.assertProblems(
"extracrap: 8080|Expecting a 'int' but got a 'Mapping' node",
"snuggem|Unknown property",
@@ -438,7 +435,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
@Ignore @Test public void testReconcileCamelCaseBeanProp() throws Exception {
Editor editor;
- TestProject p = createPredefinedMavenProject("demo");
+ IJavaProject p = createPredefinedMavenProject("demo");
useProject(p);
data("demo.bean", "demo.CamelCaser", "For testing tolerance of camelCase", null);
@@ -492,7 +489,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
}
@Ignore @Test public void testContentAssistCamelCaseBeanProp() throws Exception {
- TestProject p = createPredefinedMavenProject("demo");
+ IJavaProject p = createPredefinedMavenProject("demo");
useProject(p);
data("demo.bean", "demo.CamelCaser", "For testing tolerance of camelCase", null);
@@ -543,7 +540,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
@Ignore @Test public void testReconcileBeanPropName() throws Exception {
- TestProject p = createPredefinedMavenProject("demo-list-of-pojo");
+ IJavaProject p = createPredefinedMavenProject("demo-list-of-pojo");
useProject(p);
assertNotNull(p.findType("demo.Foo"));
data("some-foo", "demo.Foo", null, "some Foo pojo property");
@@ -575,7 +572,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
}
@Ignore @Test public void testReconcilePojoArray() throws Exception {
- TestProject p = createPredefinedMavenProject("demo-list-of-pojo");
+ IJavaProject p = createPredefinedMavenProject("demo-list-of-pojo");
useProject(p);
assertNotNull(p.findType("demo.Foo"));
@@ -652,7 +649,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
}
@Ignore @Test public void testEnumPropertyReconciling() throws Exception {
- TestProject p = createPredefinedMavenProject("demo-enum");
+ IJavaProject p = createPredefinedMavenProject("demo-enum");
useProject(p);
assertNotNull(p.findType("demo.Color"));
@@ -1834,7 +1831,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
}
@Ignore @Test public void testEnumsInLowerCaseContentAssist() throws Exception {
- TestProject p = createPredefinedMavenProject("demo-enum");
+ IJavaProject p = createPredefinedMavenProject("demo-enum");
useProject(p);
assertNotNull(p.findType("demo.ClothingSize"));
@@ -2161,13 +2158,13 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
@Ignore @Test public void test_STS4231() throws Exception {
//Should the 'predefined' project need to be recreated... use the commented code below:
// BootProjectTestHarness projectHarness = new BootProjectTestHarness(ResourcesPlugin.getWorkspace());
-// TestProject project = projectHarness.createBootProject("sts-4231",
+// IJavaProject project = projectHarness.createBootProject("sts-4231",
// bootVersionAtLeast("1.3.0"),
// withStarters("web", "cloud-config-server")
// );
//For more robust test use predefined project which is not so much a moving target:
- TestProject project = createPredefinedMavenProject("sts-4231");
+ IJavaProject project = createPredefinedMavenProject("sts-4231");
useProject(project);
assertCompletionsDisplayString(
@@ -2418,7 +2415,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
}
@Ignore @Test public void testDeprecatedBeanPropertyHoverInfo() throws Exception {
- TestProject jp = createPredefinedMavenProject("demo");
+ IJavaProject jp = createPredefinedMavenProject("demo");
useProject(jp);
data("foo", "demo.Deprecater", null, "A bean with deprecated property.");
Editor editor = newEditor(
@@ -2431,7 +2428,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
}
@Ignore @Test public void testDeprecatedBeanPropertyReconcile() throws Exception {
- TestProject jp = createPredefinedMavenProject("demo");
+ IJavaProject jp = createPredefinedMavenProject("demo");
useProject(jp);
data("foo", "demo.Deprecater", null, "A Bean with deprecated properties");
@@ -2464,7 +2461,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
}
@Ignore @Test public void testDeprecatedBeanPropertyCompletions() throws Exception {
- TestProject jp = createPredefinedMavenProject("demo");
+ IJavaProject jp = createPredefinedMavenProject("demo");
useProject(jp);
data("foo", "demo.Deprecater", null, "A Bean with deprecated properties");
diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlLanguageServerTests.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlLanguageServerTests.java
index 4d980c571..e384e6115 100644
--- a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlLanguageServerTests.java
+++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/ApplicationYamlLanguageServerTests.java
@@ -5,18 +5,14 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
import java.net.URISyntaxException;
import java.nio.file.Paths;
-import java.util.List;
+import java.util.concurrent.Callable;
import org.junit.Test;
import org.springframework.ide.vscode.testharness.LanguageServerHarness;
-import org.springframework.ide.vscode.testharness.TextDocumentInfo;
-import org.springframework.ide.vscode.yaml.ApplicationYamlLanguageServer;
-import io.typefox.lsapi.CompletionItem;
-import io.typefox.lsapi.CompletionList;
import io.typefox.lsapi.InitializeResult;
-import io.typefox.lsapi.ServerCapabilities;
import io.typefox.lsapi.TextDocumentSyncKind;
+import io.typefox.lsapi.services.LanguageServer;
public class ApplicationYamlLanguageServerTests {
@@ -24,17 +20,23 @@ public class ApplicationYamlLanguageServerTests {
return Paths.get(ApplicationYamlLanguageServerTests.class.getResource(name).toURI()).toFile();
}
+ private LanguageServerHarness newHarness() throws Exception {
+ Callable extends LanguageServer> f = () -> new ApplicationYamlLanguageServer((d) -> null, (d) -> null);
+ return new LanguageServerHarness(f);
+ }
+
@Test
public void createAndInitializeServerWithWorkspace() throws Exception {
- LanguageServerHarness harness = new LanguageServerHarness(ApplicationYamlLanguageServer::new);
+ LanguageServerHarness harness = newHarness();
File workspaceRoot = getTestResource("/workspace/");
assertExpectedInitResult(harness.intialize(workspaceRoot));
}
+
@Test
public void createAndInitializeServerWithoutWorkspace() throws Exception {
File workspaceRoot = null;
- LanguageServerHarness harness = new LanguageServerHarness(ApplicationYamlLanguageServer::new);
+ LanguageServerHarness harness = newHarness();
assertExpectedInitResult(harness.intialize(workspaceRoot));
}
diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/PropertyIndexHarness.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/PropertyIndexHarness.java
index aee4bc943..717e3dedd 100644
--- a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/PropertyIndexHarness.java
+++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/yaml/PropertyIndexHarness.java
@@ -14,8 +14,8 @@ import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertyInd
import org.springframework.ide.vscode.boot.properties.metadata.SpringPropertyIndexProvider;
import org.springframework.ide.vscode.boot.properties.metadata.ValueProviderRegistry;
import org.springframework.ide.vscode.boot.properties.util.FuzzyMap;
-import org.springframework.ide.vscode.testharness.TestProject;
-import org.springframework.ide.vscode.util.IDocument;
+import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
+import org.springframework.ide.vscode.java.IJavaProject;
/**
* Provides some convenience apis for test code to create / use test data for a SpringPropertyIndex.
@@ -25,7 +25,7 @@ public class PropertyIndexHarness {
private Map datas = new LinkedHashMap<>();
private ValueProviderRegistry valueProviders = ValueProviderRegistry.getDefault();
private SpringPropertyIndex index = null;
- private TestProject testProject = null;
+ private IJavaProject testProject = null;
protected SpringPropertyIndexProvider indexProvider = new SpringPropertyIndexProvider() {
public FuzzyMap getIndex(IDocument doc) {
@@ -40,6 +40,11 @@ public class PropertyIndexHarness {
}
};
+ public void useProject(IJavaProject p) throws Exception {
+ index = null;
+ this.testProject = p;
+ }
+
public class ItemConfigurer {
private ConfigurationMetadataProperty item;
diff --git a/vscode-extensions/vscode-application-yaml/test/examples/application.yml b/vscode-extensions/vscode-application-yaml/test/examples/application.yml
index 46d24e076..565aac561 100644
--- a/vscode-extensions/vscode-application-yaml/test/examples/application.yml
+++ b/vscode-extensions/vscode-application-yaml/test/examples/application.yml
@@ -1,2 +1,3 @@
foo: bar
- asss
+foo bar
\ No newline at end of file
diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/Main.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/Main.java
index 898c6a942..85ba3ea23 100644
--- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/Main.java
+++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/Main.java
@@ -9,7 +9,8 @@ import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
-import org.springframework.ide.vscode.util.LoggingFormat;
+import org.springframework.ide.vscode.commons.languageserver.util.LoggingFormat;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import io.typefox.lsapi.services.json.LoggingJsonAdapter;
@@ -78,7 +79,7 @@ public class Main {
* When the request stream is closed, wait for 5s for all outstanding responses to compute, then return.
*/
public static void run(Connection connection) {
- ManifestYamlLanguageServer server = new ManifestYamlLanguageServer();
+ SimpleLanguageServer server = new ManifestYamlLanguageServer();
LoggingJsonAdapter jsonServer = new LoggingJsonAdapter(server);
jsonServer.setMessageLog(new PrintWriter(System.out));
diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYamlLanguageServer.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYamlLanguageServer.java
index e443cebfe..ce442d132 100644
--- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYamlLanguageServer.java
+++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYamlLanguageServer.java
@@ -1,20 +1,15 @@
package org.springframework.ide.vscode.cloudfoundry.manifest.editor;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
import javax.inject.Provider;
-import org.springframework.ide.vscode.commons.completion.ICompletionEngine;
-import org.springframework.ide.vscode.commons.reconcile.IProblemCollector;
-import org.springframework.ide.vscode.commons.reconcile.ReconcileProblem;
-import org.springframework.ide.vscode.util.Futures;
-import org.springframework.ide.vscode.util.SimpleLanguageServer;
-import org.springframework.ide.vscode.util.SimpleTextDocumentService;
-import org.springframework.ide.vscode.util.TextDocument;
+import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
+import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
import org.springframework.ide.vscode.yaml.ast.YamlASTProvider;
+import org.springframework.ide.vscode.yaml.ast.YamlParser;
import org.springframework.ide.vscode.yaml.completion.SchemaBasedYamlAssistContextProvider;
import org.springframework.ide.vscode.yaml.completion.YamlAssistContextProvider;
import org.springframework.ide.vscode.yaml.completion.YamlCompletionEngine;
@@ -26,15 +21,8 @@ import org.yaml.snakeyaml.Yaml;
import com.google.common.collect.ImmutableList;
-import io.typefox.lsapi.CompletionItem;
-import io.typefox.lsapi.CompletionItemKind;
-import io.typefox.lsapi.CompletionList;
-import io.typefox.lsapi.ServerCapabilities;
import io.typefox.lsapi.TextDocumentSyncKind;
-import io.typefox.lsapi.impl.CompletionItemImpl;
-import io.typefox.lsapi.impl.CompletionListImpl;
import io.typefox.lsapi.impl.CompletionOptionsImpl;
-import io.typefox.lsapi.impl.DiagnosticImpl;
import io.typefox.lsapi.impl.ServerCapabilitiesImpl;
public class ManifestYamlLanguageServer extends SimpleLanguageServer {
@@ -55,7 +43,7 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer {
// SimpleWorkspaceService workspace = getWorkspaceService();
documents.onDidChangeContent(params -> {
TextDocument doc = params.getDocument();
- validateDocument(documents, doc);
+ validateWith(doc, getReconcileEngine());
});
// workspace.onDidChangeConfiguraton(settings -> {
@@ -73,34 +61,10 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer {
documents.onCompletionResolve(completionEngine::resolveCompletion);
}
- private void validateDocument(SimpleTextDocumentService documents, TextDocument doc) {
- IProblemCollector problems = new IProblemCollector() {
-
- private List diagnostics = new ArrayList<>();
-
- @Override
- public void endCollecting() {
- documents.publishDiagnostics(doc, diagnostics);
- }
-
- @Override
- public void beginCollecting() {
- diagnostics.clear();
- }
-
- @Override
- public void accept(ReconcileProblem problem) {
- DiagnosticImpl d = new DiagnosticImpl();
- d.setCode(problem.getCode());
- d.setMessage(problem.getMessage());
- d.setRange(doc.toRange(problem.getOffset(), problem.getLength()));
- diagnostics.add(d);
- }
- };
-
+ protected IReconcileEngine getReconcileEngine() {
YamlASTProvider parser = new YamlParser(yaml);
- YamlSchemaBasedReconcileEngine engine = new YamlSchemaBasedReconcileEngine(parser, schema);
- engine.reconcile(doc, problems);
+ IReconcileEngine engine = new YamlSchemaBasedReconcileEngine(parser, schema);
+ return engine;
}
@Override
diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYmlSchema.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYmlSchema.java
index 7b9e82bae..9be4e6e28 100644
--- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYmlSchema.java
+++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYmlSchema.java
@@ -15,6 +15,7 @@ import java.util.Set;
import javax.inject.Provider;
+import org.springframework.ide.vscode.util.HtmlSnippet;
import org.springframework.ide.vscode.yaml.schema.YType;
import org.springframework.ide.vscode.yaml.schema.YTypeFactory;
import org.springframework.ide.vscode.yaml.schema.YTypeFactory.YAtomicType;
@@ -23,7 +24,6 @@ import org.springframework.ide.vscode.yaml.schema.YTypeFactory.YTypedPropertyImp
import org.springframework.ide.vscode.yaml.schema.YTypeUtil;
import org.springframework.ide.vscode.yaml.schema.YValueHint;
import org.springframework.ide.vscode.yaml.schema.YamlSchema;
-import org.springframework.ide.vscode.yaml.util.Description;
import org.springframework.ide.vscode.yaml.util.DescriptionProviders;
import com.google.common.collect.ImmutableSet;
@@ -106,11 +106,11 @@ public class ManifestYmlSchema implements YamlSchema {
}
}
- private Provider descriptionFor(String propName) {
+ private Provider descriptionFor(String propName) {
return DescriptionProviders.fromClasspath(this.getClass(), "/description-by-prop-name/"+propName+".html");
}
- private Provider descriptionFor(YTypedPropertyImpl prop) {
+ private Provider descriptionFor(YTypedPropertyImpl prop) {
return descriptionFor(prop.getName());
}
diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYmlValueParsers.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYmlValueParsers.java
index 765b3ed6f..171a392aa 100644
--- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYmlValueParsers.java
+++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/ManifestYmlValueParsers.java
@@ -13,7 +13,7 @@ package org.springframework.ide.vscode.cloudfoundry.manifest.editor;
import java.util.Set;
import org.springframework.ide.vscode.util.Assert;
-import org.springframework.ide.vscode.yaml.util.ValueParser;
+import org.springframework.ide.vscode.util.ValueParser;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/VscodeCompletionEngineAdapter.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/VscodeCompletionEngineAdapter.java
index 98fcdb516..bb6e401fe 100644
--- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/VscodeCompletionEngineAdapter.java
+++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/cloudfoundry/manifest/editor/VscodeCompletionEngineAdapter.java
@@ -7,14 +7,14 @@ import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.ide.vscode.commons.completion.DocumentEdits;
-import org.springframework.ide.vscode.commons.completion.DocumentEdits.TextReplace;
-import org.springframework.ide.vscode.commons.completion.ICompletionEngine;
-import org.springframework.ide.vscode.commons.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
+import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
+import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits.TextReplace;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
+import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
+import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
import org.springframework.ide.vscode.util.Futures;
-import org.springframework.ide.vscode.util.SimpleLanguageServer;
-import org.springframework.ide.vscode.util.SimpleTextDocumentService;
-import org.springframework.ide.vscode.util.TextDocument;
import org.springframework.ide.vscode.yaml.completion.DefaultCompletionFactory;
import org.springframework.ide.vscode.yaml.structure.YamlStructureParser;
diff --git a/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/yaml/ManifestYmlSchemaTest.java b/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/yaml/ManifestYmlSchemaTest.java
index 36399ad99..00b5db39b 100644
--- a/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/yaml/ManifestYmlSchemaTest.java
+++ b/vscode-extensions/vscode-manifest-yaml/src/test/java/org/springframework/ide/vscode/yaml/ManifestYmlSchemaTest.java
@@ -112,8 +112,8 @@ public class ManifestYmlSchemaTest {
//////////////////////////////////////////////////////////////////////////////
private void assertHasRealDescription(YTypedProperty p) {
- String noDescriptionText = DescriptionProviders.NO_DESCRIPTION.get().toText();
- String actual = p.getDescription().toText();
+ String noDescriptionText = DescriptionProviders.NO_DESCRIPTION.get().toHtml();
+ String actual = p.getDescription().toHtml();
String msg = "Description missing for '"+p.getName()+"'";
assertTrue(msg, StringUtil.hasText(actual));
assertFalse(msg, noDescriptionText.equals(actual));