/** as {@link #newInstance()} but using the given translator to massage objects inserted into the Jsonya structure */ public static Navigator<MutableMap<Object,Object>> newInstanceTranslating(Function<Object,Object> translator) { return newInstance().useTranslator(translator); }
/** convenience for converting an object x to something which consists only of json primitives, doing * {@link #toString()} on anything which is not recognised. see {@link JsonPrimitiveDeepTranslator} */ public static Object convertToJsonPrimitive(Object x) { if (x==null) return null; if (x instanceof Map) return newInstancePrimitive().put((Map<?,?>)x).getRootMap(); return newInstancePrimitive().put("data", x).getRootMap().get("data"); }
/** includes the given attributes in the attributes to be passed to chef; * when combining with other attributes, this uses {@link Jsonya} semantics to add * (a deep add, combining lists and maps) */ public KnifeConvergeTaskFactory<RET> knifeAddAttributes(Map<? extends Object, ? extends Object> attributes) { if (attributes!=null && !attributes.isEmpty()) { Jsonya.of(knifeAttributes).add(attributes); } return self(); }
protected String extractPlanYamlString(ConfigBag parameters) { Object planRaw = parameters.getStringKey(BLUEPRINT_CAMP_PLAN.getName()); if (planRaw instanceof String && Strings.isBlank((String)planRaw)) planRaw = null; String url = parameters.get(BLUEPRINT_TYPE); if (url!=null && planRaw!=null) throw new IllegalArgumentException("Cannot supply both plan and url"); if (url==null && planRaw==null) throw new IllegalArgumentException("Must supply plan or url"); Map<String, Object> config = asMap(parameters, BLUEPRINT_CONFIG); if (planRaw==null) { planRaw = Jsonya.at("services").list().put("serviceType", url).putIfNotNull("brooklyn.config", config).getRootMap(); } else { if (config!=null) throw new IllegalArgumentException("Cannot supply plan with config"); } // planRaw might be a yaml string, or a map; if a map, convert to string if (planRaw instanceof Map) planRaw = Jsonya.of((Map<?,?>)planRaw).toString(); if (!(planRaw instanceof String)) throw new IllegalArgumentException("Invalid "+JavaClassNames.simpleClassName(planRaw)+" value for CAMP plan: "+planRaw); // now *all* the data is in planRaw; that is what will be submitted return (String)planRaw; }
@Test public void testJsonyaDeepMoreComplicated() { Navigator<MutableMap<Object, Object>> n = Jsonya.of(europeMap()).at("asia") .list().add("china", "japan") .root().add( Jsonya.newInstance().at("europe", "uk", "glasgow").put("weather", "even wetter").getRootMap() ); Assert.assertEquals( n.getRootMap().size(), 2 ); Assert.assertTrue( n.root().at("asia").get(List.class).contains("china") ); Assert.assertTrue( ((List<?>)n.root().get("asia")).contains("japan") ); Assert.assertEquals(n.root().at("europe", "uk").get(Map.class).size(), 2); Assert.assertEquals(n.root().at("europe", "uk", "edinburgh", "weather").get(), "wet"); Assert.assertEquals(n.root().at("europe", "uk", "glasgow", "weather").get(), "even wetter"); }
@Test public void testPrimitivedAndLiteralledMap() { Object foo = new Object() { @Override public String toString() { return "FOO"; } }; MutableMap<Object, Object> map = MutableMap.<Object,Object>of("a", 1, 2, Arrays.<Object>asList(true, 8, "8"), 'C', foo); Map<Object, Object> mapL = Jsonya.newInstanceLiteral().put(map).getRootMap(); Assert.assertEquals(mapL, map); Assert.assertEquals(mapL.get('C'), foo); Map<Object, Object> mapP = Jsonya.newInstancePrimitive().put(map).getRootMap(); Assert.assertNotEquals(mapP, map); Assert.assertEquals(mapP.get('C'), foo.toString()); Assert.assertEquals(MutableMap.copyOf(mapP).add('C', null), MutableMap.copyOf(map).add('C', null)); }
@SuppressWarnings("rawtypes") @Test public void testCreateMapInList1() { MutableMap<Object, Object> map = Jsonya.at("countries").list().map().add("europe", "uk").getRootMap(); List l = (List)map.get("countries"); Assert.assertEquals( ((Map)l.get(0)).get("europe"), "uk" ); } @SuppressWarnings("rawtypes")
/** tells whether {@link #convertToJsonPrimitive(Object)} returns an object which is identical to * the equivalent literal json structure. this is typically equivalent to saying serializing to json then * deserializing will produce something where the result is equal to the input, * modulo a few edge cases such as longs becoming ints. * note that the converse (input equal to output) may not be the case, * e.g. if the input contains special subclasses of collections of maps who care about type preservation. */ public static boolean isJsonPrimitiveCompatible(Object x) { if (x==null) return true; return convertToJsonPrimitive(x).equals(x); }
@Override protected void startWithKnifeAsync() { Entities.warnOnIgnoringConfig(entity(), ChefConfig.CHEF_LAUNCH_RUN_LIST); Entities.warnOnIgnoringConfig(entity(), ChefConfig.CHEF_LAUNCH_ATTRIBUTES); DynamicTasks.queue( ChefServerTasks .knifeConvergeRunList("postgresql::server") .knifeAddAttributes(Jsonya .at("postgresql", "config").add( "port", entity().getPostgreSqlPort(), "listen_addresses", "*").getRootMap()) .knifeAddAttributes(Jsonya .at("postgresql", "pg_hba").list().map().add( "type", "host", "db", "all", "user", "all", "addr", "0.0.0.0/0", "method", "md5").getRootMap()) // no other arguments currenty supported; chef will pick a password for us ); } @Override
public Collection<Object> getTags() { List<Object> result = new ArrayList<Object>(); for (Object t : tags) { // TODO if we had access to a mapper we could use it to give better json result.add(Jsonya.convertToJsonPrimitive(t)); } return result; }
/** convenience for {@link Navigator#at(Object, Object...)} on a {@link #newInstance()} */ public static Navigator<MutableMap<Object,Object>> at(Object ...pathSegments) { return newInstance().atArray(pathSegments); }
/** includes the given attributes in the attributes to be passed to chef; * when combining with other attributes, this uses {@link Jsonya} semantics to add * (a deep add, combining lists and maps) */ public KnifeConvergeTaskFactory<RET> knifeAddAttributes(Map<? extends Object, ? extends Object> attributes) { if (attributes!=null && !attributes.isEmpty()) { Jsonya.of(knifeAttributes).add(attributes); } return self(); }
@SuppressWarnings({ "unchecked", "rawtypes", "deprecation" }) protected void startWithKnifeAsync() { // TODO prestart, ports (as above); also, note, some aspects of this are untested as we need a chef server String primary = getPrimaryCookbook(); // put all config under brooklyn/cookbook/config Navigator<MutableMap<Object, Object>> attrs = Jsonya.newInstancePrimitive().at("brooklyn"); if (Strings.isNonBlank(primary)) attrs.at(primary); attrs.at("config"); attrs.put( entity().config().getBag().getAllConfig() ); // and put launch attrs at root try { attrs.root().put((Map<?,?>)Tasks.resolveDeepValue(entity().getConfig(CHEF_LAUNCH_ATTRIBUTES), Object.class, entity().getExecutionContext())); } catch (Exception e) { Exceptions.propagate(e); } Collection<? extends String> runList = entity().getConfig(CHEF_LAUNCH_RUN_LIST); if (runList==null) runList = entity().getConfig(CHEF_RUN_LIST); if (runList==null) { if (Strings.isNonBlank(primary)) runList = ImmutableList.of(primary+"::"+"start"); else throw new IllegalStateException("Require a primary cookbook or a run_list to effect "+"start"+" on "+entity()); } DynamicTasks.queue( ChefServerTasks.knifeConvergeTask() .knifeNodeName(getNodeName()) .knifeRunList(Strings.join(runList, ",")) .knifeAddAttributes((Map) attrs.root().get()) .knifeRunTwice(entity().getConfig(CHEF_RUN_CONVERGE_TWICE)) ); }
@SuppressWarnings("rawtypes") @Test public void testCreateMapInList2() { MutableMap<Object, Object> map = Jsonya.at("countries").list().map().add("europe", "uk") .root().at("countries").add("antarctica") .root().at("countries").map().add("asia", (Object)null) .at("asia").list().add("china", "japan").getRootMap(); List l = (List)map.get("countries"); Assert.assertEquals( ((Map)l.get(0)).get("europe"), "uk" ); }
} else { this.type = config.getTypeName(); this.defaultValue = Jsonya.convertToJsonPrimitive(config.getDefaultValue()); this.possibleValues = null;
private static String toJson(Map<?,?> x) { // was: // return new Gson().toJson(x); // but GSON does funny things with DSL, whereas toString is the right thing to do return Jsonya.newInstance().add(x).toString(); }
@SuppressWarnings("rawtypes") @Override public Object applyToKeyInMap(MapConfigKey<V> key, Map target) { return key.applyValueToMap(Jsonya.of(key.rawValue(target)).add(this).getRootMap(), target); } };
@SuppressWarnings({ "unchecked", "rawtypes", "deprecation" }) protected void startWithKnifeAsync() { // TODO prestart, ports (as above); also, note, some aspects of this are untested as we need a chef server String primary = getPrimaryCookbook(); // put all config under brooklyn/cookbook/config Navigator<MutableMap<Object, Object>> attrs = Jsonya.newInstancePrimitive().at("brooklyn"); if (Strings.isNonBlank(primary)) attrs.at(primary); attrs.at("config"); attrs.put( entity().config().getBag().getAllConfig() ); // and put launch attrs at root try { attrs.root().put((Map<?,?>)Tasks.resolveDeepValue(entity().getConfig(CHEF_LAUNCH_ATTRIBUTES), Object.class, entity().getExecutionContext())); } catch (Exception e) { Exceptions.propagate(e); } Collection<? extends String> runList = entity().getConfig(CHEF_LAUNCH_RUN_LIST); if (runList==null) runList = entity().getConfig(CHEF_RUN_LIST); if (runList==null) { if (Strings.isNonBlank(primary)) runList = ImmutableList.of(primary+"::"+"start"); else throw new IllegalStateException("Require a primary cookbook or a run_list to effect "+"start"+" on "+entity()); } DynamicTasks.queue( ChefServerTasks.knifeConvergeTask() .knifeNodeName(getNodeName()) .knifeRunList(Strings.join(runList, ",")) .knifeAddAttributes((Map) attrs.root().get()) .knifeRunTwice(entity().getConfig(CHEF_RUN_CONVERGE_TWICE)) ); }
private String toJsonString(Object payload) { return Jsonya.newInstance().add(payload).toString(); }
@SuppressWarnings("unchecked") @Test public void testJsonyaMapNew() { MutableMap<Object, Object> m = europeMap().getRootMap(); Assert.assertEquals(Jsonya.of(m).get("europe", "uk", "edinburgh", "population"), 500*1000); Assert.assertEquals(Jsonya.of(m).at("europe", "uk", "edinburgh", "population").get(), 500*1000); Assert.assertEquals(((Map<Object,Object>)Jsonya.of(m).get("europe")).keySet(), ImmutableSet.of("uk", "france")); Assert.assertEquals(Jsonya.of(m).at("europe").getFocusMap().keySet(), ImmutableSet.of("uk", "france")); }