package org.webinos.android.impl.mediacontent; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import org.webinos.api.mediacontent.CompositeDbFieldMapping; import org.webinos.api.mediacontent.MediaAudio; import org.webinos.api.mediacontent.MediaImage; import org.webinos.api.mediacontent.MediaItem; import org.webinos.api.mediacontent.MediaVideo; import org.webinos.api.mediacontent.SingleDbFieldMapping; import org.webinos.android.impl.mediacontent.Translator; class Mapping { public static abstract class DbField { private String attributeName; private Class<?> attributeType; public DbField(String attributeName, Class<?> attributeType) { this.attributeName = attributeName; this.attributeType = attributeType; } public String getAttributeName() { return attributeName; } public Class<?> getAttributeType() { return attributeType; } } final static class SingleDbField extends DbField { private String name; private Translator translator; public SingleDbField(SingleDbFieldMapping mapping) { this(null, null, mapping); } public SingleDbField(String attributeName, Class<?> attributeType, SingleDbFieldMapping mapping) { super(attributeName, attributeType); this.name = mapping.name(); try { if(mapping.translatorClass() != "") this.translator = (Translator) Class.forName("org.webinos.android.impl.mediacontent.Translator$" + mapping.translatorClass()).newInstance(); } catch (Exception e) { e.printStackTrace(); } } public String getName() { return name; } public Translator getTranslator() { return translator; } } final static class CompositeDbField extends DbField { private SingleDbField[] dbFields; private CompositeHandler compositeHandler; public CompositeDbField(String attributeName, Class<?> attributeType, CompositeDbFieldMapping mapping) { super(attributeName, attributeType); this.dbFields = new SingleDbField[mapping.fields().length]; int i = 0; for (SingleDbFieldMapping singleDbFieldMapping : mapping.fields()) { this.dbFields[i++] = new SingleDbField(singleDbFieldMapping); } try { this.compositeHandler = (CompositeHandler) Class.forName( "org.webinos.android.impl.mediacontent.CompositeHandler$" + mapping.compositeHandlerClass()).newInstance(); } catch (Exception e) { // This should not happen since it would indicate a erroneous annotation // in the API. } } public SingleDbField[] getDbFields() { return dbFields; } public CompositeHandler getCompositeHandler() { return compositeHandler; } } private static Map<String, DbField> dbMeta = new HashMap<String, DbField>(); private static void scanForMappings(Class<?>[] classesToScan) { for (Class<?> clazz : classesToScan) { for (Field attribute : clazz.getFields()) { SingleDbFieldMapping singleDbFieldMapping = (SingleDbFieldMapping) attribute .getAnnotation(SingleDbFieldMapping.class); if (singleDbFieldMapping != null) { if (!dbMeta.containsKey(attribute.getName())) { dbMeta.put(attribute.getName(), new SingleDbField(attribute.getName(), attribute.getType(), singleDbFieldMapping)); } } else { CompositeDbFieldMapping compositeDbFieldMapping = (CompositeDbFieldMapping) attribute .getAnnotation(CompositeDbFieldMapping.class); if (compositeDbFieldMapping != null) { if (!dbMeta.containsKey(attribute.getName())) { dbMeta.put(attribute.getName(), new CompositeDbField(attribute.getName(), attribute.getType(), compositeDbFieldMapping)); } } } } } } public static void init() { Class<?>[] classesToScan = new Class<?>[] {MediaItem.class, MediaAudio.class, MediaImage.class, MediaVideo.class}; scanForMappings(classesToScan); } public static String[] getAttributes() { return dbMeta.keySet().toArray(new String[dbMeta.size()]); } public static DbField getDbField(String attributeName) { return dbMeta.get(attributeName); } public static String[] getProjection() { String[] projection = new String[dbMeta.size()]; int i = 0; for (DbField dbField : dbMeta.values()) { if (dbField instanceof SingleDbField) { projection[i] = ((SingleDbField) dbField).getName(); } else if (dbField instanceof CompositeDbField) { for (SingleDbField singleDbField : ((CompositeDbField) dbField) .getDbFields()) { projection[i] = singleDbField.getName(); } } i++; } return projection; } }