Package org.structr.schema

Source Code of org.structr.schema.SchemaHelper

/**
* Copyright (C) 2010-2014 Morgner UG (haftungsbeschränkt)
*
* This file is part of Structr <http://structr.org>.
*
* Structr is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Structr is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Structr.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.structr.schema;

import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.neo4j.graphdb.PropertyContainer;
import org.structr.common.CaseHelper;
import org.structr.common.GraphObjectComparator;
import org.structr.common.PropertyView;
import org.structr.common.SecurityContext;
import org.structr.common.ValidationHelper;
import org.structr.common.View;
import org.structr.common.error.ErrorBuffer;
import org.structr.common.error.FrameworkException;
import org.structr.common.error.InvalidPropertySchemaToken;
import org.structr.core.Export;
import org.structr.core.GraphObject;
import org.structr.core.app.App;
import org.structr.core.app.StructrApp;
import org.structr.core.entity.DynamicResourceAccess;
import org.structr.core.entity.ResourceAccess;
import org.structr.core.entity.SchemaNode;
import org.structr.core.entity.relationship.SchemaRelationship;
import org.structr.core.graph.NodeAttribute;
import org.structr.core.parser.Functions;
import org.structr.core.property.PropertyKey;
import org.structr.schema.action.ActionContext;
import org.structr.schema.action.ActionEntry;
import org.structr.schema.action.Actions;
import org.structr.schema.parser.BooleanPropertyParser;
import org.structr.schema.parser.CountPropertyParser;
import org.structr.schema.parser.CypherPropertyParser;
import org.structr.schema.parser.DatePropertyParser;
import org.structr.schema.parser.DoublePropertyParser;
import org.structr.schema.parser.EnumPropertyParser;
import org.structr.schema.parser.FunctionPropertyParser;
import org.structr.schema.parser.IntPropertyParser;
import org.structr.schema.parser.JoinPropertyParser;
import org.structr.schema.parser.LongPropertyParser;
import org.structr.schema.parser.NotionPropertyParser;
import org.structr.schema.parser.PropertyParser;
import org.structr.schema.parser.StringArrayPropertyParser;
import org.structr.schema.parser.StringPropertyParser;
import org.structr.schema.parser.Validator;

/**
*
* @author Christian Morgner
*/
public class SchemaHelper {

  public enum Type {

    String, StringArray, Integer, Long, Double, Boolean, Enum, Date, Count, Function, Notion, Cypher, Join
  }

  private static final Map<String, String> normalizedEntityNameCache        = new LinkedHashMap<>();
  private static final Map<Type, Class<? extends PropertyParser>> parserMap = new LinkedHashMap<>();

  static {

    // IMPORTANT: parser map must be sorted by type name length
    //            because we look up the parsers using "startsWith"!

    parserMap.put(Type.StringArray, StringArrayPropertyParser.class);
    parserMap.put(Type.Function,    FunctionPropertyParser.class);
    parserMap.put(Type.Boolean,     BooleanPropertyParser.class);
    parserMap.put(Type.Integer,     IntPropertyParser.class);
    parserMap.put(Type.String,      StringPropertyParser.class);
    parserMap.put(Type.Double,      DoublePropertyParser.class);
    parserMap.put(Type.Notion,      NotionPropertyParser.class);
    parserMap.put(Type.Cypher,      CypherPropertyParser.class);
    parserMap.put(Type.Long,        LongPropertyParser.class);
    parserMap.put(Type.Enum,        EnumPropertyParser.class);
    parserMap.put(Type.Date,        DatePropertyParser.class);
    parserMap.put(Type.Count,       CountPropertyParser.class);
    parserMap.put(Type.Join,        JoinPropertyParser.class);
  }

