Contribution : retrieving a graph of CUBA objects with arbitrary depth

Small contribution to the community. During our tests we found the need to load entities with their embedded properties. Embedded properties are modelized as compositions so CUBA local view does not load them. Instead of defining manually a view for each entity (we have tons of them), I came to a solution by defining arbitrary views in a generic way (code below), inspired by the import/export service but lighter. Probably not perfect but does very well the job in our tests. Hopes it can help someone, and any criticism is welcome.

 /**
     * Creates a view that will fetch all local attributes plus any referenced objects recursively,
     * being single references or collection of them. The resulting object graph depth/level
     * is parameterized, and a class met a second time is not traversed anymore to save perf. 
     * Notably a one level graph is useful to be sure embedded entities are retrieved, as they are 
     * modelized as compositions.
     */

    @SuppressWarnings("unchecked")
    public static <T extends Entity> View createViewGraph(@NonNull Class<T> entityClass, int level, boolean includeSysProp) {
        return createViewGraph(entityClass, level, includeSysProp, new HashSet<>());
    }

    @SuppressWarnings("unchecked")
    protected static <T extends Entity> View createViewGraph(@NonNull Class<T> entityClass, int level, boolean includeSysProp, @NonNull Set<MetaClass> known) {
        Metadata metadata = AppBeans.get(Metadata.class);
        MetaClass meta = metadata.getClassNN(entityClass);
        known.add(meta);
        View view = new View(meta.getJavaClass(), "graph", true);
        for (MetaProperty metaProperty : meta.getProperties()) {
            if (metaProperty.isReadOnly()) {
                continue;
            }
            switch (metaProperty.getType()) {
                case DATATYPE:
                case ENUM:
                    view.addProperty(metaProperty.getName());
                    break;
                case ASSOCIATION:
                case COMPOSITION:
                    if (level <= 0) break;
                    // if meta class has already been encountered stay local
                    // to limit redundancies and save time
                    View propView =
                            known.contains(metaProperty.getRange().asClass())
                                    ? metadata.getViewRepository().getView(metaProperty.getRange().asClass(), View.LOCAL)
                                    : createViewGraph(metaProperty.getRange().asClass().getJavaClass(), level - 1, includeSysProp, known);
                    view.addProperty(metaProperty.getName(),
                            new View(propView, metaProperty.getRange().asClass().getName() + ".graph", includeSysProp));
                    break;
                default:
                    throw new IllegalStateException("unknown property type");
            }
        }
        return view;
    }