Пример #1
0
  /**
   * Load schema.
   *
   * @param schema the schema
   * @param schemaElement the schema element
   * @return the map
   * @throws Exception the exception
   */
  @SuppressWarnings("unchecked")
  private static Map<String, Object> loadSchema(
      Schema schema, org.dom4j.Element schemaElement, ServiceContext ctx) throws Exception {
    String schemaName1 =
        schemaElement.attributeValue(
            ExportConstants.NAME_ATTR); // FIXME: Do we need this local var?
    String schemaName = schema.getName();

    Map<String, Object> data = new HashMap<String, Object>();
    Iterator<org.dom4j.Element> it = schemaElement.elementIterator();
    while (it.hasNext()) {
      org.dom4j.Element element = it.next();
      String name = element.getName();
      Field field = schema.getField(name);
      if (field != null) {
        Object value = getElementData(element, field.getType(), ctx);
        data.put(name, value);
      } else {
        // FIXME: substitute an appropriate constant for "csid" below.
        // One potential class to which to add that constant, if it is not already
        // declared, might be AbstractCollectionSpaceResourceImpl - ADR 2012-09-24
        if (!name.equals("csid")) { // 'csid' elements in input payloads can be safely ignored.
          logger.warn(
              "Invalid input document. No such property was found ["
                  + name
                  + "] in schema "
                  + schemaName);
        }
      }
    }

    return data;
  }
Пример #2
0
 protected Object getValueField(T state, Field field) throws PropertyException {
   Type type = field.getType();
   String name = field.getName().getPrefixedName();
   name = internalName(name);
   if (type.isSimpleType()) {
     // scalar
     return state.getSingle(name);
   } else if (type.isComplexType()) {
     // complex property
     T childState = getChild(state, name, type);
     if (childState == null) {
       return null;
     }
     return getValueComplex(childState, (ComplexType) type);
   } else {
     // array or list
     Type fieldType = ((ListType) type).getFieldType();
     if (fieldType.isSimpleType()) {
       // array
       return state.getArray(name);
     } else {
       // complex list
       List<T> childStates = getChildAsList(state, name);
       List<Object> list = new ArrayList<>(childStates.size());
       for (T childState : childStates) {
         Object value = getValueComplex(childState, (ComplexType) fieldType);
         list.add(value);
       }
       return list;
     }
   }
 }
Пример #3
0
 protected void visitBlobsField(T state, Field field) throws PropertyException {
   Type type = field.getType();
   if (type.isSimpleType()) {
     // scalar
   } else if (type.isComplexType()) {
     // complex property
     String name = field.getName().getPrefixedName();
     T childState = getChild(state, name, type);
     if (childState != null) {
       path.addLast(name);
       visitBlobsComplex(childState, (ComplexType) type);
       path.removeLast();
     }
   } else {
     // array or list
     Type fieldType = ((ListType) type).getFieldType();
     if (fieldType.isSimpleType()) {
       // array
     } else {
       // complex list
       String name = field.getName().getPrefixedName();
       path.addLast(name);
       int i = 0;
       for (T childState : getChildAsList(state, name)) {
         path.addLast(String.valueOf(i++));
         visitBlobsComplex(childState, (ComplexType) fieldType);
         path.removeLast();
       }
       path.removeLast();
     }
   }
 }
Пример #4
0
 @Override
 public String toString() {
   if (listItem) {
     return field.getName().getPrefixedName();
   } else {
     return field.getName().getPrefixedName() + "[" + index + "]";
   }
 }
Пример #5
0
 protected Object getValueComplex(T state, ComplexType complexType) throws PropertyException {
   if (TypeConstants.isContentType(complexType)) {
     return getValueBlob(state);
   }
   Map<String, Object> map = new HashMap<>();
   for (Field field : complexType.getFields()) {
     String name = field.getName().getPrefixedName();
     Object value = getValueField(state, field);
     map.put(name, value);
   }
   return map;
 }
