blob: 0643d781e50e608f98ba95ec8ab7eba81eb9566e [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.ruta.ide.validator;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;
import org.apache.uima.UIMAFramework;
import org.apache.uima.resource.ResourceManager;
import org.apache.uima.resource.metadata.FeatureDescription;
import org.apache.uima.resource.metadata.TypeDescription;
import org.apache.uima.resource.metadata.TypeSystemDescription;
import org.apache.uima.ruta.UIMAConstants;
import org.apache.uima.ruta.ide.RutaIdeUIPlugin;
import org.apache.uima.ruta.ide.core.RutaCorePreferences;
import org.apache.uima.ruta.ide.core.builder.RutaProjectUtils;
import org.apache.uima.ruta.ide.parser.ast.FeatureMatchExpression;
import org.apache.uima.ruta.ide.parser.ast.RutaBlock;
import org.apache.uima.ruta.ide.parser.ast.RutaDeclareDeclarationsStatement;
import org.apache.uima.ruta.ide.parser.ast.RutaFeatureDeclaration;
import org.apache.uima.ruta.ide.parser.ast.RutaImportStatement;
import org.apache.uima.ruta.ide.parser.ast.RutaPackageDeclaration;
import org.apache.uima.ruta.ide.parser.ast.RutaStatementConstants;
import org.apache.uima.ruta.ide.parser.ast.RutaTypeConstants;
import org.apache.uima.ruta.ide.parser.ast.RutaTypeDeclaration;
import org.apache.uima.ruta.ide.parser.ast.RutaVariableDeclaration;
import org.apache.uima.ruta.ide.parser.ast.RutaVariableReference;
import org.apache.uima.util.InvalidXMLException;
import org.apache.uima.util.XMLInputSource;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.dltk.ast.ASTNode;
import org.eclipse.dltk.ast.ASTVisitor;
import org.eclipse.dltk.ast.declarations.MethodDeclaration;
import org.eclipse.dltk.ast.declarations.ModuleDeclaration;
import org.eclipse.dltk.ast.expressions.Expression;
import org.eclipse.dltk.ast.expressions.NumericLiteral;
import org.eclipse.dltk.ast.expressions.StringLiteral;
import org.eclipse.dltk.ast.references.SimpleReference;
import org.eclipse.dltk.ast.statements.Statement;
import org.eclipse.dltk.compiler.problem.IProblem;
import org.eclipse.dltk.compiler.problem.IProblemReporter;
import org.eclipse.dltk.compiler.problem.ProblemSeverity;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.builder.IBuildContext;
import org.eclipse.dltk.core.builder.IBuildParticipant;
import org.eclipse.dltk.core.builder.IBuildParticipantExtension;
import org.eclipse.dltk.core.builder.ISourceLineTracker;
public class RutaTypeChecker implements IBuildParticipant, IBuildParticipantExtension {
private class TypeCheckerVisitor extends ASTVisitor {
private final Stack<String> blocks;
private final Set<String> typeVariables;
private final Set<String> otherVariables;
private IProblemReporter rep;
private ISourceModule currentFile;
private ISourceLineTracker linetracker;
private Set<String> completeTypes;
private Set<String> shortTypes;
private RutaCheckerProblemFactory problemFactory;
private String packageName;
private TypeSystemDescription description;
private Set<String> otherTypes;
private Set<String> finalTypes;
private boolean reportWarningOnShortNames;
public TypeCheckerVisitor(IProblemReporter rep, ISourceLineTracker linetracker,
ISourceModule curFile, Set<String> completeTypes, Set<String> shortTypes) {
this.problemFactory = new RutaCheckerProblemFactory(curFile.getElementName(), linetracker);
this.linetracker = linetracker;
this.rep = rep;
this.typeVariables = new HashSet<String>();
this.otherVariables = new HashSet<String>();
this.blocks = new Stack<String>();
this.packageName = "";
this.currentFile = curFile;
this.completeTypes = completeTypes;
this.shortTypes = shortTypes;
this.otherTypes = new HashSet<String>();
Set<String> uimaPredefTypes = new HashSet<String>();
uimaPredefTypes.addAll(Arrays.asList(new String[] { "uima.cas.Boolean", "uima.cas.Byte",
"uima.cas.Short", "uima.cas.Integer", "uima.cas.Long", "uima.cas.Float",
"uima.cas.Double", "uima.cas.String", "uima.cas.BooleanArray", "uima.cas.ByteArray",
"uima.cas.ShortArray", "uima.cas.IntegerArray", "uima.cas.LongArray",
"uima.cas.FloatArray", "uima.cas.DoubleArray", "uima.cas.StringArray",
"uima.cas.FSArray", "uima.cas.AnnotationBase", "uima.tcas.Annotation",
"uima.tcas.DocumentAnnotation", "uima.cas.FloatList", "uima.cas.IntegerList",
"uima.cas.StringList", "uima.cas.FSList", "uima.cas.EmptyFloatList",
"uima.cas.EmptyIntegerList", "uima.cas.EmptyStringList", "uima.cas.EmptyFSList",
"uima.cas.NonEmptyFloatList", "uima.cas.NonEmptyIntegerList",
"uima.cas.NonEmptyStringList", "uima.cas.NonEmptyFSList" }));
for (String string : uimaPredefTypes) {
int indexOf = string.lastIndexOf('.');
otherTypes.add(string);
otherTypes.add(string.substring(indexOf + 1, string.length()));
}
this.finalTypes = new HashSet<String>();
Set<String> uimaFinalTypes = new HashSet<String>();
uimaFinalTypes.addAll(Arrays.asList(new String[] { "uima.cas.Boolean", "uima.cas.Byte",
"uima.cas.Short", "uima.cas.Integer", "uima.cas.Long", "uima.cas.Float",
"uima.cas.Double", "uima.cas.BooleanArray", "uima.cas.ByteArray", "uima.cas.ShortArray",
"uima.cas.IntegerArray", "uima.cas.LongArray", "uima.cas.FloatArray",
"uima.cas.DoubleArray", "uima.cas.StringArray", "uima.cas.FSArray" }));
for (String string : uimaFinalTypes) {
int indexOf = string.lastIndexOf('.');
finalTypes.add(string);
finalTypes.add(string.substring(indexOf + 1, string.length()));
}
try {
this.description = getTypeSystemOfScript();
} catch (Exception e) {
RutaIdeUIPlugin.error(e);
}
Preferences store = RutaIdeUIPlugin.getDefault().getPluginPreferences();
reportWarningOnShortNames = !store
.getBoolean(RutaCorePreferences.BUILDER_IGNORE_DUPLICATE_SHORTNAMES);
}
@Override
public boolean endvisit(MethodDeclaration s) throws Exception {
if (s instanceof RutaBlock) {
blocks.pop();
}
return super.endvisit(s);
}
public boolean visit(MethodDeclaration s) throws Exception {
if (s instanceof RutaBlock) {
RutaBlock b = (RutaBlock) s;
blocks.push(b.getName());
}
return true;
}
@Override
public boolean visit(Statement s) throws Exception {
if (s instanceof RutaPackageDeclaration) {
this.packageName = ((RutaPackageDeclaration) s).getName();
return false;
}
if (s instanceof RutaDeclareDeclarationsStatement) {
RutaDeclareDeclarationsStatement dds = (RutaDeclareDeclarationsStatement) s;
ASTNode parent = dds.getParent();
if (parent != null && parent instanceof RutaVariableReference) {
RutaVariableReference p = (RutaVariableReference) parent;
String name = p.getName();
if (finalTypes.contains(name)) {
IProblem problem = problemFactory.createInheritenceFinalProblem(p);
rep.reportProblem(problem);
}
}
return true;
}
if (s instanceof RutaVariableDeclaration) {
RutaVariableDeclaration newVar = (RutaVariableDeclaration) s;
// if (otherVariables.contains(newVar.getName())) {
// IProblem problem = problemFactory
// .createVarAlreadyDeclaredProblem(newVar);
// rep.reportProblem(problem);
// return false;
// }
if (shortTypes.contains(newVar.getName())) {
IProblem problem = problemFactory.createIdConflictsWithTypeProblem(newVar);
rep.reportProblem(problem);
return false;
}
if ((newVar.getKind() & RutaTypeConstants.RUTA_TYPE_AT) != 0) {
typeVariables.add(newVar.getName());
return false;
}
otherVariables.add(newVar.getName());
return false;
}
// if (s instanceof RutaFeatureDeclaration) {
// RutaFeatureDeclaration fd = (RutaFeatureDeclaration) s;
// }
if (s instanceof RutaTypeDeclaration) {
RutaTypeDeclaration newType = (RutaTypeDeclaration) s;
String longName = getLongLocalName(newType.getName());
if (completeTypes.contains(longName)) {
IProblem problem = problemFactory.createIdConflictsWithTypeProblem(newType);
rep.reportProblem(problem);
return false;
}
if (reportWarningOnShortNames && shortTypes.contains(newType.getName())) {
IProblem problem = problemFactory.createDuplicateShortName(newType,
ProblemSeverity.WARNING);
rep.reportProblem(problem);
return false;
}
if (typeVariables.contains(newType.getName()) || otherVariables.contains(newType.getName())) {
IProblem problem = problemFactory.createIdConflictsWithVariableProblem(newType);
rep.reportProblem(problem);
return false;
}
List<RutaFeatureDeclaration> features = newType.getFeatures();
if (features != null) {
for (RutaFeatureDeclaration each : features) {
String type = each.getType();
if (type.equals("INT") || type.equals("STRING") || type.equals("DOUBLE")
|| type.equals("FLOAT") || type.equals("BOOLEAN")) {
continue;
}
if (!shortTypes.contains(type) && !completeTypes.contains(type)
&& !otherTypes.contains(type)) {
IProblem problem = problemFactory.createUnknownFeatureTypeProblem(each);
rep.reportProblem(problem);
}
}
}
String[] nameSplit = newType.getName().split("[.]");
String shortName = nameSplit[nameSplit.length - 1];
completeTypes.add(longName);
shortTypes.add(shortName);
return false;
}
if (s instanceof RutaImportStatement) {
// handle type system imports
if (((RutaImportStatement) s).getType() == RutaStatementConstants.S_IMPORT_TYPESYSTEM) {
SimpleReference sRef = (SimpleReference) ((RutaImportStatement) s).getExpression();
String localPath = sRef.getName();
try {
boolean checkTypeSystemImport = RutaCheckerUtils.checkTypeSystemImport(localPath,
project);
if (!checkTypeSystemImport) {
rep.reportProblem(problemFactory.createFileNotFoundProblem(sRef, localPath));
}
Set<String> importedTypes = importTypeSystem(localPath);
Set<String> importedShortTypes = getShortTypeNames(importedTypes);
if (reportWarningOnShortNames) {
List<String> checkDuplicateShortNames = checkDuplicateShortNames(completeTypes,
importedTypes);
if (!checkDuplicateShortNames.isEmpty()) {
rep.reportProblem(problemFactory.createDuplicateShortNameInImported(sRef,
localPath, checkDuplicateShortNames, ProblemSeverity.WARNING));
}
}
completeTypes.addAll(importedTypes);
shortTypes.addAll(importedShortTypes);
} catch (IOException e) {
rep.reportProblem(problemFactory.createFileNotFoundProblem(sRef, localPath));
} catch (InvalidXMLException e) {
rep.reportProblem(problemFactory.createXMLProblem(sRef, localPath));
}
return false;
}
// handle script-imports
if (((RutaImportStatement) s).getType() == RutaStatementConstants.S_IMPORT_SCRIPT) {
SimpleReference sRef = (SimpleReference) ((RutaImportStatement) s).getExpression();
String localpath = sRef.getName();
// HOTFIX Peter add also the imported types of the imported type system!
try {
boolean checkScriptImport = RutaCheckerUtils.checkScriptImport(localpath, project);
if (!checkScriptImport) {
rep.reportProblem(problemFactory.createFileNotFoundProblem(sRef, localpath));
}
Set<String> importedTypes = importTypeSystem(localpath + "TypeSystem");
Set<String> importedShortTypes = getShortTypeNames(importedTypes);
Preferences store = RutaIdeUIPlugin.getDefault().getPluginPreferences();
if (reportWarningOnShortNames) {
List<String> checkDuplicateShortNames = checkDuplicateShortNames(completeTypes,
importedTypes);
if (!checkDuplicateShortNames.isEmpty()) {
rep.reportProblem(problemFactory.createDuplicateShortNameInImported(sRef,
localpath, checkDuplicateShortNames, ProblemSeverity.WARNING));
}
}
completeTypes.addAll(importedTypes);
shortTypes.addAll(importedShortTypes);
} catch (IOException e) {
rep.reportProblem(problemFactory.createFileNotFoundProblem(sRef, localpath));
}
// old stuff
Set<String> importedTypes = new HashSet<String>();
try {
importedTypes = RutaCheckerUtils.importScript(localpath, IModelElement.FIELD, project,
true);
} catch (IOException e) {
rep.reportProblem(problemFactory.createFileNotFoundProblem(sRef, localpath));
}
shortTypes.addAll(importedTypes);
return false;
}
}
return true;
}
private String getLongLocalName(String name) {
if (name.indexOf(".") == -1) {
String pack = packageName.equals("") ? "" : packageName + ".";
String longName = pack
+ currentFile.getElementName().substring(0,
currentFile.getElementName().length() - 5) + ".";
for (String each : blocks) {
longName += each + ".";
}
longName += name;
return longName;
}
return name;
}
private List<String> checkDuplicateShortNames(Set<String> types, Set<String> importedTypes) {
List<String> result = new ArrayList<String>();
for (String t1 : importedTypes) {
for (String t2 : types) {
if (checkTypeName(t1, t2)) {
result.add(t1);
result.add(t2);
}
}
}
return result;
}
private boolean checkTypeName(String t1, String t2) {
int lastIndexOf1 = t1.lastIndexOf(".");
int lastIndexOf2 = t2.lastIndexOf(".");
String shortName1 = t1.substring(lastIndexOf1 + 1, t1.length());
String shortName2 = t2.substring(lastIndexOf2 + 1, t2.length());
String namespace1 = "";
String namespace2 = "";
if (lastIndexOf1 >= 0) {
namespace1 = t1.substring(0, lastIndexOf1);
}
if (lastIndexOf2 >= 0) {
namespace2 = t2.substring(0, lastIndexOf2);
}
if (shortName1.equals(shortName2) && !namespace1.equals(namespace2)) {
return true;
}
return false;
}
private TypeSystemDescription getTypeSystemOfScript() throws InvalidXMLException, IOException {
IPath descriptorPath = RutaProjectUtils.getTypeSystemDescriptorPath(currentFile.getResource()
.getLocation(), project.getProject());
TypeSystemDescription typeSysDescr = null;
if (descriptorPath.toFile().exists()) {
typeSysDescr = UIMAFramework.getXMLParser().parseTypeSystemDescription(
new XMLInputSource(descriptorPath.toPortableString()));
ResourceManager resMgr = UIMAFramework.newDefaultResourceManager();
IFolder folder = project.getProject().getFolder(
RutaProjectUtils.getDefaultDescriptorLocation());
resMgr.setDataPath(folder.getLocation().toPortableString());
typeSysDescr.resolveImports(resMgr);
}
return typeSysDescr;
}
@Override
public boolean visit(Expression s) throws Exception {
if (s instanceof RutaVariableReference) {
RutaVariableReference ref = (RutaVariableReference) s;
// filter everything but AnnotationTypeReferences
int kind = ref.getKind();
int rutaTypeAt = RutaTypeConstants.RUTA_TYPE_AT;
int rutaTypeS = RutaTypeConstants.RUTA_TYPE_S;
if ((ref.getType() & RutaTypeConstants.RUTA_TYPE_AT) == 0) {
return false;
}
if (typeVariables.contains(ref.getName()) || completeTypes.contains(ref.getName())
|| shortTypes.contains(ref.getName()) || otherTypes.contains(ref.getName())
|| isLongLocalATRef(ref.getName()) || isLongExternalATRef(ref.getName())) {
return false;
}
if (isFeatureMatch(ref.getName()) != null) {
return false;
}
rep.reportProblem(problemFactory.createTypeProblem(ref, currentFile));
return false;
} else if (s instanceof FeatureMatchExpression) {
FeatureMatchExpression fme = (FeatureMatchExpression) s;
String featText = fme.getFeature().getText();
checkTypeOfFeatureMatch(featText, fme);
return true;
}
return true;
}
private void checkTypeOfFeatureMatch(String featText, FeatureMatchExpression fme) {
int lastIndexOf = featText.lastIndexOf(".");
if(lastIndexOf == -1) {
return;
}
String aref = featText.substring(0, lastIndexOf);
String fref = featText.substring(lastIndexOf + 1, featText.length());
String match = isFeatureMatch(aref);
if (match != null) {
int kind = -1;
if (fme.getValue() != null) {
kind = fme.getValue().getKind();
if (fme.getValue() instanceof StringLiteral) {
kind = RutaTypeConstants.RUTA_TYPE_S;
} else if (fme.getValue() instanceof NumericLiteral) {
kind = RutaTypeConstants.RUTA_TYPE_N;
}
}
boolean findFeature = findFeature(match, fref, kind);
if (findFeature) {
} else {
rep.reportProblem(problemFactory.createUnknownFeatureProblem(fme, aref));
}
} else {
rep.reportProblem(problemFactory.createUnknownFeatureProblem(fme, aref));
}
}
private String isFeatureMatch(String text) {
for (String each : shortTypes) {
String t = checkFeatureMatch(text, each);
if (t != null) {
return t;
}
}
for (String each : completeTypes) {
String t = checkFeatureMatch(text, each);
if (t != null) {
return t;
}
}
return null;
}
private boolean findFeature(String structure, String feat, int kind) {
if (description == null) {
return true;
}
if (structure == null) {
return false;
}
// TODO HOTFIX
if("begin".equals(feat)|| "end".equals(feat)) {
return true;
}
// TODO HOTFIX
if (structure.equals("Document") || structure.equals("DocumentAnnotation")
|| structure.equals("uima.tcas.DocumentAnnotation")) {
if (feat.equals("language")) {
return true;
}
}
boolean featureFound = false;
TypeDescription[] descriptions = description.getTypes();
Map<String, TypeDescription> typeMap = new HashMap<String, TypeDescription>();
for (TypeDescription typeDescription : descriptions) {
String typeName = typeDescription.getName();
typeMap.put(typeName, typeDescription);
}
for (TypeDescription typeDescription : descriptions) {
String typeName = typeDescription.getName();
String shortName = getShortName(typeName);
if (typeName.equals(structure) || shortName.equals(structure)) {
Collection<FeatureDescription> allFeatures = getAllDeclaredFeatures(typeDescription,
typeMap);
for (FeatureDescription featureDescription : allFeatures) {
String featureName = featureDescription.getName();
if (featureName.equals(feat) && checkFeatureKind(featureDescription, kind)) {
featureFound = true;
break;
}
}
}
if (featureFound) {
break;
}
}
return featureFound;
}
private boolean checkFeatureKind(FeatureDescription f, int kind) {
if (kind == -1) {
return true;
}
String t = f.getRangeTypeName();
if (t.equals(UIMAConstants.TYPE_BOOLEAN) && RutaTypeConstants.RUTA_TYPE_B == kind) {
return true;
} else if (t.equals(UIMAConstants.TYPE_STRING) && RutaTypeConstants.RUTA_TYPE_S == kind) {
return true;
} else if ((t.equals(UIMAConstants.TYPE_BYTE) || t.equals(UIMAConstants.TYPE_DOUBLE)
|| t.equals(UIMAConstants.TYPE_FLOAT) || t.equals(UIMAConstants.TYPE_INTEGER)
|| t.equals(UIMAConstants.TYPE_LONG) || t.equals(UIMAConstants.TYPE_SHORT))
&& RutaTypeConstants.RUTA_TYPE_N == kind) {
return true;
}
return false;
}
private String getShortName(String typeName) {
String[] nameSpace = typeName.split("[.]");
return nameSpace[nameSpace.length - 1];
}
private Collection<FeatureDescription> getAllDeclaredFeatures(TypeDescription typeDescription,
Map<String, TypeDescription> typeMap) {
Collection<FeatureDescription> result = new HashSet<FeatureDescription>();
if (typeDescription == null) {
return result;
}
FeatureDescription[] features = typeDescription.getFeatures();
if (features == null) {
return result;
}
result.addAll(Arrays.asList(features));
String supertypeName = typeDescription.getSupertypeName();
if (supertypeName != null) {
TypeDescription parent = typeMap.get(supertypeName);
result.addAll(getAllDeclaredFeatures(parent, typeMap));
}
return result;
}
private String checkFeatureMatch(String name, String type) {
if (name.startsWith(type)) {
boolean foundAll = true;
if (name.length() > type.length()) {
String tail = name.substring(type.length() + 1);
String[] split = tail.split("[.]");
String typeToCheck = type;
for (String feat : split) {
typeToCheck = checkFSFeatureOfType(feat, typeToCheck);
foundAll &= (typeToCheck != null);
if (!foundAll) {
return null;
}
}
return typeToCheck;
} else {
return type;
}
} else {
return null;
}
}
private String checkFSFeatureOfType(String feat, String type) {
if (type.indexOf(".") == -1) {
for (String each : completeTypes) {
String[] split = each.split("[.]");
if (split[split.length - 1].equals(type)) {
type = each;
break;
}
}
}
TypeDescription t = description.getType(type);
if (t == null)
return null;
FeatureDescription[] features = t.getFeatures();
for (FeatureDescription featureDescription : features) {
String name = featureDescription.getName();
String rangeTypeName = featureDescription.getRangeTypeName();
boolean isFS = isFeatureStructure(rangeTypeName);
if (name.equals(feat) && isFS) {
return rangeTypeName;
}
}
return null;
}
private boolean isFeatureStructure(String rangeTypeName) {
if (rangeTypeName.equals("uima.tcas.Annotation") || rangeTypeName.equals("uima.cas.TOP")) {
return true;
}
TypeDescription type = description.getType(rangeTypeName);
if (type == null) {
return false;
}
String supertypeName = type.getSupertypeName();
if (supertypeName != null) {
return isFeatureStructure(supertypeName);
}
return false;
}
private boolean isLongExternalATRef(String name) {
int lastIndexOf = name.lastIndexOf(".");
if (lastIndexOf == -1) {
return false;
}
for (String each : shortTypes) {
lastIndexOf = each.lastIndexOf(".");
if (lastIndexOf != -1 && each.endsWith(name)) {
return true;
}
}
return false;
}
private boolean isLongLocalATRef(String name) {
// TODO this methods does not work for blocks
String longName = this.packageName
+ "."
+ currentFile.getElementName()
.substring(0, currentFile.getElementName().length() - 5);
if (!name.startsWith(longName)) {
return false;
}
String ref;
try {
ref = name.substring(longName.length() + 1);
} catch (IndexOutOfBoundsException e) {
return false;
}
return shortTypes.contains(ref);
}
}
public RutaTypeChecker(IScriptProject project) throws CoreException {
this.project = project;
}
private IScriptProject project;
public boolean beginBuild(int buildType) {
return true;
}
public void endBuild(IProgressMonitor monitor) {
}
public void build(IBuildContext context) throws CoreException {
// getAST:
Object mdObj = context.get(IBuildContext.ATTR_MODULE_DECLARATION);
if (!(mdObj instanceof ModuleDeclaration)) {
return;
}
ModuleDeclaration md = (ModuleDeclaration) mdObj;
IProblemReporter problemReporter = context.getProblemReporter();
ISourceModule smod = context.getSourceModule();
// get Types:
Set<String> types = null;
try {
types = importBasicTypeSystem();
} catch (InvalidXMLException e1) {
System.err.println("ERROR: Failed to get BasicTypeSystem!! " + this.toString());
// problemReporter.reportProblem(problem)
} catch (IOException e1) {
System.err.println("ERROR: Failed to get BasicTypeSystem!! " + this.toString());
}
if (types == null) {
types = new TreeSet<String>();
}
// traverse:
ISourceLineTracker linetracker = context.getLineTracker();
Set<String> shortTypes = getShortTypeNames(types);
try {
ASTVisitor visitor = new TypeCheckerVisitor(problemReporter, linetracker, smod, types,
shortTypes);
md.traverse(visitor);
} catch (Exception e) {
RutaIdeUIPlugin.error(e);
}
}
private Set<String> importBasicTypeSystem() throws InvalidXMLException, IOException,
CoreException {
final String basicXmlFile = "BasicTypeSystem";
Set<String> types = importTypeSystem(basicXmlFile);
types.add("uima.tcas.Annotation");
types.add("uima.tcas.DocumentAnnotation");
return types;
}
public Set<String> getShortTypeNames(Set<String> types) {
Set<String> result = new TreeSet<String>();
for (String string : types) {
String[] nameSpace = string.split("[.]");
result.add(nameSpace[nameSpace.length - 1]);
}
return result;
}
/**
* @param xmlFilePath
* absolute full path. i.e.: "org.apache.uima.mytypes" ".xml" will be added.
* @return
* @throws InvalidXMLException
* @throws IOException
* when file not found
* @throws Exception
*/
private Set<String> importTypeSystem(String xmlFilePath) throws InvalidXMLException, IOException,
CoreException {
List<IFolder> folders = RutaProjectUtils.getAllDescriptorFolders(project.getProject());
String[] split = xmlFilePath.split("[.]");
String fileExtended = "";
for (String string : split) {
fileExtended += string;
fileExtended += "/";
}
fileExtended = fileExtended.substring(0, fileExtended.length() - 1) + ".xml";
Set<String> types = new TreeSet<String>();
for (IFolder folder : folders) {
types.addAll(getTypes(folder, fileExtended));
}
return types;
}
private Set<String> getTypes(IFolder folder, String filePath) throws InvalidXMLException,
IOException {
Set<String> types = new HashSet<String>();
IFile iFile = getFile(folder, filePath);
if (iFile.exists()) {
URL url;
try {
url = iFile.getLocationURI().toURL();
ResourceManager resMgr = UIMAFramework.newDefaultResourceManager();
resMgr.setDataPath(folder.getLocation().toPortableString());
types = getTypes(url, resMgr);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
return types;
}
private IFile getFile(IFolder folder, String filePath) {
int lastDot = filePath.lastIndexOf('.');
int sndLastDot = filePath.lastIndexOf('.', lastDot - 1);
String fName = filePath;
if (sndLastDot >= 0) {
String subFolder = filePath.substring(0, sndLastDot);
folder = folder.getFolder(subFolder);
fName = filePath.substring(sndLastDot + 1);
}
IFile file = folder.getFile(fName);
return file;
}
private Set<String> getTypes(URL resource, ResourceManager resMgr) throws IOException,
InvalidXMLException {
Set<String> types = new HashSet<String>();
TypeSystemDescription typeSysDescr = null;
typeSysDescr = UIMAFramework.getXMLParser().parseTypeSystemDescription(
new XMLInputSource(resource));
typeSysDescr.resolveImports(resMgr);
for (TypeDescription each : typeSysDescr.getTypes()) {
String name = each.getName();
types.add(name);
}
return types;
}
}