
org.yaml.snakeyaml.representer.Representer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.portal.tools.rest.builder
Show all versions of com.liferay.portal.tools.rest.builder
Liferay Portal Tools REST Builder
The newest version!
/**
* Copyright (c) 2008, SnakeYAML
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.yaml.snakeyaml.representer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.introspector.Property;
import org.yaml.snakeyaml.introspector.PropertyUtils;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.NodeId;
import org.yaml.snakeyaml.nodes.NodeTuple;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.nodes.SequenceNode;
import org.yaml.snakeyaml.nodes.Tag;
/**
* Represent JavaBeans
*/
public class Representer extends SafeRepresenter {
protected Map, TypeDescription> typeDefinitions = Collections.emptyMap();
public Representer(DumperOptions options) {
super(options);
this.representers.put(null, new RepresentJavaBean());
}
public TypeDescription addTypeDescription(TypeDescription td) {
if (Collections.EMPTY_MAP == typeDefinitions) {
typeDefinitions = new HashMap, TypeDescription>();
}
if (td.getTag() != null) {
addClassTag(td.getType(), td.getTag());
}
td.setPropertyUtils(getPropertyUtils());
return typeDefinitions.put(td.getType(), td);
}
@Override
public void setPropertyUtils(PropertyUtils propertyUtils) {
super.setPropertyUtils(propertyUtils);
Collection tds = typeDefinitions.values();
for (TypeDescription typeDescription : tds) {
typeDescription.setPropertyUtils(propertyUtils);
}
}
protected class RepresentJavaBean implements Represent {
public Node representData(Object data) {
return representJavaBean(getProperties(data.getClass()), data);
}
}
/**
* Tag logic: - explicit root tag is set in serializer - if there is a predefined class tag it is
* used - a global tag with class name is always used as tag. The JavaBean parent of the specified
* JavaBean may set another tag (tag:yaml.org,2002:map) when the property class is the same as
* runtime class
*
* @param properties JavaBean getters
* @param javaBean instance for Node
* @return Node to get serialized
*/
protected MappingNode representJavaBean(Set properties, Object javaBean) {
List value = new ArrayList(properties.size());
Tag tag;
Tag customTag = classTags.get(javaBean.getClass());
tag = customTag != null ? customTag : new Tag(javaBean.getClass());
// flow style will be chosen by BaseRepresenter
MappingNode node = new MappingNode(tag, value, FlowStyle.AUTO);
representedObjects.put(javaBean, node);
DumperOptions.FlowStyle bestStyle = FlowStyle.FLOW;
for (Property property : properties) {
Object memberValue = property.get(javaBean);
Tag customPropertyTag = memberValue == null ? null : classTags.get(memberValue.getClass());
NodeTuple tuple =
representJavaBeanProperty(javaBean, property, memberValue, customPropertyTag);
if (tuple == null) {
continue;
}
if (!((ScalarNode) tuple.getKeyNode()).isPlain()) {
bestStyle = FlowStyle.BLOCK;
}
Node nodeValue = tuple.getValueNode();
if (!(nodeValue instanceof ScalarNode && ((ScalarNode) nodeValue).isPlain())) {
bestStyle = FlowStyle.BLOCK;
}
value.add(tuple);
}
if (defaultFlowStyle != FlowStyle.AUTO) {
node.setFlowStyle(defaultFlowStyle);
} else {
node.setFlowStyle(bestStyle);
}
return node;
}
/**
* 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) {
// generic Enum requires the full tag
if (property.getType() != java.lang.Enum.class) {
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);
}
/**
* Remove redundant global tag for a type safe (generic) collection if it is the same as defined
* by the JavaBean property
*
* @param property - JavaBean property
* @param node - representation of the property
* @param object - instance represented by the node
*/
@SuppressWarnings("unchecked")
protected void checkGlobalTag(Property property, Node node, Object object) {
// Skip primitive arrays.
if (object.getClass().isArray() && object.getClass().getComponentType().isPrimitive()) {
return;
}
Class>[] arguments = property.getActualTypeArguments();
if (arguments != null) {
if (node.getNodeId() == NodeId.sequence) {
// apply map tag where class is the same
Class extends Object> t = arguments[0];
SequenceNode snode = (SequenceNode) node;
Iterable
© 2015 - 2025 Weber Informatics LLC | Privacy Policy