  /**
   * Tries to normalize (and singularize) the given string so that it
   * resolves to an existing entity type.
   *
   * @param possibleEntityString
   * @return the normalized entity name in its singular form
   */
  public static String normalizeEntityName(String possibleEntityString) {

    if (possibleEntityString == null) {

      return null;

    }

    if ("/".equals(possibleEntityString)) {

      return "/";

    }

    StringBuilder result = new StringBuilder();

    if (possibleEntityString.contains("/")) {

      String[] names = StringUtils.split(possibleEntityString, "/");

      for (String possibleEntityName : names) {

        // CAUTION: this cache might grow to a very large size, as it
        // contains all normalized mappings for every possible
        // property key / entity name that is ever called.
        String normalizedType = normalizedEntityNameCache.get(possibleEntityName);

        if (normalizedType == null) {

          normalizedType = StringUtils.capitalize(CaseHelper.toUpperCamelCase(possibleEntityName));

          if (normalizedType.endsWith("ies")) {

            normalizedType = normalizedType.substring(0, normalizedType.length() - 3).concat("y");

          } else if (!normalizedType.endsWith("ss") && normalizedType.endsWith("s")) {

            normalizedType = normalizedType.substring(0, normalizedType.length() - 1);
          }
        }

        result.append(normalizedType).append("/");

      }

      return StringUtils.removeEnd(result.toString(), "/");

    } else {

//                      CAUTION: this cache might grow to a very large size, as it
      // contains all normalized mappings for every possible
      // property key / entity name that is ever called.
      String normalizedType = normalizedEntityNameCache.get(possibleEntityString);

      if (normalizedType == null) {

        normalizedType = StringUtils.capitalize(CaseHelper.toUpperCamelCase(possibleEntityString));

        if (normalizedType.endsWith("ies")) {

          normalizedType = normalizedType.substring(0, normalizedType.length() - 3).concat("y");

        } else if (!normalizedType.endsWith("ss") && normalizedType.endsWith("s")) {

          normalizedType = normalizedType.substring(0, normalizedType.length() - 1);
        }
      }

      return normalizedType;
    }
  }

  public static Class getEntityClassForRawType(final String rawType) {

    // first try: raw name
    Class type = getEntityClassForRawType(rawType, false);
    if (type == null) {

      // second try: normalized name
      type = getEntityClassForRawType(rawType, true);
    }

    return type;
  }

  private static Class getEntityClassForRawType(final String rawType, final boolean normalize) {

    final String normalizedEntityName = normalize ? normalizeEntityName(rawType) : rawType;
    final ConfigurationProvider configuration = StructrApp.getConfiguration();

    // first try: node entity
    Class type = configuration.getNodeEntities().get(normalizedEntityName);

    // second try: relationship entity
    if (type == null) {
      type = configuration.getRelationshipEntities().get(normalizedEntityName);
    }

    // third try: interface
    if (type == null) {
      type = configuration.getInterfaces().get(normalizedEntityName);
    }

    // store type but only if it exists!
    if (type != null) {
      normalizedEntityNameCache.put(rawType, type.getSimpleName());
    }

    return type;
  }

  public static boolean reloadSchema(final ErrorBuffer errorBuffer) {

    try {

      for (final SchemaNode schemaNode : StructrApp.getInstance().nodeQuery(SchemaNode.class).getAsList()) {

        createDynamicGrants(schemaNode.getResourceSignature());

      }

      for (final SchemaRelationship schemaRelationship : StructrApp.getInstance().relationshipQuery(SchemaRelationship.class).getAsList()) {

        createDynamicGrants(schemaRelationship.getResourceSignature());
        createDynamicGrants(schemaRelationship.getInverseResourceSignature());

      }

    } catch (Throwable t) {

      t.printStackTrace();
    }

    return SchemaService.reloadSchema(errorBuffer);

  }

  public static List<DynamicResourceAccess> createDynamicGrants(final String signature) {

    final List<DynamicResourceAccess> grants = new LinkedList<>();
    final long initialFlagsValue             = 0;

    final App app = StructrApp.getInstance();
    try {

      ResourceAccess grant = app.nodeQuery(ResourceAccess.class).and(ResourceAccess.signature, signature).getFirst();
      if (grant == null) {

        // create new grant
        grants.add(app.create(DynamicResourceAccess.class,
          new NodeAttribute(DynamicResourceAccess.signature, signature),
          new NodeAttribute(DynamicResourceAccess.flags, initialFlagsValue)
        ));

        // create additional grant for the _schema resource
        grants.add(app.create(DynamicResourceAccess.class,
          new NodeAttribute(DynamicResourceAccess.signature, "_schema/" + signature),
          new NodeAttribute(DynamicResourceAccess.flags, initialFlagsValue)
        ));

        // create additional grant for the Ui view
        grants.add(app.create(DynamicResourceAccess.class,
          new NodeAttribute(DynamicResourceAccess.signature, signature + "/_Ui"),
          new NodeAttribute(DynamicResourceAccess.flags, initialFlagsValue)
        ));
      }

    } catch (Throwable t) {

      t.printStackTrace();
    }

    return grants;

  }