Пример #6
0
 /**
  * Builds the property.
  *
  * @param document the document
  * @param parent the parent
  * @param field the field
  * @param dateVal the dateVal
  * @throws IOException Signals that an I/O exception has occurred.
  */
 private static void buildProperty(Document document, Element parent, Field field, Object value)
     throws IOException {
   Type type = field.getType();
   // no need to qualify each element name as namespace is already added
   String propName = field.getName().getLocalName();
   Element element = document.createElement(propName);
   parent.appendChild(element);
   // extract the element content
   if (type.isSimpleType()) {
     // Avoid returning scientific notation representations of
     // very large or very small decimal values. See CSPACE-4691.
     if (isNuxeoDecimalType(type) && valueMatchesNuxeoType(type, value)) {
       element.setTextContent(nuxeoDecimalValueToDecimalString(value));
       /*
       * We need a way to produce just a Date when the specified data
       * type is an xs:date vs. xs:datetime. Nuxeo maps both to a Calendar. Sigh.
       if(logger.isTraceEnabled() && isDateType(type)) {
           String dateValType = "unknown";
           if (value instanceof java.util.Date) {
               dateValType = "java.util.Date";
           } else if (value instanceof java.util.Calendar) {
               dateValType = "java.util.Calendar";
           }
           logger.trace("building XML for date type: "+type.getName()
                   +" value type: "+dateValType
                   +" encoded: "+encodedVal);
       }
       */
     } else {
       String encodedVal = type.encode(value);
       element.setTextContent(encodedVal);
     }
   } else if (type.isComplexType()) {
     ComplexType ctype = (ComplexType) type;
     if (ctype.getName().equals(TypeConstants.CONTENT)) {
       throw new RuntimeException("Unexpected schema type: BLOB for field: " + propName);
     } else {
       buildComplex(document, element, ctype, (Map) value);
     }
   } else if (type.isListType()) {
     if (value instanceof List) {
       buildList(document, element, (ListType) type, (List) value);
     } else if (value.getClass().getComponentType() != null) {
       buildList(document, element, (ListType) type, PrimitiveArrays.toList(value));
     } else {
       throw new IllegalArgumentException(
           "A value of list type is neither list neither array: " + value);
     }
   }
 }
Пример #7
0
 protected void readPrefetchField(
     T state,
     Field field,
     String xpathGeneric,
     String xpath,
     Set<String> prefixes,
     Map<String, Serializable> prefetch) {
   String name = field.getName().getPrefixedName();
   Type type = field.getType();
   xpathGeneric = xpathGeneric == null ? name : xpathGeneric + '/' + name;
   xpath = xpath == null ? name : xpath + '/' + name;
   if (!prefixes.contains(xpathGeneric)) {
     return;
   }
   if (type.isSimpleType()) {
     // scalar
     Object value = state.getSingle(name);
     prefetch.put(xpath, (Serializable) value);
   } else if (type.isComplexType()) {
     // complex property
     T childState = getChild(state, name, type);
     if (childState != null) {
       readPrefetch(childState, (ComplexType) type, xpathGeneric, xpath, prefixes, prefetch);
     }
   } else {
     // array or list
     ListType listType = (ListType) type;
     if (listType.getFieldType().isSimpleType()) {
       // array
       Object[] value = state.getArray(name);
       prefetch.put(xpath, value);
     } else {
       // complex list
       List<T> childStates = getChildAsList(state, name);
       Field listField = listType.getField();
       xpathGeneric += "/*";
       int i = 0;
       for (T childState : childStates) {
         readPrefetch(
             childState,
             (ComplexType) listField.getType(),
             xpathGeneric,
             xpath + '/' + i++,
             prefixes,
             prefetch);
       }
     }
   }
 }
Пример #8
0
 protected Field getField(Field parent, String subFieldName, boolean finalCall) {
   if (parent != null) {
     Type type = parent.getType();
     if (type.isListType()) {
       ListType listType = (ListType) type;
       // remove indexes in case of multiple values
       if ("*".equals(subFieldName)) {
         if (!finalCall) {
           return parent;
         } else {
           return resolveSubField(listType, null, true);
         }
       }
       try {
         Integer.valueOf(subFieldName);
         if (!finalCall) {
           return parent;
         } else {
           return resolveSubField(listType, null, true);
         }
       } catch (NumberFormatException e) {
         return resolveSubField(listType, subFieldName, false);
       }
     } else if (type.isComplexType()) {
       return ((ComplexType) type).getField(subFieldName);
     }
   }
   return null;
 }
