diff --git a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshDeploymentManifestSchema.java b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshDeploymentManifestSchema.java index f9c4b8d88..3ba0128fe 100644 --- a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshDeploymentManifestSchema.java +++ b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/BoshDeploymentManifestSchema.java @@ -14,11 +14,13 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.function.Predicate; import org.apache.commons.lang3.tuple.Pair; import org.springframework.ide.vscode.bosh.models.CachingModelProvider; import org.springframework.ide.vscode.bosh.models.CloudConfigModel; import org.springframework.ide.vscode.bosh.models.DynamicModelProvider; +import org.springframework.ide.vscode.bosh.models.StemcellData; import org.springframework.ide.vscode.bosh.models.StemcellModel; import org.springframework.ide.vscode.bosh.models.StemcellsModel; import org.springframework.ide.vscode.commons.util.Assert; @@ -33,6 +35,7 @@ import org.springframework.ide.vscode.commons.yaml.path.YamlPath; import org.springframework.ide.vscode.commons.yaml.reconcile.ASTTypeCache; import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems; import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext; +import org.springframework.ide.vscode.commons.yaml.schema.SchemaContextAware; import org.springframework.ide.vscode.commons.yaml.schema.YType; import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory; import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.AbstractType; @@ -199,20 +202,34 @@ public class BoshDeploymentManifestSchema implements YamlSchema { YType t_stemcell_os_ref = f.yenumFromDynamicValues("StemcellOs", (dc) -> stemcellsProvider.getModel(dc).getStemcellOss() ); - YAtomicType t_stemcell_version_ref = f.yenumFromDynamicValues("StemcellVersion", (dc) -> { - StemcellModel currentStemcell = getCurrentStemcell(dc); - if (currentStemcell!=null) { - return stemcellsProvider.getModel(dc).getStemcells().stream() - .filter(sc -> StringUtil.hasText(sc.getVersion())) - .filter(currentStemcell.createVersionFilter()) - .map(sc -> sc.getVersion()) - .collect(CollectorUtil.toImmutableSet()); + YType t_stemcell_version_ref = f.contextAware("StemcellVersion", new SchemaContextAware() { + + YAtomicType baseType = f.yenumFromDynamicValues("StemcellVersion", (dc) -> stemcellsProvider.getModel(dc).getVersions()); + { + baseType.addHints("latest"); + baseType.alsoAccept("latest"); } - //Troubles determining the filter. So return all stemcells. - return stemcellsProvider.getModel(dc).getVersions(); - }); - t_stemcell_version_ref.addHints("latest"); - t_stemcell_version_ref.alsoAccept("latest"); + + @Override + public YType withContext(DynamicSchemaContext dc) throws Exception { + StemcellModel currentStemcell = getCurrentStemcell(dc); + if (StringUtil.hasText(currentStemcell.getName())||StringUtil.hasText(currentStemcell.getOs())) { + Predicate filter = currentStemcell.createVersionFilter(); + YAtomicType filteredType = f.yenumFromDynamicValues("StemcellVersion["+filter+"]", (_dc) -> { + //Note: it doesn't really matter whether we use _dc or dc in code below as they should be the same. + return stemcellsProvider.getModel(dc).getStemcells().stream() + .filter(sc -> StringUtil.hasText(sc.getVersion())) + .filter(currentStemcell.createVersionFilter()) + .map(sc -> sc.getVersion()) + .collect(CollectorUtil.toImmutableSet()); + }); + filteredType.addHints("latest"); + filteredType.alsoAccept("latest"); + return filteredType; + } + return baseType; + } + }).treatAsAtomic(); addProp(t_stemcell, "alias", t_stemcell_alias_def).isRequired(true); addProp(t_stemcell, "version", t_stemcell_version_ref).isRequired(true); diff --git a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/StemcellModel.java b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/StemcellModel.java index 6cc174c2e..47aad85f1 100644 --- a/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/StemcellModel.java +++ b/headless-services/bosh-language-server/src/main/java/org/springframework/ide/vscode/bosh/models/StemcellModel.java @@ -45,17 +45,50 @@ public class StemcellModel { if (StringUtil.hasText(name) && StringUtil.hasText(os)) { //User shouldn't really specify both of these... but if they do... then // let's do our best to generate proposals for the both of them. - return (sc) -> - name.equals(sc.getName()) || os.equals(sc.getOs()); + return new Predicate() { + @Override + public boolean test(StemcellData sc) { + return name.equals(sc.getName()) || os.equals(sc.getOs()); + } + + @Override + public String toString() { + return "name="+name+", os="+os; + } + }; } else if (StringUtil.hasText(name)) { - return (sc) -> - name.equals(sc.getName()); + return new Predicate() { + @Override + public boolean test(StemcellData sc) { + return name.equals(sc.getName()); + } + @Override + public String toString() { + return "name="+name; + } + }; } else if (StringUtil.hasText(os)) { - return (sc) -> - os.equals(sc.getOs()); + return new Predicate() { + @Override + public boolean test(StemcellData sc) { + return os.equals(sc.getOs()); + } + @Override + public String toString() { + return "os="+os; + } + }; } else { - return (sc) -> - true; + return new Predicate() { + @Override + public boolean test(StemcellData sc) { + return true; + } + @Override + public String toString() { + return "true"; + } + }; } } diff --git a/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java b/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java index 9d11d7f73..15ceb599a 100644 --- a/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java +++ b/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java @@ -1008,7 +1008,7 @@ public class BoshEditorTest { "123.4<*>", "222.2<*>", "333.3<*>", "latest<*>" ); - //when os or name are 'bogus' at least suggest proposals based on other prop + //when os and name are 'bogus' at least suggest proposals based on other prop editor = harness.newEditor( "stemcells:\n" + "- alias: good\n" + @@ -1094,8 +1094,8 @@ public class BoshEditorTest { ); editor.ignoreProblem(YamlSchemaProblems.MISSING_PROPERTY); editor.assertProblems( - "123.4|unknown 'StemcellVersion'. Valid values are: [222.2, 333.3]", - "333.3|unknown 'StemcellVersion'. Valid values are: [123.4, 222.2]" + "123.4|unknown 'StemcellVersion[name=centos-agent]'. Valid values are: [222.2, 333.3]", + "333.3|unknown 'StemcellVersion[os=ubuntu]'. Valid values are: [123.4, 222.2]" ); }