  public static void removeAllDynamicGrants() {

    final App app = StructrApp.getInstance();
    try {

      // delete grants
      for (DynamicResourceAccess grant : app.nodeQuery(DynamicResourceAccess.class).getAsList()) {
        app.delete(grant);
      }

    } catch (Throwable t) {

      t.printStackTrace();
    }
  }

  public static void removeDynamicGrants(final String signature) {

    final App app = StructrApp.getInstance();
    try {

      // delete grant
      DynamicResourceAccess grant = app.nodeQuery(DynamicResourceAccess.class).and(DynamicResourceAccess.signature, signature).getFirst();
      if (grant != null) {

        app.delete(grant);
      }

      // delete grant
      DynamicResourceAccess schemaGrant = app.nodeQuery(DynamicResourceAccess.class).and(DynamicResourceAccess.signature, "_schema/" + signature).getFirst();
      if (schemaGrant != null) {

        app.delete(schemaGrant);
      }
      // delete grant
      DynamicResourceAccess viewGrant = app.nodeQuery(DynamicResourceAccess.class).and(DynamicResourceAccess.signature, signature + "/_Ui").getFirst();
      if (viewGrant != null) {

        app.delete(viewGrant);
      }

    } catch (Throwable t) {

      t.printStackTrace();
    }

  }

  public static String extractProperties(final Schema entity, final Set<String> propertyNames, final Set<Validator> validators, final Set<String> enums, final Map<String, Set<String>> views, final Map<Actions.Type, List<ActionEntry>> actions, final ErrorBuffer errorBuffer) throws FrameworkException {

    final PropertyContainer propertyContainer = entity.getPropertyContainer();
     final StringBuilder src                   = new StringBuilder();

    // output property source code and collect views
    for (String propertyName : SchemaHelper.getProperties(propertyContainer)) {

      if (!propertyName.startsWith("__") && propertyContainer.hasProperty(propertyName)) {

        String rawType = propertyContainer.getProperty(propertyName).toString();

        String dbName = null;
        // detect optional db name
        if (rawType.contains("|")) {

          dbName = rawType.substring(0, rawType.indexOf("|"));
          rawType = rawType.substring(rawType.indexOf("|")+1);

        }

        boolean notNull = false;

        // detect and remove not-null constraint
        if (rawType.startsWith("+")) {
          rawType = rawType.substring(1);
          notNull = true;
        }

        String defaultValue = null;

        // detect and remove default value
        if (rawType.contains(":") && !rawType.startsWith(Type.Cypher.name())) {

          final int lastIndex = rawType.lastIndexOf(":");
          defaultValue = rawType.substring(lastIndex+1);
          rawType = rawType.substring(0, lastIndex);

        }

        PropertyParser parser = SchemaHelper.getParserForRawValue(errorBuffer, entity.getClassName(), propertyName, dbName, rawType, notNull, defaultValue);
        if (parser != null) {

          // add property name to set for later use
          propertyNames.add(parser.getPropertyName());

          // append created source from parser
          src.append(parser.getPropertySource(entity, errorBuffer));

          // register global elements created by parser
          validators.addAll(parser.getGlobalValidators());
          enums.addAll(parser.getEnumDefinitions());

          // register property in default view
          //addPropertyToView(PropertyView.Public, propertyName.substring(1), views);
          addPropertyToView(PropertyView.Ui, propertyName.substring(1), views);
        }
      }
    }

    for (final String rawViewName : getViews(propertyContainer)) {

      if (!rawViewName.startsWith("___") && propertyContainer.hasProperty(rawViewName)) {

        final String value = propertyContainer.getProperty(rawViewName).toString();
        final String[] parts = value.split("[,\\s]+");
        final String viewName = rawViewName.substring(2);

        // clear view before filling it again
        Set<String> view = views.get(viewName);
        if (view == null) {

          view = new LinkedHashSet<>();
          views.put(viewName, view);

        } else {

          view.clear();
        }

        // add parts to view, overrides defaults (because of clear() above)
        for (int i = 0; i < parts.length; i++) {
          view.add(parts[i].trim());
        }
      }
    }

    for (final String rawActionName : getActions(propertyContainer)) {

      if (propertyContainer.hasProperty(rawActionName)) {

        // split value on ";"
        final String value     = propertyContainer.getProperty(rawActionName).toString();
        final String[] parts1  = value.split("[;]+");
        final int parts1Length = parts1.length;

        for (int i=0; i<parts1Length; i++) {

          // split value on "&&"
          final String[] parts2     = parts1[i].split("\\&\\&");
          final int parts2Length    = parts2.length;

          for (int j=0; j<parts2Length; j++) {

            // since the parts in this loop are separated by "&&", all parts AFTER
            // the first one should only be run if the others before succeeded.

            final ActionEntry entry      = new ActionEntry(rawActionName, parts2[j], j == 0);
            List<ActionEntry> actionList = actions.get(entry.getType());

            if (actionList == null) {

              actionList = new LinkedList<>();
              actions.put(entry.getType(), actionList);
            }

            actionList.add(entry);

            Collections.sort(actionList);
          }

        }
      }
    }

    return src.toString();
  }