Пример #9
0
 protected void setValueField(T state, Field field, Object value) throws PropertyException {
   Type type = field.getType();
   String name = field.getName().getPrefixedName(); // normalize from map key
   name = internalName(name);
   // TODO we could check for read-only here
   if (type.isSimpleType()) {
     // scalar
     state.setSingle(name, value);
   } else if (type.isComplexType()) {
     // complex property
     T childState = getChildForWrite(state, name, type);
     setValueComplex(childState, field, value);
   } else {
     // array or list
     ListType listType = (ListType) type;
     Type fieldType = listType.getFieldType();
     if (fieldType.isSimpleType()) {
       // array
       if (value instanceof List) {
         value = ((List<?>) value).toArray(new Object[0]);
       }
       state.setArray(name, (Object[]) value);
     } else {
       // complex list
       if (value != null && !(value instanceof List)) {
         throw new PropertyException(
             "Expected List value for: "
                 + name
                 + ", got "
                 + value.getClass().getName()
                 + " instead");
       }
       @SuppressWarnings("unchecked")
       List<Object> values = value == null ? Collections.emptyList() : (List<Object>) value;
       updateList(state, name, values, listType.getField());
     }
   }
 }
Пример #10
0
 // pass field instead of just type for better error messages
 protected void setValueComplex(T state, Field field, Object value) throws PropertyException {
   ComplexType complexType = (ComplexType) field.getType();
   if (TypeConstants.isContentType(complexType)) {
     if (value != null && !(value instanceof Blob)) {
       throw new PropertyException(
           "Expected Blob value for: "
               + field.getName().getPrefixedName()
               + ", got "
               + value.getClass().getName()
               + " instead");
     }
     setValueBlob(state, (Blob) value);
     return;
   }
   if (value != null && !(value instanceof Map)) {
     throw new PropertyException(
         "Expected Map value for: "
             + field.getName().getPrefixedName()
             + ", got "
             + value.getClass().getName()
             + " instead");
   }
   @SuppressWarnings("unchecked")
   Map<String, Object> map = value == null ? Collections.emptyMap() : (Map<String, Object>) value;
   Set<String> keys = new HashSet<>(map.keySet());
   for (Field f : complexType.getFields()) {
     String name = f.getName().getPrefixedName();
     keys.remove(name);
     value = map.get(name);
     setValueField(state, f, value);
   }
   if (!keys.isEmpty()) {
     throw new PropertyException(
         "Unknown key: " + keys.iterator().next() + " for " + field.getName().getPrefixedName());
   }
 }
  /** Recomputes all the info needed for efficient access. */
  private void recomputeSourceInfos() throws DirectoryException {

    final Schema schema = schemaManager.getSchema(schemaName);
    if (schema == null) {
      throw new DirectoryException(
          String.format("Directory '%s' has unknown schema '%s'", directory.getName(), schemaName));
    }
    final Set<String> sourceFields = new HashSet<String>();
    for (Field f : schema.getFields()) {
      sourceFields.add(f.getName().getLocalName());
    }
    if (!sourceFields.contains(schemaIdField)) {
      throw new DirectoryException(
          String.format(
              "Directory '%s' schema '%s' has no id field '%s'",
              directory.getName(), schemaName, schemaIdField));
    }

    List<SourceInfo> newSourceInfos = new ArrayList<SourceInfo>(2);
    for (SourceDescriptor source : descriptor.sources) {
      int ndirs = source.subDirectories.length;
      if (ndirs == 0) {
        throw new DirectoryException(
            String.format(
                "Directory '%s' source '%s' has no subdirectories",
                directory.getName(), source.name));
      }

      final List<SubDirectoryInfo> subDirectoryInfos = new ArrayList<SubDirectoryInfo>(ndirs);

      SubDirectoryInfo authDirectoryInfo = null;
      boolean hasRequiredDir = false;
      for (SubDirectoryDescriptor subDir : source.subDirectories) {
        final String dirName = subDir.name;
        final String dirSchemaName = directoryService.getDirectorySchema(dirName);
        final String dirIdField = directoryService.getDirectoryIdField(dirName);
        final boolean dirIsAuth = directoryService.getDirectoryPasswordField(dirName) != null;
        final Map<String, String> fromSource = new HashMap<String, String>();
        final Map<String, String> toSource = new HashMap<String, String>();
        final Map<String, Serializable> defaultEntry = new HashMap<String, Serializable>();
        final boolean dirIsOptional = subDir.isOptional;

        // XXX check authenticating
        final Schema dirSchema = schemaManager.getSchema(dirSchemaName);
        if (dirSchema == null) {
          throw new DirectoryException(
              String.format(
                  "Directory '%s' source '%s' subdirectory '%s' " + "has unknown schema '%s'",
                  directory.getName(), source.name, dirName, dirSchemaName));
        }
        // record default field mappings if same name and record default
        // values
        final Set<String> dirSchemaFields = new HashSet<String>();
        for (Field f : dirSchema.getFields()) {
          final String fieldName = f.getName().getLocalName();
          dirSchemaFields.add(fieldName);
          if (sourceFields.contains(fieldName)) {
            // XXX check no duplicates!
            fromSource.put(fieldName, fieldName);
            toSource.put(fieldName, fieldName);
          }
          // XXX cast to Serializable
          defaultEntry.put(fieldName, (Serializable) f.getDefaultValue());
        }
        // treat renamings
        // XXX id field ?
        for (FieldDescriptor field : subDir.fields) {
          final String sourceFieldName = field.forField;
          final String fieldName = field.name;
          if (!sourceFields.contains(sourceFieldName)) {
            throw new DirectoryException(
                String.format(
                    "Directory '%s' source '%s' subdirectory '%s' "
                        + "has mapping for unknown field '%s'",
                    directory.getName(), source.name, dirName, sourceFieldName));
          }
          if (!dirSchemaFields.contains(fieldName)) {
            throw new DirectoryException(
                String.format(
                    "Directory '%s' source '%s' subdirectory '%s' "
                        + "has mapping of unknown field' '%s'",
                    directory.getName(), source.name, dirName, fieldName));
          }
          fromSource.put(sourceFieldName, fieldName);
          toSource.put(fieldName, sourceFieldName);
        }
        SubDirectoryInfo subDirectoryInfo =
            new SubDirectoryInfo(
                dirName,
                dirSchemaName,
                dirIdField,
                dirIsAuth,
                fromSource,
                toSource,
                defaultEntry,
                dirIsOptional);
        subDirectoryInfos.add(subDirectoryInfo);

        if (dirIsAuth) {
          if (authDirectoryInfo != null) {
            throw new DirectoryException(
                String.format(
                    "Directory '%s' source '%s' has two subdirectories "
                        + "with a password field, '%s' and '%s'",
                    directory.getName(), source.name, authDirectoryInfo.dirName, dirName));
          }
          authDirectoryInfo = subDirectoryInfo;
        }
        if (!dirIsOptional) {
          hasRequiredDir = true;
        }
      }
      if (isAuthenticating() && authDirectoryInfo == null) {
        throw new DirectoryException(
            String.format(
                "Directory '%s' source '%s' has no subdirectory " + "with a password field",
                directory.getName(), source.name));
      }
      if (!hasRequiredDir) {
        throw new DirectoryException(
            String.format(
                "Directory '%s' source '%s' only has optional subdirectories: "
                    + "no directory can be used has a reference.",
                directory.getName(), source.name));
      }
      newSourceInfos.add(new SourceInfo(source, subDirectoryInfos, authDirectoryInfo));
    }
    sourceInfos = newSourceInfos;
  }
