protected Node representSequence(Tag tag, Iterable<?> sequence, Boolean flowStyle) { int size = 10;// default for ArrayList if (sequence instanceof List<?>) { size = ((List<?>) sequence).size(); } List<Node> value = new ArrayList<Node>(size); SequenceNode node = new SequenceNode(tag, value, flowStyle); representedObjects.put(objectToRepresent, node); boolean bestStyle = true; for (Object item : sequence) { Node nodeItem = representData(item); if (!(nodeItem instanceof ScalarNode && ((ScalarNode) nodeItem).getStyle() == null)) { bestStyle = false; } value.add(nodeItem); } if (flowStyle == null) { if (defaultFlowStyle != FlowStyle.AUTO) { node.setFlowStyle(defaultFlowStyle.getStyleBoolean()); } else { node.setFlowStyle(bestStyle); } } return node; }
/** * Reads a document from a source that contains only one document. * <p> * If the stream contains more than one document an exception is thrown. * </p> * * @return The root node of the document or <code>null</code> if no document * is available. */ public Node getSingleNode() { // Drop the STREAM-START event. parser.getEvent(); // Compose a document if the stream is not empty. Node document = null; if (!parser.checkEvent(Event.ID.StreamEnd)) { document = composeDocument(); } // Ensure that the stream contains no more documents. if (!parser.checkEvent(Event.ID.StreamEnd)) { Event event = parser.getEvent(); throw new ComposerException("expected a single document in the stream", document.getStartMark(), "but found another document", event.getStartMark()); } // Drop the STREAM-END event. parser.getEvent(); return document; }
@Override public Object construct( Node node ) { if ( node.isTwoStepsConstruction() ) { throw new YAMLException( "Unexpected referential mapping structure. Node: " + node ); } Map<?, ?> raw = (Map<?, ?>) super.construct( node ); if ( raw.containsKey( ConfigurationSerialization.SERIALIZED_TYPE_KEY ) ) { Map<String, Object> typed = new LinkedHashMap<String, Object>( raw.size() ); for ( Map.Entry<?, ?> entry : raw.entrySet() ) { typed.put( entry.getKey().toString(), entry.getValue() ); } try { return ConfigurationSerialization.deserializeObject( typed ); } catch ( IllegalArgumentException ex ) { throw new YAMLException( "Could not deserialize object", ex ); } } return raw; }
@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 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; }
@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; }
/** * Construct object from the specified Node. Return existing instance if the * node is already constructed. * * @param node * Node to be constructed * @return Java instance */ protected Object constructObject(Node node) { if (constructedObjects.containsKey(node)) { return constructedObjects.get(node); } if (recursiveObjects.contains(node)) { throw new ConstructorException(null, null, "found unconstructable recursive node", node.getStartMark()); } recursiveObjects.add(node); Construct constructor = getConstructor(node); Object data = constructor.construct(node); constructedObjects.put(node, data); recursiveObjects.remove(node); if (node.isTwoStepsConstruction()) { constructor.construct2ndStep(node, data); } return data; }
protected Class<?> getClassForNode(Node node) { Class<? extends Object> classForTag = typeTags.get(node.getTag()); if (classForTag == null) { String name = node.getTag().getClassName(); Class<?> cl; try { cl = getClassForName(name); } catch (ClassNotFoundException e) { throw new YAMLException("Class not found: " + name); } typeTags.put(node.getTag(), cl); return cl; } else { return classForTag; } }
public Object construct(Node node) { ScalarNode scalar = (ScalarNode) node; try { return nf.parse(scalar.getValue()); } catch (ParseException e) { String lowerCaseValue = scalar.getValue().toLowerCase(); if (lowerCaseValue.contains("inf") || lowerCaseValue.contains("nan")) { /* * Non-finites such as (+/-)infinity and NaN are not * parseable by NumberFormat when these `Double` values are * dumped by snakeyaml. Delegate to the `Tag.FLOAT` * constructor when for this expected failure cause. */ return (Number) yamlConstructors.get(Tag.FLOAT).construct(node); } else { throw new IllegalArgumentException("Unable to parse as Number: " + scalar.getValue()); } } }
public void serialize(Node node) throws IOException { if (closed == null) { throw new SerializerException("serializer is not opened"); } else if (closed) { throw new SerializerException("serializer is closed"); } this.emitter.emit(new DocumentStartEvent(null, null, this.explicitStart, this.useVersion, useTags)); anchorNode(node); if (explicitRoot != null) { node.setTag(explicitRoot); } serializeNode(node, null); this.emitter.emit(new DocumentEndEvent(null, null, this.explicitEnd)); this.serializedNodes.clear(); this.anchors.clear(); }
public static final <T> void addSerializer(ExtensibleRepresenter representer, Class<T> type, Function<T, String> function) { representer.addRepresenter(type, new Represent() { @SuppressWarnings("unchecked") @Override public Node representData(Object data) { String txt = function.apply((T) data); if (txt == null) { return new ScalarNode(Tag.NULL, "null", null, null, null); } return new ScalarNode(Tag.STR, txt, null, null, null); } }); }
@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)); } }
public String nextAnchor(Node node) { this.lastAnchorId++; NumberFormat format = NumberFormat.getNumberInstance(); format.setMinimumIntegerDigits(3); format.setMaximumFractionDigits(0);// issue 172 format.setGroupingUsed(false); String anchorId = format.format(this.lastAnchorId); return "id" + anchorId; }
@Override public List<OpenShiftCluster> construct(Node node) { List<OpenShiftCluster> clusters = new ArrayList<>(); SequenceNode sequenceNode = (SequenceNode) node; for (Node n : sequenceNode.getValue()) { MappingNode mapNode = (MappingNode) n; Map<Object, Object> valueMap = constructMapping(mapNode); String id = (String) valueMap.get("id"); String apiUrl = (String) valueMap.get("apiUrl"); String consoleUrl = (String) valueMap.get("consoleUrl"); clusters.add(new OpenShiftCluster(id, apiUrl, consoleUrl)); } return clusters; }
/** * Reads and composes the next document. * * @return The root node of the document or <code>null</code> if no more * documents are available. */ public Node getNode() { // Get the root node of the next document. if (!parser.checkEvent(Event.ID.StreamEnd)) { return composeDocument(); } else { return null; } }
/** * Serialize a Java object into a YAML Node. * * @param data * Java object to be Serialized to YAML * * @return YAML Node */ public Node toYamlNode(@Nullable Object data) { Node represent = this.yaml().represent(data); if (data != null) { if (! (data instanceof Map) && ! (data instanceof Collection)) { represent.setType(data.getClass()); represent.setTag(new Tag(data.getClass())); } } return represent; }
@SuppressWarnings("unchecked") public Node representData(Object data) { Map<Object, Object> value = new LinkedHashMap<Object, Object>(); Set<Object> set = (Set<Object>) data; for (Object key : set) { value.put(key, null); } return representMapping(getTag(data.getClass(), Tag.SET), value, null); }
@Nullable @Override public <T> T get(String key, Class<T> type, @Nullable T def) { Node node = this.getNode(this.node, key); if (node == null) { return def; } return this.deserializeSpecial(type, node, def); }
/** * Represent one JavaBean property. * * @param javaBean * - the instance to be represented * @param property * - the property of the instance * @param propertyValue * - value to be represented * @param customTag * - user defined Tag * @return NodeTuple to be used in a MappingNode. Return null to skip the * property */ protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) { ScalarNode nodeKey = (ScalarNode) representData(property.getName()); // the first occurrence of the node must keep the tag boolean hasAlias = this.representedObjects.containsKey(propertyValue); Node nodeValue = representData(propertyValue); if (propertyValue != null && !hasAlias) { NodeId nodeId = nodeValue.getNodeId(); if (customTag == null) { if (nodeId == NodeId.scalar) { if (propertyValue instanceof Enum<?>) { nodeValue.setTag(Tag.STR); } } else { if (nodeId == NodeId.mapping) { if (property.getType() == propertyValue.getClass()) { if (!(propertyValue instanceof Map<?, ?>)) { if (!nodeValue.getTag().equals(Tag.SET)) { nodeValue.setTag(Tag.MAP); } } } } checkGlobalTag(property, nodeValue, propertyValue); } } } return new NodeTuple(nodeKey, nodeValue); }
protected void composeMappingChildren(List<NodeTuple> children, MappingNode node) { Node itemKey = composeKeyNode(node); if (itemKey.getTag().equals(Tag.MERGE)) { node.setMerged(true); } Node itemValue = composeValueNode(node); children.add(new NodeTuple(itemKey, itemValue)); }
protected Node representScalar(Tag tag, String value, Character style) { if (style == null) { style = this.defaultScalarStyle; } Node node = new ScalarNode(tag, value, null, null, style); return node; }
@Nullable public Tag getTag(String key) { Node node = this.getNode(this.node, key); if (node == null) { return null; } return node.getTag(); }
@Override public String nextAnchor(Node node) { this.lastAnchorId++; NumberFormat format = NumberFormat.getNumberInstance(); format.setMinimumIntegerDigits(3); format.setMaximumFractionDigits(0);// issue 172 format.setGroupingUsed(false); String anchorId = format.format(this.lastAnchorId); return "id" + anchorId; }
protected void processDuplicateKeys(MappingNode node) { List<NodeTuple> nodeValue = node.getValue(); Map<Object, Integer> keys = new HashMap<Object, Integer>(nodeValue.size()); Deque<Integer> toRemove = new ArrayDeque<Integer>(); int i = 0; for (NodeTuple tuple : nodeValue) { Node keyNode = tuple.getKeyNode(); if (!keyNode.getTag().equals(Tag.MERGE)) { Object key = constructObject(keyNode); if (key != null) { try { key.hashCode();// check circular dependencies } catch (Exception e) { throw new ConstructorException("while constructing a mapping", node.getStartMark(), "found unacceptable key " + key, tuple.getKeyNode().getStartMark(), e); } } Integer prevIndex = keys.put(key, i); if (prevIndex != null) { if (!isAllowDuplicateKeys()) { throw new IllegalStateException("duplicate key: " + key); } toRemove.add(prevIndex); } } i = i + 1; } Iterator<Integer> indicies2remove = toRemove.descendingIterator(); while (indicies2remove.hasNext()) { nodeValue.remove(indicies2remove.next().intValue()); } }
/** * Ensure that the stream contains a single document and construct it * * @param type the class of the instance being created * @return constructed instance * @throws ComposerException * in case there are more documents in the stream */ public Object getSingleData(Class<?> type) { // Ensure that the stream contains a single document and construct it Node node = composer.getSingleNode(); if (node != null && !Tag.NULL.equals(node.getTag())) { if (Object.class != type) { node.setTag(new Tag(type)); } else if (rootTag != null) { node.setTag(rootTag); } return constructDocument(node); } return null; }
protected void constructMapping2ndStep(MappingNode node, Map<Object, Object> mapping) { List<NodeTuple> nodeValue = node.getValue(); for (NodeTuple tuple : nodeValue) { Node keyNode = tuple.getKeyNode(); Node valueNode = tuple.getValueNode(); Object key = constructObject(keyNode); if (key != null) { try { key.hashCode();// check circular dependencies } catch (Exception e) { throw new ConstructorException("while constructing a mapping", node.getStartMark(), "found unacceptable key " + key, tuple.getKeyNode().getStartMark(), e); } } Object value = constructObject(valueNode); if (keyNode.isTwoStepsConstruction()) { /* * if keyObject is created it 2 steps we should postpone putting * it in map because it may have different hash after * initialization compared to clean just created one. And map of * course does not observe key hashCode changes. */ maps2fill.add(0, new RecursiveTuple<Map<Object, Object>, RecursiveTuple<Object, Object>>( mapping, new RecursiveTuple<Object, Object>(key, value))); } else { mapping.put(key, value); } } }
public void serialize(Node node) throws IOException { if (this.closed == null) { throw new SerializerException("serializer is not opened"); } if (this.closed) { throw new SerializerException("serializer is closed"); } // if (this.explicitRoot != null) // { // if (this.explicitRoot.getValue().startsWith(Tag.PREFIX)) // { // try // { // Class<?> type = Class.forName(this.explicitRoot.getClassName(), false, Thread.currentThread().getContextClassLoader()); // node.setType(type); // } // catch (Exception ignored) // { // } // } // } this.emitter.emit(new DocumentStartEvent(null, null, this.explicitStart, this.useVersion, this.useTags)); this.anchorNode(node); if (this.explicitRoot != null) { node.setTag(this.explicitRoot); } this.emitter.writeComment(this.comments.getHeader(), 0, 1); this.serializeNode(node, null, new LinkedList<>(), false); this.emitter.writeComment(this.comments.getFooter(), 2, 0); this.emitter.emit(new DocumentEndEvent(null, null, this.explicitEnd)); this.serializedNodes.clear(); this.anchors.clear(); }
private void dumpAll(Iterator<? extends Object> data, Writer output, Tag rootTag) { Serializer serializer = new Serializer(new Emitter(output, dumperOptions), resolver, dumperOptions, rootTag); try { serializer.open(); while (data.hasNext()) { Node node = representer.represent(data.next()); serializer.serialize(node); } serializer.close(); } catch (IOException e) { throw new YAMLException(e); } }
/** * Serialize the representation tree into Events. * * @see <a href="http://yaml.org/spec/1.1/#id859333">Processing Overview</a> * @param data * representation tree * @return Event list */ public List<Event> serialize(Node data) { SilentEmitter emitter = new SilentEmitter(); Serializer serializer = new Serializer(emitter, resolver, dumperOptions, null); try { serializer.open(); serializer.serialize(data); serializer.close(); } catch (IOException e) { throw new YAMLException(e); } return emitter.getEvents(); }
public Object construct(Node node) { String value = constructScalar((ScalarNode) node).toString().replaceAll("_", ""); int sign = +1; char first = value.charAt(0); if (first == '-') { sign = -1; value = value.substring(1); } else if (first == '+') { value = value.substring(1); } int base = 10; if ("0".equals(value)) { return Integer.valueOf(0); } else if (value.startsWith("0b")) { value = value.substring(2); base = 2; } else if (value.startsWith("0x")) { value = value.substring(2); base = 16; } else if (value.startsWith("0")) { value = value.substring(1); base = 8; } else if (value.indexOf(':') != -1) { String[] digits = value.split(":"); int bes = 1; int val = 0; for (int i = 0, j = digits.length; i < j; i++) { val += Long.parseLong(digits[j - i - 1]) * bes; bes *= 60; } return createNumber(sign, String.valueOf(val), 10); } else { return createNumber(sign, value, 10); } return createNumber(sign, value, base); }
@SuppressWarnings("unchecked") public void construct2ndStep(Node node, Object object) { if (Map.class.isAssignableFrom(node.getType())) { constructMapping2ndStep((MappingNode) node, (Map<Object, Object>) object); } else if (Set.class.isAssignableFrom(node.getType())) { constructSet2ndStep((MappingNode) node, (Set<Object>) object); } else { constructJavaBean2ndStep((MappingNode) node, object); } }
private Construct getConstructor(Node node) { Class<?> cl = getClassForNode(node); node.setType(cl); // call the constructor as if the runtime class is defined Construct constructor = yamlClassConstructors.get(node.getNodeId()); return constructor; }
@SuppressWarnings("unchecked") public void construct2ndStep(Node node, Object object) { SequenceNode snode = (SequenceNode) node; if (List.class.isAssignableFrom(node.getType())) { List<Object> list = (List<Object>) object; constructSequenceStep2(snode, list); } else if (node.getType().isArray()) { constructArrayStep2(snode, object); } else { throw new YAMLException("Immutable objects cannot be recursive."); } }
public BaseConstructor() { constructedObjects = new HashMap<Node, Object>(); recursiveObjects = new HashSet<Node>(); maps2fill = new ArrayList<RecursiveTuple<Map<Object, Object>, RecursiveTuple<Object, Object>>>(); sets2fill = new ArrayList<RecursiveTuple<Set<Object>, Object>>(); rootTag = null; explicitPropertyUtils = false; }
/** * Fail with a reminder to provide the seconds step for a recursive * structure * * @see Construct#construct2ndStep(Node, * Object) */ public void construct2ndStep(Node node, Object data) { if (node.isTwoStepsConstruction()) { throw new IllegalStateException("Not Implemented in " + getClass().getName()); } else { throw new YAMLException("Unexpected recursive structure for Node: " + node); } }
public final Node representDate(Date data) { // because SimpleDateFormat ignores timezone we have to use Calendar Calendar calendar = Calendar.getInstance((this.representer.getTimeZone() == null) ? TimeZone.getTimeZone("UTC") : this.representer.timeZone); calendar.setTime(data); return this.representCalendar(calendar); }
public Object construct(Node node) { // Note: we do not check for duplicate keys, because it's too // CPU-expensive. Map<Object, Object> omap = new LinkedHashMap<Object, Object>(); if (!(node instanceof SequenceNode)) { throw new ConstructorException("while constructing an ordered map", node.getStartMark(), "expected a sequence, but found " + node.getNodeId(), node.getStartMark()); } SequenceNode snode = (SequenceNode) node; for (Node subnode : snode.getValue()) { if (!(subnode instanceof MappingNode)) { throw new ConstructorException("while constructing an ordered map", node.getStartMark(), "expected a mapping of length 1, but found " + subnode.getNodeId(), subnode.getStartMark()); } MappingNode mnode = (MappingNode) subnode; if (mnode.getValue().size() != 1) { throw new ConstructorException("while constructing an ordered map", node.getStartMark(), "expected a single mapping item, but found " + mnode.getValue().size() + " items", mnode.getStartMark()); } Node keyNode = mnode.getValue().get(0).getKeyNode(); Node valueNode = mnode.getValue().get(0).getValueNode(); Object key = constructObject(keyNode); Object value = constructObject(valueNode); omap.put(key, value); } return omap; }
public Object construct(Node node) { SequenceNode seqNode = (SequenceNode) node; if (node.isTwoStepsConstruction()) { return createDefaultList(seqNode.getValue().size()); } else { return constructSequence(seqNode); } }