  public static void addPropertyToView(final String viewName, final String propertyName, final Map<String, Set<String>> views) {

    Set<String> view = views.get(viewName);
    if (view == null) {

      view = new LinkedHashSet<>();
      views.put(viewName, view);
    }

    view.add(SchemaHelper.cleanPropertyName(propertyName) + "Property");
  }

  public static Iterable<String> getProperties(final PropertyContainer propertyContainer) {

    final List<String> keys = new LinkedList<>();

    for (final String key : propertyContainer.getPropertyKeys()) {

      if (propertyContainer.hasProperty(key) && key.startsWith("_")) {

        keys.add(key);
      }
    }

    return keys;
  }

  public static Iterable<String> getViews(final PropertyContainer propertyContainer) {

    final List<String> keys = new LinkedList<>();

    for (final String key : propertyContainer.getPropertyKeys()) {

      if (propertyContainer.hasProperty(key) && key.startsWith("__")) {

        keys.add(key);
      }
    }

    return keys;
  }

  public static Iterable<String> getActions(final PropertyContainer propertyContainer) {

    final List<String> keys = new LinkedList<>();

    for (final String key : propertyContainer.getPropertyKeys()) {

      if (propertyContainer.hasProperty(key) && key.startsWith("___")) {

        keys.add(key);
      }
    }

    return keys;
  }

  public static void formatView(final StringBuilder src, final String _className, final String viewName, final String view, final Set<String> viewProperties) {

    // output default view
    src.append("\n\tpublic static final View ").append(viewName).append("View = new View(").append(_className).append(".class, \"").append(view).append("\",\n");
    src.append("\t\t");

    for (final Iterator<String> it = viewProperties.iterator(); it.hasNext();) {

      String propertyName = it.next();

      // convert _-prefixed property names to "real" name
      if (propertyName.startsWith("_")) {
        propertyName = propertyName.substring(1) + "Property";
      }

      src.append(propertyName);

      if (it.hasNext()) {
        src.append(", ");
      }
    }

    src.append("\n\t);\n");

  }

  public static void formatImportStatements(final StringBuilder src, final Class baseType) {

    src.append("import ").append(baseType.getName()).append(";\n");
    src.append("import ").append(ConfigurationProvider.class.getName()).append(";\n");
    src.append("import ").append(GraphObjectComparator.class.getName()).append(";\n");
    src.append("import ").append(FrameworkException.class.getName()).append(";\n");
    src.append("import ").append(ValidationHelper.class.getName()).append(";\n");
    src.append("import ").append(SecurityContext.class.getName()).append(";\n");
    src.append("import ").append(GraphObject.class.getName()).append(";\n");
    src.append("import ").append(Actions.class.getName()).append(";\n");
    src.append("import ").append(PropertyView.class.getName()).append(";\n");
    src.append("import ").append(ErrorBuffer.class.getName()).append(";\n");
    src.append("import ").append(StructrApp.class.getName()).append(";\n");
    src.append("import ").append(Export.class.getName()).append(";\n");
    src.append("import ").append(View.class.getName()).append(";\n");
    src.append("import ").append(List.class.getName()).append(";\n");

    if (hasUiClasses()) {
      src.append("import org.structr.rest.RestMethodResult;\n");
    }

    src.append("import org.structr.core.validator.*;\n");
    src.append("import org.structr.core.property.*;\n");
    src.append("import org.structr.core.notion.*;\n");
    src.append("import org.structr.core.entity.*;\n\n");

  }

  public static String cleanPropertyName(final String propertyName) {
    return propertyName.replaceAll("[^\\w]+", "");
  }