Пример #12
0
 @Override
 public Type getType() {
   return field.getType();
 }
Пример #13
0
 @Override
 public String getName() {
   return field.getName().getPrefixedName();
 }
Пример #14
0
  /** Sets a value (may be complex/list) into the document at the given xpath. */
  protected void setValueObject(T state, String xpath, Object value) throws PropertyException {
    xpath = canonicalXPath(xpath);
    String[] segments = xpath.split("/");

    ComplexType parentType = getType();
    for (int i = 0; i < segments.length; i++) {
      String segment = segments[i];
      Field field = parentType.getField(segment);
      if (field == null && i == 0) {
        // check facets
        SchemaManager schemaManager = Framework.getService(SchemaManager.class);
        for (String facet : getFacets()) {
          CompositeType facetType = schemaManager.getFacet(facet);
          field = facetType.getField(segment);
          if (field != null) {
            break;
          }
        }
      }
      if (field == null && i == 0 && getProxySchemas() != null) {
        // check proxy schemas
        for (Schema schema : getProxySchemas()) {
          field = schema.getField(segment);
          if (field != null) {
            break;
          }
        }
      }
      if (field == null) {
        throw new PropertyNotFoundException(xpath, i == 0 ? null : "Unknown segment: " + segment);
      }
      String name = field.getName().getPrefixedName(); // normalize from segment
      Type type = field.getType();

      // check if we have a complex list index in the next position
      if (i < segments.length - 1 && StringUtils.isNumeric(segments[i + 1])) {
        int index = Integer.parseInt(segments[i + 1]);
        i++;
        if (!type.isListType() || ((ListType) type).getFieldType().isSimpleType()) {
          throw new PropertyNotFoundException(xpath, "Cannot use index after segment: " + segment);
        }
        List<T> list = getChildAsList(state, name);
        if (index >= list.size()) {
          throw new PropertyNotFoundException(xpath, "Index out of bounds: " + index);
        }
        // find complex list state
        state = list.get(index);
        field = ((ListType) type).getField();
        if (i == segments.length - 1) {
          // last segment
          setValueComplex(state, field, value);
        } else {
          // not last segment
          parentType = (ComplexType) field.getType();
        }
        continue;
      }

      if (i == segments.length - 1) {
        // last segment
        setValueField(state, field, value);
      } else {
        // not last segment
        if (type.isSimpleType()) {
          // scalar
          throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment);
        } else if (type.isComplexType()) {
          // complex property
          state = getChildForWrite(state, name, type);
          parentType = (ComplexType) type;
        } else {
          // list
          ListType listType = (ListType) type;
          if (listType.isArray()) {
            // array of scalars
            throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment);
          } else {
            // complex list but next segment was not numeric
            throw new PropertyNotFoundException(
                xpath, "Missing list index after segment: " + segment);
          }
        }
      }
    }
  }
