| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.uima.cas.impl; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Vector; |
| |
| import org.apache.uima.cas.CAS; |
| import org.apache.uima.cas.Feature; |
| import org.apache.uima.cas.Type; |
| |
| /** |
| * Internal class that holds "meta" information about a CAS |
| * This object is shared by all CASes that have the same typeSystemImpl. |
| * |
| * It is accessible to classes in the cas.impl package, only. |
| */ |
| |
| class CASMetadata { |
| |
| final TypeSystemImpl ts; |
| final FSClassRegistry fsClassRegistry; |
| |
| |
| // /////////////////////////////////////////////////////// |
| // Data structures for type checking and feature encoding |
| |
| // For each feature, what the offset from the start of the FS is. |
| // That is, this will always be a number > 0. If you have the |
| // address a of a structure of type t, then you can get the value of |
| // feature f by getting (the value of) a+featureOffset[f] from the |
| // heap. If f is not appropriate for t, anything can happen |
| // (including an ArrayIndexOutOfBoundsException). |
| int[] featureOffset; |
| |
| // For each type, how large structures of that type are. This will |
| // also be > 0 for each type (since you need to store the type at a |
| // minimum. |
| int[] fsSpaceReq; |
| |
| // For each type, remember if it's a regular type that can be created |
| // with CAS.createFS() or not. Exceptions are built-in types float, int and |
| // string, as well as arrays. |
| boolean[] creatableType; |
| |
| // /////////////////////////////////////////////////////// |
| // Properties of types. |
| |
| // Those types can not be created with CAS.createFS(). |
| private static String[] nonCreatableTypes = { CAS.TYPE_NAME_INTEGER, CAS.TYPE_NAME_FLOAT, |
| CAS.TYPE_NAME_STRING, CAS.TYPE_NAME_ARRAY_BASE, CAS.TYPE_NAME_FS_ARRAY, |
| CAS.TYPE_NAME_INTEGER_ARRAY, CAS.TYPE_NAME_FLOAT_ARRAY, CAS.TYPE_NAME_STRING_ARRAY, |
| CAS.TYPE_NAME_SOFA, CAS.TYPE_NAME_BYTE, CAS.TYPE_NAME_BYTE_ARRAY, CAS.TYPE_NAME_BOOLEAN, |
| CAS.TYPE_NAME_BOOLEAN_ARRAY, CAS.TYPE_NAME_SHORT, CAS.TYPE_NAME_SHORT_ARRAY, |
| CAS.TYPE_NAME_LONG, CAS.TYPE_NAME_LONG_ARRAY, CAS.TYPE_NAME_DOUBLE, |
| CAS.TYPE_NAME_DOUBLE_ARRAY }; |
| |
| |
| |
| CASMetadata(TypeSystemImpl ts, FSClassRegistry fsClassRegistry) { |
| this.ts = ts; |
| this.fsClassRegistry = fsClassRegistry; |
| } |
| |
| CASMetadata(TypeSystemImpl ts) { |
| this.ts = ts; |
| this.fsClassRegistry = new FSClassRegistry(ts); |
| } |
| |
| |
| // called when type system is "committed" |
| // - all types are known |
| // - no new types will be added |
| // -- exception: array types |
| void setupFeaturesAndCreatableTypes() { |
| // Compute feature offsets. |
| computeFeatureOffsets(); |
| // Compute FS space requirements. |
| final int numTypes = ts.getNumberOfTypes(); |
| this.fsSpaceReq = new int[numTypes + 1]; |
| for (int i = 1; i <= numTypes; i++) { |
| this.fsSpaceReq[i] = ts.ll_getAppropriateFeatures(i).length + 1; |
| } |
| // Initialize the non-creatable types info. |
| initCreatableTypeTable(); |
| } |
| |
| // Compute the feature offsets |
| private final void computeFeatureOffsets() { |
| final int numFeats = ts.getNumberOfFeatures(); |
| this.featureOffset = new int[numFeats + 1]; |
| Type startType = ts.getTopType(); |
| // Recursively compute the offsets, starting at the top. Initial offset |
| // is 0. |
| computeFeatureOffsets(startType, 0); |
| } |
| |
| // Compute the offsets for features of a type. The offset parameter |
| // specifies |
| // how many offset values have already been used. |
| private final void computeFeatureOffsets(Type t, int offset) { |
| // Find all features for which the input type is the domain type. |
| List allFeats = t.getFeatures(); |
| ArrayList introFeats = new ArrayList(); |
| final int numAllFeats = allFeats.size(); |
| Feature feat; |
| for (int i = 0; i < numAllFeats; i++) { |
| feat = (Feature) allFeats.get(i); |
| if (feat.getDomain() == t) { |
| introFeats.add(feat); |
| } |
| } |
| // For each feature for which the input type is the domain, assign an |
| // offset |
| // arbitrarily, starting with the input offset + 1. |
| int featCode; |
| final int numFeats = introFeats.size(); |
| for (int i = 0; i < numFeats; i++) { |
| featCode = ((FeatureImpl) introFeats.get(i)).getCode(); |
| this.featureOffset[featCode] = offset + 1 + i; |
| } |
| // Call routine recursively for all subtypes. Increment input offset by |
| // number of features introduced on this type. |
| Vector immediateSubtypes = ts.getDirectlySubsumedTypes(t); |
| final int numTypes = immediateSubtypes.size(); |
| for (int i = 0; i < numTypes; i++) { |
| computeFeatureOffsets((Type) immediateSubtypes.get(i), offset + numFeats); |
| } |
| } |
| |
| private void initCreatableTypeTable() { |
| this.creatableType = new boolean[ts.getTypeArraySize()]; |
| Arrays.fill(this.creatableType, true); |
| int typeCode; |
| for (int i = 0; i < nonCreatableTypes.length; i++) { |
| typeCode = ((TypeImpl) ts.getType(nonCreatableTypes[i])).getCode(); |
| for (int subType = ts.getSmallestType(); subType < this.creatableType.length; subType++) { |
| if (ts.subsumes(typeCode, subType)) { |
| this.creatableType[subType] = false; |
| } |
| } |
| } |
| } |
| |
| } |