/* * Copyright (c) 2008-2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.db.common.schema; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlTransient; import com.google.common.base.Objects; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.emc.storageos.db.client.upgrade.MigrationCallback; import com.emc.storageos.db.exceptions.DatabaseException; public class AnnotationValue implements SchemaObject { private static final Logger log = LoggerFactory.getLogger(AnnotationType.class); private RuntimeType runtimeType; // the following field is used in unmarshalled instances private String type; // the following fields are used to distinguish instances private String name; private String value; private SchemaObject parent; public AnnotationValue() { } public AnnotationValue(RuntimeType runtimeType, Method method, SchemaObject parent) { this.runtimeType = new RuntimeType(runtimeType); this.parent = parent; this.name = method.getName(); try { Object val = method.invoke(runtimeType.getAnnotation()); if (val instanceof Class) { this.value = ((Class) val).getSimpleName(); this.runtimeType.setMigrationCallback((Class<? extends MigrationCallback>) val); } else if (val instanceof Enum[]) { Enum[] vals = (Enum[]) val; for (int i = 0; i < vals.length; i++) { this.value = vals[i].name(); } this.runtimeType.setMigrationCallback(null); } else if (val instanceof Class[]) { Class[] vals = (Class[]) val; StringBuffer sb = new StringBuffer(); for (int i=0; i < vals.length; i++) { sb.append(vals[i].getSimpleName() + ","); } this.value = sb.toString(); } else { this.value = val.toString(); this.runtimeType.setMigrationCallback(null); } } catch (InvocationTargetException e) { throw DatabaseException.fatals.failedDuringUpgrade("Failed to parse annotation value:", e); } catch (IllegalAccessException e) { throw DatabaseException.fatals.failedDuringUpgrade("Failed to parse annotation value:", e); } } @Key @XmlAttribute public String getName() { return name; } public void setName(String name) { this.name = name; } @XmlAttribute public String getValue() { return value; } public void setValue(String value) { this.value = value; } @XmlAttribute public String getType() { if (runtimeType == null) { return type; } if (runtimeType.getMigrationCallback() == null) { return null; } return runtimeType.getMigrationCallback().getCanonicalName(); } public void setType(String type) { this.type = type; } @Override public boolean equals(Object o) { if (!(o instanceof AnnotationValue)) { return false; } AnnotationValue annotationValue = (AnnotationValue) o; if (!annotationValue.getName().equals(getName())) { return false; } if (!annotationValue.getValue().equals(getValue())) { return false; } return true; } @Override public int hashCode() { return Objects.hashCode(name, value); } @XmlTransient public Class getCfClass() { return runtimeType.getCfClass(); } @XmlTransient public String getFieldName() { return runtimeType.getFieldName(); } @XmlTransient public Class<? extends Annotation> getAnnoClass() { return runtimeType.getAnnotation().annotationType(); } @Override public String describe() { return "annotation field: " + this.name + " for " + parent.describe(); } public void setParent(SchemaObject parent) { this.parent = parent; } }