if (!MappingDefinition.class.isAssignableFrom(cls)) {
throw new RuntimeException("@CustomMapping class: " + cls.getName() + " does not inherit " + MappingDefinition.class.getName());
}
try {
MappingDefinition definition = (MappingDefinition) cls.newInstance();
definition.setMarshallerInstance(new DefaultDefinitionMarshaller(definition));
addDefinition(definition);
exposedClasses.add(definition.getMappingClass().asClass());
if (log.isDebugEnabled())
log.debug("loaded custom mapping class: " + cls.getName() + " (for mapping: "
+ definition.getMappingClass().getFullyQualifiedName() + ")");
if (cls.isAnnotationPresent(InheritedMappings.class)) {
InheritedMappings inheritedMappings = cls.getAnnotation(InheritedMappings.class);
for (Class<?> c : inheritedMappings.value()) {
MappingDefinition aliasMappingDef = new MappingDefinition(c);
aliasMappingDef.setMarshallerInstance(new DefaultDefinitionMarshaller(aliasMappingDef));
addDefinition(aliasMappingDef);
exposedClasses.add(c);
if (log.isDebugEnabled())
log.debug("mapping inherited mapping " + c.getName() + " -> " + cls.getName());
}
}
}
catch (Throwable t) {
throw new RuntimeException("Failed to load definition", t);
}
}
for (MappingDefinition def : MAPPING_DEFINITIONS.values()) {
mergeDefinition(def);
}
Set<Class<?>> marshallers = scanner.getTypesAnnotatedWith(ClientMarshaller.class);
for (Class<?> marshallerCls : marshallers) {
if (Marshaller.class.isAssignableFrom(marshallerCls)) {
try {
Class<?> type = (Class<?>) Marshaller.class.getMethod("getTypeHandled").invoke(marshallerCls.newInstance());
MappingDefinition marshallMappingDef = new MappingDefinition(type);
marshallMappingDef.setClientMarshallerClass(marshallerCls.asSubclass(Marshaller.class));
addDefinition(marshallMappingDef);
exposedClasses.add(type);
if (marshallerCls.isAnnotationPresent(ImplementationAliases.class)) {
for (Class<?> aliasCls : marshallerCls.getAnnotation(ImplementationAliases.class).value()) {
MappingDefinition aliasMappingDef = new MappingDefinition(aliasCls);
aliasMappingDef.setClientMarshallerClass(marshallerCls.asSubclass(Marshaller.class));
addDefinition(aliasMappingDef);
exposedClasses.add(aliasCls);
mappingAliases.put(aliasCls.getName(), type.getName());
}
}
}
catch (Throwable t) {
throw new RuntimeException("could not instantiate marshaller class: " + marshallerCls.getName(), t);
}
}
else {
throw new RuntimeException("class annotated with " + ClientMarshaller.class.getCanonicalName()
+ " does not implement " + Marshaller.class.getName());
}
}
Set<Class<?>> exposedFromScanner = new HashSet<Class<?>>(scanner.getTypesAnnotatedWith(Portable.class));
for (Class<?> cls : exposedFromScanner) {
for (Class<?> decl : cls.getDeclaredClasses()) {
if (decl.isSynthetic()) {
continue;
}
exposedClasses.add(decl);
}
}
exposedClasses.addAll(exposedFromScanner);
exposedClasses.add(Object.class);
Properties props = scanner.getProperties("ErraiApp.properties");
if (props != null) {
log.info("Checking ErraiApp.properties for configured types ...");
for (Object o : props.keySet()) {
String key = (String) o;
if (key.equals(MarshallingGenUtil.CONFIG_ERRAI_OLD_SERIALIZABLE_TYPE)
|| key.equals(MarshallingGenUtil.CONFIG_ERRAI_SERIALIZABLE_TYPE)) {
for (String s : props.getProperty(key).split(" ")) {
try {
Class<?> cls = Class.forName(s.trim());
exposedClasses.add(cls);
}
catch (Exception e) {
throw new RuntimeException("could not find class defined in ErraiApp.properties for serialization: " + s);
}
}
break;
}
if (key.equals(MarshallingGenUtil.CONFIG_ERRAI_MAPPING_ALIASES)) {
for (String s : props.getProperty(key).split(" ")) {
try {
String[] mapping = s.split("->");
if (mapping.length != 2) {
throw new RuntimeException("syntax error: mapping for marshalling alias: " + s);
}
Class<?> fromMapping = Class.forName(mapping[0].trim());
Class<?> toMapping = Class.forName(mapping[1].trim());
mappingAliases.put(fromMapping.getName(), toMapping.getName());
}
catch (Exception e) {
throw new RuntimeException("could not find class defined in ErraiApp.properties for mapping: " + s);
}
}
break;
}
}
}
Map<Class<?>, Class<?>> aliasToMarshaller = new HashMap<Class<?>, Class<?>>();
for (Class<?> mappedClass : exposedClasses) {
if (mappedClass.isSynthetic()) continue;
Portable portable = mappedClass.getAnnotation(Portable.class);
if (portable != null && !portable.aliasOf().equals(Object.class)) {
aliasToMarshaller.put(mappedClass, portable.aliasOf());
}
else if (!hasDefinition(mappedClass)) {
MappingDefinition def = DefaultJavaDefinitionMapper.map(JavaReflectionClass.newUncachedInstance(mappedClass),
this);
def.setMarshallerInstance(new DefaultDefinitionMarshaller(def));
addDefinition(def);
}
}
for (Map.Entry<Class<?>, Class<?>> entry : aliasToMarshaller.entrySet()) {
MappingDefinition def = getDefinition(entry.getValue());
if (def == null) {
throw new InvalidMappingException("cannot alias type " + entry.getKey().getName()
+ " to " + entry.getValue().getName() + ": the specified alias type does not exist ");
}
// mappingAliases.put(entry.getKey().getName(), def.getClientMarshallerClass().getName());
MappingDefinition aliasDef = new MappingDefinition(def.getMarshallerInstance(), entry.getKey());
aliasDef.setClientMarshallerClass(def.getClientMarshallerClass());
addDefinition(aliasDef);
}
// key = all types, value = list of all types which inherit from.
Map<String, List<String>> inheritanceMap = new HashMap<String, List<String>>();
for (Map.Entry<String, MappingDefinition> entry : MAPPING_DEFINITIONS.entrySet()) {
checkInheritance(inheritanceMap, entry.getValue().getMappingClass());
}
MetaClass javaLangObjectRef = MetaClassFactory.get(Object.class);
for (Map.Entry<String, MappingDefinition> entry : MAPPING_DEFINITIONS.entrySet()) {
MappingDefinition def = entry.getValue();
InstantiationMapping instantiationMapping = def.getInstantiationMapping();
for (Mapping mapping : instantiationMapping.getMappings()) {
if (!isTypeFinal(inheritanceMap, mapping.getType())) {
mapping.setType(javaLangObjectRef);
}
}