/**
  * Returns a List of paths, being the given path and all its parents.
  *
  * @param pathString a path String
  * @param pathQuery a PathQuery object to use to create a Path object
  * @return a List of path Strings
  * @throws PathException if something goes wrong
  */
 protected static List<String> findParentPaths(String pathString, PathQuery pathQuery)
     throws PathException {
   Path path = pathQuery.makePath(pathString);
   List<String> retval = new ArrayList<String>();
   retval.add(path.getNoConstraintsString());
   while (!path.isRootPath()) {
     path = path.getPrefix();
     retval.add(path.getNoConstraintsString());
   }
   return retval;
 }
  /**
   * Return a list of string paths that are defined as WebConfig to be shown in results. This will
   * include attributes of the given class and follow references.
   *
   * @param type the class name to create a view for
   * @param model the model
   * @param webConfig we configuration
   * @return the configured view paths for the class
   */
  public static List<String> getDefaultViewForClass(String type, Model model, WebConfig webConfig) {
    List<String> view = new ArrayList<String>();
    ClassDescriptor cld = model.getClassDescriptorByName(type);
    List<FieldConfig> fieldConfigs = FieldConfigHelper.getClassFieldConfigs(webConfig, cld);

    for (FieldConfig fieldConfig : fieldConfigs) {
      String relPath = fieldConfig.getFieldExpr();
      // only add attributes, don't follow references, following references can be problematic
      // when subclasses get involved.
      if (fieldConfig.getShowInResults()) {
        try {
          Path path = new Path(model, type + "." + relPath);
          // add references
          if (path.isRootPath() || path.endIsReference()) {
            for (FieldConfig fc :
                FieldConfigHelper.getClassFieldConfigs(webConfig, path.getEndClassDescriptor())) {
              Path pathToAdd =
                  new Path(model, path.toStringNoConstraints() + "." + fc.getFieldExpr());
              if (pathToAdd.endIsAttribute()
                  && (!view.contains(pathToAdd.getNoConstraintsString()))
                  && (fc.getDisplayer() == null && fc.getShowInSummary())) {
                view.add(pathToAdd.getNoConstraintsString());
              }
            }
            // add collections
          } else if (!path.endIsCollection()) {
            view.add(path.getNoConstraintsString());
          }
        } catch (PathException e) {
          LOG.error("Invalid path configured in webconfig for class: " + type);
        }
      }
    }
    if (view.size() == 0) {
      for (AttributeDescriptor att : cld.getAllAttributeDescriptors()) {
        if (!"id".equals(att.getName())) {
          view.add(type + "." + att.getName());
        }
      }
    }
    return view;
  }
 /**
  * Get the view as configured in the webconfig. Guarantees to return a non-empty non-null list.
  *
  * @param type The type we are trying to get a view for.
  * @param model The data model
  * @param webConfig The web-configuration.
  * @param fieldConfigs
  * @return The list of paths that we can use to construct a query.
  * @throws UnconfiguredException if the class has not configured view.
  */
 private static List<String> getConfiguredView(ClassDescriptor cld, WebConfig webConfig)
     throws UnconfiguredException {
   Collection<String> view = new LinkedHashSet<String>(); // Preserve order and uniqueness.
   Model m = cld.getModel();
   for (FieldConfig fieldConfig : resultConfigs(webConfig, cld)) {
     try {
       Path p = new Path(m, cld.getUnqualifiedName() + "." + fieldConfig.getFieldExpr());
       // add subpaths of references and roots, attrs themselves, ignore collections.
       if (p.isRootPath() || p.endIsReference()) {
         view.addAll(getSubview(webConfig, m, p));
       } else if (p.endIsAttribute()) {
         view.add(p.getNoConstraintsString());
       }
     } catch (PathException e) {
       LOG.error("Invalid path configured in webconfig for class: " + cld);
     }
   }
   if (view.isEmpty()) {
     throw new UnconfiguredException();
   }
   return new ArrayList<String>(view);
 }