Пример #15
0
  /** Gets a value (may be complex/list) from the document at the given xpath. */
  protected Object getValueObject(T state, String xpath) throws PropertyException {
    xpath = canonicalXPath(xpath);
    String[] segments = xpath.split("/");

    /*
     * During this loop state may become null if we read an uninitialized complex property (DBS), in that case the
     * code must treat it as reading uninitialized values for its children.
     */
    ComplexType parentType = getType();
    for (int i = 0; i < segments.length; i++) {
      String segment = segments[i];
      Field field = parentType.getField(segment);
      if (field == null && i == 0) {
        // check facets
        SchemaManager schemaManager = Framework.getService(SchemaManager.class);
        for (String facet : getFacets()) {
          CompositeType facetType = schemaManager.getFacet(facet);
          field = facetType.getField(segment);
          if (field != null) {
            break;
          }
        }
      }
      if (field == null && i == 0 && getProxySchemas() != null) {
        // check proxy schemas
        for (Schema schema : getProxySchemas()) {
          field = schema.getField(segment);
          if (field != null) {
            break;
          }
        }
      }
      if (field == null) {
        throw new PropertyNotFoundException(xpath, i == 0 ? null : "Unknown segment: " + segment);
      }
      String name = field.getName().getPrefixedName(); // normalize from segment
      Type type = field.getType();

      // check if we have a complex list index in the next position
      if (i < segments.length - 1 && StringUtils.isNumeric(segments[i + 1])) {
        int index = Integer.parseInt(segments[i + 1]);
        i++;
        if (!type.isListType() || ((ListType) type).getFieldType().isSimpleType()) {
          throw new PropertyNotFoundException(xpath, "Cannot use index after segment: " + segment);
        }
        List<T> list = state == null ? Collections.emptyList() : getChildAsList(state, name);
        if (index >= list.size()) {
          throw new PropertyNotFoundException(xpath, "Index out of bounds: " + index);
        }
        // find complex list state
        state = list.get(index);
        parentType = (ComplexType) ((ListType) type).getFieldType();
        if (i == segments.length - 1) {
          // last segment
          return getValueComplex(state, parentType);
        } else {
          // not last segment
          continue;
        }
      }

      if (i == segments.length - 1) {
        // last segment
        return state == null ? null : getValueField(state, field);
      } else {
        // not last segment
        if (type.isSimpleType()) {
          // scalar
          throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment);
        } else if (type.isComplexType()) {
          // complex property
          state = state == null ? null : getChild(state, name, type);
          // here state can be null (DBS), continue loop with it, meaning uninitialized for read
          parentType = (ComplexType) type;
        } else {
          // list
          ListType listType = (ListType) type;
          if (listType.isArray()) {
            // array of scalars
            throw new PropertyNotFoundException(xpath, "Segment must be last: " + segment);
          } else {
            // complex list but next segment was not numeric
            throw new PropertyNotFoundException(
                xpath, "Missing list index after segment: " + segment);
          }
        }
      }
    }
    throw new AssertionError("not reached");
  }