@@ -583,32 +583,30 @@ private void findConstructor() {
583583 }
584584
585585 private PropertyDefinition getOrCreateProperty (String name , Map <String , PropertyDefinition > properties ) {
586- PropertyDefinition thisProperty = properties .get (name );
587- if (thisProperty == null ) {
588- thisProperty = new PropertyDefinition (name , mapper );
589- properties .put (name , thisProperty );
590- }
591- return thisProperty ;
586+ return properties .computeIfAbsent (name , n -> new PropertyDefinition (n , mapper ));
592587 }
593588
594589 private void loadPropertiesFromClass () {
595590 Map <String , PropertyDefinition > properties = new HashMap <>();
596- PropertyDefinition keyProperty = null ;
597591 KeyConfig keyConfig = config != null ? config .getKey () : null ;
598- for (Method thisMethod : clazz .getDeclaredMethods ()) {
599592
593+ PropertyDefinition keyProperty = null ;
594+ PropertyDefinition generationProperty = null ;
595+
596+ for (Method thisMethod : clazz .getDeclaredMethods ()) {
600597 String methodName = thisMethod .getName ();
601598 BinConfig getterConfig = getBinFromGetter (methodName );
602599 BinConfig setterConfig = getBinFromSetter (methodName );
603600
604601 boolean isKey = false ;
605602 boolean isKeyViaConfig = keyConfig != null
606603 && (keyConfig .isGetter (methodName ) || keyConfig .isSetter (methodName ));
607- if (thisMethod .isAnnotationPresent (AerospikeKey .class ) || isKeyViaConfig ) {
608604
605+ if (thisMethod .isAnnotationPresent (AerospikeKey .class ) || isKeyViaConfig ) {
609606 if (keyProperty == null ) {
610607 keyProperty = new PropertyDefinition ("_key_" , mapper );
611608 }
609+
612610 if (isKeyViaConfig ) {
613611 if (keyConfig .isGetter (methodName )) {
614612 keyProperty .setGetter (thisMethod );
@@ -623,11 +621,16 @@ private void loadPropertiesFromClass() {
623621 keyProperty .setGetter (thisMethod );
624622 }
625623 }
624+
626625 isKey = true ;
627626 }
628627
629628 // Handle @AerospikeGeneration annotation on methods (getters/setters)
630629 if (thisMethod .isAnnotationPresent (AerospikeGeneration .class )) {
630+ if (generationProperty == null ) {
631+ generationProperty = new PropertyDefinition ("_generation_" , mapper );
632+ }
633+
631634 // For getter methods, validate return type
632635 if (methodName .startsWith ("get" )) {
633636 Class <?> returnType = thisMethod .getReturnType ();
@@ -636,24 +639,29 @@ private void loadPropertiesFromClass() {
636639 "@AerospikeGeneration getter %s in class %s must return Integer or int type, but returned %s" ,
637640 methodName , clazz .getName (), returnType .getSimpleName ()));
638641 }
642+ generationProperty .setGetter (thisMethod );
639643 }
640644
641645 // For setter methods, validate parameter type
642- if (methodName .startsWith ("set" ) && thisMethod .getParameterCount () == 1 ) {
646+ else if (methodName .startsWith ("set" )) {
647+ if (thisMethod .getParameterCount () != 1 ) {
648+ throw new AerospikeException (String .format (
649+ "@AerospikeGeneration setter %s in class %s must accept a single parameter, but %d were found" ,
650+ methodName , clazz .getName (), thisMethod .getParameterCount ()));
651+ }
643652 Class <?> paramType = thisMethod .getParameterTypes ()[0 ];
644653 if (!paramType .equals (Integer .class ) && !paramType .equals (int .class )) {
645654 throw new AerospikeException (String .format (
646655 "@AerospikeGeneration setter %s in class %s must accept Integer or int type, but accepted %s" ,
647656 methodName , clazz .getName (), paramType .getSimpleName ()));
648657 }
658+ generationProperty .setSetter (thisMethod );
649659 }
650-
651- // We'll handle the generation property creation after processing all methods
652- // to ensure we can pair getters and setters properly
653660 }
654661
655662 if (thisMethod .isAnnotationPresent (AerospikeGetter .class ) || getterConfig != null ) {
656- String getterName = (getterConfig != null ) ? getterConfig .getName ()
663+ String getterName = (getterConfig != null )
664+ ? getterConfig .getName ()
657665 : thisMethod .getAnnotation (AerospikeGetter .class ).name ();
658666
659667 String name = ParserUtils .getInstance ().get (ParserUtils .getInstance ().get (getterName ));
@@ -665,54 +673,41 @@ private void loadPropertiesFromClass() {
665673 }
666674
667675 if (thisMethod .isAnnotationPresent (AerospikeSetter .class ) || setterConfig != null ) {
668- String setterName = (setterConfig != null ) ? setterConfig .getName ()
676+ String setterName = (setterConfig != null )
677+ ? setterConfig .getName ()
669678 : thisMethod .getAnnotation (AerospikeSetter .class ).name ();
679+
670680 String name = ParserUtils .getInstance ().get (ParserUtils .getInstance ().get (setterName ));
671681 PropertyDefinition thisProperty = getOrCreateProperty (name , properties );
672682 thisProperty .setSetter (thisMethod );
673683 }
674684 }
675685
676686 if (keyProperty != null ) {
677- keyProperty .validate (clazz .getName (), config , true );
678-
679687 if (key != null ) {
680688 throw new AerospikeException (String .format ("Class %s cannot have more than one key" , clazz .getName ()));
681689 }
682690
691+ keyProperty .validate (clazz .getName (), config , true );
692+
683693 AnnotatedType annotatedType = new AnnotatedType (config , keyProperty .getGetter ());
684694 TypeMapper typeMapper = TypeUtils .getMapper (keyProperty .getType (), annotatedType , this .mapper );
685695 this .key = new ValueType .MethodValue (keyProperty , typeMapper , annotatedType );
686696 }
687697
688- // Handle @AerospikeGeneration annotation on methods - find getter/setter pairs
689- PropertyDefinition generationProperty = null ;
690- for (Method thisMethod : clazz .getDeclaredMethods ()) {
691- if (thisMethod .isAnnotationPresent (AerospikeGeneration .class )) {
692- if (generationProperty == null ) {
693- generationProperty = new PropertyDefinition ("_generation_" , mapper );
694- }
695-
696- String methodName = thisMethod .getName ();
697- if (methodName .startsWith ("get" )) {
698- generationProperty .setGetter (thisMethod );
699- } else if (methodName .startsWith ("set" )) {
700- generationProperty .setSetter (thisMethod );
701- }
702- }
703- }
704-
705698 if (generationProperty != null ) {
706699 if (generationField != null ) {
707700 throw new AerospikeException (
708701 String .format ("Class %s cannot have more than one @AerospikeGeneration field" , clazz .getName ()));
709702 }
710703
711704 generationProperty .validate (clazz .getName (), config , false );
705+
712706 AnnotatedType annotatedType = new AnnotatedType (config , generationProperty .getGetter ());
713707 TypeMapper typeMapper = TypeUtils .getMapper (generationProperty .getType (), annotatedType , this .mapper );
714708 this .generationField = new ValueType .MethodValue (generationProperty , typeMapper , annotatedType );
715709 }
710+
716711 for (String thisPropertyName : properties .keySet ()) {
717712 PropertyDefinition thisProperty = properties .get (thisPropertyName );
718713 thisProperty .validate (clazz .getName (), config , false );
@@ -731,15 +726,13 @@ private void loadPropertiesFromClass() {
731726
732727 private void loadFieldsFromClass () {
733728 for (Field thisField : this .clazz .getDeclaredFields ()) {
734- boolean isKey = false ;
735729 BinConfig thisBin = getBinFromField (thisField );
736730
737731 if (Modifier .isFinal (thisField .getModifiers ()) && Modifier .isStatic (thisField .getModifiers ())) {
738732 // We cannot map static final fields
739733 continue ;
740734 }
741735
742- isKey = handleKeyField (thisField , thisBin );
743736 boolean isGenerationField = this .handleGenerationField (thisField , thisBin );
744737 if (thisField .isAnnotationPresent (AerospikeExclude .class )
745738 || (thisBin != null && thisBin .isExclude () != null && thisBin .isExclude ())) {
@@ -755,6 +748,7 @@ private void loadFieldsFromClass() {
755748
756749 if (this .mapAll || thisField .isAnnotationPresent (AerospikeBin .class ) || thisBin != null ) {
757750 // This field needs to be mapped
751+ boolean isKey = handleKeyField (thisField , thisBin );
758752 mapField (thisField , thisBin , isKey );
759753 }
760754 }
@@ -774,6 +768,7 @@ private boolean handleKeyField(Field thisField, BinConfig thisBin) {
774768 if (key != null ) {
775769 throw new AerospikeException (String .format ("Class %s cannot have more than one key" , clazz .getName ()));
776770 }
771+
777772 AerospikeKey keyAnnotation = thisField .getAnnotation (AerospikeKey .class );
778773 boolean storeAsBin = keyAnnotation == null || keyAnnotation .storeAsBin ();
779774
@@ -864,8 +859,7 @@ private void mapField(Field thisField, BinConfig thisBin, boolean isKey) {
864859 private Method findMethodWithNameAndParams (String name , Class <?>... params ) {
865860 try {
866861 Method method = this .clazz .getDeclaredMethod (name , params );
867- // TODO: Should this ascend the inheritance hierarchy using getMethod on
868- // superclasses?
862+ // TODO: Should this ascend the inheritance hierarchy using getMethod on superclasses?
869863 return method ;
870864 } catch (NoSuchMethodException nsme ) {
871865 return null ;
@@ -881,7 +875,8 @@ private void validateAccessorsForField(String binName, Field thisField) {
881875 Method getter = findMethodWithNameAndParams (getterName );
882876 if (getter == null ) {
883877 throw new AerospikeException (String .format (
884- "Expected to find getter for field %s on class %s due to it being configured to useAccessors, but no method with the signature \" %s %s()\" was found" ,
878+ "Expected to find getter for field %s on class %s due to it being configured to useAccessors," +
879+ " but no method with the signature \" %s %s()\" was found" ,
885880 fieldName , this .clazz .getSimpleName (), thisField .getType ().getSimpleName (), getterName ));
886881 }
887882
@@ -894,7 +889,8 @@ private void validateAccessorsForField(String binName, Field thisField) {
894889 }
895890 if (setter == null ) {
896891 throw new AerospikeException (String .format (
897- "Expected to find setter for field %s on class %s due to it being configured to useAccessors, but no method with the name \" %s\" was found" ,
892+ "Expected to find setter for field %s on class %s due to it being configured to useAccessors," +
893+ " but no method with the name \" %s\" was found" ,
898894 fieldName , this .clazz .getSimpleName (), setterName ));
899895 }
900896
@@ -927,7 +923,7 @@ public Object getKey(Object object) {
927923 Object key = this ._getKey (object );
928924 if (key == null ) {
929925 throw new AerospikeException (String .format (
930- "Null key from annotated object of class %s." + " Did you forget an @AerospikeKey annotation?" ,
926+ "Null key from annotated object of class %s. Did you forget an @AerospikeKey annotation?" ,
931927 this .clazz .getSimpleName ()));
932928 }
933929 return key ;
0 commit comments