From justin28@example.net Wed Sep 01 14:55:19 2010 Return-Path: <justin28@example.net> Delivered-To: justin28@example.net Received: (qmail 10044 invoked from network); 1 Sep 2010 14:55:19 -0000 Received: from unknown (HELO mail.apache.org) (83.161.120.155) by 83.161.120.155 with SMTP; 1 Sep 2010 14:55:19 -0000 Received: (qmail 56534 invoked by uid 500); 1 Sep 2010 14:55:19 -0000 Delivered-To: justin28@example.net Received: (qmail 56499 invoked by uid 500); 1 Sep 2010 14:55:17 -0000 Mailing-List: contact justin28@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:justin28@example.net> List-Unsubscribe: <mailto:justin28@example.net> List-Post: <mailto:justin28@example.net> List-Id: <commits.uima.apache.org> Reply-To: justin28@example.net Delivered-To: mailing list justin28@example.net Received: (qmail 56490 invoked by uid 99); 1 Sep 2010 14:55:17 -0000 Received: from Unknown (HELO nike.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Sep 2010 14:55:17 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Sep 2010 14:55:00 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id B494123889DA; Wed, 1 Sep 2010 14:53:41 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r991558 - /uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecification_implTest.java Date: Wed, 01 Sep 2010 14:53:41 -0000 To: justin28@example.net From: justin28@example.net X-Mailer: svnmailer-1.0.8 Message-Id: <justin28@example.net> X-Virus-Checked: Checked by ClamAV on apache.org Author: schor Date: Wed Sep 1 14:53:41 2010 New Revision: 991558 URL: http://svn.apache.org/viewvc?rev=991558&view=rev Log: [UIMA-1860] conform test case for corner cases where type / feature in result spec but not in type system. Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecification_implTest.java Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecification_implTest.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecification_implTest.java?rev=991558&r1=991557&r2=991558&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecification_implTest.java (original) +++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecification_implTest.java Wed Sep 1 14:53:41 2010 @@ -477,7 +477,7 @@ public class ResultSpecification_implTes Assert.assertFalse(rs.containsType("FakeType:FakeFeature2")); Assert.assertTrue(rs.containsFeature("AnotherType:AnotherFeature")); Assert.assertTrue(rs.containsFeature("AnotherType:YetAnotherFeature")); - Assert.assertFalse(rs.containsFeature("AnotherType:asdfghjkl")); + Assert.assertTrue(rs.containsFeature("AnotherType:asdfghjkl")); // unknown features are there, if the type says allFeats Assert.assertFalse(rs.containsType("NotThere:FakeFeature")); } catch (Exception e) { JUnitExtension.handleException(e); @@ -516,7 +516,7 @@ public class ResultSpecification_implTes Assert.assertFalse(rs.containsType("FakeType:FakeFeature2")); Assert.assertTrue(rs.containsFeature("AnotherType:AnotherFeature")); Assert.assertTrue(rs.containsFeature("AnotherType:YetAnotherFeature")); - Assert.assertFalse(rs.containsFeature("AnotherType:asdfghjkl")); + Assert.assertTrue(rs.containsFeature("AnotherType:asdfghjkl")); // unknown features are there if type says allfeats Assert.assertFalse(rs.containsType("NotThere:FakeFeature")); Assert.assertFalse(rs.containsFeature("NotThere:FakeFeature")); Assert.assertFalse(rs.containsType("SubType")); From justin28@example.net Wed Sep 01 19:25:22 2010 Return-Path: <justin28@example.net> Delivered-To: justin28@example.net Received: (qmail 9791 invoked from network); 1 Sep 2010 19:25:22 -0000 Received: from unknown (HELO mail.apache.org) (83.161.120.155) by 83.161.120.155 with SMTP; 1 Sep 2010 19:25:22 -0000 Received: (qmail 97129 invoked by uid 500); 1 Sep 2010 19:25:22 -0000 Delivered-To: justin28@example.net Received: (qmail 97096 invoked by uid 500); 1 Sep 2010 19:25:21 -0000 Mailing-List: contact justin28@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:justin28@example.net> List-Unsubscribe: <mailto:justin28@example.net> List-Post: <mailto:justin28@example.net> List-Id: <commits.uima.apache.org> Reply-To: justin28@example.net Delivered-To: mailing list justin28@example.net Received: (qmail 97089 invoked by uid 99); 1 Sep 2010 19:25:21 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Sep 2010 19:25:21 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 01 Sep 2010 19:25:21 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 81F3A23889B6; Wed, 1 Sep 2010 19:24:03 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r991664 - /uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/XMLSerializerTest.java Date: Wed, 01 Sep 2010 19:24:03 -0000 To: justin28@example.net From: justin28@example.net X-Mailer: svnmailer-1.0.8 Message-Id: <justin28@example.net> Author: schor Date: Wed Sep 1 19:24:03 2010 New Revision: 991664 URL: http://svn.apache.org/viewvc?rev=991664&view=rev Log: no Jira - add missing license header so file will build Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/XMLSerializerTest.java Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/XMLSerializerTest.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/XMLSerializerTest.java?rev=991664&r1=991663&r2=991664&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/XMLSerializerTest.java (original) +++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/XMLSerializerTest.java Wed Sep 1 19:24:03 2010 @@ -1,3 +1,21 @@ +/* + * 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.util; import java.io.ByteArrayOutputStream; From justin28@example.net Thu Sep 02 13:45:15 2010 Return-Path: <justin28@example.net> Delivered-To: justin28@example.net Received: (qmail 6627 invoked from network); 2 Sep 2010 13:45:15 -0000 Received: from unknown (HELO mail.apache.org) (83.161.120.155) by 83.161.120.155 with SMTP; 2 Sep 2010 13:45:15 -0000 Received: (qmail 97223 invoked by uid 500); 2 Sep 2010 13:45:15 -0000 Delivered-To: justin28@example.net Received: (qmail 97180 invoked by uid 500); 2 Sep 2010 13:45:13 -0000 Mailing-List: contact justin28@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:justin28@example.net> List-Unsubscribe: <mailto:justin28@example.net> List-Post: <mailto:justin28@example.net> List-Id: <commits.uima.apache.org> Reply-To: justin28@example.net Delivered-To: mailing list justin28@example.net Received: (qmail 97164 invoked by uid 99); 2 Sep 2010 13:45:11 -0000 Received: from athena.apache.org (HELO athena.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 02 Sep 2010 13:45:11 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 02 Sep 2010 13:45:09 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id DC4312388A36; Thu, 2 Sep 2010 13:43:51 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r991931 [2/2] - in /uima/uimaj/trunk/uimaj-core/src: main/java/org/apache/uima/analysis_engine/impl/ main/java/org/apache/uima/analysis_engine/impl/compatibility/ main/java/org/apache/uima/cas/impl/ test/java/org/apache/uima/analysis_engine... Date: Thu, 02 Sep 2010 13:43:51 -0000 To: justin28@example.net From: justin28@example.net X-Mailer: svnmailer-1.0.8 Message-Id: <justin28@example.net> Added: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsTypesMap.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsTypesMap.java?rev=991931&view=auto ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsTypesMap.java (added) +++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsTypesMap.java Thu Sep 2 13:43:50 2010 @@ -0,0 +1,275 @@ +/* + * 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.analysis_engine.impl; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * This object holds the set of RsTypes for a result spec + * There is one instance of this per ResultSpecification_impl + */ +public class RsTypesMap implements Iterable<RsType> { + + private final Map<String, RsType> types; + + RsTypesMap() { + types = new HashMap<String, RsType>(); + } + + /** + * cloning constructor - clones its arg + * @param src + */ + RsTypesMap(RsTypesMap src) { + types = new HashMap<String, RsType>(src.types); + for (Map.Entry<String, RsType> e : types.entrySet()) { + e.setValue(new RsType(e.getValue())); // copy + } + } + + /** + * add a type (not a type:feat) + * @param typeName + * @param isAllFeat + * @param languages + * @param replace + */ + void add(String typeName, boolean isAllFeat, String[] languages, boolean replace) { + RsType t = types.get(typeName); + if (null == t) { + t = new RsType(typeName); + types.put(typeName, t); + } + if (isAllFeat) { + if (!t.isAllFeatures) { + replace = true; // if setting for the 1st time, replace the x-unspec which is the default + } + t.isAllFeatures = true; + t.languagesAllFeat = addLanguages(t.languagesAllFeat, languages, replace); + } else { + if (!t.isSpecified) { + replace = true; + } + t.isSpecified = true; + t.languagesNotAllFeat = addLanguages(t.languagesNotAllFeat, languages, replace); + } + } + + void add(String typeName, boolean isAllFeat, RsLangs rslangs, boolean replace) { + RsType t = types.get(typeName); + if (null == t) { + t = new RsType(typeName); + types.put(typeName, t); + } + if (isAllFeat) { + if (!t.isAllFeatures) { + replace = true; + } + t.isAllFeatures = true; + t.languagesAllFeat = addLanguages(t.languagesAllFeat, rslangs, replace); + } else { + if (!t.isSpecified) { + replace = true; + } + t.isSpecified = true; + t.languagesNotAllFeat = addLanguages(t.languagesNotAllFeat, rslangs, replace); + } + } + + + /** + * add a feature (not a plain type) + * If feature exists, augments (union) its languages or replaces it + * @param typeName + * @param featName + * @param languages + * @param replace + */ + + void add(String typeName, String shortFeatName, Object rslangs, boolean replace) { + RsType t = types.get(typeName); + if (null == t) { + t = new RsType(typeName); + types.put(typeName, t); + } + RsFeats feats = t.features; + RsFeat feat = null; + if (null == feats) { + feats = new RsFeats(); + t.features = feats; + } else { + feat = feats.get(shortFeatName); + } + if (null == feat) { + feats.add(shortFeatName, rslangs); + } else { + feat.languages = addLanguages(feat.languages, rslangs, replace); + } + } + + RsLangs addLanguages(RsLangs existing, Object langs, boolean replace) { + String[] saLangs = null; + RsLangs rsLangs = null; + if (langs instanceof String[]) { + saLangs = (String[])langs; + } else { + rsLangs = (RsLangs)langs; + } + + boolean noLangs = (null == langs) ? true + : (null != saLangs) ? (0 == ((String[])langs).length) + : RsLangs.isEmpty(rsLangs); + + if (noLangs) { + if (replace) { + return null; + } + return existing; + } + if (null == existing && !replace) { // existing is x-unspecified + return null; // subsumes everything + } + if (replace) { + if (saLangs != null) { + return RsLangs.createOrNull(saLangs); + } else { + rsLangs.setShared(); + return rsLangs; + } + } + // not replace, and existing + existing = (null != saLangs) ? RsLangs.addAll(existing, saLangs) + : RsLangs.addAll(existing, rsLangs); + return existing; + } + + RsLangs addLanguages(RsLangs existing, RsLangs rslangs, boolean replace) { + if (RsLangs.isEmpty(rslangs)) { + if (replace) { + return null; + } + return existing; + } + if (null == existing && !replace) { // existing is x-unspecified + return null; + } + if (replace) { + rslangs.setShared(); + return rslangs; + } + existing = RsLangs.addAll(existing, rslangs); + return existing; + } + + + /** + * Remove a type, regardless of languages + * NOTE: doesn't remove type:feature entries associated with that type + * @param type + */ + void remove(String type) { + RsType t = types.get(type); + if (null != t) { + if (null == t.features || t.features.size() == 0) { + types.remove(type); + return; + } + t.isAllFeatures = false; + t.isSpecified = false; + t.languagesAllFeat = null; + t.languagesNotAllFeat = null; + } + } + + /** + * remove a feature, regardless of languages + * If all features are removed, null out the rsFeats slot. + * If all features are removed, and no type instance, remove the type also. + * @param typeName + * @param feature Short Name + */ + void remove(String type, String feature) { + RsType t = types.get(type); + if (null != t) { + if (null != t.features) { + t.features.remove(type, feature); + if (0 == t.features.size()) { + t.features = null; + if (!t.isAllFeatures && !t.isSpecified) { + types.remove(type); + } + } + } + } + } + + RsType getRsType(String typeName) { + return types.get(typeName); + } + + RsFeat get(String typeName, String shortFeatName) { + RsType t = types.get(typeName); + if (t == null || t.features == null) { + return null; + } + return t.features.get(shortFeatName); + } + + int nbrOfTypes() { + return types.size(); + } + + public Iterator<RsType> iterator() { + return types.values().iterator(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((types == null) ? 0 : types.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + RsTypesMap other = (RsTypesMap) obj; + if (types == null) { + if (other.types != null) { + return false; + } + } else if (!types.equals(other.types)) { + return false; + } + return true; + } + +} Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/TypeOrFeature_impl.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/TypeOrFeature_impl.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/TypeOrFeature_impl.java (original) +++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/TypeOrFeature_impl.java Thu Sep 2 13:43:50 2010 @@ -161,4 +161,42 @@ public class TypeOrFeature_impl extends return new XmlizationInfo(null, null); // this object has custom XMLization routines } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (mAllAnnotatorFeatures ? 1231 : 1237); + result = prime * result + ((mName == null) ? 0 : mName.hashCode()); + result = prime * result + (mType ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TypeOrFeature_impl other = (TypeOrFeature_impl) obj; + if (mAllAnnotatorFeatures != other.mAllAnnotatorFeatures) { + return false; + } + if (mName == null) { + if (other.mName != null) { + return false; + } + } else if (!mName.equals(other.mName)) { + return false; + } + if (mType != other.mType) { + return false; + } + return true; + } } Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/compatibility/AnnotatorAdapter.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/compatibility/AnnotatorAdapter.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/compatibility/AnnotatorAdapter.java (original) +++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/compatibility/AnnotatorAdapter.java Thu Sep 2 13:43:50 2010 @@ -168,10 +168,14 @@ public class AnnotatorAdapter implements rs = UIMAFramework.getResourceSpecifierFactory().createResultSpecification(); rs.setResultTypesAndFeatures(tofs); } else { - // special case: if annotator lists no outputs for this language, all it - // with all possible outputs. This is mainly for backwards compatibility, + // special case: if annotator lists no outputs for this language, call it + // with the actual result spec, set up by language. + + // An earlier version of this comment erroneously asserted + // "call for all possible outputs. + // This is mainly for backwards compatibility, // but here's a rationalization: the FlowController wants us to invoke the - // annotator, so calling it with no outputs doesn't really make sense. + // annotator, so calling it with no outputs doesn't really make sense." rs = mDefaultResultSpecification; } mLanguageToResultSpecMap.put(language, rs); Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java (original) +++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java Thu Sep 2 13:43:50 2010 @@ -125,7 +125,7 @@ public class TypeSystemImpl implements T // A map from the full space of feature names to feature codes. A feature // may - // be know by many different names (one for each subtype of the type the + // be known by many different names (one for each subtype of the type the // feature is declared on). private StringToIntMap featureMap; @@ -808,7 +808,7 @@ public class TypeSystemImpl implements T // We have to copy the array since we don't have const. return (this.approp.get(type)).toArrayCopy(); } - + /** * @return An offset <code>&gt;0</code> if <code>feat</code> exists; <code>0</code>, else. */ Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java (original) +++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java Thu Sep 2 13:43:50 2010 @@ -325,11 +325,17 @@ public class AnalysisEngine_implTest ext public void testProcess() throws Exception { try { // test simple primitive TextAnalysisEngine (using TestAnnotator class) + // This test should work with or without a type system description AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setPrimitive(true); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); primitiveDesc.getMetaData().setName("Test Primitive TAE"); + +// TypeSystemDescription tsd = new TypeSystemDescription_impl(); +// tsd.addType("NamedEntity", "", "uima.tcas.Annotation"); +// tsd.addType("DocumentStructure", "", "uima.cas.TOP"); +// primitiveDesc.getAnalysisEngineMetaData().setTypeSystem(tsd); Capability cap = new Capability_impl(); cap.addOutputType("NamedEntity", true); cap.addOutputType("DocumentStructure", true); @@ -337,6 +343,23 @@ public class AnalysisEngine_implTest ext primitiveDesc.getAnalysisEngineMetaData().setCapabilities(caps); _testProcess(primitiveDesc); + primitiveDesc = new AnalysisEngineDescription_impl(); + primitiveDesc.setPrimitive(true); + primitiveDesc + .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); + primitiveDesc.getMetaData().setName("Test Primitive TAE"); + + TypeSystemDescription tsd = new TypeSystemDescription_impl(); + tsd.addType("NamedEntity", "", "uima.tcas.Annotation"); + tsd.addType("DocumentStructure", "", "uima.cas.TOP"); + primitiveDesc.getAnalysisEngineMetaData().setTypeSystem(tsd); + cap = new Capability_impl(); + cap.addOutputType("NamedEntity", true); + cap.addOutputType("DocumentStructure", true); + caps = new Capability[] {cap}; + primitiveDesc.getAnalysisEngineMetaData().setCapabilities(caps); + _testProcess(primitiveDesc); + // test simple aggregate TextAnalysisEngine (again using TestAnnotator class) AnalysisEngineDescription aggDesc = new AnalysisEngineDescription_impl(); aggDesc.setPrimitive(false); @@ -409,10 +432,18 @@ public class AnalysisEngine_implTest ext // process(CAS,ResultSpecification) ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); - resultSpec.addResultType("NamedEntity", true); + resultSpec.addResultType("NamedEntity", true); // includes subtypes Person, Sentence, Place, Paragraph + // sets for lang = x-unspecified ResultSpecification expectedLastResultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); - expectedLastResultSpec.addResultType("NamedEntity", true, languages); + // interesting case: + // Because the annotator extends a UIMA Version 1.x impl class, we go thru an "adapter" interface + // which normally replaces the result spec with one that is based on language x-unspecified + // (guessing because version 1.x didn't properly support languages) + // However there's an exception to this: if the result spec would have no types or features + // for the language in the CAS, the original result spec is used, rather than a + // new one based on x-unspecified. + expectedLastResultSpec.addResultType("NamedEntity", true, languages); _testProcessInner(ae, tcas, resultSpec, expectedLastResultSpec); } @@ -429,9 +460,10 @@ public class AnalysisEngine_implTest ext // Test each form of the process method. When TestAnnotator executes, it // stores in static fields the document text and the ResultSpecification. - // We use thse to make sure the information propogates correctly to the annotator. + // We use these to make sure the information propagates correctly to the annotator. // process(CAS) + // Calls with the Result spec set to default to that of the outer annotator output capabilities tcas.setDocumentText("new test"); ae.process(tcas); assertEquals("new test", TestAnnotator.lastDocument); Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java (original) +++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java Thu Sep 2 13:43:50 2010 @@ -30,6 +30,10 @@ import org.apache.uima.analysis_engine.A import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.cas.CAS; +import org.apache.uima.cas.Feature; +import org.apache.uima.cas.Type; +import org.apache.uima.cas.admin.TypeSystemMgr; +import org.apache.uima.cas.impl.TypeSystemImpl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; @@ -43,6 +47,14 @@ public class ResultSpecTest extends Test private static final String PTBR = "pt-br"; private static final String I = "I"; // split designator + // types + + private static final TypeSystemMgr ts = new TypeSystemImpl(); + private static final Type t1 = ts.addType("T1", ts.getTopType()); + private static final Feature f1 = ts.addFeature("F1", t1, t1); + private static final Feature f1a = ts.addFeature("F1a", t1, t1); + static {ts.commit();}; + /** * Tests for https://issues.apache.org/jira/browse/UIMA-1840 */ @@ -86,16 +98,16 @@ public class ResultSpecTest extends Test String[] rs2langs = rs2List.toArray(new String[rs2List.size()]); String[] explangs = expList.toArray(new String[expList.size()]); - ResultSpecification_impl rs1 = new ResultSpecification_impl(); - ResultSpecification_impl rs2 = new ResultSpecification_impl(); - ResultSpecification_impl rsE = new ResultSpecification_impl(); //expected + ResultSpecification_impl rs1 = new ResultSpecification_impl(ts); + ResultSpecification_impl rs2 = new ResultSpecification_impl(ts); + ResultSpecification_impl rsE = new ResultSpecification_impl(ts); //expected addResultTypeOneAtATime(rs1, rs1langs); addResultTypeOneAtATime(rs2, rs2langs); addResultTypeOneAtATime(rsE, explangs); - ResultSpecification_impl rsQ = ResultSpecification_impl.intersect(rs1, rs2); - assertTrue(rsQ.equals(rsE)); + ResultSpecification_impl rsQ = rs1.intersect(rs2); + assertEquals(rsQ, rsE); } // we do this to avoid language normalization from collapsing x-unspecified @@ -120,13 +132,13 @@ public class ResultSpecTest extends Test PrimitiveAnalysisEngine_impl ae = (PrimitiveAnalysisEngine_impl) UIMAFramework .produceAnalysisEngine(aeDesc); CAS cas = ae.newCAS(); - ResultSpecification resultSpec = new ResultSpecification_impl(); + ResultSpecification_impl resultSpec = new ResultSpecification_impl(); resultSpec.addResultType("uima.tt.TokenLikeAnnotation", true); resultSpec.setTypeSystem(cas.getTypeSystem()); ResultSpecification_impl rs2 = new ResultSpecification_impl(cas.getTypeSystem()); rs2.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); - ResultSpecification acResultSpec = ResultSpecification_impl.intersect(resultSpec, rs2); + ResultSpecification acResultSpec = resultSpec.intersect(rs2); assertTrue(acResultSpec.containsType("uima.tt.TokenAnnotation")); assertFalse(acResultSpec.containsType("uima.tt.SentenceAnnotation")); assertFalse(acResultSpec.containsType("uima.tt.Lemma")); @@ -143,12 +155,12 @@ public class ResultSpecTest extends Test PrimitiveAnalysisEngine_impl ae = (PrimitiveAnalysisEngine_impl) UIMAFramework .produceAnalysisEngine(aeDesc); CAS cas = ae.newCAS(); - ResultSpecification resultSpec = new ResultSpecification_impl(cas.getTypeSystem()); + ResultSpecification_impl resultSpec = new ResultSpecification_impl(cas.getTypeSystem()); resultSpec.addResultType("uima.tcas.Annotation", true); ResultSpecification_impl rs2 = new ResultSpecification_impl(cas.getTypeSystem()); rs2.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); - ResultSpecification acResultSpec = ResultSpecification_impl.intersect(resultSpec, rs2); + ResultSpecification acResultSpec = resultSpec.intersect(rs2); assertTrue(acResultSpec.containsType("uima.tt.TokenAnnotation")); assertTrue(acResultSpec.containsType("uima.tt.SentenceAnnotation")); assertFalse(acResultSpec.containsType("uima.tt.Lemma")); Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTest.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTest.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTest.java (original) +++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTest.java Thu Sep 2 13:43:50 2010 @@ -110,11 +110,11 @@ public class ResultSpecWithTypeSystemTes check(tofT2, K.NotContain, f1); check(tofT2allFeat, K.Contains, f2); check(tofT2, K.NotContain, f2); -// check(tofT1allFeat, K.NotContain, f2); // because allFeat on T1 doesn't include F2 which is only introduced on T2 + check(tofT1allFeat, K.NotContain, f2); // because allFeat on T1 doesn't include F2 which is only introduced on T2 check(tofT2F1, K.NotContain, f1); // feature spec'd for subtype check(tofT2F1, K.Contains, "T2:F1"); -// check(tofT2F1, K.Contains, "T3:F1"); // oops, features not inheriting -// check(tofT1allFeat, K.NotContain, f4); // because allFeat on T1 doesn't include F4 which is only introduced on T4 + check(tofT2F1, K.Contains, "T3:F1"); // oops, features not inheriting + check(tofT1allFeat, K.NotContain, f4); // because allFeat on T1 doesn't include F4 which is only introduced on T4 check(tofT2allFeat, K.NotContain, f4); check(tofT1, K.NotContain, f4); } @@ -131,7 +131,7 @@ public class ResultSpecWithTypeSystemTes check(tofT1, EN, K.Contains, t2, EN_US); TofLs[] tofls = aT(tofT1allFeat, X, tofT2, X); -// check(tofls, K.NotContain, f2); // bad + check(tofls, K.NotContain, f2); // bad } @@ -142,12 +142,12 @@ public class ResultSpecWithTypeSystemTes check(tofT1allFeat, EN, K.Contains, f1, EN_US); TofLs[] tofls =aT(tofT1allFeat, X, tofT2, EN); -// check(tofls, K.NotContain, f2, X); // because f2 not in T1 -// check(tofls, K.NotContain, f2, EN); -// check(tofls, K.NotContain, f2, EN_US); + check(tofls, K.NotContain, f2, X); + check(tofls, K.NotContain, f2, EN); + check(tofls, K.NotContain, f2, EN_US); tofls =aT(tofT1allFeat, X, tofF2, EN); -// check(tofls, K.NotContain, f2, X); + check(tofls, K.NotContain, f2, X); check(tofls, K.Contains, f2, EN); check(tofls, K.Contains, f2, EN_US); @@ -163,8 +163,8 @@ public class ResultSpecWithTypeSystemTes tofls = aT(tofT1allFeat, EN_US, tofT2, EN); check(tofls, K.NotContain, f2, X); -// check(tofls, K.NotContain, f2, EN); -// check(tofls, K.NotContain, f2, EN_US); + check(tofls, K.NotContain, f2, EN); //broken + check(tofls, K.NotContain, f2, EN_US); tofls = aT(tofT1, X, tofT2, EN_US); check(tofls, K.NotContain, f2, X); @@ -178,9 +178,9 @@ public class ResultSpecWithTypeSystemTes tofls = aT(tofF1, EN, tofF2, EN_US); check(tofls, K.NotContain, "T2:F1", X); -// check(tofls, K.Contains, "T2:F1", EN); // because feats not inheriting from supers -// check(tofls, K.Contains, "T2:F1", EN_US); - check(tofls, K.NotContain, f2, EN); + check(tofls, K.Contains, "T2:F1", EN); + check(tofls, K.Contains, "T2:F1", EN_US); + check(tofls, K.NotContain, f2, EN); //broken check(tofls, K.Contains, f2, EN_US); From justin28@example.net Thu Sep 02 13:45:22 2010 Return-Path: <justin28@example.net> Delivered-To: justin28@example.net Received: (qmail 6802 invoked from network); 2 Sep 2010 13:45:22 -0000 Received: from unknown (HELO mail.apache.org) (83.161.120.155) by 83.161.120.155 with SMTP; 2 Sep 2010 13:45:22 -0000 Received: (qmail 98005 invoked by uid 500); 2 Sep 2010 13:45:22 -0000 Delivered-To: justin28@example.net Received: (qmail 97639 invoked by uid 500); 2 Sep 2010 13:45:21 -0000 Mailing-List: contact justin28@example.net; run by ezmlm Precedence: bulk List-Help: <mailto:justin28@example.net> List-Unsubscribe: <mailto:justin28@example.net> List-Post: <mailto:justin28@example.net> List-Id: <commits.uima.apache.org> Reply-To: justin28@example.net Delivered-To: mailing list justin28@example.net Received: (qmail 97632 invoked by uid 99); 2 Sep 2010 13:45:20 -0000 Received: from nike.apache.org (HELO nike.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 02 Sep 2010 13:45:20 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [83.161.120.155] (HELO eris.apache.org) (83.161.120.155) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 02 Sep 2010 13:45:12 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id CFA20238890A; Thu, 2 Sep 2010 13:43:51 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r991931 [1/2] - in /uima/uimaj/trunk/uimaj-core/src: main/java/org/apache/uima/analysis_engine/impl/ main/java/org/apache/uima/analysis_engine/impl/compatibility/ main/java/org/apache/uima/cas/impl/ test/java/org/apache/uima/analysis_engine... Date: Thu, 02 Sep 2010 13:43:51 -0000 To: justin28@example.net From: justin28@example.net X-Mailer: svnmailer-1.0.8 Message-Id: <justin28@example.net> X-Virus-Checked: Checked by ClamAV on apache.org Author: schor Date: Thu Sep 2 13:43:50 2010 New Revision: 991931 URL: http://svn.apache.org/viewvc?rev=991931&view=rev Log: [UIMA-1860] [UIMA-1840] Re-impl of result spec, supporting correct semanntics in detail. Test case updates to test additional corner cases. Added: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsFeat.java uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsFeats.java uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsFullFeatNames.java uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsLang.java uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsLangs.java uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsType.java uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/RsTypesMap.java Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/ResultSpecification_impl.java uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/TypeOrFeature_impl.java uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/compatibility/AnnotatorAdapter.java uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.java uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTest.java Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java (original) +++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/PrimitiveAnalysisEngine_impl.java Thu Sep 2 13:43:50 2010 @@ -359,14 +359,14 @@ public class PrimitiveAnalysisEngine_imp if (mLastTypeSystem != view.getTypeSystem()) { mLastTypeSystem = view.getTypeSystem(); mCurrentResultSpecification.setTypeSystem(mLastTypeSystem); - rsFromOutputCapabilities = new ResultSpecification_impl(); + rsFromOutputCapabilities = new ResultSpecification_impl(mLastTypeSystem); rsFromOutputCapabilities.addCapabilities(this.getAnalysisEngineMetaData().getCapabilities()); } // the actual ResultSpec we send to the component is formed by - // looking at this primitive AE's declared output types and eliminiating + // looking at this primitive AE's declared output types and eliminating // any that are not in mCurrentResultSpecification. ResultSpecification analysisComponentResultSpec = - ResultSpecification_impl.intersect(mCurrentResultSpecification, (ResultSpecification_impl) rsFromOutputCapabilities); + ((ResultSpecification_impl)mCurrentResultSpecification).intersect((ResultSpecification_impl)rsFromOutputCapabilities); mAnalysisComponent.setResultSpecification(analysisComponentResultSpec); mResultSpecChanged = false; } Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/ResultSpecification_impl.java URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/ResultSpecification_impl.java?rev=991931&r1=991930&r2=991931&view=diff ============================================================================== --- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/ResultSpecification_impl.java (original) +++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/analysis_engine/impl/ResultSpecification_impl.java Thu Sep 2 13:43:50 2010 @@ -20,15 +20,18 @@ package org.apache.uima.analysis_engine.impl; import java.util.ArrayList; -import java.util.BitSet; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.TypeOrFeature; +import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; +import org.apache.uima.cas.impl.TypeSystemImpl; import org.apache.uima.cas.text.Language; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.impl.MetaDataObject_impl; @@ -36,37 +39,88 @@ import org.apache.uima.resource.metadata import org.apache.uima.resource.metadata.impl.XmlizationInfo; /** - * Reference implementaion of {@link ResultSpecification}. + * Reference implementation of {@link ResultSpecification}. * * Notes on the implementation * - * There are two ways this data is used: with and without "compiling" - * Compiling means: adding subtypes of types and adding all features of a type - * Uncompiled form is called ORIGINAL. - * - * Compiling is deferred - until the first reference to containsType or Feature. + * Result Specifications (result specs, rs) are closely tied to capability specifications. + * + * They consist of instances of + * TypeOrFeatures and associated languages for which they are set. * - * Many instances of this class are made, sometimes via cloning. + * This impl supports removing previously added types and features + * for particular languages. * - * Sometimes types and features are deleted - the intent is to do this operation on the - * uncompiled form, and then "recompile" it. + * There are two forms of the data kept: + * The data as it was provided to set the items in the result spec + * This form is used when removing previously added things + * + * The data after a type system has been provided, expanded to cover + * the various implied settings, due to either + * all Features flag on a type or + * the type/subtype hierarchy in the type system + * + * TypesOrFeatures are: + * typeXXX:FeatureYYY - specifying a particular feature of a type + * (Corner case: typeXXX:FeatureYYY doesn't imply there's a + * typeXXX allFeat nor a + * typeXXX w/o allFeat. + * + * typeXXX with allFeatures - a shorthand for specifying + * typeXXX and + * typeXXX:FeatureYYY for all features YYY defined for typeXXX + * (Corner case: excludes features ZZZ defined only in subtype of typeXXX) + * typeXXX without allFeatures (w/o allFeat) - specifies a type, but says nothing about the features + * This is specifiable in the XML. It means: + * The type is produced/needed but there's no information about the features that + * are to be produced or used * - * Types and Features are kept on a per-language basis. Language can include a special value, - * x-unspecified, which "matches" any other language. + * containsType typeXXX + * returns true if typeXXX is in the RS, with or without the allFeats flag + * returns false if only features involving typeXXX are specified + * + * Intersection is done on fully expanded representations. * - * Language specifications are simplified to eliminate the country part. All refs to - * test if a type or feature is in the result spec for a language uses the simplified language. + * There are two kinds of inheritance used + * Assuming there's a type system (which must be present when intersection is used), there's type/subtype + * This means that if a resultSpec is set for typeXXX, then the containsType(typeYYY) + * returns true if typeYYY is a subtype of typeXXX. + * This also needs to work for typeXXX:featZZZ; containsFeature(typeYYY:featZZZ) + * returns true if type YYY is a subtype of typeXXX. + * + * Languages have a 3 level hierarchy: + * x-unspecified - the same as no language being specified. + * If the resultSpec contains typeXXX for language x-unspecified, + * containsType(typeXXX, languageLLL) returns true, for any languageLLL + * a "base" language, without a '-', e.g. "en" + * a sub-language, with one or more '-', e.g., "en-us" + * + * The rules for matching languages only handle these three levels of inheritance. + * (Corner case: 3 or more level language hierarchy are treated as 3 level hierarchies + * eg. zh-Hant-HK (Traditional Chinese as used in Hong Kong) + * See http://www.w3.org/International/articles/language-tags/Overview.en.php ) * - * Set operations are done to combine, for a particular type or feature, the languages for which it is valid. - * This is a Union operation - * Set operations are done to union the input types/features with the output types/features when computing the default - * result-spec for an aggregate. - * Set operations are done to intersect the result spec with the output capabilities of a component. + * Design considerations and assumptions + * Many instances of this class are made, sometimes via cloning. + * Most uses only use types, not type:features + * Most don't use languages + * A small subset of the possible types and type:features is specified explicitly + * Sometimes types and/or features are deleted. (language capability flow deletes types and/or features) * - * Languages are represented as integers; there is a hash table from the string to the integer, and - * an array to go from integer to lang string. + * Types and Features are kept on a per-language basis. Language can include a special value, + * x-unspecified, which "matches" any other language. * - * A result set of ORIGINALs consists of types/features with associated language sets. + * Set operations among different result specs: + * Union: done in aggregates over result-specs derived from input capabilities of delegates + * Intersection: done for primitive components, over result-spec derived from output capability of the primitive + * remove: one type or feature (used by language capability flow) + * (Corner cases + * removing typeXXX doesn't remove typeXXX:featureYYY + * removing typeXXX allFeat doesn't remove typeXXX w/o allFeat (may have different languages) + * removing typeXXX w/o allFeat doesn't remove typeXXX allFeat + * + * The compiled version is used in containsType, containsFeature testing, and is used when + * computing intersection. */ public final class ResultSpecification_impl extends MetaDataObject_impl implements @@ -74,131 +128,41 @@ public final class ResultSpecification_i private static final long serialVersionUID = 8516517600467270594L; - private static final int UNSPECIFIED_LANGUAGE_INDEX = 0; - /** * main language separator e.g 'en' and 'en-US' - */ - private static final char LANGUAGE_SEPARATOR = '-'; - - private class ToF_Languages implements Cloneable { - public TypeOrFeature tof; - public BitSet languages; - - ToF_Languages(TypeOrFeature aTof, String[] aLanguages) { - tof = aTof; - languages = new BitSet(); - for (String lang : aLanguages) { - languages.set(getLanguageIndex(lang)); - } - } - - ToF_Languages(TypeOrFeature aTof, BitSet aLanguages) { - tof = aTof; - languages = aLanguages; - } - - public Object clone() { - return new ToF_Languages((TypeOrFeature) tof.clone(), (BitSet)languages.clone()); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((languages == null) ? 0 : languages.hashCode()); - result = prime * result + ((tof == null) ? 0 : tof.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - final ToF_Languages other = (ToF_Languages) obj; - if (languages == null) { - if (other.languages != null) - return false; - } else if (!languages.equals(other.languages)) - return false; - if (tof == null) { - if (other.tof != null) - return false; - } else if (!tof.equals(other.tof)) - return false; - return true; - } - + */ - } - - private boolean needsCompilation = true; - - private final Map<String, Integer> lang2int; - + private static final String[] ARRAY_X_UNSPEC = new String[]{Language.UNSPECIFIED_LANGUAGE}; /** - * hash map used to map fully qualified type and feature names to associated - * ToF_Languages instances. This used for ORIGINAL types and features. - * - * Another hash map is used for compiled types and features - these include - * the subtypes of the ORIGINAL types. We keep the originals because the - * operations of adding and removing types and features are done with respect - * to the originals, only, and then the other map for compiled types is recomputed. - * - * A case in particular: we need to be able to distinguish which types were - * originally marked allAnnotatorFeatures, versus those types which were - * added because they were subtypes. The corner case happens when a type is both - * an original and is also an added-via-subtype, where the allAnnotatorFeatures - * flag of the original is not set but the subtype version is set. - * + * form used in hash table of compilied version to represent x-unspecified + * (can't use null - that means entry not in table) */ - private final Map<String, ToF_Languages> name2tof_langs; - + private static final RsLangs compiledXunspecified = RsLangs.createSharableEmpty(); // a distinct object + /** - * hash map used to map fully qualified type and feature names to associated - * ToF_Languages instances. This used for COMPILED types and features. + * used for empty type subsumption lists in subtype iterator */ - - private final Map<String, ToF_Languages> withSubtypesName2tof_langs; - -// /** -// * Map from TypeOrFeature objects to HashSets that include the language codes (Strings) for which -// * that type or feature should be produced. -// */ -// private Map<TypeOrFeature, Set<String>> mTypesAndFeatures = new HashMap<TypeOrFeature, Set<String>>(); -// -// /** -// * Map from String type or feature names to HashSets that include the language codes (Strings) for -// * which that type or feature should be produced. This is populated by the compile() method, and -// * includes subtypes as well as the individual feature names for types that have -// * allAnnotatorFeatures=true. -// */ -// private final Map<String, Set<String>> mCompiledNameToLanguageMap = -// new HashMap<String, Set<String>>(); + public static final List<Type> EMPTY_TYPE_LIST = new ArrayList<Type>(0); /** - * Default language set to use if nothing else is specified + * For this Result-specification, the collection of language-sets + * Uncompiled format */ - private static final String[] UNSPECIFIED_LANGUAGE_IN_ARRAY_OF_1 = new String[] {Language.UNSPECIFIED_LANGUAGE}; - + private final RsTypesMap rsTypesMap; + /** * The type system used to compute the subtypes and allAnnotatorFeatures of types */ - private TypeSystem mTypeSystem; + private TypeSystem mTypeSystem = null; + + // compiled forms + private boolean needsCompilation = true; + private final Map<String, RsLangs> rsCompiled; - /** - * constructor: init the default languge set with the language x-unspecified - */ public ResultSpecification_impl() { - name2tof_langs = new HashMap<String, ToF_Languages>(); - withSubtypesName2tof_langs = new HashMap<String, ToF_Languages>(); - lang2int = new HashMap<String, Integer>(); - lang2int.put(Language.UNSPECIFIED_LANGUAGE, 0); + rsTypesMap = new RsTypesMap(); + rsCompiled = new HashMap<String, RsLangs>(); } /** @@ -213,294 +177,109 @@ public final class ResultSpecification_i this(); mTypeSystem = aTypeSystem; } - - private ResultSpecification_impl(ResultSpecification_impl original) { - name2tof_langs = new HashMap<String, ToF_Languages>(original.name2tof_langs.size()); - withSubtypesName2tof_langs = new HashMap<String, ToF_Languages>(original.withSubtypesName2tof_langs.size()); - - // don't share this - unless prove there are no multi-tasking interlocks possible - lang2int = new HashMap<String, Integer>(original.lang2int); - - for (Map.Entry<String, ToF_Languages> entry : original.name2tof_langs.entrySet()) { - ToF_Languages tof_langs = entry.getValue(); - - // note: TypeOrFeature instances are not cloned, but shared - // If they are modified, things may break - name2tof_langs.put(entry.getKey(), - new ToF_Languages(tof_langs.tof, (BitSet)(tof_langs.languages.clone()))); - } - mTypeSystem = original.mTypeSystem; - } - - private int getBaseLanguageIndex(String language) { - return getLanguageIndex(getBaseLanguage(language)); - } - - private int getLanguageIndex(String language) { - Integer r = lang2int.get(language); - if (null == r) { - int i = lang2int.size(); - lang2int.put(language, Integer.valueOf(i)); - return i; - } - return r.intValue(); - } - private void compileIfNeeded() { - if (needsCompilation) { - compile(); - } - } - - private static String getBaseLanguage(String language) { - String baseLanguage = language; - int index = language.indexOf(LANGUAGE_SEPARATOR); - if (index > -1) { - baseLanguage = language.substring(0, index); - } - return baseLanguage; - } - /** - * @see org.apache.uima.analysis_engine.ResultSpecification#getResultTypesAndFeatures() + * copies the result spec passed in so that updates to it + * don't affect the original + * @param original */ - public TypeOrFeature[] getResultTypesAndFeatures() { - TypeOrFeature[] arr = new TypeOrFeature[name2tof_langs.size()]; - int i = 0; - for (ToF_Languages tof_langs : name2tof_langs.values()) { - arr[i++] = tof_langs.tof; - } - return arr; - } - - private Map<String, ToF_Languages> availName2tof_langs() { - if (needsCompilation) { - return name2tof_langs; + private ResultSpecification_impl(ResultSpecification_impl original) { + mTypeSystem = original.mTypeSystem; // not cloned + rsTypesMap = new RsTypesMap(original.rsTypesMap); + needsCompilation = original.needsCompilation; + rsCompiled = new HashMap<String, RsLangs>(original.rsCompiled); + for (Map.Entry<String, RsLangs> e : rsCompiled.entrySet()) { + e.getValue().setShared(); } - return withSubtypesName2tof_langs; } - + /** - * return the set of languages for this type or feature, or null if no such type/feature + * @see org.apache.uima.analysis_engine.ResultSpecification#getResultTypesAndFeatures() */ - private ToF_Languages getLanguagesForTypeOrFeature(String typeOrFeature) { - boolean isType = typeOrFeature.indexOf(TypeSystem.FEATURE_SEPARATOR) == -1; - Map<String, ToF_Languages> tofMap = (isType) ? availName2tof_langs() : name2tof_langs; - return tofMap.get(typeOrFeature); - } + public TypeOrFeature[] getResultTypesAndFeatures() { + return getResultTypesAndFeatures(true, null); + } /** * @see org.apache.uima.analysis_engine.ResultSpecification#getResultTypesAndFeatures(java.lang.String) + * May contain near-duplicates - same type, but with different settings of allannotatorfeatures + * (only if they have different languages) */ public TypeOrFeature[] getResultTypesAndFeatures(String language) { - - int languageIndex = getLanguageIndex(language); - int baseLanguageIndex = getBaseLanguageIndex(language); - - // holds the found ToFs for the specified language - List<TypeOrFeature> foundToF = new ArrayList<TypeOrFeature>(); - - for (Map.Entry<String, ToF_Languages> entry : name2tof_langs.entrySet()) { - if (languageMatches(entry.getValue(), languageIndex, baseLanguageIndex)) { - foundToF.add(entry.getValue().tof); - } - } - return foundToF.toArray(new TypeOrFeature[foundToF.size()]); + return getResultTypesAndFeatures(false, language); } - - // private helper functions -// private boolean sameLanguages(String [] s, BitSet b) { -// if (s.length != b.cardinality()) { -// return false; -// } -// for (String lang : s) { -// if ( ! b.get(getLanguageIndex(lang))) { -// return false; -// } -// } -// return true; -// } - - /** - * change null languages to the unspecified language - * change a set of languages that includes the unspecified language to - * just the unspecified language. - * This is OK when storing things into a result spec, since - * the unspecified language will match any query. - * This doesn't apply for querying because the queries only - * specify one language, not a set - */ - private String [] normalizeLanguages(String [] languages) { - if (null == languages) { - return UNSPECIFIED_LANGUAGE_IN_ARRAY_OF_1; - } else { - for (String lang : languages) { - if (lang.equals(Language.UNSPECIFIED_LANGUAGE)) { - return UNSPECIFIED_LANGUAGE_IN_ARRAY_OF_1; + private TypeOrFeature[] getResultTypesAndFeatures(boolean skipLanguageFilter, String language) { + List<TypeOrFeature> r = new ArrayList<TypeOrFeature>(); + if ((rsTypesMap == null || rsTypesMap.nbrOfTypes() == 0) && needsCompilation == false) { + // being called on results of intersection + // probably by a test case, not a normal call + // attempt to construct a plausible representation + reconstructRsTypesFromCompiled(); + } + for (RsType t : rsTypesMap) { + if (t.isAllFeatures && (skipLanguageFilter || RsLangs.subsumes(t.languagesAllFeat, language))) { + r.add(createTypeOrFeature(t.typeName, true, true)); + } + if (t.isSpecified && (skipLanguageFilter || RsLangs.subsumes(t.languagesNotAllFeat, language))) { + if (!(t.isAllFeatures && t.languagesAllFeat.equals(t.languagesNotAllFeat))) // don't make a duplicate + r.add(createTypeOrFeature(t.typeName, true, false)); + } + if (t.features != null) { + for (RsFeat f : t.features) { + if (skipLanguageFilter || f.subsumes(language)) + r.add(createTypeOrFeature(t.typeName, f.shortFeatName)); } } } - // normalization is expensive - so do this once as part of parsing capabilities -// int i = 0; -// for (String language : languages) { -// languages[i++] = normalizeLanguage(language); -// } - return languages; + return r.toArray(new TypeOrFeature[r.size()]); } - -// private String normalizeLanguage(String language) { -// String result = language.toLowerCase(Locale.ENGLISH); // language specs are in English locale -// return result.replace('_', '-'); -// } - - private void setNeedsCompilation() { - needsCompilation = true; - if (0 != withSubtypesName2tof_langs.size()) { - withSubtypesName2tof_langs.clear(); - } - } - - private void addTypeOrFeatureInternal(TypeOrFeature tof, String[] languages) { - languages = normalizeLanguages(languages); - - ToF_Languages tof_langs = name2tof_langs.get(tof.getName()); - if (null == tof_langs) { - name2tof_langs.put(tof.getName(), new ToF_Languages(tof, languages)); - setNeedsCompilation(); - return; - } - tof_langs.tof.setAllAnnotatorFeatures(tof.isAllAnnotatorFeatures()); - BitSet langBitSet = tof_langs.languages; - langBitSet.clear(); - for (String lang : languages) { - langBitSet.set(getLanguageIndex(lang)); - } - setNeedsCompilation(); - } - - /** - * Create an entry in this result spec from the type or feature and its languages - * @param tofLangs - */ - private void addClonedToF_Languages(ToF_Languages tofLangs, ResultSpecification_impl rs) { - List<String> languages = new ArrayList<String>(); - BitSet bs = tofLangs.languages; - for (Map.Entry<String, Integer> si : rs.lang2int.entrySet()) { - if (bs.get(si.getValue())) { - languages.add(si.getKey()); - } - } - - ToF_Languages n = new ToF_Languages( - tofLangs.tof, - languages.toArray(new String[languages.size()])); - name2tof_langs.put(n.tof.getName(), n); - setNeedsCompilation(); - } - - private TypeOrFeature createTypeOrFeature(String name, boolean isType, boolean aAllAnnotatorFeatures) { - TypeOrFeature r = new TypeOrFeature_impl(); - r.setType(isType); - r.setName(name); - if (isType) { - r.setAllAnnotatorFeatures(aAllAnnotatorFeatures); - } - return r; - } - - private void addResultTypeOrFeatureAddLanguage(String name, boolean isType, boolean allAnnotatorFeatures, String[] languages) { - - ToF_Languages tof_langs = name2tof_langs.get(name); - - if (null == tof_langs) { - addTypeOrFeatureInternal(createTypeOrFeature(name, isType, allAnnotatorFeatures), languages); - setNeedsCompilation(); - return; - } - - // tof_langs entry for this name exists, so update it - addResultTypeOrFeatureAddLanguageCommon(tof_langs, allAnnotatorFeatures, languages); - } - - private void addResultTypeOrFeatureAddLanguage(TypeOrFeature tof, String[] languages) { - - ToF_Languages tof_langs = name2tof_langs.get(tof.getName()); - - if (null == tof_langs) { - addTypeOrFeatureInternal(tof, languages); - setNeedsCompilation(); - return; - } - - addResultTypeOrFeatureAddLanguageCommon(tof_langs, tof.isAllAnnotatorFeatures(), languages); - } - - private void addResultTypeOrFeatureAddLanguageCommon( - ToF_Languages tof_langs, boolean allAnnotatorFeatures, String [] languages) { - // tof_langs entry for this name exists, so update it - if (allAnnotatorFeatures) { - if (!tof_langs.tof.isAllAnnotatorFeatures()) { - tof_langs.tof.setAllAnnotatorFeatures(true); - setNeedsCompilation(); + private void reconstructRsTypesFromCompiled() { + // First, recompute basic rsTypes and rsFeatures hooked to types + for (Entry<String, RsLangs> e : rsCompiled.entrySet()) { + String tofName = e.getKey(); + int b = tofName.indexOf(TypeSystem.FEATURE_SEPARATOR); + if (b == -1) { + rsTypesMap.add(tofName, false, e.getValue(), false); + } else { + String typeName = tofName.substring(0, b); + String featName = tofName.substring(b+1); + rsTypesMap.add(typeName, featName, e.getValue(), false); } } - - // update the languages by adding the new languages passed in - languages = normalizeLanguages(languages); - BitSet langBitSet = tof_langs.languages; - // "==" ok here due to normalizeLanguages call above - if (languages == UNSPECIFIED_LANGUAGE_IN_ARRAY_OF_1) { - if ( ! langBitSet.get(UNSPECIFIED_LANGUAGE_INDEX)) { - langBitSet.clear(); - langBitSet.set(UNSPECIFIED_LANGUAGE_INDEX); - setNeedsCompilation(); + // Second merge + // if the types features all have the same lang and are all the features, + // set the allFeats flag, and merge in the langs + for (RsType t : rsTypesMap) { + if (t.hasAllFeaturesExplicitly(mTypeSystem) && t.allFeaturesHaveSameLangs()) { + t.isAllFeatures = true; + RsLangs l = t.features.features.get(0).languages; + if (l != null && RsLangs.isEmpty(l)) { + l = null; + } + if (l != null) { + if (t.languagesAllFeat == null) { + t.languagesAllFeat = RsLangs.createOrNull(l); + } else { // merge in langs l + t.languagesAllFeat = RsLangs.addAll(t.languagesAllFeat, l); + } + } + t.features = null; } - return; - } - - // languages set already exists; add new ones to existing set - for (String lang : languages) { - langBitSet.set(getLanguageIndex(lang)); - } - setNeedsCompilation(); - } - - /** - * version used by compile to add subtypes - * @param aTypeName - * @param aAllAnnotatorFeatures - * @param languages - */ - private void addResultType(String name, boolean allAnnotatorFeatures, BitSet languages) { - ToF_Languages tof_langs = withSubtypesName2tof_langs.get(name); - - if (null == tof_langs) { - withSubtypesName2tof_langs.put( - name, - new ToF_Languages(createTypeOrFeature(name, true, allAnnotatorFeatures), (BitSet)languages.clone())); - return; - } - - // tof_langs entry for this name exists, so update it - if (allAnnotatorFeatures) { - if (!tof_langs.tof.isAllAnnotatorFeatures()) { - tof_langs.tof.setAllAnnotatorFeatures(true); + if (t.isSpecified && t.isAllFeatures && equalsOrBothNull(t.languagesAllFeat, t.languagesNotAllFeat)) { + t.isSpecified = false; + t.languagesNotAllFeat = null; } - } - - // update the languages by adding the new languages passed in - tof_langs.languages.or(languages); + } } - - + /** * @see org.apache.uima.analysis_engine.ResultSpecification#setResultTypesAndFeatures(org.apache.uima.analysis_engine.TypeOrFeature[]) */ public void setResultTypesAndFeatures(TypeOrFeature[] aTypesAndFeatures) { - setResultTypesAndFeatures(aTypesAndFeatures, UNSPECIFIED_LANGUAGE_IN_ARRAY_OF_1); + setResultTypesAndFeatures(aTypesAndFeatures, ARRAY_X_UNSPEC); } /** @@ -508,34 +287,51 @@ public final class ResultSpecification_i * java.lang.String[]) */ public void setResultTypesAndFeatures(TypeOrFeature[] aTypesAndFeatures, String[] aLanguageIDs) { - name2tof_langs.clear(); + for (TypeOrFeature tof : aTypesAndFeatures) { - name2tof_langs.put(tof.getName(), new ToF_Languages(tof, normalizeLanguages(aLanguageIDs))); - } - setNeedsCompilation(); + addResultTof(tof, aLanguageIDs, true); + } } - + + private void addResultTof(TypeOrFeature tof, String[] langs, boolean replace) { + String name = tof.getName(); + String typeName = null; + String shortFeatName = null; + int i = name.indexOf(TypeSystem.FEATURE_SEPARATOR); + if (i < 0) { + typeName = name; + rsTypesMap.add(typeName, tof.isAllAnnotatorFeatures(), langs, replace); + } else { + typeName = name.substring(0, i); + shortFeatName = name.substring(i+1); + rsTypesMap.add(typeName, shortFeatName, langs, replace); + } + setCompileNeeded(); + } + /** * @see org.apache.uima.analysis_engine.ResultSpecification#addResultTypeOrFeature(org.apache.uima.analysis_engine.TypeOrFeature) */ public void addResultTypeOrFeature(TypeOrFeature aTypeOrFeature) { - addTypeOrFeatureInternal(aTypeOrFeature, UNSPECIFIED_LANGUAGE_IN_ARRAY_OF_1); + addResultTypeOrFeature(aTypeOrFeature, ARRAY_X_UNSPEC); } /** * @see org.apache.uima.analysis_engine.ResultSpecification#addResultTypeOrFeature(org.apache.uima.analysis_engine.TypeOrFeature, * java.lang.String[]) + * + * Note: Javadoc makes assumption that there's one tof per type, but this design allows 2 (one with allAnnotatorFeatures set or not). */ - public void addResultTypeOrFeature(TypeOrFeature aTypeOrFeature, String[] aLanguageIDs) { - addTypeOrFeatureInternal(aTypeOrFeature, aLanguageIDs); - } + public void addResultTypeOrFeature(TypeOrFeature tof, String[] languages) { + addResultTof(tof, languages, true); + } /** * @see org.apache.uima.analysis_engine.ResultSpecification#addResultType(java.lang.String, * boolean) */ public void addResultType(String aTypeName, boolean aAllAnnotatorFeatures) { - addTypeOrFeatureInternal(createTypeOrFeature(aTypeName, true, aAllAnnotatorFeatures), UNSPECIFIED_LANGUAGE_IN_ARRAY_OF_1); + addResultType(aTypeName, aAllAnnotatorFeatures, ARRAY_X_UNSPEC); } /** @@ -543,14 +339,15 @@ public final class ResultSpecification_i * boolean, java.lang.String[]) */ public void addResultType(String aTypeName, boolean aAllAnnotatorFeatures, String[] aLanguageIDs) { - addResultTypeOrFeatureAddLanguage(aTypeName, true, aAllAnnotatorFeatures, aLanguageIDs); + rsTypesMap.add(aTypeName, aAllAnnotatorFeatures, aLanguageIDs, false); + setCompileNeeded(); } /** * @see org.apache.uima.analysis_engine.ResultSpecification#addResultFeature(java.lang.String) */ public void addResultFeature(String aFullFeatureName) { - addResultFeature(aFullFeatureName, UNSPECIFIED_LANGUAGE_IN_ARRAY_OF_1); + addResultFeature(aFullFeatureName, ARRAY_X_UNSPEC); } /** @@ -558,112 +355,39 @@ public final class ResultSpecification_i * java.lang.String[]) */ public void addResultFeature(String aFullFeatureName, String[] aLanguageIDs) { - addResultTypeOrFeatureAddLanguage(aFullFeatureName, false, false, aLanguageIDs); + String typeName = null; + String shortFeatName = null; + int i = aFullFeatureName.indexOf(TypeSystem.FEATURE_SEPARATOR); + typeName = aFullFeatureName.substring(0, i); + shortFeatName = aFullFeatureName.substring(i+1); + rsTypesMap.add(typeName, shortFeatName, aLanguageIDs, false); + setCompileNeeded(); } /** * @see org.apache.uima.analysis_engine.ResultSpecification#compile(org.apache.uima.cas.TypeSystem) + * @deprecated no longer needed, remove call to this */ + @Deprecated public void compile(TypeSystem aTypeSystem) { setTypeSystem(aTypeSystem); - compileIfNeeded(); + compile(); } - -// private static class TypeToCompile { -// String name; -// boolean allFeatures; -// String[] languages; -// TypeToCompile(String aName, boolean aAllFeatures, String[] aLanguages) { -// name = aName; -// allFeatures = aAllFeatures; -// languages = aLanguages; -// } -// } - - private void compile() { - if (null == mTypeSystem) { - return; - } - - needsCompilation = false; - // get set of current type names - // for each name, get set of implied additional names (allAnnotatorFeatures and subtypes), recursively - // add with languages - // issue: can a result spec hold for language 1 types a b c, for language 2 types a b? yes - // can it hold for lang 1 type a(allfeats) and for lang 2 type a(not all feat)? no - -// Map<String, TypeToCompile> typesToCompile = new HashMap<String, TypeToCompile>(mNameToTofLang.size()); -// for (ToF_Languages tof_langs : mNameToTofLang.values()) { -// TypeOrFeature tof = tof_langs.tof; -// if (tof.isType()) { -// String typeName = tof.getName(); -// typesToCompile.put(typeName, new TypeToCompile(typeName, tof.isAllAnnotatorFeatures(), tof_langs.languages)); -// } -// } - - for (ToF_Languages tof_langs : name2tof_langs.values()) { - TypeOrFeature tof = tof_langs.tof; - - addResultType(tof.getName(), tof.isAllAnnotatorFeatures(), tof_langs.languages); - - if (tof.isType()) { - compileTypeRecursively(mTypeSystem.getType(tof.getName()), tof.isAllAnnotatorFeatures(), tof_langs.languages); - } + private TypeOrFeature createTypeOrFeature(String name, boolean isType, boolean aAllAnnotatorFeatures) { + TypeOrFeature r = new TypeOrFeature_impl(); + r.setType(isType); + r.setName(name); + if (isType) { + r.setAllAnnotatorFeatures(aAllAnnotatorFeatures); } + return r; } - -// mCompiledNameToLanguageMap.clear(); -// for (Map.Entry<TypeOrFeature, Set<String>> elem : mTypesAndFeatures.entrySet()) { -// TypeOrFeature tof = elem.getKey(); -// if (tof.isType()) { -// Type t = aTypeSystem.getType(tof.getName()); -// if (t != null) { -// addTypeRecursive(t, aTypeSystem, elem.getValue(), tof.isAllAnnotatorFeatures()); -// } -// } else { // feature -// mCompiledNameToLanguageMap.put(tof.getName(), elem.getValue()); -// } -// } -// // TODO: process the set of intersections -// } - - private void compileTypeRecursively(Type type, boolean allFeatures, BitSet languages) { - - if (null != type) { -// if (allFeatures) { -// for (Feature f : (List<Feature>) type.getFeatures()) { -// addResultFeature(f.getName(), languages); // this add "merges" -// // langauges with existing -// // ones -// } -// } - - for (Type subType : (List<Type>) mTypeSystem.getDirectSubtypes(type)) { - String subTypeName = subType.getName(); - addResultType(subTypeName, allFeatures, languages); - compileTypeRecursively(subType, allFeatures, languages); - } - } + + private TypeOrFeature createTypeOrFeature(String typeName, String featureName) { + return createTypeOrFeature(typeName + TypeSystem.FEATURE_SEPARATOR + featureName, false, false); } -// /** -// * @param t -// */ -// private void addTypeRecursive(Type type, TypeSystem typeSystem, Set<String> languages, -// boolean allFeatures) { -// mCompiledNameToLanguageMap.put(type.getName(), languages); -// if (allFeatures) { -// for (Feature f : (List<Feature>)type.getFeatures()) { -// mCompiledNameToLanguageMap.put(f.getName(), languages); -// } -// } -// // recurse on subtypes -// for (Type subtype : (List<Type>)typeSystem.getDirectSubtypes(type)) { -// addTypeRecursive(subtype, typeSystem, languages, allFeatures); -// } -// } - /** * @see org.apache.uima.analysis_engine.ResultSpecification#containsType(java.lang.String) */ @@ -673,16 +397,27 @@ public final class ResultSpecification_i /** * @see org.apache.uima.analysis_engine.ResultSpecification#containsType(java.lang.String,java.lang.String) + * method: + * + * for each type (with all-feat, without all-feat): + * for each type, and supertypes + * check if one of the resultSpec languages subsumes the given language. + *
{'source': 'Apache Software Foundation Public Mail Archives'}