| /* |
| * 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.lang.invoke.MethodHandle; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.function.IntConsumer; |
| |
| import org.apache.uima.UIMARuntimeException; |
| import org.apache.uima.UIMA_IllegalStateException; |
| import org.apache.uima.UimaSerializableFSs; |
| import org.apache.uima.cas.CAS; |
| import org.apache.uima.cas.CASRuntimeException; |
| import org.apache.uima.cas.CommonArrayFS; |
| import org.apache.uima.cas.Feature; |
| import org.apache.uima.cas.FeatureStructure; |
| import org.apache.uima.cas.SofaFS; |
| import org.apache.uima.cas.Type; |
| import org.apache.uima.cas.impl.SlotKinds.SlotKind; |
| import org.apache.uima.internal.util.Misc; |
| import org.apache.uima.jcas.JCas; |
| import org.apache.uima.jcas.cas.BooleanArray; |
| import org.apache.uima.jcas.cas.ByteArray; |
| import org.apache.uima.jcas.cas.DoubleArray; |
| import org.apache.uima.jcas.cas.FSArray; |
| import org.apache.uima.jcas.cas.FloatArray; |
| import org.apache.uima.jcas.cas.IntegerArray; |
| import org.apache.uima.jcas.cas.LongArray; |
| import org.apache.uima.jcas.cas.ShortArray; |
| import org.apache.uima.jcas.cas.Sofa; |
| import org.apache.uima.jcas.cas.StringArray; |
| import org.apache.uima.jcas.cas.TOP; |
| import org.apache.uima.jcas.impl.JCasImpl; |
| |
| //@formatter:off |
| /** |
| * Feature structure implementation (for non JCas and JCas) |
| * |
| * Each FS has |
| * - int data |
| * - used for boolean, byte, short, int, long, float, double data |
| * -- long and double use 2 int slots |
| * - may be null if all slots are in JCas cover objects as fields |
| * - ref data |
| * - used for references to other Java objects, such as |
| * -- strings |
| * -- other feature structures |
| * -- arbitrary Java Objects |
| * - may be null if all slots are in JCas cover objects as fields |
| * - an id: an incrementing integer, starting at 1, per CAS, of all FSs created for that CAS |
| * - a ref to the casView where this FS was created |
| * - a ref to the TypeImpl for this class |
| * -- can't be static - may be multiple type systems in use |
| * |
| */ |
| //@formatter:on |
| public class FeatureStructureImplC implements FeatureStructureImpl { |
| |
| // note: these must be enabled to make the test cases work |
| public static final String DISABLE_RUNTIME_FEATURE_VALIDATION = "uima.disable_runtime_feature_validation"; |
| public static final boolean IS_ENABLE_RUNTIME_FEATURE_VALIDATION = !Misc |
| .getNoValueSystemProperty(DISABLE_RUNTIME_FEATURE_VALIDATION); |
| |
| public static final String DISABLE_RUNTIME_FEATURE_VALUE_VALIDATION = "uima.disable_runtime_feature_value_validation"; |
| public static final boolean IS_ENABLE_RUNTIME_FEATURE_VALUE_VALIDATION = !Misc |
| .getNoValueSystemProperty(DISABLE_RUNTIME_FEATURE_VALUE_VALIDATION); |
| |
| public static final String V2_PRETTY_PRINT = "uima.v2_pretty_print_format"; |
| public static final boolean IS_V2_PRETTY_PRINT = // debug true || |
| Misc.getNoValueSystemProperty(V2_PRETTY_PRINT); |
| |
| private static final boolean traceFSs = CASImpl.traceFSs; |
| |
| // next is for experiment (Not implemented) of allocating multiple int arrays for different fss |
| |
| //@formatter:off |
| // // 3322 2222 2222 1111 1111 1100 0000 0000 |
| // // 1098 7654 3210 9876 5432 1098 7654 3210 |
| // //------------------------------------------- |
| // // 0000 0000 0001 1111 1111 1000 0000 0000 int offset mask |
| // // 0111 1111 1110 0000 0000 0000 0000 0000 ref offset mask |
| // |
| // private static final int bitMaskIntOffset = 0x001ff800; |
| // private static final int bitMaskRefOffset = 0x7fe00000; |
| // private static final int shiftIntOffset = 11; |
| // private static final int shiftRefOffset = 21; |
| //@formatter:on |
| |
| private static final int _BIT_IN_SET_SORTED_INDEX = 1; |
| private static final int _BIT_PEAR_TRAMPOLINE = 2; |
| private static final int _BIT_JCASHASHMAP_RESERVE = 4; |
| |
| // data storage |
| // slots start with _ to prevent name collision with JCas style getters and setters. |
| |
| //@formatter:off |
| /** |
| * Experiment: |
| * goal: speed up allocation and maybe improve locality of reference |
| * a) have _intData and _refData point to |
| * 1) for array sizes < 256, a common shared array used with an offset |
| * 2) for array sizes > 256, individual arrays as is the previous design case |
| * |
| * b) have accesses use an offset kept in the flags; |
| * allocate in blocks of 1k |
| * the larger, the less java object overhead per |
| * the larger, the less "breakage" waste |
| * the smaller, the better GC |
| * offset = 10 bits * 2 (one for int, one for ref) |
| * |
| * results: on 16-way processor (64 hyperthreaded cores), caused 2x slowdown, probably due to cache |
| * contention. |
| */ |
| //@formatter:on |
| private final int[] _intData; |
| private final Object[] _refData; |
| protected final int _id; // a separate slot for access without loading _intData object |
| private int _flags = 0; // a set of flags |
| // bit 0 (least significant): fs is in one or more non-bag indexes |
| // bit 1 is on for Pear trampoline FS sharing base int/ref data |
| // bit 2 is on for "reserve" element in JCasHashMap |
| // bit 3-20 reserved |
| // bits 21-30 reserved // experiment: ref offset |
| // bits 11-20 reserved // experiment: int offset |
| // bit 31 reserved |
| |
| /** |
| * These next two object references are the same for every FS of this class created in one view. |
| * So, they could be stored in a shared object But that would trade off saving one "reference" for |
| * adding one extra load to get to the value This design uses more space instead. |
| */ |
| |
| /** |
| * The view this Feature Structure was originally created in. Feature Structures may be indexed in |
| * multiple views, or in no views. |
| * |
| * Also used to access other metadata including the type system |
| */ |
| public final CASImpl _casView; |
| |
| private TypeImpl _typeImpl; // for backwards compatibility and deser typed arrays: support |
| // switching the type |
| |
| // Called only to generate a dummy value for the REMOVED flag in bag indexes |
| |
| public FeatureStructureImplC() { |
| _casView = null; |
| _typeImpl = null; |
| _intData = null; |
| _refData = null; |
| _id = 0; |
| } |
| |
| /** |
| * For use in creating search keys |
| * |
| * @param id |
| * - |
| */ |
| protected FeatureStructureImplC(int id) { |
| _casView = null; |
| _typeImpl = null; |
| _intData = null; |
| _refData = null; |
| _id = id; |
| } |
| |
| /** |
| * For non-JCas use, Internal Use Only, called by cas.createFS via generators |
| */ |
| protected FeatureStructureImplC(TypeImpl type, CASImpl casView) { |
| _casView = casView; |
| _typeImpl = type; |
| |
| _id = casView.getNextFsId((TOP) this); |
| |
| if (_casView.maybeMakeBaseVersionForPear(this, _typeImpl)) { |
| _setPearTrampoline(); |
| } |
| |
| FeatureStructureImplC baseFs = _casView.pearBaseFs; |
| if (null != baseFs) { |
| _intData = baseFs._intData; |
| _refData = baseFs._refData; |
| _casView.pearBaseFs = null; |
| } else { |
| _intData = _allocIntData(); |
| _refData = _allocRefData(); |
| } |
| |
| if (traceFSs && !(this instanceof CommonArrayFS)) { |
| _casView.traceFSCreate(this); |
| } |
| |
| _casView.maybeHoldOntoFS(this); |
| } |
| |
| /** |
| * For JCas use (done this way to allow "final") The TypeImpl is derived from the JCas cover class |
| * name |
| * |
| * @param jcasImpl |
| * - the view this is being created in |
| */ |
| protected FeatureStructureImplC(JCasImpl jcasImpl) { |
| _casView = jcasImpl.getCasImpl(); |
| _typeImpl = _casView.getTypeSystemImpl().getJCasRegisteredType(getTypeIndexID()); |
| _id = _casView.getNextFsId((TOP) this); |
| |
| if (null == _typeImpl) { |
| throw new CASRuntimeException(CASRuntimeException.JCAS_TYPE_NOT_IN_CAS, |
| this.getClass().getName()); |
| } |
| |
| if (_casView.maybeMakeBaseVersionForPear(this, _typeImpl)) { |
| _setPearTrampoline(); |
| } |
| |
| FeatureStructureImplC baseFs = _casView.pearBaseFs; |
| if (null != baseFs) { |
| _intData = baseFs._intData; |
| _refData = baseFs._refData; |
| _casView.pearBaseFs = null; |
| } else { |
| _intData = _allocIntData(); |
| _refData = _allocRefData(); |
| } |
| |
| if (traceFSs && !(this instanceof CommonArrayFS)) { |
| _casView.traceFSCreate(this); |
| } |
| |
| _casView.maybeHoldOntoFS(this); |
| |
| // if (_typeImpl.featUimaUID != null) { |
| // final int id = _casView.getAndIncrUimaUID(); |
| // _setLongValueNcNj(_typeImpl.featUimaUID, id); |
| // _casView.add2uid2fs(id, (TOP)this); |
| // } |
| } |
| |
| /** |
| * For temporary marker annotations. Does not assign an ID from the CAS ID generator and never |
| * retains the annotation. We also do not trace this annotation. |
| */ |
| protected FeatureStructureImplC(JCasImpl jcasImpl, int aId) { |
| _casView = jcasImpl.getCasImpl(); |
| _typeImpl = _casView.getTypeSystemImpl().getJCasRegisteredType(getTypeIndexID()); |
| _id = aId; |
| |
| if (null == _typeImpl) { |
| throw new CASRuntimeException(CASRuntimeException.JCAS_TYPE_NOT_IN_CAS, |
| this.getClass().getName()); |
| } |
| |
| if (_casView.maybeMakeBaseVersionForPear(this, _typeImpl)) { |
| _setPearTrampoline(); |
| } |
| |
| FeatureStructureImplC baseFs = _casView.pearBaseFs; |
| if (null != baseFs) { |
| _intData = baseFs._intData; |
| _refData = baseFs._refData; |
| _casView.pearBaseFs = null; |
| } else { |
| _intData = _allocIntData(); |
| _refData = _allocRefData(); |
| } |
| } |
| |
| private int[] _allocIntData() { |
| final int c = _typeImpl.nbrOfUsedIntDataSlots; |
| if (c != 0) { |
| // _setIntDataArrayOffset(_casView.allocIntData(c)); |
| // return _casView.getReturnIntDataForAlloc(); |
| return new int[c]; |
| } |
| return null; |
| } |
| |
| private Object[] _allocRefData() { |
| final int c = _typeImpl.nbrOfUsedRefDataSlots; |
| if (c != 0) { |
| // _setRefDataArrayOffset(_casView.allocRefData(c)); |
| // return _casView.getReturnRefDataForAlloc(); |
| return new Object[c]; |
| } |
| return null; |
| } |
| |
| // *********************** |
| // Index Add Remove |
| // *********************** |
| |
| /** |
| * add the corresponding FeatureStructure to all Cas indexes in the view where this FS was created |
| */ |
| public void addToIndexes() { |
| _casView.addFsToIndexes(this); |
| } |
| |
| /** |
| * add this FS to indexes in a specific view, perhaps different from the creation view |
| * |
| * @param jcas |
| * the JCas |
| */ |
| public void addToIndexes(JCas jcas) { |
| jcas.getCas().addFsToIndexes(this); |
| } |
| |
| public void addToIndexes(CAS cas) { |
| cas.addFsToIndexes(this); |
| } |
| |
| /** |
| * remove the corresponding FeatureStructure from all Cas indexes in the view where this FS was |
| * created |
| */ |
| public void removeFromIndexes() { |
| removeFromIndexes(_casView); |
| } |
| |
| /** |
| * remove this FS from indexes in a specific view, perhaps different from the view where this was |
| * created. |
| * |
| * @param cas |
| * the Cas |
| */ |
| public void removeFromIndexes(CAS cas) { |
| cas.removeFsFromIndexes(this); |
| } |
| |
| /** |
| * remove this FS from indexes in a specific view, perhaps different from the view where this was |
| * created. |
| * |
| * @param jcas |
| * the Cas |
| */ |
| public void removeFromIndexes(JCas jcas) { |
| jcas.removeFsFromIndexes(this); |
| } |
| |
| public LowLevelCAS getLowLevelCas() { |
| return _casView; |
| } |
| |
| // ******************************* |
| // IDs and Type |
| // ******************************* |
| /** |
| * NOTE: Possible name collision |
| * |
| * @return the internal id of this fs - unique to this CAS, a positive int |
| */ |
| @Override |
| public final int getAddress() { |
| return _casView.ll_getFSRef(this); // adds this fs to the internal map if needed |
| }; |
| |
| @Override |
| public final int _id() { |
| return _id; |
| }; |
| |
| /** |
| * Returns the UIMA TypeImpl value |
| */ |
| @Override |
| public Type getType() { |
| return _typeImpl; |
| } |
| |
| /** |
| * starts with _ |
| * |
| * @return the UIMA TypeImpl for this Feature Structure |
| */ |
| @Override |
| public int _getTypeCode() { |
| return _typeImpl.getCode(); |
| } |
| |
| public CASImpl _getView() { |
| return _casView; |
| } |
| |
| //@formatter:off |
| /* ********************************************************* |
| * Get and Set features indirectly, via Feature objects |
| * |
| * There are two implementations, depending on whether or not |
| * the feature has a JCas getter/setter. |
| * - If yes, then these just delegate to that (via a |
| * functional interface stored in the Feature) |
| * -- there are multiple functional interfaces, corresponding |
| * to the all the different (primitive) return values: |
| * boolean, byte, short, int, long, float, double, and "Object" |
| * used for String and FeatureStructures |
| * - if no, then converge the code to an _intData or _refData reference |
| ***********************************************************/ |
| //@formatter:on |
| |
| //@formatter:off |
| /************************************** |
| * S E T T E R S |
| * 4 levels of checking: |
| * - check feature for validity (fv) |
| * -- this is skipped with feature comes from fs type info (internal calls) |
| * - check for setting something which could corrupt indexes (ci) |
| * -- this is skipped when the caller knows |
| * --- the FS is not in the index, perhaps because they just created it |
| * -- skipped when the range is not a valid index key |
| * - check for needing to log (journal) setting (jrnl) |
| * -- this is skipped when the caller knows |
| * --- no journalling is enabled or |
| * --- the FS is a new (above-the-line) FS |
| * - check the value is suitable |
| * -- this can be skipped if Java is doing the checking (via the type of the argument) |
| * -- done for string subtypes and Feature References |
| * --- skipped if the caller knows the value is OK (e.g., it is copying an existing FS) |
| * |
| * The jrnl and ic checks require the FeatureImpl. |
| * For setters using these checks, there are two versions: |
| * - one with the arg being the FeatureImpl (if it is available at the caller) and |
| * - one with the int offset (common code coverts this to the Feature Impl). |
| * |
| * all 4 checks are normally done by the standard API call in the FeatureStructure interface |
| * setXyzValue(Feature, value) |
| * |
| * Besides the standard API call, other setter methods have suffixes and prefixes to the setter name |
| * - prefix is "_" to avoid conflicting with existing other names |
| * - suffixes are: |
| * -- Nfc: skip feature validity checking, ( ! fv, jrnl, ci ) (int/Feat) |
| * -- NcNj: implies Nfc, ( ! fv, ! jrnl, ! ci ) (int/Feat) |
| * -- NcWj: implies Nfc, ( ! fv, jrnl, ! ci ) (int) |
| * The is for setters where value checking might be needed (i.e., Java checking isn't sufficient) |
| * -- NcNjNv: implies Nfc, skips all checks |
| * |
| * For JCas setters: convert offset to feature |
| **************************************/ |
| //@formatter:on |
| |
| private void checkFeatRange(Feature feat, String shortRangeName) { |
| if (!(feat.getRange().getShortName().equals(shortRangeName))) { |
| /* Trying to access value of feature "{0}" as "{1}", but range of feature is "{2}". */ |
| throw new CASRuntimeException(CASRuntimeException.INAPPROP_RANGE, feat.getName(), |
| "uima.cas." + shortRangeName, feat.getRange().getName()); |
| } |
| |
| } |
| |
| @Override |
| public void setBooleanValue(Feature feat, boolean v) { |
| checkFeatRange(feat, "Boolean"); |
| _setIntValueCJ((FeatureImpl) feat, v ? 1 : 0); |
| } |
| |
| public void _setBooleanValueNfc(int adjOffset, boolean v) { |
| _setIntValueNfcCJ(adjOffset, v ? 1 : 0); |
| } |
| |
| public final void _setBooleanValueNcNj(FeatureImpl fi, boolean v) { |
| _setIntValueCommon(fi, v ? 1 : 0); |
| } |
| |
| public final void _setBooleanValueNcNj(int adjOffset, boolean v) { |
| _setIntValueCommon(adjOffset, v ? 1 : 0); |
| } |
| |
| @Override |
| public void setByteValue(Feature feat, byte v) { |
| checkFeatRange(feat, "Byte"); |
| _setIntValueCJ((FeatureImpl) feat, v); |
| } |
| |
| public void _setByteValueNfc(int adjOffset, byte v) { |
| _setIntValueNfcCJ(adjOffset, v); |
| } |
| |
| public void _setByteValueNcNj(FeatureImpl fi, byte v) { |
| _setIntValueCommon(fi, v); |
| } |
| |
| public void _setByteValueNcNj(int adjOffset, byte v) { |
| _setIntValueCommon(adjOffset, v); |
| } |
| |
| @Override |
| public void setShortValue(Feature feat, short v) { |
| checkFeatRange(feat, "Short"); |
| _setIntValueCJ((FeatureImpl) feat, v); |
| } |
| |
| public void _setShortValueNfc(int adjOffset, short v) { |
| _setIntValueNfcCJ(adjOffset, v); |
| } |
| |
| public void _setShortValueNcNj(FeatureImpl fi, short v) { |
| _setIntValueCommon(fi, v); |
| } |
| |
| public void _setShortValueNcNj(int adjOffset, short v) { |
| _setIntValueCommon(adjOffset, v); |
| } |
| |
| @Override |
| public void setIntValue(Feature feat, int v) { |
| checkFeatRange(feat, "Integer"); |
| _setIntValueCJ((FeatureImpl) feat, v); |
| } |
| |
| public void _setIntValueNfc(int adjOffset, int v) { |
| _setIntValueNfcCJ(adjOffset, v); |
| } |
| |
| public void _setIntValueNcNj(FeatureImpl fi, int v) { |
| _setIntValueCommon(fi, v); |
| } |
| |
| public void _setIntValueNcNj(int adjOffset, int v) { |
| _setIntValueCommon(adjOffset, v); |
| } |
| |
| @Override |
| public void setLongValue(Feature feat, long v) { |
| checkFeatRange(feat, "Long"); |
| _setLongValueCJ((FeatureImpl) feat, v); |
| } |
| |
| public void _setLongValueNfc(int adjOffset, long v) { |
| FeatureImpl fi = _getFeatFromAdjOffset(adjOffset, true); |
| _casView.setLongValue(this, fi, v); // has trace call |
| } |
| |
| public void _setLongValueNcNj(FeatureImpl fi, long v) { |
| _setLongValueNcNj(fi.getAdjustedOffset(), v); |
| } |
| |
| public void _setLongValueNcNj(int adjOffset, long v) { |
| // final int offset = adjOffset + _getIntDataArrayOffset(); |
| _intData[adjOffset] = (int) v; // narrowing cast discards all but lowest 32 bits; may change |
| // sign of value |
| _intData[adjOffset + 1] = (int) (v >> 32); |
| if (traceFSs) { |
| _casView.traceFSfeat(this, _getFeatFromAdjOffset(adjOffset, true), v); |
| } |
| } |
| |
| @Override |
| public void setFloatValue(Feature feat, float v) { |
| checkFeatRange(feat, "Float"); |
| _setIntValueCJ((FeatureImpl) feat, CASImpl.float2int(v)); |
| } |
| |
| protected void _setFloatValueNfc(int adjOffset, float v) { |
| _setIntValueNfc(adjOffset, CASImpl.float2int(v)); |
| } |
| |
| public void _setFloatValueNcNj(FeatureImpl fi, float v) { |
| _setIntValueCommon(fi, CASImpl.float2int(v)); |
| // _intData[fi.getAdjustedOffset()] = CASImpl.float2int(v); |
| } |
| |
| public void _setFloatValueNcNj(int adjOffset, float v) { |
| _setIntValueCommon(adjOffset, CASImpl.float2int(v)); |
| // _intData[adjOffset] = CASImpl.float2int(v); |
| } |
| |
| @Override |
| public void setDoubleValue(Feature feat, double v) { |
| checkFeatRange(feat, "Double"); |
| _setLongValueCJ((FeatureImpl) feat, CASImpl.double2long(v)); |
| } |
| |
| protected void _setDoubleValueNfc(int adjOffset, double v) { |
| _setLongValueNfc(adjOffset, CASImpl.double2long(v)); |
| } |
| |
| public void _setDoubleValueNcNj(FeatureImpl fi, double v) { |
| _setLongValueNcNj(fi, CASImpl.double2long(v)); |
| } |
| |
| public void _setDoubleValueNcNj(int adjOffset, double v) { |
| _setLongValueNcNj(adjOffset, CASImpl.double2long(v)); |
| } |
| |
| @Override |
| public void setStringValue(Feature feat, String v) { |
| if (IS_ENABLE_RUNTIME_FEATURE_VALUE_VALIDATION) { |
| featureValueValidation(feat, v); // verifies feat can take a string |
| } |
| subStringRangeCheck(feat, v); |
| _setRefValueCJ((FeatureImpl) feat, v); |
| } |
| |
| public void _setStringValueNfc(int adjOffset, String v) { |
| FeatureImpl fi = _getFeatFromAdjOffset(adjOffset, false); |
| subStringRangeCheck(fi, v); |
| _setRefValueNfcCJ(fi, v); |
| } |
| |
| public void _setStringValueNcNj(FeatureImpl fi, String v) { |
| subStringRangeCheck(fi, v); |
| _setRefValueCommon(fi, v); |
| } |
| |
| /** |
| * Skips substring range checking, but maybe does journalling |
| * |
| * @param adjOffset |
| * offset |
| * @param v |
| * to set |
| */ |
| public void _setStringValueNcWj(int adjOffset, String v) { |
| _setRefValueCommonWj(_getFeatFromAdjOffset(adjOffset, false), v); |
| } |
| |
| @Override |
| public void setFeatureValue(Feature feat, FeatureStructure v) { |
| FeatureImpl fi = (FeatureImpl) feat; |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(feat); |
| } |
| if (IS_ENABLE_RUNTIME_FEATURE_VALUE_VALIDATION) { |
| featureValueValidation(feat, v); |
| } |
| // no need to check for index corruption because fs refs can't be index keys |
| _setRefValueCommon(fi, _maybeGetBaseForPearFs((TOP) v)); |
| _casView.maybeLogUpdate(this, fi); |
| } |
| |
| public void _setFeatureValueNcNj(FeatureImpl fi, Object v) { |
| _setRefValueCommon(fi, v); |
| } |
| |
| public void _setFeatureValueNcNj(int adjOffset, Object v) { |
| _setRefValueCommon(adjOffset, v); |
| } |
| |
| /** |
| * Called when setting a FS value which might be a trampoline |
| * |
| * @param v |
| * the FS to check |
| * @param <N> |
| * the type of the FS |
| * @return the FS or if it was a trampoline, the base FS |
| */ |
| protected <N extends TOP> N _maybeGetBaseForPearFs(N v) { |
| return (v == null) ? null : v._maybeGetBaseForPearFs(); |
| } |
| |
| /** |
| * Called to convert to the base FS from a Pear version |
| * |
| * @param <N> |
| * the type of the FS |
| * @return the FS or if it was a trampoline, the base FS |
| */ |
| public <N extends TOP> N _maybeGetBaseForPearFs() { |
| return _isPearTrampoline() ? _casView.getBaseFsFromTrampoline((N) this) : (N) this; |
| } |
| |
| /** |
| * Called when getting a FS value which might need to return a Pear context's trampoline |
| * |
| * @param v |
| * the FS to check |
| * @param <N> |
| * the type of the FS |
| * @return the FS or if we're in a Pear context, perhaps the trampoline (only some classes might |
| * have trampolines) |
| */ |
| protected <N extends TOP> N _maybeGetPearFs(N v) { |
| return (_casView.inPearContext()) ? CASImpl.pearConvert(v) : v; |
| } |
| |
| /** |
| * @param <N> |
| * the type of the FS |
| * @return the FS or if we're in a Pear context and the PEAR defines a different version, the PEAR |
| * version. |
| */ |
| public <N extends TOP> N _maybeGetPearFs() { |
| return (_casView.inPearContext()) ? CASImpl.pearConvert((N) this) : (N) this; |
| } |
| |
| /** |
| * Nc - no check, Wj = with journaling if needed |
| * |
| * @param adjOffset |
| * - |
| * @param v |
| * - |
| */ |
| public void _setFeatureValueNcWj(int adjOffset, FeatureStructure v) { |
| _setRefValueCommonWj(_getFeatFromAdjOffset(adjOffset, false), _maybeGetBaseForPearFs((TOP) v)); |
| } |
| |
| // @Override |
| // public void setJavaObjectValue(Feature feat, Object v) { |
| // FeatureImpl fi = (FeatureImpl) feat; |
| // |
| // if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) featureValidation(feat); |
| // if (IS_ENABLE_RUNTIME_FEATURE_VALUE_VALIDATION) featureValueValidation(feat, v); |
| // _setRefValueCJ(fi, v); |
| // } |
| |
| // public void _setJavaObjectValueNcNj(FeatureImpl fi, Object v) { |
| // _setRefValueCommon(fi, v); |
| // } |
| |
| @Override |
| public void setFeatureValueFromString(Feature feat, String s) throws CASRuntimeException { |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(feat); |
| } |
| CASImpl.setFeatureValueFromString(this, (FeatureImpl) feat, s); |
| } |
| |
| /** |
| * All 3 checks |
| * |
| * @param fi |
| * - the feature |
| * @param v |
| * - the value |
| */ |
| protected void _setIntValueCJ(FeatureImpl fi, int v) { |
| if (!fi.isInInt) { |
| |
| /** Trying to access value of feature "{0}" as "{1}", but range of feature is "{2}". */ |
| throw new CASRuntimeException(CASRuntimeException.INAPPROP_RANGE, fi.getName(), |
| "boolean, byte, short, int, or float", fi.getRange().getName()); |
| |
| } |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(fi); |
| } |
| _casView.setWithCheckAndJournal((TOP) this, fi.getCode(), () -> _setIntValueCommon(fi, v)); |
| |
| } |
| |
| /** |
| * All 3 checks for long |
| * |
| * @param fi |
| * - the feature |
| * @param v |
| * - the value |
| */ |
| protected void _setLongValueCJ(FeatureImpl fi, long v) { |
| if (!fi.isInInt) { |
| /** Trying to access value of feature "{0}" as "{1}", but range of feature is "{2}". */ |
| throw new CASRuntimeException(CASRuntimeException.INAPPROP_RANGE, fi.getName(), |
| "long or double", fi.getRange().getName()); |
| } |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(fi); |
| } |
| _casView.setLongValue(this, fi, v); |
| } |
| |
| /** |
| * 2 checks, no feature check |
| * |
| * @param adjOffset |
| * - the feature offset |
| * @param v |
| * - the value |
| */ |
| protected void _setIntValueNfcCJ(int adjOffset, int v) { |
| FeatureImpl fi = _getFeatFromAdjOffset(adjOffset, true); |
| _casView.setWithCheckAndJournal((TOP) this, fi, () -> _setIntValueCommon(adjOffset, v)); |
| } |
| |
| /** |
| * 2 checks, no feature check |
| * |
| * @param fi |
| * - the feature |
| * @param v |
| * - the value |
| */ |
| protected void _setLongValueNfcCJ(FeatureImpl fi, long v) { |
| _casView.setLongValue(this, fi, v); |
| } |
| |
| protected void _setRefValueCJ(FeatureImpl fi, Object v) { |
| if (fi.isInInt) { |
| /** Trying to access value of feature "{0}" as "{1}", but range of feature is "{2}". */ |
| throw new CASRuntimeException(CASRuntimeException.INAPPROP_RANGE, fi.getName(), "int", |
| fi.getRange().getName()); |
| } |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(fi); |
| } |
| _casView.setWithCheckAndJournal((TOP) this, fi.getCode(), () -> _setRefValueCommon(fi, v)); |
| |
| } |
| |
| /** |
| * 2 checks, no feature check |
| * |
| * @param fi |
| * - the feature |
| * @param v |
| * - the value |
| */ |
| protected void _setRefValueNfcCJ(FeatureImpl fi, Object v) { |
| _casView.setWithCheckAndJournal((TOP) this, fi.getCode(), () -> _setRefValueCommon(fi, v)); |
| } |
| |
| //@formatter:off |
| /******************************************************************************************************** |
| * G E T T E R S |
| * |
| * (The array getters are part of the Classes for the built-in arrays, here are only the non-array ones) |
| * |
| * getXyzValue(Feature feat) - this is the standard from V2 plain API |
| * - it does validity checking (normally) that the feature belongs to the type |
| * getXyzValueNc(FeatureImpl feat) - skips the validity checking that the feature belongs to the type. |
| *********************************************************************************************************/ |
| //@formatter:on |
| @Override |
| public boolean getBooleanValue(Feature feat) { |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(feat); |
| } |
| checkFeatRange(feat, "Boolean"); |
| return _getBooleanValueNc((FeatureImpl) feat); |
| } |
| |
| public boolean _getBooleanValueNc(FeatureImpl fi) { |
| return _getIntValueCommon(fi) == 1; |
| } |
| |
| // for JCas use |
| public boolean _getBooleanValueNc(int adjOffset) { |
| return _getIntValueCommon(adjOffset) == 1; |
| } |
| |
| @Override |
| public byte getByteValue(Feature feat) { |
| checkFeatRange(feat, "Byte"); |
| return (byte) _getIntValueCommon((FeatureImpl) feat); |
| } |
| |
| public byte _getByteValueNc(FeatureImpl feat) { |
| return (byte) _getIntValueNc(feat); |
| } |
| |
| public byte _getByteValueNc(int adjOffset) { |
| return (byte) _getIntValueNc(adjOffset); |
| } |
| |
| @Override |
| public short getShortValue(Feature feat) { |
| checkFeatRange(feat, "Short"); |
| return (short) _getIntValueCommon((FeatureImpl) feat); |
| } |
| |
| public short _getShortValueNc(FeatureImpl feat) { |
| return (short) _getIntValueNc(feat); |
| } |
| |
| public short _getShortValueNc(int adjOffset) { |
| return (short) _getIntValueNc(adjOffset); |
| } |
| |
| @Override |
| public int getIntValue(Feature feat) { |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(feat); |
| } |
| checkFeatRange(feat, "Integer"); |
| return _getIntValueCommon((FeatureImpl) feat); |
| } |
| |
| public int _getIntValueNc(FeatureImpl feat) { |
| return _getIntValueCommon(feat); |
| } |
| |
| public int _getIntValueNc(int adjOffset) { |
| return _getIntValueCommon(adjOffset); |
| } |
| |
| @Override |
| public long getLongValue(Feature feat) { |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(feat); |
| } |
| checkFeatRange(feat, "Long"); |
| return _getLongValueNc((FeatureImpl) feat); |
| } |
| |
| public long _getLongValueNc(FeatureImpl feat) { |
| return _getLongValueNc(feat.getAdjustedOffset()); |
| |
| } |
| |
| public long _getLongValueNc(int adjOffset) { |
| /** |
| * When converting the lower 32 bits to a long, sign extension is done, so have to 0 out those |
| * bits before or-ing in the high order 32 bits. |
| */ |
| // final int offset = adjOffset + _getIntDataArrayOffset(); |
| return ((_intData[adjOffset]) & 0x00000000ffffffffL) | (((long) _intData[adjOffset + 1]) << 32); |
| } |
| |
| @Override |
| public float getFloatValue(Feature feat) { |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(feat); |
| } |
| checkFeatRange(feat, "Float"); |
| return _getFloatValueNc(((FeatureImpl) feat).getAdjustedOffset()); |
| } |
| |
| public float _getFloatValueNc(FeatureImpl fi) { |
| return _getFloatValueNc(fi.getAdjustedOffset()); |
| } |
| |
| public float _getFloatValueNc(int adjOffset) { |
| return CASImpl.int2float(_getIntValueCommon(adjOffset)); |
| } |
| |
| @Override |
| public double getDoubleValue(Feature feat) { |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(feat); |
| } |
| checkFeatRange(feat, "Double"); |
| return _getDoubleValueNc((FeatureImpl) feat); |
| } |
| |
| public double _getDoubleValueNc(FeatureImpl fi) { |
| return _getDoubleValueNc(fi.getAdjustedOffset()); |
| } |
| |
| public double _getDoubleValueNc(int adjOffset) { |
| return CASImpl.long2double(_getLongValueNc(adjOffset)); |
| } |
| |
| @Override |
| public String getStringValue(Feature feat) { |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(feat); |
| } |
| // checkFeatRange(feat, "String"); |
| return _getStringValueNc((FeatureImpl) feat); |
| } |
| |
| public String _getStringValueNc(FeatureImpl feat) { |
| return _getStringValueNc(feat.getAdjustedOffset()); |
| } |
| |
| public String _getStringValueNc(int adjOffset) { |
| return (String) _refData[adjOffset /* + _getRefDataArrayOffset() */]; |
| } |
| |
| @Override |
| public TOP getFeatureValue(Feature feat) { |
| if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) { |
| _Check_feature_defined_for_this_type(feat); |
| } |
| _check_feature_range_is_FeatureStructure(feat, this); |
| return _getFeatureValueNc((FeatureImpl) feat); |
| } |
| |
| public TOP _getFeatureValueNc(FeatureImpl feat) { |
| return _getFeatureValueNc(feat.getAdjustedOffset()); |
| } |
| |
| public TOP _getFeatureValueNc(int adjOffset) { |
| return _maybeGetPearFs((TOP) _refData[adjOffset /* + _getRefDataArrayOffset() */]); |
| } |
| |
| // @Override |
| // public Object getJavaObjectValue(Feature feat) { |
| // if (IS_ENABLE_RUNTIME_FEATURE_VALIDATION) featureValidation(feat); |
| // return _getJavaObjectValueNc((FeatureImpl) feat); |
| // } |
| // |
| // public Object _getJavaObjectValueNc(FeatureImpl fi) { return _getRefValueCommon(fi); } |
| // |
| // public Object _getJavaObjectValueNc(int adjOffset) { return _getRefValueCommon(adjOffset); } |
| // |
| /** |
| * @return the CAS view where this FS was created |
| */ |
| @Override |
| public CAS getCAS() { |
| return _casView; |
| } |
| |
| public CASImpl getCASImpl() { // was package private 9-03 |
| return _casView; |
| } |
| |
| //@formatter:off |
| /** |
| * See http://www.javaworld.com/article/2076332/java-se/how-to-avoid-traps-and-correctly-override-methods-from-java-lang-object.html |
| * for suggestions on avoiding bugs in implementing clone |
| * |
| * Because we have final fields for _intData, _refData, and _id, we can't use clone. |
| * Instead, we use the createFS to create the FS of the right type. This will use the generators. |
| * |
| * Strategy for cloning: |
| * Goal is to create an independent instance of some subtype of this class, with |
| * all the fields properly copied from this instance. |
| * - some fields could be in the _intData and _refData |
| * - some fields could be stored as features |
| * |
| * Subcases to handle: |
| * - arrays - these have no features. |
| * |
| * Note: CasCopier doesn't call this because it needs to do a deep copy |
| * This is not used by the framework |
| * |
| * @return a new Feature Structure as a new instance of the same class, |
| * with a new _id field, |
| * with its features set to the values of the features in this Feature Structure |
| * @throws CASRuntimeException (different from Object.clone()) if an exception occurs |
| */ |
| //@formatter:on |
| @Override |
| public FeatureStructureImplC clone() throws CASRuntimeException { |
| |
| if (_typeImpl.isArray()) { |
| CommonArrayFS original = (CommonArrayFS) this; |
| CommonArrayFS copy = (CommonArrayFS) _casView.createArray(_typeImpl, original.size()); |
| copy.copyValuesFrom(original); |
| return (FeatureStructureImplC) copy; |
| } |
| |
| TOP fs = _casView.createFS(_typeImpl); |
| TOP srcFs = (TOP) this; |
| |
| fs._copyIntAndRefArraysEqTypesFrom(srcFs); |
| |
| /* copy all the feature values except the sofa ref which is already set as part of creation */ |
| // for (FeatureImpl feat : _typeImpl.getFeatureImpls()) { |
| // CASImpl.copyFeature(srcFs, feat, fs); |
| // } // end of for loop |
| return fs; |
| } |
| |
| @Override |
| public int hashCode() { |
| return _id; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see java.lang.Object#equals(java.lang.Object) must match hashCode must match comparator == 0, |
| * equal == true Only valid for FSs in same CAS |
| */ |
| @Override |
| public boolean equals(Object obj) { |
| if (obj instanceof FeatureStructureImplC) { |
| FeatureStructureImplC c2 = (FeatureStructureImplC) obj; |
| |
| if (c2._id != _id) { |
| return false; |
| } |
| |
| return (_casView == null && c2._casView == null) || (_casView != null && c2._casView != null |
| && (_casView == c2._casView || _casView.getBaseCAS() == c2._casView.getBaseCAS())); |
| |
| // if (_casView == null && c2._casView == null) { |
| // return true; // special case for removed marker |
| // } |
| // if (_casView != null && c2._casView != null && |
| // (_casView == c2._casView || |
| // _casView.getBaseCAS() == c2._casView.getBaseCAS())) { |
| // return true; |
| // } |
| } |
| // throw new IllegalArgumentException("Can't invoke equals on two FS from different CASes."); |
| return false; |
| } |
| |
| // /////////////////////////////////////////////////////////////////////////// |
| // Pretty printing. |
| // public for use by superclass for backwards compatibility |
| public static class PrintReferences { |
| |
| static final int NO_LABEL = 0; |
| |
| static final int WITH_LABEL = 1; |
| |
| static final int JUST_LABEL = 2; |
| |
| private static final String refNamePrefix = "#"; |
| |
| // map from fs to special string #nnnn for printing refs |
| // three states: |
| // 1) key not in map |
| // 2) key in map, but value is "seen once" - first time value seen |
| // 3) key in map, value is #nnnn - when value is seen more than once |
| private Map<FeatureStructure, String> tree = new HashMap<>(); |
| |
| private Set<FeatureStructure> seen = new HashSet<>(); |
| |
| private int count; |
| |
| private PrintReferences() { |
| count = 0; |
| } |
| |
| /** |
| * @param fs |
| * - |
| * @return true if seen before |
| */ |
| boolean addReference(FeatureStructure fs) { |
| String v = tree.get(fs); |
| if (null == v) { |
| tree.put(fs, "seen once"); |
| return false; |
| } |
| if (v.equals("seen once")) { |
| tree.put(fs, refNamePrefix + Integer.toString(count++)); |
| } |
| return true; |
| } |
| |
| String getLabel(FeatureStructure ref) { |
| return tree.get(ref); |
| } |
| |
| int printInfo(FeatureStructure ref) { |
| String k = tree.get(ref); |
| if (k == null || k.equals("seen once")) { |
| return NO_LABEL; |
| } |
| if (seen.contains(ref)) { |
| return JUST_LABEL; |
| } |
| seen.add(ref); |
| return WITH_LABEL; |
| } |
| |
| } |
| |
| private final void getPrintRefs(PrintReferences printRefs) { |
| getPrintRefs(printRefs, this); |
| } |
| |
| /** |
| * This is called, once, at the top level thing being printed. It recursively descends any |
| * references, and updates the PrintReferences with info needed to handle circular structures |
| * |
| * @param printRefs |
| * the PrintReferences to update |
| * @param fs |
| * the top level FS being pretty printed, to descend if needed |
| */ |
| private final void getPrintRefs(PrintReferences printRefs, FeatureStructureImplC fs) { |
| if (null == fs) { |
| return; |
| } |
| boolean seenBefore = printRefs.addReference(fs); |
| if (seenBefore) { |
| return; |
| } |
| |
| final TypeImpl ti = fs._typeImpl; |
| if (ti != null) { // null for REMOVED marker |
| // for v2 style, don't descend fs arrays; these are omitted |
| if (!IS_V2_PRETTY_PRINT && ti.isArray() && (fs instanceof FSArray)) { |
| for (TOP item : ((FSArray) fs)._getTheArray()) { |
| getPrintRefs(printRefs, item); |
| } |
| } else { |
| if (fs instanceof UimaSerializableFSs) { |
| ((UimaSerializableFSs) fs)._save_fsRefs_to_cas_data(); |
| } |
| ti.getFeaturesAsStream().filter(fi -> fi.getRangeImpl().isRefType) // is ref type |
| .map(fi -> fs.getFeatureValue(fi)) // get the feature value |
| .filter(refFs -> refFs != null) // skip null ones |
| .forEachOrdered(refFs -> getPrintRefs(printRefs, refFs)); |
| } |
| } |
| } |
| |
| @Override |
| public String toString() { |
| return toString(3); |
| } |
| |
| @Override |
| public String toString(int indent) { |
| StringBuilder buf = new StringBuilder(); |
| prettyPrint(0, indent, buf, true, null); |
| return buf.toString(); |
| } |
| |
| /* |
| * This next bit is to remain backward compatible with callers using StringBuilders or |
| * StringBuffers. (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.impl.FeatureStructureImpl#prettyPrint(int, int, |
| * java.lang.StringBuilder, boolean) |
| */ |
| @Override |
| public void prettyPrint(int indent, int incr, StringBuilder buf, boolean useShortNames) { |
| prettyPrint(indent, incr, buf, useShortNames, null); |
| } |
| |
| @Override |
| public void prettyPrint(int indent, int incr, StringBuffer buf, boolean useShortNames) { |
| prettyPrint(indent, incr, buf, useShortNames, null); |
| } |
| |
| /** |
| * Top level, does computation of self-ref Pretty prints this Feature Structure, no trailing nl |
| * Old form - uses string buffer. |
| * |
| * @param indent |
| * the indent amount |
| * @param incr |
| * the amount the indent is increased for a level |
| * @param buf |
| * where the resulting string is built |
| * @param useShortNames |
| * true to use short name |
| * @param s |
| * extra string to print |
| * @deprecated use form with StringBuilder (not StringBuffer) |
| */ |
| @Deprecated |
| @Override |
| public void prettyPrint(int indent, int incr, StringBuffer buf, boolean useShortNames, String s) { |
| PrintReferences printRefs = new PrintReferences(); |
| getPrintRefs(printRefs); |
| prettyPrint(indent, incr, buf, useShortNames, s, printRefs); |
| } |
| |
| /** |
| * Top level, does computation of self-ref Pretty prints this Feature Structure, no trailing nl |
| * |
| * @param indent |
| * the indent amount |
| * @param incr |
| * the amount the indent is increased for a level |
| * @param buf |
| * where the resulting string is built |
| * @param useShortNames |
| * true to use short name |
| * @param s |
| * extra string to print |
| */ |
| @Override |
| public void prettyPrint(int indent, int incr, StringBuilder buf, boolean useShortNames, |
| String s) { |
| PrintReferences printRefs = new PrintReferences(); |
| getPrintRefs(printRefs); |
| prettyPrint(indent, incr, buf, useShortNames, s, printRefs); |
| } |
| |
| // old version from v2 using StringBuffer |
| /** |
| * Internal Use Only, public only for backwards compatibility |
| * |
| * @param indent |
| * - |
| * @param incr |
| * - |
| * @param buf |
| * - |
| * @param useShortNames |
| * - |
| * @param s |
| * - |
| * @param printRefs |
| * - |
| * @deprecated because uses StringBuffer, not builder, for version 2 compatibility only |
| */ |
| @Deprecated |
| public void prettyPrint(int indent, int incr, StringBuffer buf, boolean useShortNames, String s, |
| PrintReferences printRefs) { |
| |
| StringBuilder b2 = new StringBuilder(buf); |
| prettyPrint(indent, incr, b2, useShortNames, s, printRefs); |
| |
| buf.setLength(0); |
| buf.append(b2.toString()); |
| } |
| |
| public void prettyPrint(int indent, // the current indent position |
| int incr, // the delta to indent this FS printing |
| StringBuilder buf, boolean useShortNames, String s, // carries the "#123" id refs for |
| // others to use, labels this fs with |
| // that. |
| PrintReferences printRefs) { |
| prettyPrint(indent, incr, buf, useShortNames, s, printRefs, false); |
| } |
| |
| /** |
| * |
| * @param sb |
| * - |
| */ |
| public void prettyPrintShort(StringBuilder sb) { |
| prettyPrint(0, 2, sb, true, "", new PrintReferences(), true); |
| } |
| |
| /** |
| * recursively called by ppval |
| * |
| * @param indent |
| * - |
| * @param incr |
| * - |
| * @param buf |
| * - |
| * @param useShortNames |
| * - |
| * @param s |
| * - |
| * @param printRefs |
| * - |
| * @param isShortForm_arg |
| * - |
| */ |
| private void prettyPrint(int indent, // the current indent position |
| int incr, // the delta to indent this FS printing |
| final StringBuilder buf, boolean useShortNames, String s, // carries the "#123" id refs |
| // for others to use, labels |
| // this fs with that. |
| PrintReferences printRefs, boolean isShortForm_arg) { // short form only prints type:_id |
| // for refs |
| |
| final boolean isShortForm = |
| // isShortForm_arg; |
| // debug |
| // (this._id == 2512) |
| // ? false |
| // : |
| isShortForm_arg; |
| |
| try { |
| indent += incr; |
| if (!IS_V2_PRETTY_PRINT && indent > 20 * incr) { |
| buf.append(" ... past indent limit ... "); |
| return; |
| } |
| |
| final int printInfo = printRefs.printInfo(this); |
| if (printInfo != PrintReferences.NO_LABEL) { |
| String label = printRefs.getLabel(this); |
| if (!label.equals("seen once")) { |
| buf.append(printRefs.getLabel(this)); |
| } |
| if (printInfo == PrintReferences.JUST_LABEL) { |
| buf.append(IS_V2_PRETTY_PRINT ? ' ' : '\n'); |
| return; |
| } |
| buf.append(' '); |
| } |
| if (_typeImpl == null) { |
| buf.append((_id == 0) ? " Special REMOVED marker " |
| : _isJCasHashMapReserve() ? (" Special JCasHashMap Reserve, id = " + _id) |
| : " Special Search Key, id = " + _id); |
| } else { |
| if (useShortNames) { |
| buf.append(getType().getShortName()); |
| } else { |
| buf.append(getType().getName()); |
| } |
| |
| if (!IS_V2_PRETTY_PRINT) { |
| buf.append(':').append(_id); |
| } |
| |
| if (s != null) { |
| buf.append(" \"" + s + "\""); |
| } |
| } |
| buf.append('\n'); |
| |
| // final int typeClass = this._casView.ll_getTypeClass(this.getType()); |
| |
| if (_typeImpl == null) { // happens for special version which is REMOVED marker |
| return; |
| } |
| switch (_getTypeCode()) { |
| case TypeSystemConstants.stringArrayTypeCode: { |
| StringArray a = (StringArray) this; |
| printArrayElements(a.size(), i -> appendOrNull(buf, a.get(i)), indent, incr, buf); |
| return; |
| } |
| case TypeSystemConstants.intArrayTypeCode: { |
| IntegerArray a = (IntegerArray) this; |
| printArrayElements(a.size(), i -> appendOrNull(buf, Integer.toString(a.get(i))), indent, |
| incr, buf); |
| return; |
| } |
| case TypeSystemConstants.floatArrayTypeCode: { |
| FloatArray a = (FloatArray) this; |
| printArrayElements(a.size(), i -> appendOrNull(buf, Float.toString(a.get(i))), indent, |
| incr, buf); |
| return; |
| } |
| case TypeSystemConstants.booleanArrayTypeCode: { |
| BooleanArray a = (BooleanArray) this; |
| printArrayElements(a.size(), i -> appendOrNull(buf, Boolean.toString(a.get(i))), indent, |
| incr, buf); |
| return; |
| } |
| case TypeSystemConstants.byteArrayTypeCode: { |
| ByteArray a = (ByteArray) this; |
| printArrayElements(a.size(), i -> appendOrNull(buf, Byte.toString(a.get(i))), indent, |
| incr, buf); |
| return; |
| } |
| case TypeSystemConstants.shortArrayTypeCode: { |
| ShortArray a = (ShortArray) this; |
| printArrayElements(a.size(), i -> appendOrNull(buf, Short.toString(a.get(i))), indent, |
| incr, buf); |
| return; |
| } |
| case TypeSystemConstants.longArrayTypeCode: { |
| LongArray a = (LongArray) this; |
| printArrayElements(a.size(), i -> appendOrNull(buf, Long.toString(a.get(i))), indent, |
| incr, buf); |
| return; |
| } |
| case TypeSystemConstants.doubleArrayTypeCode: { |
| DoubleArray a = (DoubleArray) this; |
| printArrayElements(a.size(), i -> appendOrNull(buf, Double.toString(a.get(i))), indent, |
| incr, buf); |
| return; |
| } |
| case TypeSystemConstants.fsArrayTypeCode: { |
| if (IS_V2_PRETTY_PRINT) { |
| break; // v2 did not descend to print FSArray contents |
| } |
| FSArray a = (FSArray) this; |
| printFSArrayElements(a, indent, incr, buf, useShortNames, printRefs, isShortForm); |
| |
| return; |
| } // end of case |
| |
| } // end of switch |
| |
| // if get here, non of the cases in the above switch fit |
| |
| if (this instanceof FSArray) { // catches instance of FSArrays which are "typed" to hold |
| // specific element types |
| if (IS_V2_PRETTY_PRINT) { |
| return; // v2 did not descend to print fs array contents |
| } |
| FSArray a = (FSArray) this; |
| printFSArrayElements(a, indent, incr, buf, useShortNames, printRefs, isShortForm); |
| return; |
| } |
| |
| for (FeatureImpl fi : _typeImpl.getFeatureImpls()) { |
| Misc.indent(buf, indent); |
| buf.append(fi.getShortName() + ": "); |
| TypeImpl range = (TypeImpl) fi.getRange(); |
| if (range.isPrimitive()) { // Strings and string subtypes are primitive |
| addStringOrPrimitive(buf, fi); |
| continue; |
| } |
| |
| // not primitive |
| FeatureStructureImplC val = null; |
| boolean hadException = false; |
| try { |
| val = getFeatureValue(fi); |
| } catch (Exception e) { |
| buf.append("<exception ").append(e.getMessage()).append(">\n"); |
| hadException = true; |
| } |
| if (!hadException) { |
| if (isShortForm) { |
| if (null == val) { |
| buf.append("<null>"); |
| } else { |
| buf.append(val._getTypeImpl().getShortName()).append(':').append(val._id); |
| } |
| } else { |
| // treat sofa refs special, since they're pervasive |
| if (val instanceof Sofa) { |
| buf.append(((Sofa) val).getSofaID()); |
| } else { |
| ppval(val, indent, incr, buf, useShortNames, printRefs, false); |
| } |
| } |
| |
| // if (val != null && !val._typeImpl.getName().equals(CAS.TYPE_NAME_SOFA)) { |
| // val.prettyPrint(indent, incr, buf, useShortNames, null, printRefs); |
| // } else { |
| // buf.append((val == null) ? "<null>\n" : ((SofaFS) val).getSofaID() + '\n'); |
| // } |
| } |
| |
| } |
| } catch (Exception e) { |
| buf.append("**Caught exception: ").append(e); |
| // StringWriter sw = new StringWriter(); |
| // e.printStackTrace(new PrintWriter(sw, true)); |
| // buf.append(sw.toString()); |
| } |
| } |
| |
| public StringBuilder addStringOrPrimitive(StringBuilder sb, FeatureImpl fi) { |
| TypeImpl range = (TypeImpl) fi.getRange(); |
| |
| if (range.isStringOrStringSubtype()) { |
| String stringVal = getStringValue(fi); |
| stringVal = (null == stringVal) ? "<null>" : "\"" + Misc.elideString(stringVal, 80) + "\""; |
| sb.append(stringVal); // caller adds nl |
| } else { |
| sb.append(getFeatureValueAsString(fi)); |
| } |
| return sb; |
| } |
| |
| private void ppval(FeatureStructureImplC val, int indent, int incr, StringBuilder buf, |
| boolean useShortNames, PrintReferences printRefs, boolean isShortForm) { |
| if (val != null && !val._typeImpl.getName().equals(CAS.TYPE_NAME_SOFA)) { |
| val.prettyPrint(indent, incr, buf, useShortNames, null, printRefs, isShortForm); |
| } else { |
| buf.append((val == null) ? "<null>" : "sofa id: " + ((SofaFS) val).getSofaID()); |
| } |
| } |
| |
| //@formatter:off |
| /** |
| * For printing arrays except FSArrays; called after printing the type:nnn |
| * prints the length |
| * if the length = 0 that's all |
| * otherwise: |
| * uses Misc.addElementsToStringBuilder to output the elements. This routine does |
| * [ + array contents + ], unless the line is too long, in which case it switches to multi-line |
| * @param arrayLen the length |
| * @param f the feature structure |
| * @param indent the current indent |
| * @param incr the indent incr |
| * @param buf the stringbuilder where the result is added |
| */ |
| //@formatter:on |
| private void printArrayElements(int arrayLen, IntConsumer f, int indent, int incr, |
| StringBuilder buf) { |
| Misc.indent(buf, indent); |
| buf.append("Array length: " + arrayLen); |
| if (arrayLen == 0) { |
| return; |
| } |
| |
| Misc.indent(buf, indent); |
| buf.append("Array elements: "); |
| if (IS_V2_PRETTY_PRINT) { |
| buf.append("["); |
| for (int i = 0; i < arrayLen; i++) { |
| if (i > 0) { |
| buf.append(", "); |
| } |
| f.accept(i); // this._casView.ll_getStringArrayValue(this.getAddress(), i); |
| } |
| buf.append("]"); // no extra new line |
| } else { |
| // no limit to size |
| Misc.addElementsToStringBuilder(buf, arrayLen, arrayLen, indent, incr, |
| (sb, i) -> f.accept(i)); |
| } |
| } |
| |
| //@formatter:off |
| /** |
| * For printing FSArrays; called after printing the type:nnn |
| * Only called if ! IS_V2_PRETTY_PRINT, since v2 didn't print the array contents |
| * prints the length |
| * if the length = 0 that's all |
| * otherwise: |
| * |
| * @param arrayLen |
| * the length |
| * @param f |
| * the feature structure |
| * @param indent |
| * the current indent |
| * @param incr |
| * the indent incr |
| * @param buf |
| * the stringbuilder where the result is added |
| */ |
| //@formatter:on |
| private void printFSArrayElements(FSArray fsarray, int indent, int incr, StringBuilder buf, |
| boolean useShortNames, PrintReferences printRefs, boolean isShortForm) { |
| Misc.indent(buf, indent); |
| int arraylen = fsarray.size(); |
| buf.append("Array length: " + arraylen); |
| if (arraylen == 0) { |
| return; |
| } |
| |
| Misc.indent(buf, indent); |
| buf.append("Array elements: ["); |
| |
| indent += incr; |
| for (int i = 0; i < arraylen; i++) { |
| Misc.indent(buf, indent); |
| ppval((TOP) fsarray.get(i), indent, incr, buf, useShortNames, printRefs, isShortForm); |
| } |
| Misc.indent(buf, indent - incr); |
| buf.append(']'); |
| } |
| |
| private void appendOrNull(StringBuilder sb, String v) { |
| sb.append((v == null) ? "null" : v); |
| } |
| |
| public int getTypeIndexID() { |
| throw new CASRuntimeException(UIMARuntimeException.INTERNAL_ERROR); // dummy, always overridden |
| } |
| |
| /** |
| * Internal Use only |
| * |
| * @param slotKind |
| * - |
| * @param fi |
| * - |
| * @param v |
| * - |
| */ |
| public void _setIntLikeValue(SlotKind slotKind, FeatureImpl fi, int v) { |
| switch (slotKind) { |
| case Slot_Boolean: |
| setBooleanValue(fi, v == 1); |
| break; |
| case Slot_Byte: |
| setByteValue(fi, (byte) v); |
| break; |
| case Slot_Short: |
| setShortValue(fi, (short) v); |
| break; |
| case Slot_Int: |
| setIntValue(fi, v); |
| break; |
| case Slot_Float: |
| setFloatValue(fi, CASImpl.int2float(v)); |
| break; |
| default: |
| Misc.internalError(); |
| } |
| } |
| |
| /** |
| * Internal Use only - no feature check, no journaling |
| * |
| * @param slotKind |
| * - |
| * @param fi |
| * - |
| * @param v |
| * - |
| */ |
| public void _setIntLikeValueNcNj(SlotKind slotKind, FeatureImpl fi, int v) { |
| switch (slotKind) { |
| case Slot_Boolean: |
| _setBooleanValueNcNj(fi, v == 1); |
| break; |
| case Slot_Byte: |
| _setByteValueNcNj(fi, (byte) v); |
| break; |
| case Slot_Short: |
| _setShortValueNcNj(fi, (short) v); |
| break; |
| case Slot_Int: |
| _setIntValueNcNj(fi, v); |
| break; |
| case Slot_Float: |
| _setFloatValueNcNj(fi, CASImpl.int2float(v)); |
| break; |
| default: |
| Misc.internalError(); |
| } |
| } |
| |
| /** |
| * for compressed form 4 - for getting the prev value of int-like slots Uses unchecked forms for |
| * feature access |
| * |
| * @param slotKind |
| * - |
| * @param f |
| * - |
| * @return - |
| */ |
| public int _getIntLikeValue(SlotKind slotKind, FeatureImpl f) { |
| if (null == f) { |
| switch (slotKind) { |
| |
| case Slot_Boolean: { |
| BooleanArray a = (BooleanArray) this; |
| return (a.size() == 0) ? 0 : a.get(0) ? 1 : 0; |
| } |
| |
| case Slot_Byte: { |
| ByteArray a = (ByteArray) this; |
| return (a.size() == 0) ? 0 : a.get(0); |
| } |
| |
| case Slot_Short: { |
| ShortArray a = (ShortArray) this; |
| return (a.size() == 0) ? 0 : a.get(0); |
| } |
| |
| case Slot_Int: { |
| IntegerArray a = (IntegerArray) this; |
| return (a.size() == 0) ? 0 : a.get(0); |
| } |
| |
| case Slot_Float: { |
| FloatArray a = (FloatArray) this; |
| return (a.size() == 0) ? 0 : CASImpl.float2int(a.get(0)); |
| } |
| default: |
| Misc.internalError(); |
| return 0; |
| } |
| } |
| |
| switch (slotKind) { |
| case Slot_Boolean: |
| return _getBooleanValueNc(f) ? 1 : 0; |
| case Slot_Byte: |
| return _getByteValueNc(f); |
| case Slot_Short: |
| return _getShortValueNc(f); |
| case Slot_Int: |
| return _getIntValueNc(f); |
| case Slot_Float: |
| return CASImpl.float2int(_getFloatValueNc(f)); |
| default: |
| Misc.internalError(); |
| return 0; |
| } |
| } |
| |
| @Override |
| public String getFeatureValueAsString(Feature feat) { |
| FeatureImpl fi = (FeatureImpl) feat; |
| TypeImpl range = fi.getRangeImpl(); |
| if (fi.isInInt) { |
| switch (range.getCode()) { |
| case TypeSystemConstants.floatTypeCode: |
| return Float.toString(getFloatValue(feat)); |
| case TypeSystemConstants.booleanTypeCode: |
| return Boolean.toString(getBooleanValue(feat)); |
| case TypeSystemConstants.longTypeCode: |
| return Long.toString(getLongValue(feat)); |
| case TypeSystemConstants.doubleTypeCode: |
| return Double.toString(getDoubleValue(feat)); |
| case TypeSystemConstants.byteTypeCode: |
| return Byte.toString(getByteValue(feat)); |
| case TypeSystemConstants.shortTypeCode: |
| return Short.toString(getShortValue(feat)); |
| default: // int, |
| return Integer.toString(getIntValue(feat)); |
| } |
| } |
| |
| if (range instanceof TypeImpl_string) { |
| return getStringValue(feat); |
| } |
| |
| // if (range.getCode() == TypeSystemConstants.javaObjectTypeCode) { |
| // return CASImpl.serializeJavaObject(getJavaObjectValue(feat)); |
| // } |
| |
| if (range.isRefType) { |
| TOP ref = getFeatureValue(feat); |
| return (ref == null) ? null : ref.toString(); |
| } |
| |
| Misc.internalError(); |
| return null; // needed to avoid compile error |
| } |
| |
| protected boolean _inSetSortedIndex() { |
| return (_flags & _BIT_IN_SET_SORTED_INDEX) != 0; |
| } |
| |
| protected void _setInSetSortedIndexed() { |
| _flags |= _BIT_IN_SET_SORTED_INDEX; |
| } |
| |
| /** |
| * All callers of this must insure fs is not indexed in **Any** View |
| */ |
| protected void _resetInSetSortedIndex() { |
| _flags &= ~_BIT_IN_SET_SORTED_INDEX; |
| } |
| |
| protected void _setJCasHashMapReserve() { |
| _flags |= _BIT_JCASHASHMAP_RESERVE; |
| } |
| |
| public boolean _isJCasHashMapReserve() { |
| return (_flags & _BIT_JCASHASHMAP_RESERVE) != 0; |
| } |
| |
| protected void _setPearTrampoline() { |
| _flags |= _BIT_PEAR_TRAMPOLINE; |
| } |
| |
| protected boolean _isPearTrampoline() { |
| return (_flags & _BIT_PEAR_TRAMPOLINE) != 0; |
| } |
| |
| protected FeatureImpl _getFeatFromAdjOffset(int adjOffset, boolean isInInt) { |
| return _typeImpl.getFeatureByAdjOffset(adjOffset, isInInt); |
| } |
| |
| private int _getIntValueCommon(FeatureImpl feat) { |
| return _intData[feat.getAdjustedOffset() /* + _getIntDataArrayOffset() */]; |
| } |
| |
| private int _getIntValueCommon(int adjOffset) { |
| return _intData[adjOffset /* + _getIntDataArrayOffset() */]; |
| } |
| |
| private Object _getRefValueCommon(FeatureImpl feat) { |
| return _refData[feat.getAdjustedOffset() /* + _getRefDataArrayOffset() */]; |
| } |
| |
| public Object _getRefValueCommon(int adjOffset) { |
| return _refData[adjOffset /* + _getRefDataArrayOffset() */]; |
| } |
| |
| private void _setIntValueCommon(FeatureImpl fi, int v) { |
| _intData[fi.getAdjustedOffset() /* + _getIntDataArrayOffset() */] = v; |
| if (traceFSs) { |
| _casView.traceFSfeat(this, fi, v); |
| } |
| } |
| |
| private void _setIntValueCommon(int adjOffset, int v) { |
| _intData[adjOffset /* + _getIntDataArrayOffset() */] = v; |
| if (traceFSs) { |
| _casView.traceFSfeat(this, _getFeatFromAdjOffset(adjOffset, true), v); |
| } |
| } |
| |
| private void _setRefValueCommon(FeatureImpl fi, Object v) { |
| final int adjOffset = fi.getAdjustedOffset(); |
| // if (adjOffset >= _refData.length) { |
| // System.out.format("Debug feature %s has adjusted Offset: %d but length of refs is %d%n", |
| // fi.getName(), adjOffset, _refData.length); |
| // System.out.format("Debug domain: %s, highest def type: %s%n", |
| // ((TypeImpl)fi.getDomain()).toString(2), fi.getHighestDefiningType()); |
| // } |
| |
| _setRefValueCommon(adjOffset, v); |
| } |
| |
| public void _setRefValueCommon(int adjOffset, Object v) { |
| _refData[adjOffset /* + _getRefDataArrayOffset() */] = v; |
| if (traceFSs) { |
| _casView.traceFSfeat(this, _getFeatFromAdjOffset(adjOffset, false), v); |
| } |
| |
| } |
| |
| // used also for sofa string setting |
| protected void _setRefValueCommonWj(FeatureImpl fi, Object v) { |
| _setRefValueCommon(fi, v); |
| _casView.maybeLogUpdate(this, fi); |
| } |
| |
| // private String getTraceRepOfObj(Object v) { |
| // if (v instanceof TOP) { |
| // TOP fs = (TOP) v; |
| // return fs._typeImpl.getShortName() + ':' + fs._id; |
| // } else { |
| // return (v == null) ? "null" : v.toString(); |
| // } |
| // } |
| |
| /************************************* |
| * Validation checking |
| *************************************/ |
| private void _Check_feature_defined_for_this_type(Feature feat) { |
| if (!(((TypeImpl) (feat.getDomain())).subsumes(_typeImpl))) { |
| /* Feature "{0}" is not defined for type "{1}". */ |
| throw new CASRuntimeException(CASRuntimeException.INAPPROP_FEAT, feat.getName(), |
| _typeImpl.getName()); |
| } |
| } |
| |
| private void _check_feature_range_is_FeatureStructure(Feature feat, FeatureStructureImplC fs) { |
| Type range = feat.getRange(); |
| if (range.isPrimitive()) { |
| throw new CASRuntimeException(CASRuntimeException.INAPPROP_RANGE_NOT_FS, feat.getName(), |
| fs.getType().getName(), feat.getRange().getName()); |
| } |
| } |
| |
| // private void featureValidation(Feature feat, Object x) { |
| // featureValidation(feat); |
| // if (feat.getRange()) |
| // } |
| |
| private void featureValueValidation(Feature feat, Object v) { |
| TypeImpl range = (TypeImpl) feat.getRange(); |
| if ((range.isArray() && !isOkArray(range, v)) |
| || (!range.isArray() && (!range.subsumesValue(v)))) { |
| throw new CASRuntimeException(CASRuntimeException.INAPPROP_RANGE, feat.getName(), |
| range.getName(), (v == null) ? "null" : v.getClass().getName()); |
| } |
| } |
| |
| // called when range isArray() is true, only |
| private boolean isOkArray(TypeImpl range, Object v) { |
| if (v == null) { |
| return true; |
| } |
| |
| final int rangeTypeCode = range.getCode(); |
| |
| /* The assignment is stricter than the Java rules - must match */ |
| switch (rangeTypeCode) { |
| case TypeSystemConstants.booleanArrayTypeCode: |
| return v instanceof BooleanArray; |
| case TypeSystemConstants.byteArrayTypeCode: |
| return v instanceof ByteArray; |
| case TypeSystemConstants.shortArrayTypeCode: |
| return v instanceof ShortArray; |
| case TypeSystemConstants.intArrayTypeCode: |
| return v instanceof IntegerArray; |
| case TypeSystemConstants.floatArrayTypeCode: |
| return v instanceof FloatArray; |
| case TypeSystemConstants.longArrayTypeCode: |
| return v instanceof LongArray; |
| case TypeSystemConstants.doubleArrayTypeCode: |
| return v instanceof DoubleArray; |
| case TypeSystemConstants.stringArrayTypeCode: |
| return v instanceof StringArray; |
| // case TypeSystemConstants.javaObjectArrayTypeCode: |
| // return v instanceof JavaObjectArray; |
| case TypeSystemConstants.fsArrayTypeCode: |
| return v instanceof FSArray; |
| } |
| |
| // it is possible that the array has a special type code corresponding to a type |
| // "someUserType"[] |
| // meaning an array of some user type. UIMA implements these as instances of FSArray (I think) |
| |
| if (!(v instanceof FSArray)) { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| private void subStringRangeCheck(Feature feat, String v) { |
| Type range = feat.getRange(); |
| if (range instanceof TypeImpl_stringSubtype) { |
| if (v != null) { // null values always OK |
| ((TypeImpl_stringSubtype) range).validateIsInAllowedValues(v); |
| } |
| } |
| } |
| |
| // protected Object[] _getRefData() { |
| // return _refData; |
| // } |
| |
| /** |
| * @param src |
| * the FS to copy features from |
| */ |
| public void _copyIntAndRefArraysFrom(FeatureStructureImplC src) { |
| if (src._intData != null && _intData != null) { |
| // System.arraycopy(src._intData, src._getIntDataArrayOffset(), _intData, |
| // _getIntDataArrayOffset(), |
| // Math.min(src._typeImpl.nbrOfUsedIntDataSlots, _typeImpl.nbrOfUsedIntDataSlots)); |
| System.arraycopy(src._intData, 0, _intData, 0, |
| Math.min(src._intData.length, _intData.length)); |
| } |
| if (src._refData != null && _refData != null) { |
| // System.arraycopy(src._refData, src._getRefDataArrayOffset(), _refData, |
| // _getRefDataArrayOffset(), |
| // Math.min(src._typeImpl.nbrOfUsedRefDataSlots, _typeImpl.nbrOfUsedRefDataSlots)); |
| System.arraycopy(src._refData, 0, _refData, 0, |
| Math.min(src._refData.length, _refData.length)); |
| } |
| } |
| |
| /** |
| * copy int and ref data for two instances, each having the exact same type |
| * |
| * @param src |
| * the FS to copy features from |
| */ |
| public void _copyIntAndRefArraysEqTypesFrom(FeatureStructureImplC src) { |
| if (_intData != null) { |
| // System.arraycopy(src._intData, src._getIntDataArrayOffset(), _intData, |
| // _getIntDataArrayOffset(), _typeImpl.nbrOfUsedIntDataSlots); |
| System.arraycopy(src._intData, 0, _intData, 0, _typeImpl.nbrOfUsedIntDataSlots); |
| } |
| if (_refData != null) { |
| // System.arraycopy(src._refData, src._getRefDataArrayOffset(), _refData, |
| // _getRefDataArrayOffset(), _typeImpl.nbrOfUsedRefDataSlots); |
| System.arraycopy(src._refData, 0, _refData, 0, _typeImpl.nbrOfUsedRefDataSlots); |
| } |
| } |
| |
| /** |
| * @param src |
| * the FS to copy features from |
| */ |
| public void _copyIntArrayEqTypesFrom(FeatureStructureImplC src) { |
| if (_intData != null) { |
| System.arraycopy(src._intData, 0, _intData, 0, _intData.length); |
| } |
| } |
| |
| public String toShortString() { |
| return new StringBuilder(_typeImpl.getShortName()).append(':').append(_id).toString(); |
| } |
| |
| // private int _getIntDataArrayOffset() { |
| // return (_flags & bitMaskIntOffset) >> shiftIntOffset; |
| // } |
| // |
| // private void _setIntDataArrayOffset(int v) { |
| // _flags = (_flags & ~bitMaskIntOffset) | v << shiftIntOffset; |
| // } |
| // |
| // private int _getRefDataArrayOffset() { |
| // return _flags >> shiftRefOffset; |
| // } |
| // |
| // private void _setRefDataArrayOffset(int v) { |
| // _flags = (_flags & ~bitMaskRefOffset) | v << shiftRefOffset; |
| // } |
| |
| public final TypeImpl _getTypeImpl() { |
| return _typeImpl; |
| } |
| |
| protected final void _setTypeImpl(TypeImpl ti) { |
| _typeImpl = ti; |
| } |
| |
| public static int compare(FeatureStructureImplC a, FeatureStructureImplC b) { |
| return Integer.compare(a._id, b._id); |
| } |
| |
| protected final static int wrapGetIntCatchException(MethodHandle mh) { |
| try { |
| return (int) mh.invokeExact(); |
| } catch (Throwable t) { |
| throw new UIMA_IllegalStateException(UIMA_IllegalStateException.JCAS_NO_TYPE, null, t); |
| } |
| } |
| |
| } |