Question

I am trying to set up a small metamodel in order to reference some properties on multiple classes.

Example: Using the classes below, I'd like to store only Person.name and Person.surname in MetaManager.config. The problem is, I don't want to store the values of name and surname, but a reference to the field. By storing these references of the field, later on I can retrieve the name and surname of any instance of Person I would pass to MetaManager.getValues().

This code is similar to Metamodel API, though I am not sure whether I should use this (since Metamodel is part of persistence and this is not related to persistence). In this API the reference is made like this Person_.name using the EntityType object.

The question is, in what way can I store a reference to these properties so I can retrieve the value of these properties from an instance later on?

The code below gives a sketch of what I'm trying to accomplish. As you can see, my problem is in Person.getValue() and a toString() on this reference (a reference on ssn would thus return "ssn").

interface IMetable {
    Object getValue(Meta meta);
}

class Person implements IMetable {
    String ssn;
    String name;
    String surname;

    Person(String ssn, String name, String surname) {
        this.ssn = ssn;
        this.name = name;
        this.surname = surname;
    }

    @Override
    Object getValue(ClassMeta meta) {
        // Return the value of the (by meta) referenced field
        return null;
    }
}

class MetaManager {
    Map<Class, Meta[]> config;

    public Map<String, String> getValues(IMetable object) {
        if(config.containsKey(object.class)) {
            ClassMeta[] metamodel = config.get(object.class);
            Map<String, String> values = new HashMap();

            for(Meta meta : metamodel) {
                values.put(meta.toString(), object.getValue(meta).toString());
            }
            return values;
        }
        else {
            throw new Exception("This class has not been configurated.");
        }
    }
}
Was it helpful?

Solution

You appear to be trying to recreate the reflection API.

Why wouldn't you just implement MetaManager like this:

public class MetaManager 
{
  public Map<String, Object> getValues(Object object) 
  {
    Map<String, Object> values = new HashMap<String, Object>();

    for (Field field : object.getClass().getFields())
    {
      boolean wasAccessible = field.isAccessible();
      try 
      {
        field.setAccessible(true);     
        values.put(field.getName(), field.get(object));
      }
      finally
      {
        field.setAccessible(wasAccessible); 
      }
    }

    return values;  
  }
}   

If you need a subset of fields then use an Annotation to mark those fields and then check for that Annotation before adding it to the values map.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top