private void generateView( Map<String, DesignDocument.View> views, Method me, Class<?> handledType) { String name = me.getName(); if (!name.startsWith("findBy") && !name.equals("getAll")) { throw new ViewGenerationException( String.format( "The method: %s in %s annotated with GenerateView does not conform to the naming convention of 'findByXxxx'", name, me.getDeclaringClass())); } Class<?> type = resolveReturnType(me); if (type == null) { if (handledType != null) { type = handledType; } else { throw new ViewGenerationException( "Could not resolve return type for method: %s in %s", me.getName(), me.getDeclaringClass()); } } String typeDiscriminator = resolveTypeDiscriminator(type); if (name.equals("getAll")) { if (typeDiscriminator.length() < 1) { throw new ViewGenerationException( String.format( "Cannot generate 'all' view for %s. No type discriminator could be resolved. Try annotate unique field(s) with @TypeDiscriminator", type.getDeclaringClass())); } views.put("all", generateAllView(typeDiscriminator)); return; } String finderName = name.substring(6); String fieldName = resolveFieldName(me, finderName); Method getter = findMethod(type, "get" + fieldName); if (getter == null) { // try pluralis fieldName += "s"; getter = findMethod(type, "get" + fieldName); } if (getter == null) { throw new ViewGenerationException( "Could not generate view for method %s. No get method found for property %s in %s", name, name.substring(6), type); } fieldName = firstCharToLowerCase(fieldName); DesignDocument.View view; if (isIterable(getter.getReturnType())) { view = generateFindByIterableView(fieldName, typeDiscriminator); } else { view = generateFindByView(fieldName, typeDiscriminator); } views.put("by_" + firstCharToLowerCase(finderName), view); }
private Class<?> resolveReturnType(Method me) { Type returnType = me.getGenericReturnType(); if (returnType instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) returnType; Type[] typeArguments = type.getActualTypeArguments(); for (Type typeArgument : typeArguments) { if (typeArgument instanceof Class<?>) { return (Class<?>) typeArgument; } } return null; } return (Class<?>) returnType; }
protected void generateView( Map<String, org.ektorp.support.DesignDocument.View> views, Method me) { DocumentReferences referenceMetaData = me.getAnnotation(DocumentReferences.class); if (referenceMetaData == null) { LOG.warn("No DocumentReferences annotation found in method: ", me.getName()); return; } if (!me.getName().startsWith("get")) { throw new ViewGenerationException( String.format( "The method: %s in %s annotated with DocumentReferences does not conform to the naming convention of 'getXxxx'", me.getName(), me.getDeclaringClass())); } if (Set.class.isAssignableFrom(me.getReturnType())) { generateSetBasedDocRefView(views, me, referenceMetaData); } else { throw new ViewGenerationException( String.format( "The return type of: %s in %s annotated with DocumentReferences is not supported. (Must be assignable from java.util.Set)", me.getName(), me.getDeclaringClass())); } }
private String resolveFieldName(Method me, String finderName) { GenerateView g = me.getAnnotation(GenerateView.class); String field = g.field(); return field.length() == 0 ? finderName : g.field(); }