All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mx.path.model.mdx.model.MdxBaseReflector Maven / Gradle / Ivy

There is a newer version: 16.0.0
Show newest version
package com.mx.path.model.mdx.model;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import com.mx.path.core.common.reflection.Annotations;

/**
 * Provides MdxBase reflection utilities.
 *
 * 

ID: * *

Extract the ID of an object: *

{@code
 *   Account account = new Account();
 *   account.setId("account1");
 *
 *   // Get the ID
 *   String id = new MdxBaseReflector().getId(account);
 *
 * }
* *

Relations: *

{@code
 *   class Transfer extends MdxBase {
 *     private String fromAccountId;
 *
 *     @MdxRelationId(referredClass = Account.class)
 *     public String getFromAccountId() {
 *       return fromAccountId;
 *     }
 *   }
 * }
* *

To discover the relationship * *

{@code
 *   Transfer transfer = new Transfer();
 *   transfer.setFromAccountId("account-1");
 *
 *   // Get the relationship definitions:
 *   List relationships = new MdxBaseReflector().getRelations(transfer);
 *
 *   // Get the relationship values:
 *   List ids = new MdxBaseReflector().getRelationIds(transfer);
 * }
*/ public class MdxBaseReflector { // Cached map of ID methods. So they don't need to be retrieved every time they need to be invoked. These shouldn't change during runtime. private static final Map, Method> METHODS = new HashMap<>(); // Cached map of relation defs. So they don't need to be rebuilt every time they are needed. These shouldn't change during runtime. private static final Map, List> RELATIONS = new HashMap<>(); /** * Extract the id from obj * * @param obj instance of MdxBase * @return the extracted id */ public final String getId(MdxBase obj) { Method getIdMethod; String id; Class klass = obj.getClass(); try { getIdMethod = getIdMethod(klass); id = (String) getIdMethod.invoke(obj); } catch (IllegalAccessException | InvocationTargetException e) { throw new MdxReflectorException("Unable to extract id from model " + klass.getCanonicalName(), e); } return id; } /** * Get list of relations annotated on parentClass that refers to referredClass * * @param parentClass the class with relation annotation * @param referredClass the class that the parentClass refers to * @return list of relation defs */ public final List getRelationDefs(Class> parentClass, Class referredClass) { return getRelationMethods(parentClass).stream() .filter(relation -> relation.getRelation().referredClass() == referredClass) .collect(Collectors.toList()); } /** * Extract the reference values from obj that refer to referredClass * * @param obj * @param referredClass * @return list of reference ids */ @SuppressWarnings("unchecked") public final List getRelationIds(MdxBase obj, Class referredClass) { Class> parentClass = (Class>) obj.getClass(); List relations = getRelationDefs(parentClass, referredClass); return relations.stream().map(relation -> { try { return (String) relation.getMethod().invoke(obj); } catch (IllegalAccessException | InvocationTargetException e) { throw new MdxReflectorException("Unable to extract relation (" + parentClass.getCanonicalName() + " -> " + referredClass.getCanonicalName() + ") id using " + relation.getMethod().getName(), e); } }).filter(Objects::nonNull).collect(Collectors.toList()); } private Method getIdMethod(Class klass) { Method idMethod = METHODS.get(klass); if (idMethod == null) { try { idMethod = klass.getMethod("getId"); } catch (NoSuchMethodException e) { throw new MdxReflectorException("Unable to reflect getId method from model " + klass.getCanonicalName(), e); } METHODS.put(klass, idMethod); } return idMethod; } private List getRelationMethods(Class> targetClass) { List relations = RELATIONS.get(targetClass); if (relations == null) { relations = Annotations.methodsWithAnnotation(MdxRelationId.class, targetClass) .stream() .map(method -> MdxRelationDef.builder() .relation(method.getAnnotation(MdxRelationId.class)) .method(method) .build()) .collect(Collectors.toList()); RELATIONS.put(targetClass, relations); } return relations; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy