Exemplo n.º 1
0
  /**
   * Creates a simple property from given definition and given value.
   *
   * <p>If the property is a boolean, it is true if the value is non-null.
   *
   * <p>If the property has enumerated possible values, the value is compared to them in case
   * insensitive manner.
   *
   * @param definition the definition of the property to create
   * @param value the value of the property
   * @return a new simple property
   */
  public static PropertySimple createPropertySimple(
      PropertyDefinitionSimple definition, String value) {
    String name = definition.getName();
    if (definition.getType() == PropertySimpleType.BOOLEAN) {
      return new PropertySimple(name, value != null);
    }

    if (!definition.getEnumeratedValues().isEmpty()) {
      // options with empty values correspond to null values
      if (value == null) value = "";

      // apache configuration values are usually case-insensitive.
      String valLowerCase = value.toLowerCase();
      for (PropertyDefinitionEnumeration option : definition.getEnumeratedValues()) {
        if (option.getValue().toLowerCase().equals(valLowerCase)) {
          value = option.getValue();
        }
      }
    }

    return new PropertySimple(name, value);
  }
  /**
   * Update objects of type on:property (simple-property, map-property, list-property
   *
   * @param existingProperty
   * @param newProperty
   */
  private void updatePropertyDefinition(
      PropertyDefinition existingProperty, PropertyDefinition newProperty) {
    existingProperty.setDescription(newProperty.getDescription());
    existingProperty.setDisplayName(newProperty.getDisplayName());
    existingProperty.setActivationPolicy(newProperty.getActivationPolicy());
    existingProperty.setVersion(newProperty.getVersion());
    existingProperty.setRequired(newProperty.isRequired());
    existingProperty.setReadOnly(newProperty.isReadOnly());
    existingProperty.setSummary(newProperty.isSummary());
    existingProperty.setPropertyGroupDefinition(newProperty.getPropertyGroupDefinition());

    /*
     * After the general things have been set, go through the subtypes of PropertyDefinition. If the new type is the
     * same as the old, we update. Else we simply replace
     */

    if (existingProperty instanceof PropertyDefinitionMap) {
      if (newProperty instanceof PropertyDefinitionMap) {

        // alter existingPropDefs to reflect newPropDefs
        Map<String, PropertyDefinition> existingPropDefs =
            ((PropertyDefinitionMap) existingProperty).getMap();

        Map<String, PropertyDefinition> newPropDefs =
            ((PropertyDefinitionMap) newProperty).getMap();
        Set<String> newKeys = newPropDefs.keySet();

        // remove obsolete propDefs
        List<String> doomedKeys = new ArrayList<String>();
        for (String existingKey : existingPropDefs.keySet()) {
          if (!newKeys.contains(existingKey)) {
            doomedKeys.add(existingKey);
          }
        }
        for (String doomedKey : doomedKeys) {
          PropertyDefinition doomed = existingPropDefs.get(doomedKey);
          existingPropDefs.remove(doomedKey);
          entityManager.remove(
              entityManager.getReference(PropertyDefinition.class, doomed.getId()));
        }

        int order = 0;
        for (String key : newKeys) {
          PropertyDefinition existingPropDef = existingPropDefs.get(key);
          PropertyDefinition newPropDef = newPropDefs.get(key);
          if (null == existingPropDef) {
            newPropDef.setOrder(order++);
            newPropDef.setParentPropertyMapDefinition((PropertyDefinitionMap) existingProperty);
            entityManager.persist(newPropDef);
            existingPropDefs.put(key, newPropDef);
          } else {
            existingPropDef.setOrder(order++);
            updatePropertyDefinition(existingPropDef, newPropDef);
          }
        }

        existingProperty = entityManager.merge(existingProperty);

      } else { // different type

        replaceProperty(existingProperty, newProperty);
      }
    } else if (existingProperty instanceof PropertyDefinitionList) {
      PropertyDefinitionList exList = (PropertyDefinitionList) existingProperty;
      if (newProperty instanceof PropertyDefinitionList) {
        PropertyDefinitionList newList = (PropertyDefinitionList) newProperty;
        replaceListProperty(exList, newList);
      } else { // simple property or map-property
        replaceProperty(existingProperty, newProperty);
      }
    } else if (existingProperty instanceof PropertyDefinitionSimple) {
      PropertyDefinitionSimple existingPDS = (PropertyDefinitionSimple) existingProperty;

      if (newProperty instanceof PropertyDefinitionSimple) {
        PropertyDefinitionSimple newPDS = (PropertyDefinitionSimple) newProperty;

        existingPDS.setType(newPDS.getType());

        // handle <property-options>?
        List<PropertyDefinitionEnumeration> existingOptions = existingPDS.getEnumeratedValues();
        List<PropertyDefinitionEnumeration> newOptions = newPDS.getEnumeratedValues();

        List<PropertyDefinitionEnumeration> toPersist =
            missingInFirstList(existingOptions, newOptions);
        List<PropertyDefinitionEnumeration> toDelete =
            missingInFirstList(newOptions, existingOptions);
        List<PropertyDefinitionEnumeration> changed = intersection(existingOptions, newOptions);

        // sync the enumerated values and then merge the changes into the PDS, I think this
        // solves previous issues with orderIndex values.
        // First remove obsolete values
        for (PropertyDefinitionEnumeration pde : toDelete) {
          existingPDS.removeEnumeratedValues(pde);
        }

        // save new ones
        for (PropertyDefinitionEnumeration pde : toPersist) {
          existingPDS.addEnumeratedValues(pde);
          entityManager.persist(pde);
        }

        // update others
        for (PropertyDefinitionEnumeration pde : changed) {
          for (PropertyDefinitionEnumeration nPde : newOptions) {
            if (nPde.equals(pde)) {
              pde.setValue(nPde.getValue());
              pde.setName(nPde.getName());
            }
          }
        }
        existingPDS = entityManager.merge(existingPDS);

        // handle <constraint> [0..*]

        Set<Constraint> exCon = existingPDS.getConstraints();
        if (exCon.size() > 0) {
          for (Constraint con : exCon) {
            con.setPropertyDefinitionSimple(null);
            entityManager.remove(con);
          }

          existingPDS.getConstraints().clear(); // clear out existing
        }

        for (Constraint con : newPDS.getConstraints()) {
          existingPDS.addConstraints(con);
        }

        // handle <defaultValue> [0..1]
        existingPDS.setDefaultValue(newPDS.getDefaultValue());

        // handle <c:source>
        existingPDS.setOptionsSource(newPDS.getOptionsSource());
      } else {
        // other type
        replaceProperty(existingProperty, newProperty);
      }
    }
  }