Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2023, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* 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 boofcv.io.serialize;
import boofcv.struct.Configuration;
import org.ddogleg.struct.DogArray;
import org.ddogleg.struct.FastAccess;
import org.ddogleg.struct.FastArray;
import org.jetbrains.annotations.Nullable;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Base class for java serialization of public field variables. Custom error handling is provided by
* the {@link #errorHandler} function. By default any error will throw an exception.
*
* @author Peter Abeles
*/
@SuppressWarnings({"NullAway", "rawtypes", "unchecked"})
public class SerializeFieldsYamlBase {
/** Used to provide custom error handling */
public HandleError errorHandler = ( type, description, e ) -> {
if (e != null)
throw e;
else throw new RuntimeException(description);
};
/** Specifies which classes it can deserialize for security. */
public AllowClasses allowClasses = SerializeFieldsYamlBase::allowedDeserialize;
/**
* Serializes the specified config. If a 'canonical' reference is provided then only what is not identical
* in value to the canonical is serialized.
*
* @param config Object that is to be serialized
* @param canonical Canonical object.
*/
public Map serialize( Object config, @Nullable Object canonical ) {
Map state = new HashMap<>();
Class type = config.getClass();
Field[] fields = type.getFields();
// Get a list of active fields, if a list is specified by the configuration
List active = new ArrayList<>();
if (config instanceof Configuration) {
active = ((Configuration)config).serializeActiveFields();
}
for (Field f : fields) {
if (!(active.isEmpty() || active.contains(f.getName())))
continue;
try {
if (f.getType().isEnum() || f.getType().isPrimitive() || f.getType().getName().equals("java.lang.String")) {
try {
// Only add if they are not identical
Object targetValue = f.get(config);
Object canonicalValue = canonical == null ? null : f.get(canonical);
if (canonicalValue == null && targetValue == null)
continue;
if (targetValue == null || !targetValue.equals(canonicalValue))
state.put(f.getName(), f.getType().isEnum() ? ((Enum>)targetValue).name() : targetValue);
} catch (RuntimeException e) {
errorHandler.handle(ErrorType.MISC, "class=" + type.getSimpleName() + " field=" + f.getName(), e);
}
continue;
}
// FastArray are a special case. Serialize each element in the list
if (FastAccess.class.isAssignableFrom(f.getType())) {
FastAccess> list = (FastAccess>)f.get(config);
// See if the lists are identical. If they are then skip them
escape:
if (canonical != null) {
FastAccess> listCanon = (FastAccess>)f.get(canonical);
if (list.size() != listCanon.size())
break escape;
if (list.isEmpty())
continue;
for (int i = 0; i < list.size(); i++) {
if (!list.get(i).equals(listCanon.get(i)))
break escape;
}
continue;
}
// Encode the list. Basic types are just copied. Everything else is serialized.
Class> itemType = list.type;
boolean basic = itemType.isEnum() || itemType.isPrimitive() || itemType.getName().equals("java.lang.String");
// Create the canonical if possible
Object canonicalOfData = null;
if (canonical != null && !basic) {
try {
canonicalOfData = list.type.getConstructor().newInstance();
} catch (Exception e) {
errorHandler.handle(ErrorType.MISC, "Failed to create instance of '" + list.type.getSimpleName() + "'", null);
}
}
List