blob: 8666ebf26e3770f0bd6fa460b6274a2ecce7b8c9 [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.tools.jcasgen;
/*
* One Jg instance per use. --> GUI instance (if GUI used) which is a JFrame
*/
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.swing.UIManager;
import org.apache.uima.UIMAFramework;
import org.apache.uima.analysis_engine.AnalysisEngineDescription;
import org.apache.uima.cas.BuiltinTypeKinds;
import org.apache.uima.cas.CAS;
import org.apache.uima.cas.Feature;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.TypeSystem;
import org.apache.uima.cas.impl.CASImpl;
import org.apache.uima.cas.impl.TypeImpl;
import org.apache.uima.cas.impl.TypeImpl_string;
import org.apache.uima.cas.impl.TypeSystemImpl;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.metadata.FeatureDescription;
import org.apache.uima.resource.metadata.FsIndexDescription;
import org.apache.uima.resource.metadata.TypeDescription;
import org.apache.uima.resource.metadata.TypePriorities;
import org.apache.uima.resource.metadata.TypeSystemDescription;
import org.apache.uima.util.CasCreationUtils;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLInputSource;
import org.apache.uima.util.XMLizable;
/**
* Class holds type plugin-wide collections and static methods. Also implements the runnable that is
* called to do the processing
*/
public class Jg {
/**
* Interface implemeted by JCAS code generation's templates.
*/
public interface IJCasTypeTemplate {
/**
* Generate.
*
* @param argument the argument
* @return the string
*/
public String generate(Object argument);
}
/** The Constant jControlModel. */
static final String jControlModel = "jMergeCtl.xml";
/** The Constant featureDescriptionArray0. */
static final FeatureDescription[] featureDescriptionArray0 = new FeatureDescription[0];
/** The Constant reservedFeatureNames. */
static final Collection reservedFeatureNames = new ArrayList();
{
reservedFeatureNames.add("Address");
reservedFeatureNames.add("CAS");
reservedFeatureNames.add("CASImpl");
reservedFeatureNames.add("Class");
reservedFeatureNames.add("FeatureValue");
reservedFeatureNames.add("FeatureValueAsString");
reservedFeatureNames.add("FeatureValueFromString");
reservedFeatureNames.add("FloatValue");
reservedFeatureNames.add("IntValue");
reservedFeatureNames.add("LowLevelCas");
reservedFeatureNames.add("StringValue");
reservedFeatureNames.add("Type");
reservedFeatureNames.add("View");
reservedFeatureNames.add("TypeIndexID");
}
/**
* Set of types not generated from the CAS type set because they're already in existence as
* builtins in the JCas impl. and if they're generated, the generated forms are wrong.
*/
static final Set noGenTypes = new HashSet();
/** The Constant casCreateProperties. */
public static final Properties casCreateProperties = new Properties();
static {
casCreateProperties.setProperty(UIMAFramework.CAS_INITIAL_HEAP_SIZE, "200");
}
/** The Constant extendableBuiltInTypes. */
static final Map extendableBuiltInTypes = new HashMap();
// create a hash map of built-in types, where the
// key is the fully-qualified name "uima.tcas.Annotation"
// and the value is a Collection of FeatureDescription objects,
// representing the features. These will be merged with the
// specified features. Supertype features are not included.
/** The Constant emptyFds. */
static final FeatureDescription[] emptyFds = new FeatureDescription[0];
/** The built in type system. */
static TypeSystem builtInTypeSystem;
static {
CAS tcas = null;
try {
tcas = CasCreationUtils.createCas((TypeSystemDescription) null, null,
new FsIndexDescription[0], casCreateProperties);
} catch (ResourceInitializationException e1) {
// never get here
}
((CASImpl) tcas).commitTypeSystem();
builtInTypeSystem = ((CASImpl) tcas).getTypeSystemImpl(); // follow commit because commit may reuse existing type system
for (Iterator it = builtInTypeSystem.getTypeIterator(); it.hasNext();) {
Type type = (Type) it.next();
if (type.isFeatureFinal()) {
noGenTypes.add(type.getName());
continue; // skip if feature final
}
String typeName = type.getName();
List<Feature> fs = type.getFeatures();
List<Feature> features = new ArrayList<Feature>(fs.size());
// get list of features defined in this type excluding those defined in supertypes
for (int i = 0; i < fs.size(); i++) {
Feature f = fs.get(i);
String fName = f.getName();
String fTypeName = fName.substring(0, fName.indexOf(':'));
if (typeName.equals(fTypeName))
features.add(f);
}
FeatureDescription[] fds = new FeatureDescription[features.size()];
for (int i = 0; i < features.size(); i++) {
FeatureDescription fd = UIMAFramework.getResourceSpecifierFactory()
.createFeatureDescription();
Feature f = features.get(i);
fd.setName(f.getShortName());
fd.setRangeTypeName(f.getRange().getName());
fds[i] = fd;
}
extendableBuiltInTypes.put(typeName, fds);
}
}
/** The built in types. */
// table builtInTypes initialized inside TypeInfo constructor
static Map<String, TypeInfo> builtInTypes = new HashMap<>();
/**
* Adds the built in type info.
*
* @param casName the cas name
* @param javaName the java name
* @param casElementName the cas element name
*/
static private void addBuiltInTypeInfo(String casName, String javaName, String casElementName) {
TypeInfo ti = new TypeInfo(casName, javaName, casElementName);
builtInTypes.put(casName, ti);
}
/**
* Adds the built in type info.
*
* @param casName the cas name
* @param javaName the java name
*/
static private void addBuiltInTypeInfo(String casName, String javaName) {
addBuiltInTypeInfo(casName, javaName, null);
}
// first type needed by fsArrayType; in hash map will be overwritten, though
static {
// addBuiltInTypeInfo("uima.cas.TOP", "org.apache.uima.cas.FeatureStructure"); // overridden below
addBuiltInTypeInfo("uima.cas.Integer", "int");
addBuiltInTypeInfo("uima.cas.Float", "float");
addBuiltInTypeInfo("uima.cas.String", "String");
addBuiltInTypeInfo("uima.cas.Byte", "byte");
addBuiltInTypeInfo("uima.cas.Short", "short");
addBuiltInTypeInfo("uima.cas.Long", "long");
addBuiltInTypeInfo("uima.cas.Double", "double");
addBuiltInTypeInfo("uima.cas.Boolean", "boolean");
addBuiltInTypeInfo("uima.cas.TOP", "org.apache.uima.jcas.cas.TOP");
addBuiltInTypeInfo("uima.cas.FSArray", "org.apache.uima.jcas.cas.FSArray", "uima.cas.TOP");
addBuiltInTypeInfo("uima.cas.IntegerArray", "org.apache.uima.jcas.cas.IntegerArray",
"uima.cas.Integer");
addBuiltInTypeInfo("uima.cas.FloatArray", "org.apache.uima.jcas.cas.FloatArray",
"uima.cas.Float");
addBuiltInTypeInfo("uima.cas.StringArray", "org.apache.uima.jcas.cas.StringArray",
"uima.cas.String");
addBuiltInTypeInfo("uima.cas.BooleanArray", "org.apache.uima.jcas.cas.BooleanArray",
"uima.cas.Boolean");
addBuiltInTypeInfo("uima.cas.ByteArray", "org.apache.uima.jcas.cas.ByteArray", "uima.cas.Byte");
addBuiltInTypeInfo("uima.cas.ShortArray", "org.apache.uima.jcas.cas.ShortArray",
"uima.cas.Short");
addBuiltInTypeInfo("uima.cas.LongArray", "org.apache.uima.jcas.cas.LongArray", "uima.cas.Long");
addBuiltInTypeInfo("uima.cas.DoubleArray", "org.apache.uima.jcas.cas.DoubleArray",
"uima.cas.Double");
addBuiltInTypeInfo("uima.cas.AnnotationBase", "org.apache.uima.jcas.cas.AnnotationBase");
addBuiltInTypeInfo("uima.tcas.Annotation", "org.apache.uima.jcas.tcas.Annotation");
addBuiltInTypeInfo("uima.tcas.DocumentAnnotation",
"org.apache.uima.jcas.tcas.DocumentAnnotation");
addBuiltInTypeInfo("uima.cas.EmptyFloatList", "org.apache.uima.jcas.cas.EmptyFloatList");
addBuiltInTypeInfo("uima.cas.EmptyFSList", "org.apache.uima.jcas.cas.EmptyFSList");
addBuiltInTypeInfo("uima.cas.EmptyIntegerList", "org.apache.uima.jcas.cas.EmptyIntegerList");
addBuiltInTypeInfo("uima.cas.EmptyStringList", "org.apache.uima.jcas.cas.EmptyStringList");
addBuiltInTypeInfo("uima.cas.FloatList", "org.apache.uima.jcas.cas.FloatList");
addBuiltInTypeInfo("uima.cas.FSList", "org.apache.uima.jcas.cas.FSList");
addBuiltInTypeInfo("uima.cas.IntegerList", "org.apache.uima.jcas.cas.IntegerList");
addBuiltInTypeInfo("uima.cas.StringList", "org.apache.uima.jcas.cas.StringList");
addBuiltInTypeInfo("uima.cas.NonEmptyFloatList", "org.apache.uima.jcas.cas.NonEmptyFloatList");
addBuiltInTypeInfo("uima.cas.NonEmptyFSList", "org.apache.uima.jcas.cas.NonEmptyFSList");
addBuiltInTypeInfo("uima.cas.NonEmptyIntegerList",
"org.apache.uima.jcas.cas.NonEmptyIntegerList");
addBuiltInTypeInfo("uima.cas.NonEmptyStringList", "org.apache.uima.jcas.cas.NonEmptyStringList");
addBuiltInTypeInfo("uima.cas.Sofa", "org.apache.uima.jcas.cas.Sofa");
// not built-in
// addBuiltInTypeInfo("uima.cas.IntegerArrayList", "org.apache.uima.jcas.cas.IntegerArrayList");
// addBuiltInTypeInfo("uima.cas.FSArrayList", "org.apache.uima.jcas.cas.FSArrayList");
// addBuiltInTypeInfo("uima.cas.FSHashSet", "org.apache.uima.jcas.cas.FSHashSet");
}
/** The resource bundle. */
// Resource bundle.
private static ResourceBundle resourceBundle;
static {
try {
resourceBundle = ResourceBundle
.getBundle("org.apache.uima.tools.jcasgen.jcasgenpPluginResources");
} catch (MissingResourceException x) {
resourceBundle = null;
}
}
/** The imports. */
// Instance fields
final Map imports = new HashMap(); // can't be final - one per instance running
/** The imports. */
final Map _imports = new HashMap();
/** The class path. */
String classPath = "";
/** The xml source file name. */
String xmlSourceFileName;
/** The cas. */
CAS cas;
/** The gui. */
GUI gui;
/** The merger. */
IMerge merger;
/** The progress monitor. */
IProgressMonitor progressMonitor;
/** The error. */
public IError error; // referenced by the plugin
/** The waiter. */
Waiter waiter;
/** The package name. */
String packageName;
/** The simple class name. */
String simpleClassName;
/** The type system. */
private TypeSystem typeSystem = null;
/** The cas string type. */
private Type casStringType;
/** The tcas annotation type. */
private Type tcasAnnotationType;
/** The merged types adding features. */
private Map<String, Set<String>> mergedTypesAddingFeatures = new TreeMap<String, Set<String>>(); // a Map of types and the xml files that were merged to create them
/** The project path dir. */
private String projectPathDir;
/** The limit J cas gen to project scope. */
private boolean limitJCasGenToProjectScope;
/**
* Instantiates a new jg.
*/
public Jg() { // default constructor
}
/**
* Returns the string from the plugin's resource bundle, or 'key' if not found.
*
* @param key the key
* @return the resource string
*/
public String getResourceString(String key) {
ResourceBundle bundle = getResourceBundle();
try {
return bundle.getString(key);
} catch (MissingResourceException e) {
return key;
}
}
/**
* Gets the string.
*
* @param key the key
* @param substitutions the substitutions
* @return the string
*/
public String getString(String key, Object[] substitutions) {
return MessageFormat.format(getResourceString(key), substitutions);
}
/**
* Returns the plugin's resource bundle,.
*
* @return the resource bundle
*/
public ResourceBundle getResourceBundle() {
return resourceBundle;
}
/**
* The Class ErrorExit.
*/
public static class ErrorExit extends RuntimeException {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = -3314235749649859540L;
}
// ************
// * driveGui *
/**
* Drive gui.
*/
// ************
public void driveGui() {
// usingGui = true;
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
System.err.println("Could not set look and feel: " + e.getMessage());
}
gui = new GUI(this);
gui.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
Prefs.set(gui);
waiter.finished();
}
});
Prefs.get(gui);
gui.pnG.taStatus.setLineWrap(true);
gui.pnG.taStatus.setWrapStyleWord(true);
gui.show();
waiter = new Waiter();
waiter.waitforGUI();
}
/**
* The main method.
*
* @param args the arguments
*/
// exits with -1 if failure
public static void main(String[] args) {
int rc = (new Jg()).main0(args, null, null, new LogThrowErrorImpl());
System.exit(rc);
}
/**
* Main for cde.
*
* @param aMerger the a merger
* @param aProgressMonitor the a progress monitor
* @param aError the a error
* @param inputFile the input file
* @param outputDirectory the output directory
* @param tds the tds
* @param aCas the a cas
* @throws IOException Signals that an I/O exception has occurred.
*/
public void mainForCde(IMerge aMerger, IProgressMonitor aProgressMonitor, IError aError,
String inputFile, String outputDirectory, TypeDescription[] tds, CASImpl aCas)
throws IOException {
mainForCde(aMerger, aProgressMonitor, aError,
inputFile, outputDirectory, tds, aCas, "", false, null);
}
/**
* Main for cde.
*
* @param aMerger the a merger
* @param aProgressMonitor the a progress monitor
* @param aError the a error
* @param inputFile the input file
* @param outputDirectory the output directory
* @param tds the tds
* @param aCas the a cas
* @param projectPathDir the project path dir
* @param limitJCasGenToProjectScope the limit J cas gen to project scope
* @param mergedTypesAddingFeatures the merged types adding features
* @throws IOException Signals that an I/O exception has occurred.
*/
public void mainForCde(IMerge aMerger, IProgressMonitor aProgressMonitor, IError aError,
String inputFile, String outputDirectory, TypeDescription[] tds, CASImpl aCas,
String projectPathDir, boolean limitJCasGenToProjectScope,
Map<String, Set<String>> mergedTypesAddingFeatures)
throws IOException {
try {
// Generate type classes by using DEFAULT templates
mainGenerateAllTypesFromTemplates(aMerger, aProgressMonitor, aError, inputFile,
outputDirectory, tds, aCas, JCasTypeTemplate.class,
projectPathDir, limitJCasGenToProjectScope, mergedTypesAddingFeatures);
// convert thrown things to IOExceptions to avoid changing API for this
// FIXME later
} catch (InstantiationException e) {
throw new IOException(e.toString());
} catch (IllegalAccessException e) {
throw new IOException(e.toString());
}
}
/**
* Main generate all types from templates.
*
* @param aMerger the a merger
* @param aProgressMonitor the a progress monitor
* @param aError the a error
* @param inputFile the input file
* @param outputDirectory the output directory
* @param tds the tds
* @param aCas the a cas
* @param jcasTypeClass the jcas type class
* @param jcas_TypeClass the jcas type class
* @throws IOException Signals that an I/O exception has occurred.
* @throws InstantiationException the instantiation exception
* @throws IllegalAccessException the illegal access exception
*/
// use template classes to generate code
public void mainGenerateAllTypesFromTemplates(IMerge aMerger, IProgressMonitor aProgressMonitor,
IError aError, String inputFile, String outputDirectory, TypeDescription[] tds,
CASImpl aCas, Class jcasTypeClass, // Template class
Class jcas_TypeClass) // Template class
throws IOException, InstantiationException, IllegalAccessException {
mainGenerateAllTypesFromTemplates(aMerger, aProgressMonitor,
aError, inputFile, outputDirectory, tds, aCas,
jcasTypeClass, "", false, null);
}
/**
* Main generate all types from templates.
*
* @param aMerger the a merger
* @param aProgressMonitor the a progress monitor
* @param aError the a error
* @param inputFile the input file
* @param outputDirectory the output directory
* @param tds the tds
* @param aCas the a cas
* @param jcasTypeClass the jcas type class
* @param projectPathDir the project path dir
* @param limitJCasGenToProjectScope the limit J cas gen to project scope
* @param mergedTypesAddingFeatures the merged types adding features
* @throws IOException Signals that an I/O exception has occurred.
* @throws InstantiationException the instantiation exception
* @throws IllegalAccessException the illegal access exception
*/
public void mainGenerateAllTypesFromTemplates(IMerge aMerger, IProgressMonitor aProgressMonitor,
IError aError, String inputFile, String outputDirectory, TypeDescription[] tds,
CASImpl aCas, Class jcasTypeClass, // Template class
String projectPathDir, boolean limitJCasGenToProjectScope,
Map<String, Set<String>> mergedTypesAddingFeatures) // Template class
throws IOException, InstantiationException, IllegalAccessException {
this.merger = aMerger;
this.error = aError;
this.progressMonitor = aProgressMonitor;
xmlSourceFileName = inputFile.replaceAll("\\\\", "/");
this.projectPathDir = projectPathDir;
this.limitJCasGenToProjectScope = limitJCasGenToProjectScope;
this.mergedTypesAddingFeatures = mergedTypesAddingFeatures;
// Generate type classes by using SPECIFIED templates
generateAllTypesFromTemplates(outputDirectory, tds, aCas, jcasTypeClass);
}
/**
* Main 0.
*
* @param args the args
* @param aMerger the a merger
* @param aProgressMonitor the a progress monitor
* @param aError the a error
* @return the int
*/
public int main0(String[] args, IMerge aMerger, IProgressMonitor aProgressMonitor, IError aError) {
this.merger = aMerger;
this.error = aError;
this.progressMonitor = aProgressMonitor;
boolean foundInput = false;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-jcasgeninput")) {
if (i == args.length - 1) {
driveGui();
return 0;
} else {
foundInput = true;
break;
}
}
}
if (foundInput)
return main1(args);
else {
driveGui();
return 0;
}
}
/**
* Arguments are:
* -jcasgeninput xxxx
* -jcasgenoutput xxxx
* -jcasgenclasspath xxxx
*
*
* @param arguments the arguments
* @return the int
*/
public int main1(String[] arguments) {
boolean hadError = false;
try {
try {
if (null == progressMonitor) {
progressMonitor = new UimaLoggerProgressMonitor();
}
if (null == error)
error = new LogThrowErrorImpl();
String inputFile = null;
String outputDirectory = null;
TypeSystemDescription typeSystemDescription = null;
TypeDescription[] tds = null;
projectPathDir = ""; // init to default value
limitJCasGenToProjectScope = false;
for (int i = 0; i < arguments.length - 1; i++) {
if (arguments[i].equalsIgnoreCase("-jcasgeninput")) {
inputFile = arguments[++i];
continue;
}
if (arguments[i].equalsIgnoreCase("-jcasgenoutput")) {
outputDirectory = arguments[++i];
continue;
}
// This is used by the jcasgen maven plugin
if (arguments[i].equalsIgnoreCase("=jcasgenclasspath") || // https://issues.apache.org/jira/browse/UIMA-3044
arguments[i].equalsIgnoreCase("-jcasgenclasspath")) { // https://issues.apache.org/jira/browse/UIMA-3044
classPath = arguments[++i];
continue;
}
if (arguments[i].equalsIgnoreCase("-limitToDirectory")) {
projectPathDir = arguments[++i];
limitJCasGenToProjectScope = (projectPathDir.length() > 0);
continue;
}
}
xmlSourceFileName = inputFile.replaceAll("\\\\", "/");
URL url;
if(inputFile.substring(0, 4).equalsIgnoreCase("jar:")) {
// https://issues.apache.org/jira/browse/UIMA-1793 get things out of Jars
try {
url = new URL(inputFile);
// if (null == url) { // is never null from above line
// error.newError(IError.ERROR, getString("fileNotFound", new Object[] { inputFile }), null);
// }
if(null == outputDirectory || outputDirectory.equals("")) {
error.newError(IError.ERROR, getString("sourceArgNeedsDirectory", new Object[] { inputFile }), null);
}
} catch (MalformedURLException e) {
error.newError(IError.ERROR, getString("fileNotFound", new Object[] { inputFile }), null);
url = null; // never get here, the previous statement throws. Needed, though for java path analysis.
}
} else {
File file = new File(inputFile);
if (!file.exists()) {
error.newError(IError.ERROR, getString("fileNotFound", new Object[] { inputFile }), null);
}
if (null == outputDirectory || outputDirectory.equals("")) {
File dir = file.getParentFile();
if (null == dir) {
error.newError(IError.ERROR, getString("sourceArgNeedsDirectory",
new Object[] { inputFile }), null);
}
outputDirectory = dir.getPath() + File.separator + "JCas"
+ ((null != merger) ? "" : "New");
}
url = file.toURI().toURL();
}
progressMonitor.beginTask("", 5);
progressMonitor.subTask("Output going to '" + outputDirectory + "'");
progressMonitor.subTask(getString("ReadingDescriptorAndCreatingTypes",
new Object[] { inputFile }));
// code to read xml and make cas type instance
CASImpl casLocal = null;
// handle classpath
try {
XMLInputSource in = new XMLInputSource(url);
XMLizable specifier = UIMAFramework.getXMLParser().parse(in);
mergedTypesAddingFeatures.clear();
if (specifier instanceof AnalysisEngineDescription) {
AnalysisEngineDescription aeSpecifier = (AnalysisEngineDescription) specifier;
if (!aeSpecifier.isPrimitive())
typeSystemDescription = CasCreationUtils.mergeDelegateAnalysisEngineTypeSystems(
aeSpecifier, createResourceManager(), mergedTypesAddingFeatures);
else
typeSystemDescription = mergeTypeSystemImports(aeSpecifier
.getAnalysisEngineMetaData().getTypeSystem());
} else if (specifier instanceof TypeSystemDescription)
typeSystemDescription = mergeTypeSystemImports(((TypeSystemDescription) specifier));
else {
error.newError(IError.ERROR, getString("fileDoesntParse", new Object[] { inputFile }),
null);
}
if (mergedTypesAddingFeatures.size() > 0) {
error.newError(IError.WARN, getString("typesHaveFeaturesAdded",
new Object[] { makeMergeMessage(mergedTypesAddingFeatures) }), null);
}
TypePriorities typePriorities = null;
FsIndexDescription[] fsIndexDescription = null;
try {
// no ResourceManager, since everything has been
// imported/merged by previous actions
casLocal = (CASImpl) CasCreationUtils.createCas(typeSystemDescription, typePriorities,
fsIndexDescription);
} catch (ResourceInitializationException e) {
error.newError(IError.WARN, getString("resourceInitializationException",
new Object[] { e.getLocalizedMessage() }), e);
casLocal = null; // continue with null cas, anyway
}
} catch (IOException e) {
e.printStackTrace();
} catch (InvalidXMLException e) {
error.newError(IError.ERROR, getString("invalidXML", new Object[] { inputFile }), e);
} catch (ResourceInitializationException e) {
error.newError(IError.ERROR, getString("resourceInitializationExceptionError",
new Object[] {}), e);
}
progressMonitor.worked(1);
tds = typeSystemDescription.getTypes();
// Generate type classes from DEFAULT templates
generateAllTypesFromTemplates(outputDirectory, tds, casLocal, JCasTypeTemplate.class);
} catch (IOException e) {
error.newError(IError.ERROR, getString("IOException", new Object[] {}), e);
} catch (ErrorExit e) {
hadError = true;
} catch (InstantiationException e) {
error.newError(IError.ERROR, getString("InstantiationException", new Object[] {}), e);
} catch (IllegalAccessException e) {
error.newError(IError.ERROR, getString("IllegalAccessException", new Object[] {}), e);
}
} finally {
progressMonitor.done();
}
return (hadError) ? -1 : 0;
}
/**
* Make merge message.
*
* @param m the m
* @return the string
*/
// message: TypeName = ".....", URLs defining this type = "xxxx", "xxxx", ....
private String makeMergeMessage(Map m) {
StringBuffer sb = new StringBuffer();
for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String typeName = (String) entry.getKey();
sb.append("\n ");
sb.append("TypeName having merged features = ").append(typeName).append(
"\n URLs defining this type =");
Set urls = (Set) entry.getValue();
boolean afterFirst = false;
for (Iterator itUrls = urls.iterator(); itUrls.hasNext();) {
if (afterFirst)
sb.append(",\n ");
else
sb.append("\n ");
afterFirst = true;
String url = (String) itUrls.next();
sb.append('"').append(url).append('"');
}
}
return sb.toString();
}
/**
* Generate all types from templates.
*
* @param outputDirectory the output directory
* @param tds the tds
* @param aCas the a cas
* @param jcasTypeClass the jcas type class
* @throws IOException Signals that an I/O exception has occurred.
* @throws InstantiationException the instantiation exception
* @throws IllegalAccessException the illegal access exception
*/
// This is also the interface for CDE
private void generateAllTypesFromTemplates(String outputDirectory, TypeDescription[] tds,
CASImpl aCas, Class jcasTypeClass) throws IOException,
InstantiationException, IllegalAccessException {
// Create instances of Template classes
IJCasTypeTemplate jcasTypeInstance = (IJCasTypeTemplate) jcasTypeClass.newInstance();
Set generatedBuiltInTypes = new TreeSet();
this.cas = aCas;
this.typeSystem = cas.getTypeSystem();
this.casStringType = typeSystem.getType(CAS.TYPE_NAME_STRING);
this.tcasAnnotationType = typeSystem.getType(CAS.TYPE_NAME_ANNOTATION);
for (int i = 0; i < tds.length; i++) {
TypeDescription td = tds[i];
// System.out.println("Description: " + td.getDescription() );
if (noGenTypes.contains(td.getName()))
continue;
if (td.getSupertypeName().equals("uima.cas.String"))
continue;
if (limitJCasGenToProjectScope &&
isOutOfScope(td, projectPathDir)) {
Set<String> mt = mergedTypesAddingFeatures.get(td.getName());
if (null == mt) {
continue;
}
StringBuilder sb = new StringBuilder("\n");
for (String p : mt) {
sb.append(" ").append(p).append('\n');
}
error.newError(IError.ERROR, getString("limitingButTypeWasExtended", new Object[] { td.getName(), sb.toString()}), null);
continue;
}
// if the type is built-in - augment it with the built-in's features
FeatureDescription[] builtInFeatures = (FeatureDescription[]) extendableBuiltInTypes.get(td
.getName());
if (null != builtInFeatures) {
generatedBuiltInTypes.add(td.getName());
List newFeatures = setDifference(td.getFeatures(), builtInFeatures);
int newFeaturesSize = newFeatures.size();
if (newFeaturesSize > 0) {
int newSize = builtInFeatures.length + newFeaturesSize;
FeatureDescription[] newFds = new FeatureDescription[newSize];
System.arraycopy(builtInFeatures, 0, newFds, 0, builtInFeatures.length);
for (int j = builtInFeatures.length, k = 0; k < newFeaturesSize; j++, k++)
newFds[j] = (FeatureDescription) newFeatures.get(k);
td.setFeatures(newFds);
} else {
// The only built-in type which is extensible is DocumentAnnotation.
// If we get here, the user defined DocumentAnnotation, but did not add any features
// In this case, skip generation
continue;
}
}
generateClassesFromTemplate(td, outputDirectory, jcasTypeInstance);
}
/*
* This code was supposed to generate extendable built-in types that were not
* extended by the input types
* But the only extendable built-in type is DocumentAnnotation, and it should
* not be generated by default - there's one provided by the framework.
*
for (Iterator it = extendableBuiltInTypes.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String typeName = (String) entry.getKey();
if (noGenTypes.contains(typeName) || generatedBuiltInTypes.contains(typeName))
continue;
TypeDescription td = createTdFromType(typeName);
generateClasses(td, outputDirectory);
}
*/
}
/* This code was only called by above commented out section
private TypeDescription createTdFromType(String typeName) {
TypeDescription td = UIMAFramework.getResourceSpecifierFactory().createTypeDescription();
Type type = builtInTypeSystem.getType(typeName);
td.setName(typeName);
td.setSupertypeName(builtInTypeSystem.getParent(type).getName());
ArrayList featuresOfType = new ArrayList();
final List vFeatures = type.getFeatures();
for (int i = 0; i < vFeatures.size(); i++) {
Feature f = (Feature) vFeatures.get(i);
if (f.getDomain().equals(type)) {
FeatureDescription fd = UIMAFramework.getResourceSpecifierFactory()
.createFeatureDescription();
fd.setName(f.getShortName());
fd.setRangeTypeName(f.getRange().getName());
featuresOfType.add(fd);
}
}
td.setFeatures((FeatureDescription[]) featuresOfType
.toArray(new FeatureDescription[featuresOfType.size()]));
return td;
}
*/
/**
* return true if td is not defined in this project, of
* it is defined, but is also in merged and any of the other
* merged urls are not defined in this project.
*
* @param td the td
* @param projectDirPath the project dir path
* @return true, if is out of scope
*/
private boolean isOutOfScope(TypeDescription td, String projectDirPath) {
URI typeDefinitionUri;
try {
typeDefinitionUri = new URI (td.getSourceUrlString());
} catch (URISyntaxException e) {
return true; // may be overkill - but if td's source can't be parsed ... likely out of project
}
String tdPath = typeDefinitionUri.getPath();
// Issue UIMA-4080 - If a type system resides in a JAR, then the path is null and it is
// certainly out of scope.
if (tdPath == null) {
return true;
}
// UIMA-4119 - On windows, the default path representation and the URI path representation
// differ: "/C:/..." vs. "C:\...". If the projectDirPath does not start with a /, we can be sure
// that it is not an absolute path in URI notation, so we try to resolve it.
// In this way, we can handle clients that use the URI notation (e.g. the Eclipse plugin)
// as well as clients that use file-system notation (e.g. jcasgen-maven-plugin or a simple
// invocation from the command line.
String resolvedProjectPath;
if (!projectDirPath.startsWith("/")) {
resolvedProjectPath = new File(projectDirPath).getAbsoluteFile().toURI().getPath();
}
else {
resolvedProjectPath = projectDirPath;
}
// UIMA-4131 - Make sure that paths end in a slash so that "/my/project1" is not considered
// to be in the scope of "/my/project"
if (!tdPath.endsWith("/")) {
tdPath += "/";
}
if (!resolvedProjectPath.endsWith("/")) {
resolvedProjectPath += "/";
}
boolean r = !tdPath.startsWith(resolvedProjectPath);
if (r) {
return true;
}
Set<String> mergedPaths = mergedTypesAddingFeatures.get(td.getName());
if (null != mergedPaths) {
for (String p : mergedPaths) {
URI tempURI;
try {
tempURI = new URI(p);
} catch (URISyntaxException e) {
return true; //because a merged path is out of the project
}
String tempPath = tempURI.getPath();
if (!tempPath.startsWith(resolvedProjectPath)) {
return true;
}
}
}
return false;
}
/**
* Generate type classes from the specified templates.
*
* @param td TypeDescription object
* @param outputDirectory output directory
* @param jcasTypeInstance Template instance used to generate class
* @return void
* @throws IOException -
*/
private void generateClassesFromTemplate(TypeDescription td, String outputDirectory,
IJCasTypeTemplate jcasTypeInstance)
throws IOException {
simpleClassName = removePkg(getJavaName(td));
generateClass(progressMonitor, outputDirectory, td, jcasTypeInstance.generate(new Object[] {
this, td }), getJavaName(td), merger);
// simpleClassName = removePkg(getJavaName_Type(td));
// generateClass(progressMonitor, outputDirectory, td, jcas_TypeInstance.generate(new Object[] {
// this, td }), getJavaName_Type(td), merger);
}
/**
* Gets the pkg.
*
* @param td the td
* @return the pkg
*/
String getPkg(TypeDescription td) {
return getPkg(td.getName());
}
/**
* Gets the pkg.
*
* @param nameWithPkg the name with pkg
* @return the pkg
*/
String getPkg(String nameWithPkg) {
int lastDot = nameWithPkg.lastIndexOf('.');
if (lastDot >= 0)
return nameWithPkg.substring(0, lastDot);
return "";
}
/**
* Generate class.
*
* @param progressMonitorGenerateClass the progress monitor generate class
* @param outputDirectory the output directory
* @param td the td
* @param sourceContents the source contents
* @param className the class name
* @param mergerGenerateClass the merger generate class
* @throws IOException Signals that an I/O exception has occurred.
*/
private void generateClass(IProgressMonitor progressMonitorGenerateClass, String outputDirectory,
TypeDescription td, String sourceContents, String className, IMerge mergerGenerateClass)
throws IOException {
String pkgName = getJavaPkg(td);
String qualifiedClassName = (0 != pkgName.length()) ? pkgName + "." + className : className;
String targetContainer = outputDirectory + '/' + pkgName.replace('.', '/');
String targetPath = targetContainer + "/" + className + ".java";
File targetFile = new File(targetPath);
if (null != mergerGenerateClass) {
mergerGenerateClass.doMerge(this, progressMonitorGenerateClass, sourceContents,
targetContainer, targetPath, qualifiedClassName, targetFile);
} else {
if (targetFile.exists()) {
progressMonitorGenerateClass.subTask(getString("replacingTarget",
new Object[] { qualifiedClassName }));
} else
progressMonitorGenerateClass.subTask(getString("creatingTarget",
new Object[] { qualifiedClassName }));
(new File(targetContainer)).mkdirs();
FileWriter fw = new FileWriter(targetPath);
try {
fw.write(sourceContents);
} finally {
fw.close();
}
}
}
/**
* Removes the pkg.
*
* @param name the name
* @return the string
*/
public static String removePkg(String name) {
int lastDot = name.lastIndexOf('.');
String simpleName = name;
if (lastDot >= 0)
simpleName = name.substring(lastDot + 1);
return simpleName;
}
// **************************************************
// * sc (jTname) = return word that *
// * goes into generated Cas get/set *
// **************************************************
/**
* Sc.
*
* @param v the v
* @return the string
*/
String sc(String v) {
// return part of word that goes in calls like get<insert>Value
// input is Java type spec
if (v.equals("int"))
return "Int";
if (v.equals("float"))
return "Float";
if (v.equals("String"))
return "String";
if (v.equals("boolean"))
return "Boolean";
if (v.equals("byte"))
return "Byte";
if (v.equals("short"))
return "Short";
if (v.equals("long"))
return "Long";
if (v.equals("double"))
return "Double";
return "Feature"; // for user defined features and other built-ins which are FSs
}
// * Functions that convert between CAS fully-qualified names and Java names.
// * Handles both import issues and switching packages for some built-ins.
/**
* Gets the java pkg.
*
* @param td the td
* @return the java pkg
*/
String getJavaPkg(TypeDescription td) {
TypeInfo bi = Jg.builtInTypes.get(td.getName());
if (null == bi)
return getPkg(td);
return getPkg(bi.javaNameWithPkg);
}
/**
* Gets the java name with pkg.
*
* @param casTypeName the cas type name
* @return the java name with pkg
*/
String getJavaNameWithPkg(String casTypeName) {
TypeInfo bi = Jg.builtInTypes.get(casTypeName);
return (null == bi) ? casTypeName : bi.javaNameWithPkg;
}
/**
* Checks for pkg prefix.
*
* @param name the name
* @return true, if successful
*/
boolean hasPkgPrefix(String name) {
return name.lastIndexOf('.') >= 0;
}
/**
* Gets the java name.
*
* @param td the td
* @return the java name
*/
String getJavaName(TypeDescription td) {
return getJavaName(td.getName());
}
/**
* Gets the java name type.
*
* @param td the td
* @return the java name type
*/
String getJavaName_Type(TypeDescription td) {
return getJavaName(td) + "_Type";
}
/**
* Gets the java name.
*
* @param name the name
* @return the java name
*/
String getJavaName(String name) {
if (!hasPkgPrefix(name))
return name;
String javaNameWithPkg = getJavaNameWithPkg(name);
String simpleName = removePkg(javaNameWithPkg);
if (getPkg(javaNameWithPkg).equals(packageName))
return simpleName;
if (javaNameWithPkg.equals(imports.get(simpleName)))
return simpleName;
return javaNameWithPkg;
}
/** The non importable java names. */
private static ArrayList nonImportableJavaNames = new ArrayList(8);
static {
nonImportableJavaNames.add("String");
nonImportableJavaNames.add("float");
nonImportableJavaNames.add("int");
nonImportableJavaNames.add("boolean");
nonImportableJavaNames.add("byte");
nonImportableJavaNames.add("short");
nonImportableJavaNames.add("long");
nonImportableJavaNames.add("double");
}
/**
* Collect import.
*
* @param casName the cas name
* @param _Type the type
*/
void collectImport(String casName, boolean _Type) {
if (!hasPkgPrefix(casName))
return;
String javaNameWithPkg = getJavaNameWithPkg(casName);
if (nonImportableJavaNames.contains(javaNameWithPkg))
return;
String pkg = getPkg(javaNameWithPkg);
if (pkg.equals(packageName))
return;
if (_Type)
javaNameWithPkg += "_Type";
String simpleName = removePkg(javaNameWithPkg);
if (simpleName.equals(simpleClassName))
return;
if (null == imports.get(simpleName)) {
if (_Type)
_imports.put(simpleName, javaNameWithPkg);
else
imports.put(simpleName, javaNameWithPkg);
}
}
/**
* Collect imports.
*
* @param td the td
* @param _Type the type
* @return the collection
*/
Collection collectImports(TypeDescription td, boolean _Type) {
if (_Type)
_imports.clear();
else
imports.clear();
collectImport(td.getName(), _Type);
collectImport(td.getSupertypeName(), _Type);
if (!_Type) {
FeatureDescription[] fds = td.getFeatures();
for (int i = 0; i < fds.length; i++) {
FeatureDescription fd = fds[i];
if (null != typeSystem) {
String rangeTypeNameCAS = fd.getRangeTypeName();
Type rangeCasType = typeSystem.getType(rangeTypeNameCAS);
if (typeSystem.subsumes(casStringType, rangeCasType))
continue;
}
collectImport(fd.getRangeTypeName(), false);
if (hasArrayRange(fd)) {
collectImport(getJavaRangeArrayElementType(fd), false);
}
}
}
return (_Type) ? _imports.values() : imports.values();
}
/**
* Gets the java range type.
*
* @param fd the fd
* @return the java range type
*/
String getJavaRangeType(FeatureDescription fd) {
String rangeTypeNameCAS = fd.getRangeTypeName();
if (null != typeSystem) {
Type rangeCasType = typeSystem.getType(rangeTypeNameCAS);
if (rangeCasType instanceof TypeImpl_string) {
// type is a subtype of string, make its java type = to string
return "String";
}
}
return getJavaName(rangeTypeNameCAS);
}
/**
* Checks if is sub type of annotation.
*
* @param td the td
* @return true, if is sub type of annotation
*/
boolean isSubTypeOfAnnotation(TypeDescription td) {
if (null == cas)
return false;
Type type = typeSystem.getType(td.getName());
if (null == type) // happens when type hasn't been defined
return false;
return typeSystem.subsumes(tcasAnnotationType, type);
}
/**
* Checks for array range.
*
* @param fd the fd
* @return true, if successful
*/
boolean hasArrayRange(FeatureDescription fd) {
TypeInfo bi = Jg.builtInTypes.get(fd.getRangeTypeName());
if (null == bi)
return false;
return bi.isArray;
}
/**
* Checks if is possible index key.
*
* @param fd the fd
* @return true, if is possible index key
*/
boolean isPossibleIndexKey(FeatureDescription fd) {
String rangeTypeName = fd.getRangeTypeName();
// keys are primitives + string + string subtypes
TypeImpl rangeType = (null == typeSystem) ? null : (TypeImpl) typeSystem.getType(rangeTypeName);
return (null == typeSystem) || // default is to do checking
rangeType.isStringSubtype() ||
BuiltinTypeKinds.primitiveTypeNames_contains(rangeTypeName); // includes String
}
/**
* Checks if is string subtype.
*
* @param fd the fd
* @return true, if is string subtype
*/
boolean isStringSubtype(FeatureDescription fd) {
if (null != typeSystem) {
String rangeTypeName = fd.getRangeTypeName();
TypeImpl rangeType = (TypeImpl) typeSystem.getType(rangeTypeName);
return rangeType.getSuperType() == ((TypeSystemImpl)typeSystem).stringType;
}
return false;
}
/**
* Gets the java range array element type.
*
* @param fd the fd
* @return the java range array element type
*/
String getJavaRangeArrayElementType(FeatureDescription fd) {
String arrayElementCasNameWithNameSpace = fd.getElementType();
TypeInfo bi = Jg.builtInTypes.get(fd.getRangeTypeName());
if (null == bi) {
if (null == arrayElementCasNameWithNameSpace)
return "";
return getJavaName(arrayElementCasNameWithNameSpace);
}
if (null != arrayElementCasNameWithNameSpace && !"".equals(arrayElementCasNameWithNameSpace)) {
return getJavaName(arrayElementCasNameWithNameSpace);
}
return getJavaName(bi.arrayElNameWithPkg);
}
// **************************************************
// * uc1(featurename) make uppercase feature name for use by getters/setters
/**
* Uc 1.
*
* @param name the name
* @return the string
*/
// **************************************************
String uc1(String name) { // upper case first letter
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
/**
* Gets the date.
*
* @return the date
*/
String getDate() {
return (new Date()).toString();
}
// *******************************
// * castResult *
/**
* Cast result.
*
* @param resultType the result type
* @param core the core
* @return the string
*/
// *******************************
String castResult(String resultType, String core) {
if ("Feature".equals(sc(resultType)) && resultType != null
&& !resultType.equals("FeatureStructure"))
return "(" + resultType + ")(" + core + ")";
return core;
}
// instance generate get/setRefValue int
// get/setIntValue
// get/setStringValue String
// get/setFloatValue float
// range = Feature, String, Float, Int
/**
* Wrap to get FS.
*
* @param core string representing the get or set code
* @param range Boolean, Byte, Short, Int, Long, Float, Double, String, or Feature
* @return -
*/
String wrapToGetFS(String core, String range) {
if (range.equals("Feature"))
return "jcasType.ll_cas.ll_getFSForRef(" + core + ")";
return core;
}
/**
* Simple core.
*
* @param get_set get or set
* @param range Boolean, Byte, Short, Int, Long, Float, Double, String, or Feature
* @param fname feature name (e.g. "begin"
* @return the string
*/
String simpleCore(String get_set, String range, String fname) {
String v = ", v";
// if (get_set.equals("set") && range.equals("Feature"))
// v = ", jcasType.ll_cas.ll_getFSRef(v)";
boolean isInInt = ! (range.equals("String") || range.equals("Feature") || range.equals("JavaObject"));
String chksfx = getCheckSuffix(get_set, range);
String featOrOffset = "_FI_" + fname;
return "_" + get_set + range + "Value" + chksfx + "(" + featOrOffset +
((get_set.equals("set")) ? v : "") + ")";
}
/**
* Simple LL core.
*
* @param get_set the get set
* @param range the range
* @param fname the fname
* @return the string
*/
String simpleLLCore(String get_set, String range, String fname) {
String v = ", v";
// if (get_set.equals("set") && range.equals("Feature"))
// v = ", ll_cas.ll_getFSRef(v)";
return "ll_cas.ll_" + get_set + range + "Value(addr, casFeatCode_" + fname
+ ((get_set.equals("set")) ? v : "") + ")";
}
// return string that starts with FS whose value is not an array object, but
// a normal CAS type, one of whose features is the array object
/**
* Array core.
*
* @param get_set get or set
* @param range the component range: Boolean, Byte, Short, Int, Long, Float, Double, String, Feature
* @param arrayRange the array range
* @param fname the fname
* @return the string
*/
String arrayCore(String get_set, String range, String arrayRange, String fname) {
String v = ", v";
// if (get_set.equals("set") && range.equals("Feature"))
// v = ", jcasType.ll_cas.ll_getFSRef(v)";
return
"((" + arrayRange + ")(" + simpleCore("get", "Feature", fname) + "))." + get_set +
"(i" + ((get_set.equals("set")) ? v : "") + ")";
}
/**
* Array LL core.
*
* @param get_set the get set
* @param range the range
* @param fname the fname
* @return the string
*/
String arrayLLCore(String get_set, String range, String fname) {
String v = ", v";
return "ll_cas.ll_" + get_set + range + "ArrayValue(" + simpleLLCore("get", "Feature", fname)
+ ", i" + ((get_set.equals("set")) ? v : "") + ")";
}
/**
* Array LL core chk.
*
* @param get_set the get set
* @param range the range
* @param fname the fname
* @return the string
*/
String arrayLLCoreChk(String get_set, String range, String fname) {
String v = ", v";
return "ll_cas.ll_" + get_set + range + "ArrayValue(" + simpleLLCore("get", "Feature", fname)
+ ", i" + ((get_set.equals("set")) ? v : "") + ", true)";
}
/**
* Gets the feature value.
*
* @param fd the fd
* @param td the td
* @return the feature value
*/
String getFeatureValue(FeatureDescription fd, TypeDescription td) {
String getSetNamePart = getGetSetNamePart(fd);
String core = simpleCore("get", getSetNamePart, fd.getName());
return castResult(getJavaRangeType(fd), core);
}
/**
* Sets the feature value.
*
* @param fd the fd
* @param td the td
* @return the string
*/
String setFeatureValue(FeatureDescription fd, TypeDescription td) {
return simpleCore("set", getGetSetNamePart(fd), fd.getName());
}
/**
* Gets the array feature value.
*
* @param fd the fd
* @param td the td
* @return the array feature value
*/
String getArrayFeatureValue(FeatureDescription fd, TypeDescription td) {
String getSetArrayNamePart = getGetSetArrayNamePart(fd);
String core = arrayCore("get", getSetArrayNamePart, getJavaRangeType(fd), fd.getName());
return castResult(getJavaRangeArrayElementType(fd), core);
}
/**
* Sets the array feature value.
*
* @param fd the fd
* @param td the td
* @return the string
*/
String setArrayFeatureValue(FeatureDescription fd, TypeDescription td) {
return arrayCore("set", getGetSetArrayNamePart(fd), getJavaRangeType(fd), fd.getName());
}
/**
* Gets the gets the set name part.
*
* @param fd the fd
* @return the gets the set name part
*/
String getGetSetNamePart(FeatureDescription fd) {
return sc(getJavaRangeType(fd));
}
/**
* Gets the gets the set array name part.
*
* @param fd the fd
* @return the gets the set array name part
*/
String getGetSetArrayNamePart(FeatureDescription fd) {
return sc(getJavaRangeArrayElementType(fd));
}
/**
* Null blank.
*
* @param s the s
* @return the string
*/
String nullBlank(String s) {
if (null == s)
return "";
return s;
}
/**
* Creates the resource manager.
*
* @return the resource manager
*/
public ResourceManager createResourceManager() {
ResourceManager resourceManager = UIMAFramework.newDefaultResourceManager();
try {
resourceManager.setExtensionClassPath(this.getClass().getClassLoader(), classPath, true);
} catch (MalformedURLException e1) {
error.newError(IError.ERROR, getString("Internal Error", null), e1);
}
return resourceManager;
}
/**
* Merge type system imports.
*
* @param tsd the tsd
* @return the type system description
* @throws ResourceInitializationException the resource initialization exception
*/
private TypeSystemDescription mergeTypeSystemImports(TypeSystemDescription tsd)
throws ResourceInitializationException {
Collection tsdc = new ArrayList(1);
tsdc.add(tsd.clone());
mergedTypesAddingFeatures.clear();
TypeSystemDescription mergedTsd = CasCreationUtils.mergeTypeSystems(tsdc,
createResourceManager(), mergedTypesAddingFeatures);
return mergedTsd;
}
/**
* Sets the difference.
*
* @param newFeatures the new features
* @param alreadyDefinedFeatures the already defined features
* @return the list
*/
List setDifference(FeatureDescription[] newFeatures, FeatureDescription[] alreadyDefinedFeatures) {
List result = new ArrayList();
outerLoop: for (int i = 0; i < newFeatures.length; i++) {
for (int j = 0; j < alreadyDefinedFeatures.length; j++) {
if (isSameFeatureDescription(newFeatures[i], alreadyDefinedFeatures[j]))
continue outerLoop;
}
result.add(newFeatures[i]);
}
return result;
}
/**
* Checks if is same feature description.
*
* @param f1 the f 1
* @param f2 the f 2
* @return true, if is same feature description
*/
private boolean isSameFeatureDescription(FeatureDescription f1, FeatureDescription f2) {
if (!f2.getName().equals(f1.getName()))
return false;
if (!f2.getRangeTypeName().equals(f1.getRangeTypeName()))
return false;
return true;
}
/**
* Gets the check suffix.
*
* @param get_set the get set
* @param range the range
* @return the check suffix
*/
private String getCheckSuffix(String get_set, String range) {
if (get_set.equals("get")) return "Nc";
return (range.equals("Feature")) ? "NcWj" : "Nfc";
}
}