blob: 7f8f0d51fcc9a61922c2d640ddfbcf5c7cd028c1 [file] [log] [blame]
/*
* 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.jcas.cas;
import org.apache.uima.cas.CASRuntimeException;
import org.apache.uima.cas.FeatureStructure;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.impl.CASImpl;
import org.apache.uima.cas.impl.FSGenerator;
import org.apache.uima.cas.impl.LowLevelCAS;
import org.apache.uima.cas.impl.TypeImpl;
import org.apache.uima.jcas.JCas;
// *********************************
// * Implementation of TOP_Type *
// *********************************
/**
* hold Cas type information, link to JCas instance. One instance per Type, per CAS
*/
public class TOP_Type {
/**
* each cover class when loaded sets an index. used in the JCas typeArray to go from the cover
* class or class instance to the corresponding instance of the _Type class
*/
public final static int typeIndexID = TOP.typeIndexID;
// public final static int type = typeIndexID;
/**
* used to obtain reference to the TOP_Type instance
*
* @return the type array index
*/
public int getTypeIndexID() {
return typeIndexID;
}
/** the Cas Type associated with this Java Cas Model class */
public final Type casType; // JCas may refer to it?
public final int casTypeCode; // public so getters/setters in another package can see
/** reference to the Java Cas root */
public final JCas jcas; // public so _type generators can find it
/** ref to CAS for faster getters/setters */
public final CASImpl casImpl;
public final LowLevelCAS ll_cas;
// switch this to true if debugging wanted
final protected boolean lowLevelTypeChecks; // if true check int type
final protected boolean lowLevelArrayBoundChecks;
// next has to be public to be visible to inner class?
final public boolean useExistingInstance; // if true, implements reuse of existing instance
// generator used by the CAS system when it needs to make a new instance
/**
* This generator can be set up to either get the identical Java object (if it exists) or just
* make a new one. If making a new one - the java object made cannot contain any other data
* (because updates won't be reflected). Each class generated by JCasGen either does this (if it
* has additional java fields imbedded) or not.
*/
// protected because field shared by all subtypes
// next field no longer needed except for backwards compatibility
// new subtypes of TOP_Type use <class-name>.this instead
protected final TOP_Type instanceOf_Type; // allow ref to this in inner class
protected FSGenerator getFSGenerator() {
return fsGenerator;
}
private FSGenerator fsGenerator = new FSGenerator() {
public FeatureStructure createFS(int addr, CASImpl cas) {
if (TOP_Type.this.useExistingInstance) {
// Return eq fs instance if already created
FeatureStructure fs = TOP_Type.this.jcas.getJfsFromCaddr(addr);
if (null == fs) {
fs = new TOP(addr, TOP_Type.this);
TOP_Type.this.jcas.putJfsFromCaddr(addr, fs);
return fs;
}
return fs;
} else
return new TOP(addr, TOP_Type.this);
}
};
// cas.getKnownJCas().getType(TOP.typeIndexID));}
// private static final String casTypeName = CAS.TYPE_NAME_TOP;
// private String jTypeName = CAS.TYPE_NAME_TOP;
// protected String getCasTypeName() {return casTypeName;}
// protected String getJTypeName() {return jTypeName;}
/**
* protected constructor - disable default constructor - never called.
*/
protected TOP_Type() { // block default new operator
instanceOf_Type = null;
jcas = null;
casTypeCode = 0;
casType = null;
casImpl = null;
lowLevelTypeChecks = false;
lowLevelArrayBoundChecks = false;
throw new RuntimeException("Internal Error-this constructor should never be called.");
}
/**
* Internal - this constructor is called when new CAS creates corresponding jcas instance. During
* this process, all the types defined in the CAS are used to see if there are any corresponding
* jcas type defs defined. If so, they are loaded. This constructor is called via its being the
* superclass of classes being loaded.
*/
// constructor execution order: 1: super, 2: instance expr, 3: body
public TOP_Type(JCas jcas, Type casType) {
this(jcas, casType, true);
}
/**
* DO NOT USE - for backwards compatibility only.
*/
// constructor execution order: 1: super, 2: instance expr, 3: body
protected TOP_Type(JCas jcas, Type casType, boolean installGenerator) {
this.jcas = jcas;
this.casImpl = jcas.getCasImpl();
this.ll_cas = this.casImpl;
this.casType = casType;
this.instanceOf_Type = this;
this.casTypeCode = ((TypeImpl) this.casType).getCode();
this.lowLevelTypeChecks = false;
this.lowLevelArrayBoundChecks = false;
this.useExistingInstance = true;
// Add generator to CASImpl for this type
// NOTE Getter used for FSGenerator to get the subtype instance value
// NOTE Above comment is irrelevant - because this call has to be in
// every subclass, because at the time this executes in TOP_Type,
// it is because the subclass invoked it via super(x,y), and the
// subclass's instance vars haven't yet been set
// Solution: every superClass that could be instantiated (TOP is not one of them)
// during the super calls will incorrectly set the generator for the casType, but
// this is OK because after the supers all run, the bottom one runs and sets it correctly.
if (installGenerator) {
((CASImpl) ll_cas).getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType,
getFSGenerator());
}
}
// ************ No Object support ********************
protected void checkType(int inst) {
if (!casImpl.getTypeSystemImpl().subsumes(casTypeCode, casImpl.getHeapValue(inst)))
invalidTypeArg(inst);
}
protected void invalidTypeArg(int inst) {
CASRuntimeException e = new CASRuntimeException(CASRuntimeException.INAPPROP_TYPE,
new String[] { casType.getName(),
this.casImpl.getTypeSystemImpl().ll_getTypeForCode(casImpl.getHeapValue(inst)).getName() });
throw e;
}
/** add the corresponding FeatureStructure to all Cas indexes */
public void addToIndexes(int inst) {
jcas.getLowLevelIndexRepository().ll_addFS(inst);
}
/** remove the corresponding FeatureStructure from all Cas indexes */
public void removeFromIndexes(int inst) {
jcas.getLowLevelIndexRepository().ll_removeFS(inst);
}
public int noObjCreate() {
return casImpl.ll_createFS(casTypeCode);
}
}