  public static void formatValidators(final StringBuilder src, final Set<Validator> validators) {

    if (!validators.isEmpty()) {

      src.append("\n\t@Override\n");
      src.append("\tpublic boolean isValid(final ErrorBuffer errorBuffer) {\n\n");
      src.append("\t\tboolean error = !super.isValid(errorBuffer);\n\n");

      for (final Validator validator : validators) {
        src.append("\t\terror |= ").append(validator.getSource("this", true)).append(";\n");
      }

      src.append("\n\t\treturn !error;\n");
      src.append("\t}\n");
    }

  }

  public static void formatDynamicValidators(final StringBuilder src, final Set<Validator> validators) {

    if (!validators.isEmpty()) {

      src.append("\tpublic static boolean isValid(final AbstractNode obj, final ErrorBuffer errorBuffer) {\n\n");
      src.append("\t\tboolean error = false;\n\n");

      for (final Validator validator : validators) {
        src.append("\t\terror |= ").append(validator.getSource("obj", false)).append(";\n");
      }

      src.append("\n\t\treturn !error;\n");
      src.append("\t}\n\n");
    }
  }

  public static void formatSaveActions(final StringBuilder src, final Map<Actions.Type, List<ActionEntry>> saveActions) {

    // save actions..
    for (final Map.Entry<Actions.Type, List<ActionEntry>> entry : saveActions.entrySet()) {

      final List<ActionEntry> actionList = entry.getValue();
      final Actions.Type type            = entry.getKey();

      if (!actionList.isEmpty()) {

        switch (type) {

          case Custom:
            // active actions are exported stored functions
            // that can be called by POSTing on the entity
            formatActiveActions(src, actionList);
            break;

          default:
            // passive actions are actions that are executed
            // automtatically on creation / modification etc.
            formatPassiveSaveActions(src, type, actionList);
            break;
        }
      }
    }

  }

  public static void formatDynamicSaveActions(final StringBuilder src, final Map<Actions.Type, List<ActionEntry>> saveActions) {

    // save actions..
    for (final Map.Entry<Actions.Type, List<ActionEntry>> entry : saveActions.entrySet()) {

      final List<ActionEntry> actionList = entry.getValue();
      final Actions.Type type            = entry.getKey();

      if (!actionList.isEmpty()) {

        switch (type) {

          case Custom:
            throw new UnsupportedOperationException("Active save actions are not supported for overridable types.");

          default:
            // passive actions are actions that are executed
            // automtatically on creation / modification etc.
            formatDynamicPassiveSaveActions(src, type, actionList);
            break;
        }
      }
    }

  }

  public static void formatActiveActions(final StringBuilder src, final List<ActionEntry> actionList) {

    for (final ActionEntry action : actionList) {

      src.append("\n\t@Export\n");
      src.append("\tpublic RestMethodResult ");
      src.append(action.getName());
      src.append("() throws FrameworkException {\n\n");

      src.append("\t\t");
      src.append(action.getSource("this"));
      src.append(";\n\n");

      src.append("\t\treturn new RestMethodResult(200);\n");
      src.append("\t}\n");
    }

  }

  public static void formatDynamicActiveActions(final StringBuilder src, final List<ActionEntry> actionList) {

    for (final ActionEntry action : actionList) {

      src.append("\tpublic static RestMethodResult ");
      src.append(action.getName());
      src.append("(final AbstractNode obj) throws FrameworkException {\n\n");

      src.append("\t\t");
      src.append(action.getSource("obj"));
      src.append(";\n\n");

      src.append("\t\treturn new RestMethodResult(200);\n");
      src.append("\t}\n");
    }

  }

  public static void formatPassiveSaveActions(final StringBuilder src, final Actions.Type type, final List<ActionEntry> actionList) {

    src.append("\n\t@Override\n");
    src.append("\tpublic boolean ");
    src.append(type.getMethod());
    src.append("(");
    src.append(type.getSignature());
    src.append(") throws FrameworkException {\n\n");
    src.append("\t\tboolean error = !super.");
    src.append(type.getMethod());
    src.append("(");
    src.append(type.getParameters());
    src.append(");\n\n");

    if (!actionList.isEmpty()) {

      src.append("\t\tif (!error) {\n");

      for (final ActionEntry action : actionList) {

        if (action.runOnError()) {

          src.append("\t\t\terror |= ").append(action.getSource("this")).append(";\n");

        } else {

          src.append("\t\tif (!error) {\n");
          src.append("\t\t\terror |= ").append(action.getSource("this")).append(";\n");
          src.append("\t\t}\n");

        }
      }

      src.append("\t\t}\n");
    }

    src.append("\n\t\treturn !error;\n");
    src.append("\t}\n");

  }

