Ejemplo n.º 1
0
  public static Map<String, UiConfigImpl> getUiConfigs(Class<?> entityClass) {
    Map<String, UiConfigImpl> map = cache.get(entityClass);
    if (map == null || AppInfo.getStage() == Stage.DEVELOPMENT) {
      GenericGenerator genericGenerator =
          AnnotationUtils.getAnnotatedPropertyNameAndAnnotations(
                  entityClass, GenericGenerator.class)
              .get("id");
      boolean idAssigned =
          genericGenerator != null && "assigned".equals(genericGenerator.strategy());
      Map<String, NaturalId> naturalIds =
          AnnotationUtils.getAnnotatedPropertyNameAndAnnotations(entityClass, NaturalId.class);
      Set<String> hides = new HashSet<String>();
      map = new HashMap<String, UiConfigImpl>();
      PropertyDescriptor[] pds =
          org.springframework.beans.BeanUtils.getPropertyDescriptors(entityClass);
      for (PropertyDescriptor pd : pds) {
        String propertyName = pd.getName();
        if (pd.getReadMethod() == null
            || pd.getWriteMethod() == null
                && pd.getReadMethod().getAnnotation(UiConfig.class) == null) continue;
        Class<?> declaredClass = pd.getReadMethod().getDeclaringClass();
        Version version = pd.getReadMethod().getAnnotation(Version.class);
        if (version == null)
          try {
            Field f = declaredClass.getDeclaredField(propertyName);
            if (f != null) version = f.getAnnotation(Version.class);
          } catch (Exception e) {
          }
        if (version != null) continue;
        Transient trans = pd.getReadMethod().getAnnotation(Transient.class);
        if (trans == null)
          try {
            Field f = declaredClass.getDeclaredField(propertyName);
            if (f != null) trans = f.getAnnotation(Transient.class);
          } catch (Exception e) {
          }
        SearchableProperty searchableProperty =
            pd.getReadMethod().getAnnotation(SearchableProperty.class);
        if (searchableProperty == null)
          try {
            Field f = declaredClass.getDeclaredField(propertyName);
            if (f != null) searchableProperty = f.getAnnotation(SearchableProperty.class);
          } catch (Exception e) {
          }
        SearchableId searchableId = pd.getReadMethod().getAnnotation(SearchableId.class);
        if (searchableId == null)
          try {
            Field f = declaredClass.getDeclaredField(propertyName);
            if (f != null) searchableId = f.getAnnotation(SearchableId.class);
          } catch (Exception e) {
          }
        UiConfig uiConfig = pd.getReadMethod().getAnnotation(UiConfig.class);
        if (uiConfig == null)
          try {
            Field f = declaredClass.getDeclaredField(propertyName);
            if (f != null) uiConfig = f.getAnnotation(UiConfig.class);
          } catch (Exception e) {
          }

        if (uiConfig != null && uiConfig.hidden()) continue;
        if ("new".equals(propertyName)
            || !idAssigned && "id".equals(propertyName)
            || "class".equals(propertyName)
            || "fieldHandler".equals(propertyName)
            || pd.getReadMethod() == null
            || hides.contains(propertyName)) continue;
        Column columnannotation = pd.getReadMethod().getAnnotation(Column.class);
        if (columnannotation == null)
          try {
            Field f = declaredClass.getDeclaredField(propertyName);
            if (f != null) columnannotation = f.getAnnotation(Column.class);
          } catch (Exception e) {
          }
        Basic basic = pd.getReadMethod().getAnnotation(Basic.class);
        if (basic == null)
          try {
            Field f = declaredClass.getDeclaredField(propertyName);
            if (f != null) basic = f.getAnnotation(Basic.class);
          } catch (Exception e) {
          }
        Lob lob = pd.getReadMethod().getAnnotation(Lob.class);
        if (lob == null)
          try {
            Field f = declaredClass.getDeclaredField(propertyName);
            if (f != null) lob = f.getAnnotation(Lob.class);
          } catch (Exception e) {
          }
        UiConfigImpl uci = new UiConfigImpl(pd.getPropertyType(), uiConfig);
        if (idAssigned && propertyName.equals("id")) uci.addCssClass("required checkavailable");
        if (Attributable.class.isAssignableFrom(entityClass) && pd.getName().equals("attributes")) {
          uci.setType("attributes");
        }
        if (trans != null) {
          uci.setExcludedFromCriteria(true);
          uci.setExcludedFromLike(true);
          uci.setExcludedFromOrdering(true);
        }
        if (lob != null) {
          uci.setExcludedFromCriteria(true);
          if (uci.getMaxlength() == 0) uci.setMaxlength(2 * 1024 * 1024);
        }
        if (columnannotation != null && !columnannotation.nullable()
            || basic != null && !basic.optional()) uci.setRequired(true);
        if (columnannotation != null && columnannotation.length() != 255 && uci.getMaxlength() == 0)
          uci.setMaxlength(columnannotation.length());
        if (lob != null || uci.getMaxlength() > 255) uci.setExcludedFromOrdering(true);
        Class<?> returnType = pd.getPropertyType();
        if (returnType.isEnum()) {
          uci.setType("enum");
          try {
            returnType.getMethod("getName");
            uci.setListKey("name");
          } catch (NoSuchMethodException e) {
            uci.setListKey("top");
          }
          try {
            returnType.getMethod("getDisplayName");
            uci.setListValue("displayName");
          } catch (NoSuchMethodException e) {
            uci.setListValue(uci.getListKey());
          }
          map.put(propertyName, uci);
          continue;
        } else if (Persistable.class.isAssignableFrom(returnType)) {
          JoinColumn joincolumnannotation = pd.getReadMethod().getAnnotation(JoinColumn.class);
          if (joincolumnannotation == null)
            try {
              Field f = declaredClass.getDeclaredField(propertyName);
              if (f != null) joincolumnannotation = f.getAnnotation(JoinColumn.class);
            } catch (Exception e) {
            }
          if (joincolumnannotation != null && !joincolumnannotation.nullable())
            uci.setRequired(true);
          ManyToOne manyToOne = pd.getReadMethod().getAnnotation(ManyToOne.class);
          if (manyToOne == null)
            try {
              Field f = declaredClass.getDeclaredField(propertyName);
              if (f != null) manyToOne = f.getAnnotation(ManyToOne.class);
            } catch (Exception e) {
            }
          if (manyToOne != null && !manyToOne.optional()) uci.setRequired(true);
          uci.setType("listpick");
          uci.setExcludeIfNotEdited(true);
          if (StringUtils.isBlank(uci.getPickUrl())) {
            String url = AutoConfigPackageProvider.getEntityUrl(returnType);
            StringBuilder sb =
                url != null
                    ? new StringBuilder(url)
                    : new StringBuilder("/")
                        .append(StringUtils.uncapitalize(returnType.getSimpleName()));
            sb.append("/pick");
            Set<String> columns = new LinkedHashSet<String>();
            columns.addAll(
                AnnotationUtils.getAnnotatedPropertyNameAndAnnotations(returnType, NaturalId.class)
                    .keySet());
            Map<String, UiConfigImpl> configs = getUiConfigs(returnType);
            for (String column : "fullname,name,code".split(","))
              if (configs.containsKey(column)
                  && (!columns.contains("fullname") && column.equals("name")
                      || !column.equals("name"))) columns.add(column);
            for (Map.Entry<String, UiConfigImpl> entry : configs.entrySet())
              if (entry.getValue().isShownInPick()) columns.add(entry.getKey());
            if (!columns.isEmpty()) {
              sb.append("?columns=" + StringUtils.join(columns, ','));
            }
            uci.setPickUrl(sb.toString());
          }
          map.put(propertyName, uci);
          continue;
        }
        if (returnType == Integer.TYPE
            || returnType == Short.TYPE
            || returnType == Long.TYPE
            || returnType == Double.TYPE
            || returnType == Float.TYPE
            || Number.class.isAssignableFrom(returnType)) {
          if (returnType == Integer.TYPE
              || returnType == Integer.class
              || returnType == Short.TYPE
              || returnType == Short.class) {
            uci.setInputType("number");
            uci.addCssClass("integer");

          } else if (returnType == Long.TYPE || returnType == Long.class) {
            uci.setInputType("number");
            uci.addCssClass("long");
          } else if (returnType == Double.TYPE
              || returnType == Double.class
              || returnType == Float.TYPE
              || returnType == Float.class
              || returnType == BigDecimal.class) {
            uci.setInputType("number");
            uci.addCssClass("double");
          }
          Set<String> cssClasses = uci.getCssClasses();
          if (cssClasses.contains("double") && !uci.getDynamicAttributes().containsKey("step"))
            uci.getDynamicAttributes().put("step", "0.01");
          if (cssClasses.contains("positive") && !uci.getDynamicAttributes().containsKey("min")) {
            uci.getDynamicAttributes().put("min", "1");
            if (cssClasses.contains("double")) uci.getDynamicAttributes().put("min", "0.01");
            if (cssClasses.contains("zero")) uci.getDynamicAttributes().put("min", "0");
          }
        } else if (Date.class.isAssignableFrom(returnType)) {
          Temporal temporal = pd.getReadMethod().getAnnotation(Temporal.class);
          if (temporal == null)
            try {
              Field f = declaredClass.getDeclaredField(propertyName);
              if (f != null) temporal = f.getAnnotation(Temporal.class);
            } catch (Exception e) {
            }
          String temporalType = "date";
          if (temporal != null)
            if (temporal.value() == TemporalType.TIMESTAMP) temporalType = "datetime";
            else if (temporal.value() == TemporalType.TIME) temporalType = "time";
          uci.addCssClass(temporalType);
          // uci.setInputType(temporalType);
          if (StringUtils.isBlank(uci.getCellEdit())) uci.setCellEdit("click," + temporalType);
        } else if (String.class == returnType
            && pd.getName().toLowerCase().contains("email")
            && !pd.getName().contains("Password")) {
          uci.setInputType("email");
          uci.addCssClass("email");
        } else if (returnType == Boolean.TYPE || returnType == Boolean.class) {
          uci.setType("checkbox");
        }
        if (columnannotation != null && columnannotation.unique()) uci.setUnique(true);
        if (searchableProperty != null || searchableId != null) uci.setSearchable(true);

        if (naturalIds.containsKey(pd.getName())) {
          uci.setRequired(true);
          if (naturalIds.size() == 1) uci.addCssClass("checkavailable");
        }
        map.put(propertyName, uci);
      }
      List<Map.Entry<String, UiConfigImpl>> list =
          new ArrayList<Map.Entry<String, UiConfigImpl>>(map.entrySet());
      Collections.sort(list, comparator);
      Map<String, UiConfigImpl> sortedMap = new LinkedHashMap<String, UiConfigImpl>();
      for (Map.Entry<String, UiConfigImpl> entry : list)
        sortedMap.put(entry.getKey(), entry.getValue());
      map = sortedMap;
      cache.put(entityClass, Collections.unmodifiableMap(map));
    }
    return map;
  }
  private void readField(DeployBeanProperty prop) {

    // all Enums will have a ScalarType assigned...
    boolean isEnum = prop.getPropertyType().isEnum();
    Enumerated enumerated = get(prop, Enumerated.class);
    if (isEnum || enumerated != null) {
      util.setEnumScalarType(enumerated, prop);
    }

    // its persistent and assumed to be on the base table
    // rather than on a secondary table
    prop.setDbRead(true);
    prop.setDbInsertable(true);
    prop.setDbUpdateable(true);

    Column column = get(prop, Column.class);
    if (column != null) {
      readColumn(column, prop);
    }
    Expose expose = get(prop, Expose.class);
    if (expose != null) {
      prop.setExposeSerialize(expose.serialize());
      prop.setExposeDeserialize(expose.deserialize());
    }

    if (prop.getDbColumn() == null) {
      // No @Column annotation or @Column.name() not set
      // Use the NamingConvention to set the DB column name
      String dbColumn = namingConvention.getColumnFromProperty(beanType, prop.getName());
      prop.setDbColumn(dbColumn);
    }

    GeneratedValue gen = get(prop, GeneratedValue.class);
    if (gen != null) {
      readGenValue(gen, prop);
    }

    Id id = (Id) get(prop, Id.class);
    if (id != null) {
      readId(id, prop);
    }

    // determine the JDBC type using Lob/Temporal
    // otherwise based on the property Class
    Lob lob = get(prop, Lob.class);
    Temporal temporal = get(prop, Temporal.class);
    if (temporal != null) {
      readTemporal(temporal, prop);

    } else if (lob != null) {
      util.setLobType(prop);
    }

    Formula formula = get(prop, Formula.class);
    if (formula != null) {
      prop.setSqlFormula(formula.select(), formula.join());
    }

    Version version = get(prop, Version.class);
    if (version != null) {
      // explicitly specify a version column
      prop.setVersionColumn(true);
      generatedPropFactory.setVersion(prop);
    }

    Basic basic = get(prop, Basic.class);
    if (basic != null) {
      prop.setFetchType(basic.fetch());
      if (!basic.optional()) {
        prop.setNullable(false);
      }
    } else if (prop.isLob()) {
      // use the default Lob fetchType
      prop.setFetchType(defaultLobFetchType);
    }

    CreatedTimestamp ct = get(prop, CreatedTimestamp.class);
    if (ct != null) {
      generatedPropFactory.setInsertTimestamp(prop);
    }

    UpdatedTimestamp ut = get(prop, UpdatedTimestamp.class);
    if (ut != null) {
      generatedPropFactory.setUpdateTimestamp(prop);
    }

    if (validationAnnotations) {
      NotNull notNull = get(prop, NotNull.class);
      if (notNull != null && isNotNullOnAllValidationGroups(notNull.groups())) {
        // Not null on all validation groups so enable
        // DDL generation of Not Null Constraint
        prop.setNullable(false);
      }

      Size size = get(prop, Size.class);
      if (size != null) {
        if (size.max() < Integer.MAX_VALUE) {
          // explicitly specify a version column
          prop.setDbLength(size.max());
        }
      }
    }

    EmbeddedColumns columns = get(prop, EmbeddedColumns.class);
    if (columns != null) {
      if (prop instanceof DeployBeanPropertyCompound) {
        DeployBeanPropertyCompound p = (DeployBeanPropertyCompound) prop;

        // convert into a Map
        String propColumns = columns.columns();
        Map<String, String> propMap = StringHelper.delimitedToMap(propColumns, ",", "=");

        p.getDeployEmbedded().putAll(propMap);

        CtCompoundType<?> compoundType = p.getCompoundType();
        if (compoundType == null) {
          throw new RuntimeException("No registered CtCompoundType for " + p.getPropertyType());
        }

      } else {
        throw new RuntimeException(
            "Can't use EmbeddedColumns on ScalarType " + prop.getFullBeanName());
      }
    }

    // Want to process last so we can use with @Formula
    Transient t = get(prop, Transient.class);
    if (t != null) {
      // it is not a persistent property.
      prop.setDbRead(false);
      prop.setDbInsertable(false);
      prop.setDbUpdateable(false);
      prop.setTransient(true);
    }

    if (!prop.isTransient()) {

      EncryptDeploy encryptDeploy =
          util.getEncryptDeploy(info.getDescriptor().getBaseTableFull(), prop.getDbColumn());
      if (encryptDeploy == null || encryptDeploy.getMode().equals(Mode.MODE_ANNOTATION)) {
        Encrypted encrypted = get(prop, Encrypted.class);
        if (encrypted != null) {
          setEncryption(prop, encrypted.dbEncryption(), encrypted.dbLength());
        }
      } else if (Mode.MODE_ENCRYPT.equals(encryptDeploy.getMode())) {
        setEncryption(prop, encryptDeploy.isDbEncrypt(), encryptDeploy.getDbLength());
      }
    }

    Index index = get(prop, Index.class);
    if (index != null) {
      if (hasRelationshipItem(prop)) {
        throw new RuntimeException("Can't use Index on foreign key relationships.");
      }
      prop.setIndexed(true);
      prop.setIndexName(index.value());
    }
  }