Basic concourse pipeline editor working

This commit is contained in:
Kris De Volder
2016-12-13 14:14:59 -08:00
parent 8075dc12e0
commit fece70fa8d
92 changed files with 1076 additions and 1054 deletions

View File

@@ -94,6 +94,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
try {
VersionedTextDocumentIdentifier docId = params.getTextDocument();
String url = docId.getUri();
LOG.info("didChange: "+url);
if (url!=null) {
TextDocument doc = getOrCreateDocument(url);
for (TextDocumentContentChangeEvent change : params.getContentChanges()) {
@@ -108,7 +109,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
@Override
public void didOpen(DidOpenTextDocumentParams params) {
//LOG.info("didOpen: "+params);
LOG.info("didOpen: "+params.getUri());
//Example message:
//{
// "jsonrpc":"2.0",
@@ -150,7 +151,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
@Override
public void didClose(DidCloseTextDocumentParams params) {
System.out.println("closing: "+params.getTextDocument().getUri());
LOG.info("didClose: "+params.getTextDocument().getUri());
String url = params.getTextDocument().getUri();
if (url!=null) {
documents.remove(url);

View File

@@ -241,42 +241,52 @@ public class Renderables {
}
public static Renderable fromClasspath(final Class<?> klass, final String resourcePath) {
return new Renderable() {
@Override
public void renderAsMarkdown(StringBuilder buffer) {
String extension = ".md";
String value = getText(klass, resourcePath, extension);
if (value != null) {
buffer.append(value);
} else {
NO_DESCRIPTION.renderAsMarkdown(buffer);
}
}
@Override
public void renderAsHtml(HtmlBuffer buffer) {
String extension = ".html";
String value = getText(klass, resourcePath, extension);
if (value != null) {
buffer.raw(value);
} else {
NO_DESCRIPTION.renderAsHtml(buffer);
}
}
private String getText(final Class<?> klass, final String resourcePath, String extension) {
try {
InputStream stream = klass.getResourceAsStream(resourcePath + extension);
if (stream != null) {
return IOUtil.toString(stream);
if (resourcePath.endsWith(".html")) {
return htmlBlob((HtmlBuffer html) -> {
html.raw(getText(klass, resourcePath, null));
});
} else {
return new Renderable() {
@Override
public void renderAsMarkdown(StringBuilder buffer) {
String extension = ".md";
String value = getText(klass, resourcePath, extension);
if (value != null) {
buffer.append(value);
} else {
NO_DESCRIPTION.renderAsMarkdown(buffer);
}
} catch (Exception e) {
logger.error("Error", e);
}
return null;
@Override
public void renderAsHtml(HtmlBuffer buffer) {
String extension = ".html";
String value = getText(klass, resourcePath, extension);
if (value != null) {
buffer.raw(value);
} else {
NO_DESCRIPTION.renderAsHtml(buffer);
}
}
};
}
}
private static String getText(final Class<?> klass, String resourcePath, String extension) {
if (extension!=null) {
resourcePath = resourcePath + extension;
}
try {
InputStream stream = klass.getResourceAsStream(resourcePath);
if (stream != null) {
return IOUtil.toString(stream);
}
};
} catch (Exception e) {
logger.error("Error", e);
}
return null;
}
private static class ConcatRenderables implements Renderable {

View File

@@ -41,6 +41,8 @@ public abstract class AbstractYamlAssistContext implements YamlAssistContext {
public final int documentSelector;
public final YamlPath contextPath;
private final YamlDocument doc;
private static PrefixFinder prefixfinder = new PrefixFinder() {
protected boolean isPrefixChar(char c) {
@@ -48,6 +50,10 @@ public abstract class AbstractYamlAssistContext implements YamlAssistContext {
}
};
@Override
public YamlDocument getDocument() {
return doc;
}
protected final String getPrefix(YamlDocument doc, SNode node, int offset) {
//For value completions... in general we would like to determine the whole text
@@ -78,7 +84,8 @@ public abstract class AbstractYamlAssistContext implements YamlAssistContext {
}
public AbstractYamlAssistContext(int documentSelector, YamlPath contextPath) {
public AbstractYamlAssistContext(YamlDocument doc, int documentSelector, YamlPath contextPath) {
this.doc = doc;
this.documentSelector = documentSelector;
this.contextPath = contextPath;
}

View File

@@ -33,6 +33,11 @@ public class SchemaBasedYamlAssistContextProvider implements YamlAssistContextPr
protected YamlAssistContext getDocumentContext(int documentSelector) {
return new YTypeAssistContext(this, documentSelector, schema.getTopLevelType(), schema.getTypeUtil());
}
@Override
public YamlDocument getDocument() {
return doc;
}
};
}
}

View File

@@ -13,7 +13,6 @@ package org.springframework.ide.vscode.commons.yaml.completion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -25,18 +24,20 @@ import org.springframework.ide.vscode.commons.languageserver.completion.IComplet
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
import org.springframework.ide.vscode.commons.util.CollectionUtil;
import org.springframework.ide.vscode.commons.util.FuzzyMatcher;
import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.util.Renderable;
import org.springframework.ide.vscode.commons.yaml.hover.YPropertyInfoTemplates;
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment.YamlPathSegmentType;
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
import org.springframework.ide.vscode.commons.yaml.schema.SNodeDynamicSchemaContext;
import org.springframework.ide.vscode.commons.yaml.schema.YType;
import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil;
import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty;
import org.springframework.ide.vscode.commons.yaml.schema.YValueHint;
import org.springframework.ide.vscode.commons.yaml.structure.YamlDocument;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SChildBearingNode;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SKeyNode;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNode;
import org.springframework.ide.vscode.commons.yaml.util.YamlIndentUtil;
@@ -49,14 +50,14 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
final private YamlAssistContext parent;
public YTypeAssistContext(YTypeAssistContext parent, YamlPath contextPath, YType YType, YTypeUtil typeUtil) {
super(parent.documentSelector, contextPath);
super(parent.getDocument(), parent.documentSelector, contextPath);
this.parent = parent;
this.type = YType;
this.typeUtil = typeUtil;
}
public YTypeAssistContext(TopLevelAssistContext parent, int documentSelector, YType type, YTypeUtil typeUtil) {
super(documentSelector, YamlPath.EMPTY);
super(parent.getDocument(), documentSelector, YamlPath.EMPTY);
this.type = type;
this.typeUtil = typeUtil;
this.parent = parent;
@@ -74,11 +75,12 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
public List<ICompletionProposal> getKeyCompletions(YamlDocument doc, int offset, String query) throws Exception {
int queryOffset = offset - query.length();
List<YTypedProperty> properties = typeUtil.getProperties(type);
SNode contextNode = getContextNode(doc);
DynamicSchemaContext dynamicCtxt = new SNodeDynamicSchemaContext(contextNode);
List<YTypedProperty> properties = typeUtil.getProperties(type, dynamicCtxt);
if (CollectionUtil.hasElements(properties)) {
ArrayList<ICompletionProposal> proposals = new ArrayList<>(properties.size());
SNode contextNode = getContextNode(doc);
Set<String> definedProps = getDefinedProperties(contextNode);
Set<String> definedProps = dynamicCtxt.getDefinedProperties();
for (YTypedProperty p : properties) {
String name = p.getName();
double score = FuzzyMatcher.matchScore(query, name);
@@ -140,26 +142,6 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
}
}
private Set<String> getDefinedProperties(SNode contextNode) {
try {
if (contextNode instanceof SChildBearingNode) {
List<SNode> children = ((SChildBearingNode)contextNode).getChildren();
if (CollectionUtil.hasElements(children)) {
Set<String> keys = new HashSet<>(children.size());
for (SNode c : children) {
if (c instanceof SKeyNode) {
keys.add(((SKeyNode) c).getKey());
}
}
return keys;
}
}
} catch (Exception e) {
logger.error("Error getting defined props", e);
}
return Collections.emptySet();
}
private List<ICompletionProposal> getValueCompletions(YamlDocument doc, int offset, String query) {
YValueHint[] values = typeUtil.getHintValues(type);
if (values!=null) {
@@ -179,13 +161,15 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
}
@Override
public YamlAssistContext traverse(YamlPathSegment s) {
public YamlAssistContext traverse(YamlPathSegment s) throws Exception {
if (s.getType()==YamlPathSegmentType.VAL_AT_KEY) {
if (typeUtil.isSequencable(type) || typeUtil.isMap(type)) {
return contextWith(s, typeUtil.getDomainType(type));
}
String key = s.toPropString();
Map<String, YTypedProperty> subproperties = typeUtil.getPropertiesMap(type);
SNode contextNode = getContextNode(getDocument());
DynamicSchemaContext dynamicCtxt = new SNodeDynamicSchemaContext(contextNode);
Map<String, YTypedProperty> subproperties = typeUtil.getPropertiesMap(type, dynamicCtxt);
if (subproperties!=null) {
return contextWith(s, getType(subproperties.get(key)));
}
@@ -246,6 +230,16 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
return null;
}
private DynamicSchemaContext getSchemaContext() {
try {
SNode contextNode = getContextNode(getDocument());
return new SNodeDynamicSchemaContext(contextNode);
} catch (Exception e) {
Log.log(e);
return DynamicSchemaContext.NULL;
}
}
@Override
public Renderable getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
//By default we don't provide value-specific hover, so just show the same hover
@@ -254,6 +248,6 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
}
private YTypedProperty getProperty(String name) {
return typeUtil.getPropertiesMap(getType()).get(name);
return typeUtil.getPropertiesMap(getType(), getSchemaContext()).get(name);
}
}

View File

@@ -32,4 +32,6 @@ public interface YamlAssistContext extends YamlNavigable<YamlAssistContext> {
Renderable getHoverInfo(YamlPathSegment lastSegment);
Renderable getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion);
YamlDocument getDocument();
}

View File

@@ -10,6 +10,8 @@ import org.springframework.ide.vscode.commons.util.StringUtil;
import org.springframework.ide.vscode.commons.util.ValueParser;
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
import org.springframework.ide.vscode.commons.yaml.schema.ASTDynamicSchemaContext;
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
import org.springframework.ide.vscode.commons.yaml.schema.YType;
import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil;
import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty;
@@ -53,7 +55,8 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
reconcile(entry.getValueNode(), typeUtil.getDomainType(type));
}
} else if (typeUtil.isBean(type)) {
Map<String, YTypedProperty> beanProperties = typeUtil.getPropertiesMap(type);
DynamicSchemaContext schemaContext = new ASTDynamicSchemaContext(map);
Map<String, YTypedProperty> beanProperties = typeUtil.getPropertiesMap(type, schemaContext);
for (NodeTuple entry : map.getValue()) {
Node keyNode = entry.getKeyNode();
String key = NodeUtil.asScalar(keyNode);

View File

@@ -0,0 +1,50 @@
/*******************************************************************************
* 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.yaml.schema;
import java.util.Collections;
import java.util.Set;
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.NodeTuple;
import com.google.common.collect.ImmutableSet;
/**
* Adapts a SnakeYaml ast node as a {@link DynamicSchemaContext} (so it
* can be used in YamlSchema based reconciler.
*
* @author Kris De Volder
*/
public class ASTDynamicSchemaContext extends CachingSchemaContext {
private MappingNode mapNode;
public ASTDynamicSchemaContext(MappingNode map) {
this.mapNode = map;
}
@Override
protected Set<String> computeDefinedProperties() {
if (mapNode!=null) {
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
for (NodeTuple entry : mapNode.getValue()) {
String key = NodeUtil.asScalar(entry.getKeyNode());
if (key!=null) { //key not a scalar? => something funky so skip it
builder.add(key);
}
}
return builder.build();
}
return Collections.emptySet();
}
}

View File

@@ -0,0 +1,18 @@
package org.springframework.ide.vscode.commons.yaml.schema;
import java.util.Set;
public abstract class CachingSchemaContext implements DynamicSchemaContext {
private Set<String> definedProps;
protected abstract Set<String> computeDefinedProperties();
@Override
final public Set<String> getDefinedProperties() {
if (definedProps==null) {
definedProps = computeDefinedProperties();
}
return definedProps;
}
}

View File

@@ -0,0 +1,50 @@
/*******************************************************************************
* 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.yaml.schema;
import java.util.Set;
import com.google.common.collect.ImmutableSet;
/**
* Exposes some 'dynamic' contextual information to schema implementations.
* <p>
* This is necessary to enable the impementation of schema features where one
* part of a yaml structure depends details of another part. A typical example
* could be 'type' property, so that different values assigned to that property
* change the structure that is expected for the rest of the node.
*
* @author Kris De Volder
*/
public interface DynamicSchemaContext {
DynamicSchemaContext NULL = new DynamicSchemaContext() {
@Override
public Set<String> getDefinedProperties() {
return ImmutableSet.of();
}
};
/**
* Returns the set of property names that are already defined in the current context.
* <p>
* In Content assist scenarios this is only a 'best effort' result. An empty set may
* be returned because either no properties are yet defined, or because the sloppy parser
* can not quite make out the yaml structure because yaml text is incomplete or too complex
* for its analysis.
* <p>
* In a validation scenario however, the returned information should precisely reflect what
* properties are defined in the surrounding object.
*/
Set<String> getDefinedProperties();
}

View File

@@ -0,0 +1,59 @@
/*******************************************************************************
* 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.yaml.schema;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.ide.vscode.commons.util.CollectionUtil;
import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SChildBearingNode;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SKeyNode;
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNode;
/**
* Adapts an SNode so it can be used by a YamlSchema as a {@link DynamicSchemaContext}
*
* @author Kris De Volder
*/
public class SNodeDynamicSchemaContext extends CachingSchemaContext {
private SNode contextNode;
public SNodeDynamicSchemaContext(SNode contextNode) {
this.contextNode = contextNode;
}
@Override
protected Set<String> computeDefinedProperties() {
try {
if (contextNode instanceof SChildBearingNode) {
List<SNode> children = ((SChildBearingNode)contextNode).getChildren();
if (CollectionUtil.hasElements(children)) {
Set<String> keys = new HashSet<>(children.size());
for (SNode c : children) {
if (c instanceof SKeyNode) {
keys.add(((SKeyNode) c).getKey());
}
}
return keys;
}
}
} catch (Exception e) {
Log.log(e);
}
return Collections.emptySet();
}
}

View File

@@ -13,19 +13,26 @@ package org.springframework.ide.vscode.commons.yaml.schema;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.inject.Provider;
import org.springframework.ide.vscode.commons.util.Assert;
import org.springframework.ide.vscode.commons.util.EnumValueParser;
import org.springframework.ide.vscode.commons.util.Renderable;
import org.springframework.ide.vscode.commons.util.Renderables;
import org.springframework.ide.vscode.commons.util.ValueParser;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableList.Builder;
import com.google.common.collect.ImmutableMap;
/**
* Static utility method for creating YType objects representing either
* 'array-like', 'map-like' or 'object-like' types which can be used
@@ -35,6 +42,10 @@ import org.springframework.ide.vscode.commons.util.ValueParser;
*/
public class YTypeFactory {
public YType yany(String name) {
return new YAny(name);
}
public YType yseq(YType el) {
return new YSeqType(el);
}
@@ -47,6 +58,14 @@ public class YTypeFactory {
return new YBeanType(name, properties);
}
public YType yunion(String name, YBeanType... types) {
Assert.isLegal(types.length>0);
if (types.length==1) {
return types[0];
}
return new YBeanUnionType(name, types);
}
/**
* YTypeUtil instances capable of 'interpreting' the YType objects created by this
* YTypeFactory
@@ -69,13 +88,13 @@ public class YTypeFactory {
}
@Override
public Map<String, YTypedProperty> getPropertiesMap(YType type) {
return ((AbstractType)type).getPropertiesMap();
public Map<String, YTypedProperty> getPropertiesMap(YType type, DynamicSchemaContext dc) {
return ((AbstractType)type).getPropertiesMap(dc);
}
@Override
public List<YTypedProperty> getProperties(YType type) {
return ((AbstractType)type).getProperties();
public List<YTypedProperty> getProperties(YType type, DynamicSchemaContext dc) {
return ((AbstractType)type).getProperties(dc);
}
@Override
@@ -164,11 +183,11 @@ public class YTypeFactory {
}
}
public final List<YTypedProperty> getProperties() {
public List<YTypedProperty> getProperties(DynamicSchemaContext dc) {
return Collections.unmodifiableList(propertyList);
}
public final Map<String, YTypedProperty> getPropertiesMap() {
public Map<String, YTypedProperty> getPropertiesMap(DynamicSchemaContext dc) {
if (cachedPropertyMap==null) {
cachedPropertyMap = new LinkedHashMap<>();
for (YTypedProperty p : propertyList) {
@@ -212,12 +231,55 @@ public class YTypeFactory {
}
}
}
public void addHints(YValueHint... extraHints) {
for (YValueHint h : extraHints) {
if (!hints.contains(h)) {
hints.add(h);
}
}
}
public void parseWith(ValueParser parser) {
this.parser = parser;
}
public ValueParser getParser() {
return parser;
}
}
/**
* Represents a type that is completely unconstrained. Anything goes: A map, a sequence or some
* atomic value.
*/
public static class YAny extends AbstractType {
private final String name;
public YAny(String name) {
this.name = name;
}
@Override
public boolean isAtomic() {
return true;
}
@Override
public boolean isSequenceable() {
return true;
}
@Override
public boolean isMap() {
return true;
}
@Override
public String toString() {
return name;
}
}
public static class YMapType extends AbstractType {
@@ -293,6 +355,26 @@ public class YTypeFactory {
public boolean isBean() {
return true;
}
/**
* Deprecated. This method disregards {@link DynamicSchemaContext}. This may be
* alright for Schemas which don't rely on it but it will result in incorrect/inaccurate
* behavior for Schemas that do.
*/
@Deprecated
public List<YTypedProperty> getProperties() {
return getProperties(DynamicSchemaContext.NULL);
}
/**
* Deprecated. This method disregards {@link DynamicSchemaContext}. This may be
* alright for Schemas which don't rely on it but it will result in incorrect/inaccurate
* behavior for Schemas that do.
*/
@Deprecated
public Map<String, YTypedProperty> getPropertiesMap() {
return getPropertiesMap(DynamicSchemaContext.NULL);
}
}
public static class YAtomicType extends AbstractType {
@@ -309,6 +391,103 @@ public class YTypeFactory {
return true;
}
}
/**
* Represents a union of several bean types. It is assumed one primary property
* exists in each of the the sub-bean types that can be used to identify the
* type. In other words the primary property has a unique name so that when
* this property is being assigned a value we can infer from that which
* specific bean-type we are dealing with.
*/
public class YBeanUnionType extends AbstractType {
private final String name;
private Map<String, AbstractType> typesByPrimary = new HashMap<>();
private ImmutableList<YTypedProperty> primaryProps;
public YBeanUnionType(String name, YBeanType... types) {
this.name = name;
for (YType _t : types) {
AbstractType t = (AbstractType)_t;
typesByPrimary.put(findPrimary(t, types), t);
}
}
private String findPrimary(AbstractType t, YBeanType[] types) {
//Note: passing null dynamic context below is okay, assuming the properties in YBeanType
// do not care about dynamic context.
for (YTypedProperty p : t.getProperties(DynamicSchemaContext.NULL)) {
String name = p.getName();
if (isUniqueFor(name, t, types)) {
return name;
}
}
Assert.isLegal(false, "Couldn't find a unique property key for "+t);
return null; //unreachable, but compiler doesn't know.
}
private boolean isUniqueFor(String name, AbstractType t, YBeanType[] types) {
for (YBeanType other : types) {
if (other!=t) {
//Note: passing null dynamic context below is okay, assuming the properties in YBeanType
// do not care about dynamic context.
if (other.getPropertiesMap(DynamicSchemaContext.NULL).containsKey(name)) {
return false;
}
}
}
return true;
}
@Override
public String toString() {
return name;
}
@Override
public boolean isBean() {
return true;
}
@Override
public Map<String, YTypedProperty> getPropertiesMap(DynamicSchemaContext dc) {
return asMap(getProperties(dc));
}
private Map<String, YTypedProperty> asMap(List<YTypedProperty> properties) {
ImmutableMap.Builder<String, YTypedProperty> builder = ImmutableMap.builder();
for (YTypedProperty p : properties) {
builder.put(p.getName(), p);
}
return builder.build();
}
@Override
public List<YTypedProperty> getProperties(DynamicSchemaContext dc) {
Set<String> existingProps = dc.getDefinedProperties();
if (!existingProps.isEmpty()) {
for (Entry<String, AbstractType> entry : typesByPrimary.entrySet()) {
String primaryName = entry.getKey();
if (existingProps.contains(primaryName)) {
return entry.getValue().getProperties(dc);
}
}
}
//Reaching here means we couldn't guess the type from existing props.
//We'll just return the primary properties, these are good to give as hints
//then, since at least one of them should typically be added.
return getPrimaryProps(dc);
}
private List<YTypedProperty> getPrimaryProps(DynamicSchemaContext dc) {
if (primaryProps==null) {
Builder<YTypedProperty> builder = ImmutableList.builder();
for (Entry<String, AbstractType> entry : typesByPrimary.entrySet()) {
builder.add(entry.getValue().getPropertiesMap(dc).get(entry.getKey()));
}
primaryProps = builder.build();
}
return primaryProps;
}
}
public static class YTypedPropertyImpl implements YTypedProperty {
@@ -360,4 +539,9 @@ public class YTypeFactory {
t.parseWith(new EnumValueParser(name, values));
return t;
}
public YValueHint hint(String value, String label) {
return new BasicYValueHint(value, label);
}
}

View File

@@ -35,6 +35,6 @@ public interface YTypeUtil {
ValueParser getValueParser(YType type);
//TODO: only one of these two should be enough?
List<YTypedProperty> getProperties(YType type);
Map<String, YTypedProperty> getPropertiesMap(YType yType);
List<YTypedProperty> getProperties(YType type, DynamicSchemaContext dc);
Map<String, YTypedProperty> getPropertiesMap(YType yType, DynamicSchemaContext dc);
}