throw new RuntimeException("@CustomMapping class: " + cls.getName() + " does not inherit "
+ MappingDefinition.class.getName());
}
try {
final MappingDefinition definition = (MappingDefinition) cls.newInstance();
definition.setMarshallerInstance(new DefaultDefinitionMarshaller(definition));
addDefinition(definition);
exposedClasses.add(definition.getMappingClass());
if (log.isDebugEnabled())
log.debug("loaded custom mapping class: " + cls.getName() + " (for mapping: "
+ definition.getMappingClass().getFullyQualifiedName() + ")");
if (cls.isAnnotationPresent(InheritedMappings.class)) {
final InheritedMappings inheritedMappings = cls.getAnnotation(InheritedMappings.class);
for (final Class<?> c : inheritedMappings.value()) {
final MetaClass metaClass = MetaClassFactory.get(c);
final MappingDefinition aliasMappingDef = new MappingDefinition(metaClass, definition.alreadyGenerated());
aliasMappingDef.setMarshallerInstance(new DefaultDefinitionMarshaller(aliasMappingDef));
addDefinition(aliasMappingDef);
exposedClasses.add(metaClass);
if (log.isDebugEnabled())
log.debug("mapping inherited mapping " + c.getName() + " -> " + cls.getName());
}
}
}
catch (Throwable t) {
throw new RuntimeException("Failed to load definition", t);
}
}
for (final MappingDefinition def : MAPPING_DEFINITIONS.values()) {
mergeDefinition(def);
}
final Set<Class<?>> cliMarshallers = scanner.getTypesAnnotatedWith(ClientMarshaller.class);
for (final Class<?> marshallerCls : cliMarshallers) {
if (Marshaller.class.isAssignableFrom(marshallerCls)) {
try {
final Class<?> type = (Class<?>) Marshaller.class.getMethod("getTypeHandled").invoke(marshallerCls.newInstance());
final MappingDefinition marshallMappingDef = new MappingDefinition(type, true);
marshallMappingDef.setClientMarshallerClass(marshallerCls.asSubclass(Marshaller.class));
addDefinition(marshallMappingDef);
exposedClasses.add(MetaClassFactory.get(type));
if (marshallerCls.isAnnotationPresent(ImplementationAliases.class)) {
for (final Class<?> aliasCls : marshallerCls.getAnnotation(ImplementationAliases.class).value()) {
final MappingDefinition aliasMappingDef = new MappingDefinition(aliasCls, true);
aliasMappingDef.setClientMarshallerClass(marshallerCls.asSubclass(Marshaller.class));
addDefinition(aliasMappingDef);
exposedClasses.add(MetaClassFactory.get(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());
}
}
final Set<Class<?>> serverMarshallers = scanner.getTypesAnnotatedWith(ServerMarshaller.class);
for (final Class<?> marshallerCls : serverMarshallers) {
if (Marshaller.class.isAssignableFrom(marshallerCls)) {
try {
final Class<?> type = (Class<?>) Marshaller.class.getMethod("getTypeHandled").invoke(marshallerCls.newInstance());
final MappingDefinition definition;
if (hasDefinition(type)) {
definition = getDefinition(type);
definition.setServerMarshallerClass(marshallerCls.asSubclass(Marshaller.class));
}
else {
definition = new MappingDefinition(type, true);
definition.setServerMarshallerClass(marshallerCls.asSubclass(Marshaller.class));
addDefinition(definition);
exposedClasses.add(MetaClassFactory.get(marshallerCls));
}
if (marshallerCls.isAnnotationPresent(ImplementationAliases.class)) {
for (final Class<?> aliasCls : marshallerCls.getAnnotation(ImplementationAliases.class).value()) {
if (hasDefinition(aliasCls)) {
getDefinition(aliasCls).setServerMarshallerClass(marshallerCls.asSubclass(Marshaller.class));
}
else {
final MappingDefinition aliasMappingDef = new MappingDefinition(aliasCls, true);
aliasMappingDef.setClientMarshallerClass(marshallerCls.asSubclass(Marshaller.class));
addDefinition(aliasMappingDef);
exposedClasses.add(MetaClassFactory.get(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 " + ServerMarshaller.class.getCanonicalName()
+ " does not implement " + Marshaller.class.getName());
}
}
exposedClasses.add(MetaClassFactory.get(Object.class));
exposedClasses.addAll(getEnvironmentConfig().getExposedClasses());
mappingAliases.putAll(getEnvironmentConfig().getMappingAliases());
final Map<MetaClass, MetaClass> aliasToMarshaller = new HashMap<MetaClass, MetaClass>();
final List<MetaClass> enums = new ArrayList<MetaClass>();
for (final MetaClass mappedClass : exposedClasses) {
if (mappedClass.isSynthetic()) continue;
final Portable portable = mappedClass.getAnnotation(Portable.class);
if (portable != null && !portable.aliasOf().equals(Object.class)) {
aliasToMarshaller.put(mappedClass, MetaClassFactory.get(portable.aliasOf()));
}
else if (!hasDefinition(mappedClass)) {
final MappingDefinition def = DefaultJavaDefinitionMapper.map(mappedClass, this);
def.setMarshallerInstance(new DefaultDefinitionMarshaller(def));
addDefinition(def);
for (final Mapping mapping : def.getAllMappings()) {
if (mapping.getType().isEnum()) {
enums.add(mapping.getType());
}
}
}
}
for (final MetaClass enumType : enums) {
if (!hasDefinition(enumType)) {
final MappingDefinition enumDef = DefaultJavaDefinitionMapper
.map(MetaClassFactory.get(enumType.asClass()), this);
enumDef.setMarshallerInstance(new DefaultDefinitionMarshaller(enumDef));
addDefinition(enumDef);
exposedClasses.add(MetaClassFactory.get(enumType.asClass()));
}
}
// it is not accidental that we're not re-using the mappingAliases collection above
// we only want to deal with the property file specified aliases here.
for (final Map.Entry<String, String> entry : getEnvironmentConfig().getMappingAliases().entrySet()) {
try {
aliasToMarshaller.put(MetaClassFactory.get(entry.getKey()), MetaClassFactory.get(entry.getValue()));
}
catch (Throwable t) {
throw new RuntimeException("error loading mapping alias", t);
}
}
for (final Map.Entry<MetaClass, MetaClass> entry : aliasToMarshaller.entrySet()) {
final 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 ");
}
final MappingDefinition aliasDef = new MappingDefinition(
def.getMarshallerInstance(), entry.getKey(), false
);
if (def.getMarshallerInstance() instanceof DefaultDefinitionMarshaller) {
aliasDef.setMarshallerInstance(new DefaultDefinitionMarshaller(aliasDef));
}
else {
aliasDef.setClientMarshallerClass(def.getClientMarshallerClass());
aliasDef.setServerMarshallerClass(def.getServerMarshallerClass());
}
mergeDefinition(aliasDef);
addDefinition(aliasDef);
}
for (final Map.Entry<String, MappingDefinition> entry : MAPPING_DEFINITIONS.entrySet()) {
fillInheritanceMap(entry.getValue().getMappingClass());
}
final MetaClass javaLangObjectRef = MetaClassFactory.get(Object.class);
for (final Map.Entry<String, MappingDefinition> entry : MAPPING_DEFINITIONS.entrySet()) {
final MappingDefinition def = entry.getValue();
final InstantiationMapping instantiationMapping = def.getInstantiationMapping();
for (final Mapping mapping : instantiationMapping.getMappings()) {
if (shouldUseObjectMarshaller(mapping.getType())) {
mapping.setType(javaLangObjectRef);
}
}