protected Node representMapping(Tag tag, Map<?, ?> mapping, Boolean flowStyle) { List<NodeTuple> value = new ArrayList<NodeTuple>(mapping.size()); MappingNode node = new MappingNode(tag, value, flowStyle); representedObjects.put(objectToRepresent, node); boolean bestStyle = true; for (Map.Entry<?, ?> entry : mapping.entrySet()) { Node nodeKey = representData(entry.getKey()); Node nodeValue = representData(entry.getValue()); if (!(nodeKey instanceof ScalarNode && ((ScalarNode) nodeKey).getStyle() == null)) { bestStyle = false; } if (!(nodeValue instanceof ScalarNode && ((ScalarNode) nodeValue).getStyle() == null)) { bestStyle = false; } value.add(new NodeTuple(nodeKey, nodeValue)); } if (flowStyle == null) { if (defaultFlowStyle != FlowStyle.AUTO) { node.setFlowStyle(defaultFlowStyle.getStyleBoolean()); } else { node.setFlowStyle(bestStyle); } } return node; }
@Override public void construct2ndStep(Node node, Object object) { // Compact Object Notation may contain only one entry MappingNode mnode = (MappingNode) node; NodeTuple nodeTuple = mnode.getValue().iterator().next(); Node valueNode = nodeTuple.getValueNode(); if (valueNode instanceof MappingNode) { valueNode.setType(object.getClass()); constructJavaBean2ndStep((MappingNode) valueNode, object); } else { // value is a list applySequence(object, constructSequence((SequenceNode) valueNode)); } }
protected Object createEmptyJavaBean(MappingNode node) { try { /** * Using only default constructor. Everything else will be * initialized on 2nd step. If we do here some partial * initialization, how do we then track what need to be done on * 2nd step? I think it is better to get only object here (to * have it as reference for recursion) and do all other thing on * 2nd step. */ java.lang.reflect.Constructor<?> c = node.getType().getDeclaredConstructor(); c.setAccessible(true); return c.newInstance(); } catch (Exception e) { throw new YAMLException(e); } }
protected void constructSet2ndStep(MappingNode node, Set<Object> set) { List<NodeTuple> nodeValue = (List<NodeTuple>) node.getValue(); for (NodeTuple tuple : nodeValue) { Node keyNode = tuple.getKeyNode(); Object key = constructObject(keyNode); if (key != null) { try { key.hashCode();// check circular dependencies } catch (Exception e) { throw new ConstructorException("while constructing a Set", node.getStartMark(), "found unacceptable key " + key, tuple.getKeyNode().getStartMark(), e); } } if (keyNode.isTwoStepsConstruction()) { /* * if keyObject is created it 2 steps we should postpone putting * it into the set because it may have different hash after * initialization compared to clean just created one. And set of * course does not observe value hashCode changes. */ sets2fill.add(0, new RecursiveTuple<Set<Object>, Object>(set, key)); } else { set.add(key); } } }
protected void constructSet2ndStep(MappingNode node, Set<Object> set) { List<NodeTuple> nodeValue = node.getValue(); for (NodeTuple tuple : nodeValue) { Node keyNode = tuple.getKeyNode(); Object key = constructObject(keyNode); if (key != null) { try { key.hashCode();// check circular dependencies } catch (Exception e) { throw new ConstructorException("while constructing a Set", node.getStartMark(), "found unacceptable key " + key, tuple.getKeyNode().getStartMark(), e); } } if (keyNode.isTwoStepsConstruction()) { /* * if keyObject is created it 2 steps we should postpone putting * it into the set because it may have different hash after * initialization compared to clean just created one. And set of * course does not observe value hashCode changes. */ sets2fill.add(0, new RecursiveTuple<Set<Object>, Object>(set, key)); } else { set.add(key); } } }
@Test public void notNullMapProperty() { bean.setMapProperty(ImmutableMap.<String, Long> builder().put("first", 1L).put("second", 2L).build()); Property property = new MethodProperty(getPropertyDescriptor("mapProperty")); NodeTuple nodeTuple = representer.representJavaBeanProperty(bean, property, bean.getMapProperty(), null); assertThat(nodeTuple, is(notNullValue())); assertThat(nodeTuple.getKeyNode(), is(instanceOf(ScalarNode.class))); assertThat(((ScalarNode) nodeTuple.getKeyNode()).getValue(), is("map-property")); assertThat(nodeTuple.getValueNode(), is(instanceOf(MappingNode.class))); assertThat(((MappingNode) nodeTuple.getValueNode()).getValue().size(), is(2)); assertThat(((MappingNode) nodeTuple.getValueNode()).getValue().get(0), is(instanceOf(NodeTuple.class))); assertThat(((ScalarNode) ((MappingNode) nodeTuple.getValueNode()).getValue().get(0).getKeyNode()).getValue(), is("first")); assertThat(((ScalarNode) ((MappingNode) nodeTuple.getValueNode()).getValue().get(0).getValueNode()).getValue(), is("1")); assertThat(((ScalarNode) ((MappingNode) nodeTuple.getValueNode()).getValue().get(1).getKeyNode()).getValue(), is("second")); assertThat(((ScalarNode) ((MappingNode) nodeTuple.getValueNode()).getValue().get(1).getValueNode()).getValue(), is("2")); }
@SuppressWarnings("unchecked") @Override public Map<Object, Object> constructMapping(MappingNode node) { Object collection; if (Map.class.isAssignableFrom(node.getType())) { collection = YamlCollectionCreator.createCollection(node.getType(), node.getValue().size()); } else { collection = YamlCollectionCreator.createCollection(Map.class, node.getValue().size()); } this.constructMapping2ndStep(node, (Map<Object, Object>) collection); return super.constructMapping(node); }
@Override @SuppressWarnings("unchecked") public void construct2ndStep(Node node, Object object) { if (Map.class.isAssignableFrom(node.getType())) { this.yamlConstructor.constructMapping2ndStep((MappingNode) node, (Map<Object, Object>) object); } else if (Set.class.isAssignableFrom(node.getType())) { this.yamlConstructor.constructSet2ndStep((MappingNode) node, (Set<Object>) object); } else { this.constructJavaBean2ndStep((MappingNode) node, object); } }
protected Object createEmptyJavaBean(MappingNode node) { try { /* * Using only default constructor. Everything else will be * initialized on 2nd step. If we do here some partial * initialization, how do we then track what need to be done on * 2nd step? I think it is better to get only object here (to * have it as reference for recursion) and do all other thing on * 2nd step. */ java.lang.reflect.Constructor<?> c = node.getType().getDeclaredConstructor(); c.setAccessible(true); return c.newInstance(); } catch (Exception e) { throw new YAMLException(e); } }
@Override public Set<String> getKeys() { if (this.node instanceof MappingNode) { List<NodeTuple> tuples = ((MappingNode) this.node).getValue(); Set<String> result = new LinkedHashSet<>(tuples.size()); for (NodeTuple tuple : tuples) { Node keyNode = tuple.getKeyNode(); if (keyNode instanceof ScalarNode) { result.add(((ScalarNode) keyNode).getValue()); } } return result; } return Collections.emptySet(); }
@Override public boolean containsKey(String key) { if (this.node instanceof MappingNode) { return this.getNode((MappingNode) this.node, key) != null; } if (this.node instanceof SequenceNode) { int i = DioriteMathUtils.asInt(key, - 1); if (i == - 1) { return false; } return i < ((SequenceNode) this.node).getValue().size(); } return false; }
@Nullable private Node getNode(Node node, String key) { if (key.isEmpty()) { return node; } if (node instanceof SequenceNode) { SequenceNode sequenceNode = (SequenceNode) node; List<Node> sequenceNodeValue = sequenceNode.getValue(); int i = DioriteMathUtils.asInt(key, - 1); if ((i == - 1) || (i < sequenceNodeValue.size())) { return null; } return sequenceNodeValue.get(i); } if (node instanceof MappingNode) { return this.getNode((MappingNode) node, key); } return null; }
@Nullable private Node getNode(MappingNode node, String key, boolean remove) { for (Iterator<NodeTuple> iterator = node.getValue().iterator(); iterator.hasNext(); ) { NodeTuple tuple = iterator.next(); Node keyNode = tuple.getKeyNode(); if (! (keyNode instanceof ScalarNode)) { return null; } if (key.equals(((ScalarNode) keyNode).getValue())) { if (remove) { iterator.remove(); } return tuple.getValueNode(); } } return null; }
@SuppressWarnings("unchecked") @Override public <K, T, M extends Map<K, T>> void getMap(String key, Function<String, K> keyMapper, Class<T> type, M map) { Node node = this.getNode(this.node, key); if (! (node instanceof MappingNode)) { throw new DeserializationException(type, this, "Can't find valid value for key: " + key); } MappingNode mappingNode = (MappingNode) node; Tag typeTag = new Tag(type); for (NodeTuple tuple : mappingNode.getValue()) { Node keyNode = tuple.getKeyNode(); keyNode.setTag(Tag.STR); K keyObj = keyMapper.apply(this.constructor.constructObject(keyNode).toString()); Node valueNode = tuple.getValueNode(); if (type != Object.class) { valueNode.setTag(typeTag); } map.put(keyObj, (T) this.constructor.constructObject(valueNode)); } }
protected Node composeMappingNode(String anchor) { MappingStartEvent startEvent = (MappingStartEvent) parser.getEvent(); String tag = startEvent.getTag(); Tag nodeTag; boolean resolved = false; if (tag == null || tag.equals("!")) { nodeTag = resolver.resolve(NodeId.mapping, null, startEvent.getImplicit()); resolved = true; } else { nodeTag = new Tag(tag); } final List<NodeTuple> children = new ArrayList<NodeTuple>(); MappingNode node = new MappingNode(nodeTag, resolved, children, startEvent.getStartMark(), null, startEvent.getFlowStyle()); if (anchor != null) { anchors.put(anchor, node); } while (!parser.checkEvent(Event.ID.MappingEnd)) { composeMappingChildren(children, node); } Event endEvent = parser.getEvent(); node.setEndMark(endEvent.getEndMark()); return node; }
@Override protected void constructMapping2ndStep(MappingNode node, Map<Object, Object> mapping) { List<NodeTuple> nodeValue = (List<NodeTuple>) node.getValue(); for (NodeTuple tuple : nodeValue) { Node keyNode = tuple.getKeyNode(); Node valueNode = tuple.getValueNode(); Object key = constructObject(keyNode); if (key != null) { key.hashCode();// check circular dependencies } Object value = constructObject(valueNode); Object old = mapping.put(key, value); if (old != null) { throw new YAMLException("The key is not unique " + key); } } }
@SuppressWarnings("unchecked") public Car construct(Node node) { Car car = new Car(); MappingNode mapping = (MappingNode) node; List<NodeTuple> list = mapping.getValue(); for (NodeTuple tuple : list) { String field = toScalarString(tuple.getKeyNode()); if ("plate".equals(field)) { car.setPlate(toScalarString(tuple.getValueNode())); } if ("wheels".equals(field)) { SequenceNode snode = (SequenceNode) tuple.getValueNode(); List<Wheel> wheels = (List<Wheel>) constructSequence(snode); car.setWheels(wheels); } } return car; }
@Override public Node getSingleNode() { Node node = super.getSingleNode(); if (!MappingNode.class.isAssignableFrom(node.getClass())) { throw new RuntimeException( "Document is not structured as expected. Root element should be a map!"); } MappingNode root = (MappingNode) node; for (NodeTuple tuple : root.getValue()) { Node keyNode = tuple.getKeyNode(); if (ScalarNode.class.isAssignableFrom(keyNode.getClass())) { if (((ScalarNode) keyNode).getValue().equals(nodeName)) { return tuple.getValueNode(); } } } throw new RuntimeException("Did not find key \"" + nodeName + "\" in document-level map"); }
private void loadYamlLookupSets(MappingNode entry, String filename) { // LOG.info("Loading lookupSet.({}:{})", filename, entry.getStartMark().getLine()); String name = null; Set<String> lookupSet = new HashSet<>(); for (NodeTuple tuple : entry.getValue()) { switch (getKeyAsString(tuple, filename)) { case "name": name = getValueAsString(tuple, filename); break; case "values": SequenceNode node = getValueAsSequenceNode(tuple, filename); List<String> values = getStringValues(node, filename); for (String value: values) { lookupSet.add(value.toLowerCase(Locale.ENGLISH)); } break; default: break; } } lookupSets.put(name, lookupSet); }
@Override public Object construct(Node node) { Population pop = new Population(); Map<Object, Object> values = constructMapping((MappingNode)node); pop.setInitAround((Double) values.get("initAround")); pop.setInitMethod(PopulationInitMethod.valueOf((String) values.get("initMethod"))); ArrayList<Double> initPos = (ArrayList<Double>) values.get("initPos"); pop.setInitPos(initPos.stream().mapToDouble(Double::doubleValue).toArray()); pop.setPopMetric((InterfaceDistanceMetric) values.get("popMetric")); //pop.setSeedCardinality((Pair<Integer, Integer>) values.get("seedCardinality")); pop.setTargetSize((Integer) values.get("targetSize")); return pop; }
private static Node getNode(final MappingNode node, final String key, final boolean remove) { for (final Iterator<NodeTuple> it = node.getValue().iterator(); it.hasNext(); ) { final NodeTuple nodeTuple = it.next(); final Node keyNode = nodeTuple.getKeyNode(); if (keyNode instanceof ScalarNode) { if (key.equals(((ScalarNode) keyNode).getValue())) { if (remove) { it.remove(); } return nodeTuple.getValueNode(); } } } return null; }