public void typeSystemInit()

in uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureValuePathImpl.java [826:977]


  public void typeSystemInit(int fsType, LowLevelTypeSystem ts) throws CASRuntimeException {
    if (typeNameInSnippet != null) { // if the feature path snippet
      // defines
      // its own
      // type,
      // we use that one instead of the one that's passed in
      fsType = ts.ll_getCodeForTypeName(typeNameInSnippet);
    }

    if (fsType == LowLevelTypeSystem.UNKNOWN_TYPE_CODE) {
      throw new CASRuntimeException(CASRuntimeException.INVALID_FEATURE_PATH, typeNameInSnippet);
    }

    // the range type denotes what type of FSes (or
    // built-in type) is contained in this feature
    int rangeTypeCode = LowLevelTypeSystem.UNKNOWN_TYPE_CODE;

    if (!(isBuiltInFeature() || isBracketsOnly)) {
      // find the feature in fsType that corresponds to this path snippet
      int[] features = ts.ll_getAppropriateFeatures(fsType);
      boolean found = false;

      int i = 0;
      for (; i < features.length && (!found); i++) {
        Feature feature = ts.ll_getFeatureForCode(features[i]);
        found = feature.getShortName().equals(featureName);
      }

      if (found) {
        // store the feature code that corresponds to this path snippet
        featureCode = features[i - 1];
        rangeTypeCode = ts.ll_getRangeType(featureCode);
      } else {
        Type type = ts.ll_getTypeForCode(fsType);
        throw new CASRuntimeException(CASRuntimeException.INAPPROP_FEAT, featureName,
                type.getName());
      }
    }

    if (isBracketsOnly) {
      rangeTypeCode = fsType;
    }

    typeCode = fsType;

    // TODO: check mismatch between isArray and the actual rangeTypeCode

    // find out whether the type is a "simple" type that may only be used in
    // the last snippet of a path
    Type type = ts.ll_getTypeForCode(rangeTypeCode);
    featureRangeType = rangeTypeCode;

    if (isBuiltInFeature()) {
      isSimpleRangeType = true;
    } else {
      isSimpleRangeType = Arrays.binarySearch(SIMPLE_VAL_TYPES, type.getName()) >= 0;
    }

    if (isArrayOrList) {
      int arrayType = ts.ll_getCodeForTypeName(CAS.TYPE_NAME_ARRAY_BASE);
      isArrayType = ((TypeSystemImpl) ts).subsumes(arrayType, rangeTypeCode);
      if (!isArrayType) {
        // check whether the feature points to a list
        for (int i = 0; i < LIST_TYPE_NAMES.length && !isListType; i++) {
          int candidateType = ts.ll_getCodeForTypeName(LIST_TYPE_NAMES[i]);
          isListType = ((TypeSystemImpl) ts).subsumes(candidateType, rangeTypeCode);
          if (isListType) {
            // determine the type class of the list
            listType = i;
          }
        }

        // determine the right head and tail feature, depending on the
        // list type
        switch (listType) {
          case TYPE_CLASS_FSLIST:
            headFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_FS_LIST_HEAD);
            tailFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_FS_LIST_TAIL);
            break;
          case TYPE_CLASS_STRINGLIST:
            headFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_STRING_LIST_HEAD);
            tailFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_STRING_LIST_TAIL);
            break;
          case TYPE_CLASS_INTEGERLIST:
            headFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_INTEGER_LIST_HEAD);
            tailFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_INTEGER_LIST_TAIL);
            break;
          case TYPE_CLASS_FLOATLIST:
            headFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_FLOAT_LIST_HEAD);
            tailFeature = ts.ll_getCodeForFeatureName(CAS.FEATURE_FULL_NAME_FLOAT_LIST_TAIL);
            break;
          default:
            break;
        }

        emptyListTypes = new Type[EMPTY_LIST_TYPE_NAMES.length];
        for (int i = 0; i < EMPTY_LIST_TYPE_NAMES.length; i++) {
          emptyListTypes[i] = ts
                  .ll_getTypeForCode(ts.ll_getCodeForTypeName(EMPTY_LIST_TYPE_NAMES[i]));
        }

      }

    }

    if (childPath != null) {
      // for simple range types, only [] and fsId() are allowed as child
      // path
      if (isSimpleRangeType && !(childPath.isBracketsOnly() || childPath.isFsIdFeature)) {
        throw new CASRuntimeException(CASRuntimeException.INVALID_FEATURE_PATH, featureName);
      }

      // continue with the child path
      childPath.typeSystemInit(rangeTypeCode, ts);
    } else if (isCoveredTextFeature) {
      // make sure that the type is a subtype of annotation
      int annotationType = ts.ll_getCodeForTypeName(CAS.TYPE_NAME_ANNOTATION);
      if (!((TypeSystemImpl) ts).subsumes(annotationType, fsType)) {
        throw new CASRuntimeException(CASRuntimeException.INVALID_FEATURE_PATH, featureName);
      }

      valueTypeName = SIMPLE_VAL_TYPES[Arrays.binarySearch(SIMPLE_VAL_TYPES, CAS.TYPE_NAME_STRING)];
    } else if (isFsIdFeature) {
      valueTypeName = SIMPLE_VAL_TYPES[Arrays.binarySearch(SIMPLE_VAL_TYPES,
              CAS.TYPE_NAME_INTEGER)];
    } else if (isUniqueIdFeature) {
      valueTypeName = SIMPLE_VAL_TYPES[Arrays.binarySearch(SIMPLE_VAL_TYPES,
              CAS.TYPE_NAME_INTEGER)];
    } else if (isTypeNameFeature) {
      valueTypeName = SIMPLE_VAL_TYPES[Arrays.binarySearch(SIMPLE_VAL_TYPES, CAS.TYPE_NAME_STRING)];
    } else {
      if (!isSimpleRangeType) {
        CASRuntimeException exception = new CASRuntimeException(
                CASRuntimeException.NO_PRIMITIVE_TAIL);
        throw exception;
      }

      if (isArrayOrList && (arrayIndex != USE_ALL_ENTRIES)) {
        // in the case of, say, authornames[0], the feature is of type
        // string array, but it will evaluate to a string.
        valueTypeName = CONTAINER_TO_ELEMENTYPE_MAP.get(type.getName());
      } else if (isListType) { // here, we can assume that
        // arrayIndex =
        // USE_ALL_ENTRIES
        // we don't return lists, but arrays, so we need to map the type
        // accordingly
        valueTypeName = LIST_TO_ARRAYTYPE_MAP.get(type.getName());
      } else {
        valueTypeName = SIMPLE_VAL_TYPES[Arrays.binarySearch(SIMPLE_VAL_TYPES, type.getName())];
      }
    }
  }