下面列出了怎么用com.fasterxml.jackson.databind.introspect.BasicBeanDescription的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public HiveProxyingSubScan deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
final JsonNode node = jsonParser.getCodec().readTree(jsonParser);
final String pluginName = node.get("pluginName").asText();
final CatalogService catalogService = (CatalogService) deserializationContext
.findInjectableValue(CatalogService.class.getName(), null, null);
final StoragePluginCreator.PF4JStoragePlugin plugin = catalogService.getSource(pluginName);
final Class<? extends HiveProxiedSubScan> scanClazz = plugin.getSubScanClass();
final JavaType scanType = deserializationContext.getTypeFactory().constructType(scanClazz);
final BasicBeanDescription description = deserializationContext.getConfig().introspect(scanType);
final JsonDeserializer<Object> subScanDeserializer = deserializationContext.getFactory().createBeanDeserializer(
deserializationContext, scanType, description);
if (subScanDeserializer instanceof ResolvableDeserializer) {
((ResolvableDeserializer) subScanDeserializer).resolve(deserializationContext);
}
final JsonParser movedParser = jsonParser.getCodec().treeAsTokens(node.get("wrappedHiveScan"));
deserializationContext.getConfig().initialize(movedParser);
if (movedParser.getCurrentToken() == null) {
movedParser.nextToken();
}
final HiveProxiedSubScan scan = (HiveProxiedSubScan) subScanDeserializer.deserialize(movedParser, deserializationContext);
return new HiveProxyingSubScan(pluginName, scan);
}
@Override
public HiveProxyingOrcScanFilter deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
// TODO: Optimize performance as described in https://dremio.atlassian.net/browse/DX-17732
final JsonNode node = jsonParser.getCodec().readTree(jsonParser);
final String pluginName = node.get(HiveProxyingOrcScanFilter.JSON_PROP_PLUGINNAME).asText();
final CatalogService catalogService = (CatalogService) deserializationContext
.findInjectableValue(CatalogService.class.getName(), null, null);
final StoragePluginCreator.PF4JStoragePlugin plugin = catalogService.getSource(pluginName);
final Class<? extends HiveProxiedOrcScanFilter> scanClazz = plugin.getOrcScanFilterClass();
final JavaType scanType = deserializationContext.getTypeFactory().constructType(scanClazz);
final BasicBeanDescription description = deserializationContext.getConfig().introspect(scanType);
final JsonDeserializer<Object> orcScanFilterDeserializer = deserializationContext.getFactory().createBeanDeserializer(
deserializationContext, scanType, description);
if (orcScanFilterDeserializer instanceof ResolvableDeserializer) {
((ResolvableDeserializer) orcScanFilterDeserializer).resolve(deserializationContext);
}
final JsonParser movedParser = jsonParser.getCodec().treeAsTokens(node.get(HiveProxyingOrcScanFilter.JSON_PROP_WRAPPEDHIVEORCSCANFILTER));
deserializationContext.getConfig().initialize(movedParser);
if (movedParser.getCurrentToken() == null) {
movedParser.nextToken();
}
final HiveProxiedOrcScanFilter orcScanFilter = (HiveProxiedOrcScanFilter) orcScanFilterDeserializer.deserialize(movedParser, deserializationContext);
return new HiveProxyingOrcScanFilter(pluginName, orcScanFilter);
}
@Override
public void serialize(Entity entity, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
try {
BasicBeanDescription beanDescription = serializers.getConfig().introspect(serializers.constructType(entity.getClass()));
List<BeanPropertyDefinition> properties = beanDescription.findProperties();
for (BeanPropertyDefinition property : properties) {
serializeProperty(property, entity, properties, gen, serializers, beanDescription);
}
} catch (IOException | RuntimeException exc) {
throw new IOException("could not serialize Entity", exc);
} finally {
gen.writeEndObject();
}
}
private void serializeProperty(
BeanPropertyDefinition property,
Entity entity,
List<BeanPropertyDefinition> properties,
JsonGenerator gen,
SerializerProvider serializers,
BasicBeanDescription beanDescription) throws IOException {
if (property.getAccessor() == null) {
LOGGER.warn("Null Accessor found for {}.{}. Missing @JsonIgnore?", entity.getEntityType(), property.getName());
return;
}
// 0. check if it should be serialized
// If not, we still have to check if it is expanded, hence no
// direct continue.
boolean selected = true;
Set<String> selectedProperties = entity.getSelectedPropertyNames();
if (selectedProperties != null && !selectedProperties.contains(property.getName())) {
selected = false;
}
// 1. is it a NavigableElement?
if (NavigableElement.class.isAssignableFrom(property.getAccessor().getRawType())) {
selected = serialiseNavigationElement(property, entity, selected, gen);
}
if (!selected) {
return;
}
// 2. check if property has CustomSerialization annotation -> use custom serializer
Annotation annotation = property.getAccessor().getAnnotation(CustomSerialization.class);
if (annotation != null) {
serializeFieldCustomized(
entity,
gen,
property,
properties,
(CustomSerialization) annotation);
} else {
serializeField(entity, gen, serializers, beanDescription, property);
}
// 3. check if property is EntitySet than write count if needed.
if (EntitySet.class.isAssignableFrom(property.getAccessor().getRawType())) {
writeCountNextlinkForSet(property, entity, gen);
}
}
/**
* Use jackson serialization api to extract all configuration values with paths from configuration object.
* Always analyze types, even if actual branch is not present at all (null value) in order to always bind
* nulls and avoid "Schrodinger's binding" case. In short, bindings should not depend on configuration values
* (presence).
* <p>
* Still, bindings may vary: for example, bound implementations may differ (best example is dropwizard server type),
* as a consequences, parsed type may be different and so different properties paths could be recognized.
*
* @param config jackson serialization config
* @param content currently parsed paths
* @param type analyzed part type
* @param object analyzed part instance (may be null)
* @return all configuration paths values
*/
@SuppressWarnings("checkstyle:CyclomaticComplexity")
private static List<ConfigPath> resolvePaths(final SerializationConfig config,
final ConfigPath root,
final List<ConfigPath> content,
final Class type,
final Object object,
final GenericsContext genericsContext) {
final BasicBeanDescription description = config.introspect(
config.constructType(type)
);
for (BeanPropertyDefinition prop : description.findProperties()) {
// ignore write-only or groovy special property
if (!prop.couldSerialize() || prop.getName().equals("metaClass")) {
continue;
}
final Object value;
// if configuration doesn't expect serialization and throws error on access
// (like netflix dynamic properties) it should not break app startup
try {
value = readValue(prop.getAccessor(), object);
} catch (Exception ex) {
LOGGER.warn("Can't bind configuration path '{}' due to {}: {}. Enable debug logs to see "
+ "complete stack trace or use @JsonIgnore on property getter.",
fullPath(root, prop), ex.getClass().getSimpleName(), ex.getMessage());
LOGGER.debug("Complete error: ", ex);
continue;
}
final ConfigPath item = createItem(root, prop, value, genericsContext);
content.add(item);
if (root != null) {
root.getChildren().add(item);
}
if (item.isCustomType() && !detectRecursion(item)) {
// build generics context for actual value type (if not null)
final GenericsContext subContext = prop.getGetter() != null
? genericsContext.method(prop.getGetter().getAnnotated()).returnTypeAs(item.getValueType())
: genericsContext.fieldTypeAs(prop.getField().getAnnotated(), item.getValueType());
resolvePaths(config, item, content, item.getValueType(),
item.getValue(), subContext);
}
}
if (root != null) {
// simple properties goes up and composite objects go lower (both groups sorted alphabetically)
root.getChildren().sort(Comparator.comparing(o -> (o.isCustomType() ? 'b' : 'a') + o.getPath()));
}
return content;
}