/*
* Copyright 2014 Higher Frequency Trading
*
* http://www.higherfrequencytrading.com
*
* 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 net.openhft.lang.io.serialization.direct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static net.openhft.lang.io.serialization.direct.DirectSerializationMetadata.SerializationMetadata;
final class ObjectMarshallers {
private static final Logger Log = LoggerFactory.getLogger(ObjectMarshallers.class);
private static final Map<Class, ObjectMarshaller> metadata = new HashMap<Class, ObjectMarshaller>();
@SuppressWarnings("unchecked")
public static <T> ObjectMarshaller<T> forClass(Class<T> clazz) {
ObjectMarshaller om = metadata.get(clazz);
if (om == null) {
List<Field> fields = Introspect.fields(clazz);
List<Field> eligibleFields = DirectSerializationFilter.stopAtFirstIneligibleField(fields);
SerializationMetadata serializationMetadata;
if (hasIneligibleFields(fields, eligibleFields)) {
WarnAboutIneligibleFields.apply(clazz, fields, eligibleFields);
serializationMetadata = DirectSerializationMetadata.extractMetadataForPartialCopy(eligibleFields);
} else {
serializationMetadata = DirectSerializationMetadata.extractMetadata(eligibleFields);
}
om = new ObjectMarshaller<T>(serializationMetadata);
Log.warn("Class {} has metadata {}", clazz.getName(), serializationMetadata);
metadata.put(clazz, om);
}
return (ObjectMarshaller<T>) om;
}
private static boolean hasIneligibleFields(List<Field> allFields, List<Field> eligibleFields) {
return allFields.size() != eligibleFields.size();
}
private static class WarnAboutIneligibleFields {
static void apply(Class clazz, List<Field> allFields, List<Field> eligibleFields) {
List<Field> ineligibleFields = allFields.subList(eligibleFields.size(), allFields.size());
Log.warn(
"The following fields in Class {} will not be copied by ObjectMarshaller:\n{}",
clazz.getName(),
commaSeparate(ineligibleFields)
);
}
private static String commaSeparate(Collection<Field> fields) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Field field : fields) {
if (first) {
sb.append('\t');
sb.append(field.getName());
first = false;
} else {
sb.append("\n\t");
sb.append(field.getName());
}
}
return sb.toString();
}
}
}