Beispiel #1
0
  protected DocumentType recomputeDocumentType(
      String name, DocumentTypeDescriptor dtd, DocumentType parent) {
    // find the facets and schemas names
    Set<String> facetNames = new HashSet<>();
    Set<String> schemaNames = SchemaDescriptor.getSchemaNames(dtd.schemas);
    facetNames.addAll(Arrays.asList(dtd.facets));

    // inherited
    if (parent != null) {
      facetNames.addAll(parent.getFacets());
      schemaNames.addAll(Arrays.asList(parent.getSchemaNames()));
    }

    // add schemas names from facets
    for (String facetName : facetNames) {
      CompositeType ct = facets.get(facetName);
      if (ct == null) {
        log.warn("Undeclared facet: " + facetName + " used in document type: " + name);
        // register it with no schemas
        ct = registerFacet(facetName, Collections.<String>emptySet());
      }
      schemaNames.addAll(Arrays.asList(ct.getSchemaNames()));
    }

    // find the schemas
    List<Schema> docTypeSchemas = new ArrayList<>();
    for (String schemaName : schemaNames) {
      Schema schema = schemas.get(schemaName);
      if (schema == null) {
        log.error("Document type: " + name + " uses unknown schema: " + schemaName);
        continue;
      }
      docTypeSchemas.add(schema);
    }

    // create doctype
    PrefetchInfo prefetch = dtd.prefetch == null ? prefetchInfo : new PrefetchInfo(dtd.prefetch);
    DocumentTypeImpl docType =
        new DocumentTypeImpl(name, parent, docTypeSchemas, facetNames, prefetch);
    registerDocumentType(docType);

    return docType;
  }
Beispiel #2
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);
          }
        }
      }
    }
  }
Beispiel #3
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");
  }