package com.hwlcn.ldap.ldap.sdk.persist; import java.io.Serializable; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import com.hwlcn.ldap.ldap.sdk.Attribute; import com.hwlcn.ldap.ldap.sdk.schema.AttributeTypeDefinition; import com.hwlcn.core.annotation.NotMutable; import com.hwlcn.core.annotation.ThreadSafety; import com.hwlcn.ldap.util.ThreadSafetyLevel; import static com.hwlcn.ldap.ldap.sdk.persist.PersistMessages.*; import static com.hwlcn.ldap.util.Debug.*; import static com.hwlcn.ldap.util.StaticUtils.*; import static com.hwlcn.ldap.util.Validator.*; @NotMutable() @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) public final class GetterInfo implements Serializable { private static final long serialVersionUID = 1578187843924054389L; private final boolean includeInAdd; private final boolean includeInModify; private final boolean includeInRDN; private final Class<?> containingClass; private final FilterUsage filterUsage; private final Method method; private final ObjectEncoder encoder; private final String attributeName; private final String[] objectClasses; GetterInfo(final Method m, final Class<?> c) throws LDAPPersistException { ensureNotNull(m, c); method = m; m.setAccessible(true); final LDAPGetter a = m.getAnnotation(LDAPGetter.class); if (a == null) { throw new LDAPPersistException(ERR_GETTER_INFO_METHOD_NOT_ANNOTATED.get( m.getName(), c.getName())); } final LDAPObject o = c.getAnnotation(LDAPObject.class); if (o == null) { throw new LDAPPersistException(ERR_GETTER_INFO_CLASS_NOT_ANNOTATED.get( c.getName())); } containingClass = c; includeInRDN = a.inRDN(); includeInAdd = (includeInRDN || a.inAdd()); includeInModify = ((! includeInRDN) && a.inModify()); filterUsage = a.filterUsage(); final int modifiers = m.getModifiers(); if (Modifier.isStatic(modifiers)) { throw new LDAPPersistException(ERR_GETTER_INFO_METHOD_STATIC.get( m.getName(), c.getName())); } final Type[] params = m.getGenericParameterTypes(); if (params.length > 0) { throw new LDAPPersistException(ERR_GETTER_INFO_METHOD_TAKES_ARGUMENTS.get( m.getName(), c.getName())); } try { encoder = a.encoderClass().newInstance(); } catch (Exception e) { debugException(e); throw new LDAPPersistException(ERR_GETTER_INFO_CANNOT_GET_ENCODER.get( a.encoderClass().getName(), m.getName(), c.getName(), getExceptionMessage(e)), e); } if (! encoder.supportsType(m.getGenericReturnType())) { throw new LDAPPersistException( ERR_GETTER_INFO_ENCODER_UNSUPPORTED_TYPE.get( encoder.getClass().getName(), m.getName(), c.getName(), String.valueOf(m.getGenericReturnType()))); } final String structuralClass; if (o.structuralClass().length() == 0) { structuralClass = getUnqualifiedClassName(c); } else { structuralClass = o.structuralClass(); } final String[] ocs = a.objectClass(); if ((ocs == null) || (ocs.length == 0)) { objectClasses = new String[] { structuralClass }; } else { objectClasses = ocs; } for (final String s : objectClasses) { if (! s.equalsIgnoreCase(structuralClass)) { boolean found = false; for (final String oc : o.auxiliaryClass()) { if (s.equalsIgnoreCase(oc)) { found = true; break; } } if (! found) { throw new LDAPPersistException(ERR_GETTER_INFO_INVALID_OC.get( m.getName(), c.getName(), s)); } } } final String attrName = a.attribute(); if ((attrName == null) || (attrName.length() == 0)) { final String methodName = m.getName(); if (methodName.startsWith("get") && (methodName.length() >= 4)) { attributeName = toInitialLowerCase(methodName.substring(3)); } else { throw new LDAPPersistException(ERR_GETTER_INFO_CANNOT_INFER_ATTR.get( methodName, c.getName())); } } else { attributeName = attrName; } } public Method getMethod() { return method; } public Class<?> getContainingClass() { return containingClass; } public boolean includeInAdd() { return includeInAdd; } public boolean includeInModify() { return includeInModify; } public boolean includeInRDN() { return includeInRDN; } public FilterUsage getFilterUsage() { return filterUsage; } public ObjectEncoder getEncoder() { return encoder; } public String getAttributeName() { return attributeName; } public String[] getObjectClasses() { return objectClasses; } AttributeTypeDefinition constructAttributeType() throws LDAPPersistException { return constructAttributeType(DefaultOIDAllocator.getInstance()); } AttributeTypeDefinition constructAttributeType(final OIDAllocator a) throws LDAPPersistException { return encoder.constructAttributeType(method, a); } Attribute encode(final Object o) throws LDAPPersistException { try { final Object methodValue = method.invoke(o); if (methodValue == null) { return null; } return encoder.encodeMethodValue(method, methodValue, attributeName); } catch (Exception e) { debugException(e); throw new LDAPPersistException(ERR_GETTER_INFO_CANNOT_ENCODE.get( method.getName(), containingClass.getName(), getExceptionMessage(e)), e); } } }