  public static void formatDynamicPassiveSaveActions(final StringBuilder src, final Actions.Type type, final List<ActionEntry> actionList) {

    src.append("\tpublic static boolean ");
    src.append(type.getMethod());
    src.append("(final AbstractNode obj, SecurityContext securityContext, ErrorBuffer errorBuffer) throws FrameworkException {\n\n");
    src.append("\t\tboolean error = !obj.isValid(errorBuffer);\n\n");

    if (!actionList.isEmpty()) {

      src.append("\t\tif (!error) {\n");

      for (final ActionEntry action : actionList) {

        if (action.runOnError()) {

          src.append("\t\t\terror |= ").append(action.getSource("obj")).append(";\n");

        } else {

          src.append("\t\tif (!error) {\n");
          src.append("\t\t\terror |= ").append(action.getSource("obj")).append(";\n");
          src.append("\t\t}\n");

        }
      }

      src.append("\t\t}\n");
    }

    src.append("\n\t\treturn !error;\n");
    src.append("\t}\n\n");

  }

  public static String getPropertyWithVariableReplacement(SecurityContext securityContext, final GraphObject entity, ActionContext renderContext, PropertyKey<String> key) throws FrameworkException {

    return replaceVariables(securityContext, entity, renderContext, entity.getProperty(key));

  }

  public static String replaceVariables(final SecurityContext securityContext, final GraphObject entity, final ActionContext actionContext, final Object rawValue) throws FrameworkException {

    String value = null;

    if (rawValue == null) {

      return null;

    }

    if (rawValue instanceof String) {

      value = (String) rawValue;

      if (!actionContext.returnRawValue(securityContext)) {

        final Map<String, String> replacements = new LinkedHashMap<>();

        int start = value.indexOf("${");
        int end   = value.indexOf("}", start);

        while (start >= 0 && end >= 0) {

          String group          = value.substring(start,   end+1);
          String source         = value.substring(start+2, end);
          Object extractedValue = Functions.evaluate(securityContext, actionContext, entity, source);

          if (extractedValue == null) {
            extractedValue = "";
          }

          String partValue = extractedValue.toString();
          if (partValue != null) {

            replacements.put(group, partValue);

          } else {

            // If the whole expression should be replaced, and partValue is null
            // replace it by null to make it possible for HTML attributes to not be rendered
            // and avoid something like ... selected="" ... which is interpreted as selected==true by
            // all browsers
            if (!value.equals(group)) {
              replacements.put(group, "");
            }
          }

          start = value.indexOf("${", end);
          end   = value.indexOf("}", start);
        }

        // apply replacements
        for (final Entry<String, String> entry : replacements.entrySet()) {

          final String group       = entry.getKey();
          final String replacement = entry.getValue();

          value = value.replace(group, replacement);
        }

      }

    } else if (rawValue instanceof Boolean) {

      value = Boolean.toString((Boolean) rawValue);

    } else {

      value = rawValue.toString();

    }

    // return literal null
    if (Functions.NULL_STRING.equals(value)) {
      return null;
    }

    return value;

  }

  // ----- private methods -----
  private static PropertyParser getParserForRawValue(final ErrorBuffer errorBuffer, final String className, final String propertyName, final String dbName, final String source, final boolean notNull, final String defaultValue) throws FrameworkException {

    for (final Map.Entry<Type, Class<? extends PropertyParser>> entry : parserMap.entrySet()) {

      if (source.startsWith(entry.getKey().name())) {

        try {

          final PropertyParser parser = entry.getValue().getConstructor(ErrorBuffer.class, String.class, String.class, String.class, String.class, String.class).newInstance(errorBuffer, className, propertyName, dbName, source, defaultValue);
          parser.setNotNull(notNull);

          return parser;

        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
    }

    errorBuffer.add(SchemaNode.class.getSimpleName(), new InvalidPropertySchemaToken(source, "invalid_property_definition", "Unknow value type " + source + ", options are " + Arrays.asList(Type.values()) + "."));
    throw new FrameworkException(422, errorBuffer);
  }

  private static boolean hasUiClasses() {

    try {

      Class.forName("org.structr.rest.RestMethodResult");

      // success
      return true;

    } catch (Throwable t) {}

    return false;
  }
}
TOP

Related Classes of org.structr.schema.SchemaHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.