You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2013/06/18 22:25:40 UTC
svn commit: r1494286 - in /uima/uimaj/trunk/uimaj-core/src:
main/java/org/apache/uima/ main/java/org/apache/uima/cas/impl/
main/java/org/apache/uima/util/ main/resources/org/apache/uima/
test/java/org/apache/uima/cas_data/impl/ test/java/org/apache/uim...
Author: schor
Date: Tue Jun 18 20:25:39 2013
New Revision: 1494286
URL: http://svn.apache.org/r1494286
Log:
[UIMA-2409] Add copyCasView with target new view. Add one little test case, add a new comparator to check the results.
Added:
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/CasComparerViewChange.java (with props)
Modified:
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/UIMARuntimeException.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/util/CasCopier.java
uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/CasCopierTest.java
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/UIMARuntimeException.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/UIMARuntimeException.java?rev=1494286&r1=1494285&r2=1494286&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/UIMARuntimeException.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/UIMARuntimeException.java Tue Jun 18 20:25:39 2013
@@ -102,6 +102,11 @@ public class UIMARuntimeException extend
/**
* Message key for a standard UIMA exception message:
+ * "CAS Copying of the same view to the same CAS with the same view name is not allowed."
+ */
+ public static final String ILLEGAL_CAS_COPY_TO_SAME_CAS_SAME_VIEW = "illegal_copy_same_cas_same_view";
+ /**
+ * Message key for a standard UIMA exception message:
* Saved UIMA context is null; probable cause: Annotator initialize(context) method failed to call super.initialize(context).
*/
public static final String UIMA_CONTEXT_NULL = "uima_context_null";
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java?rev=1494286&r1=1494285&r2=1494286&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java Tue Jun 18 20:25:39 2013
@@ -2570,6 +2570,7 @@ public class CASImpl extends AbstractCas
// get Sofa and switch to view
SofaFS sofa = getSofa(absoluteSofaName);
// sofa guaranteed to be non-null by above method
+ // unless sofa doesn't exist, which will cause a throw.
return getView(sofa);
}
Modified: uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/util/CasCopier.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/util/CasCopier.java?rev=1494286&r1=1494285&r2=1494286&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/util/CasCopier.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/util/CasCopier.java Tue Jun 18 20:25:39 2013
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.uima.UIMARuntimeException;
+import org.apache.uima.cas.AnnotationBaseFS;
import org.apache.uima.cas.ArrayFS;
import org.apache.uima.cas.BooleanArrayFS;
import org.apache.uima.cas.ByteArrayFS;
@@ -56,11 +57,18 @@ import org.apache.uima.cas.text.Annotati
public class CasCopier {
private CAS mSrcCas;
private CAS mDestCas;
+ private String mSrcCasViewName;
+ private String mTgtCasViewName;
private LowLevelCAS mLowLevelDestCas;
- private Feature mDestSofaFeature;
- private boolean lenient = false; //true: ignore feature structures and features that are not defined in the destination CAS
+ final private Feature mDestSofaFeature;
+ final private boolean lenient; //true: ignore feature structures and features that are not defined in the destination CAS
- private Map<FeatureStructure, FeatureStructure> mFsMap = new HashMap<FeatureStructure, FeatureStructure>();
+ /**
+ * key is source FS, value is target FS
+ * Target not set for DocumentAnnotation or SofaFSs
+ * Target not set if lenient specified and src type isn't in target
+ */
+ final private Map<FeatureStructure, FeatureStructure> mFsMap = new HashMap<FeatureStructure, FeatureStructure>();
/**
* feature structures whose slots need copying are put on this list, together with their source
@@ -103,7 +111,6 @@ public class CasCopier {
public CasCopier(CAS aSrcCas, CAS aDestCas, boolean lenient) {
mSrcCas = aSrcCas;
mDestCas = aDestCas;
- mLowLevelDestCas = aDestCas.getLowLevelCAS();
mDestSofaFeature = aDestCas.getTypeSystem().getFeatureByFullName(CAS.FEATURE_FULL_NAME_SOFA);
this.lenient = lenient;
}
@@ -167,38 +174,136 @@ public class CasCopier {
}
/**
- * Does a deep copy of the contents of one CAS View into another CAS.
- * If a view with the same name as <code>aSrcCasView</code> exists in the destination CAS,
+ * Does a deep copy of the contents of one CAS View into another CAS's same-named-view
+ * If the destination view already exists in the destination CAS,
* then it will be the target of the copy. Otherwise, a new view will be created with
- * that name and will become the target of the copy. All FeatureStructures that are indexed
+ * that name and will become the target of the copy. All FeatureStructures
+ * (except for those dropped because the target type system doesn't have the needed type) that are indexed
+ * in the source CAS view will become indexed in the target view.
+ * Cross-view references may result in creating additional views in the destination CAS;
+ * for these views, any Sofa data in the source is *not* copied.
+ *
+ * @param aSrcCasView the CAS to copy from
+ * @param aCopySofa if true, the sofa data and mimeType will be copied. If false they will not.
+ */
+ public void copyCasView(CAS aSrcCasView, boolean aCopySofa) {
+ copyCasView(aSrcCasView, getOrCreateView(mDestCas, aSrcCasView.getViewName()), aCopySofa);
+ }
+
+ /**
+ * Does a deep copy of the contents of one CAS View into another CAS's same-named-view
+ * If the destination view already exists in the destination CAS,
+ * then it will be the target of the copy. Otherwise, a new view will be created with
+ * that name and will become the target of the copy. All FeatureStructures
+ * (except for those dropped because the target type system doesn't have the needed type) that are indexed
+ * in the source CAS view will become indexed in the target view.
+ * Cross-view references may result in creating additional views in the destination CAS;
+ * for these views, any Sofa data in the source is *not* copied. Any views created because
+ * of cross-view references will have the same view name as in the source.
+ *
+ * @param aSrcCasViewName the name of the view in the source CAS to copy from
+ * @param aCopySofa if true, the sofa data and mimeType will be copied. If false they will not.
+ */
+ public void copyCasView(String aSrcCasViewName, boolean aCopySofa) {
+ copyCasView(getOrCreateView(mSrcCas, aSrcCasViewName), aCopySofa);
+ }
+
+ /**
+ * Does a deep copy of the contents of one CAS View into another CAS view,
+ * with a possibly different name.
+ * If the destination view already exists in the destination CAS,
+ * then it will be the target of the copy. Otherwise, a new view will be created with
+ * that name and will become the target of the copy. All FeatureStructures
+ * (except for those dropped because the target type system doesn't have the needed type) that are indexed
+ * in the source CAS view will become indexed in the target view.
+ * Cross-view references may result in creating additional views in the destination CAS;
+ * for these views, any Sofa data in the source is *not* copied. Any views created because
+ * of cross-view references will have the same view name as in the source.
+ *
+ * @param aSrcCasView The view in the source to copy from
+ * @param aTgtCasViewName The name of the view in the destination CAS to copy into
+ * @param aCopySofa if true, the sofa data and mimeType will be copied. If false they will not.
+ */
+ public void copyCasView(CAS aSrcCasView, String aTgtCasViewName, boolean aCopySofa) {
+ copyCasView(aSrcCasView, getOrCreateView(mDestCas, aTgtCasViewName), aCopySofa);
+ }
+
+ /**
+ * Does a deep copy of the contents of one CAS View into another CAS view,
+ * with a possibly different name.
+ * All FeatureStructures
+ * (except for those dropped because the target type system doesn't have the needed type) that are indexed
+ * in the source CAS view will become indexed in the target view.
+ * Cross-view references may result in creating additional views in the destination CAS;
+ * for these views, any Sofa data in the source is *not* copied. Any views created because
+ * of cross-view references will have the same view name as in the source.
+ *
+ * @param aSrcCasViewName The name of the view in the Source CAS to copy from
+ * @param aTgtCasView The view in the destination CAS to copy into
+ * @param aCopySofa if true, the sofa data and mimeType will be copied. If false they will not.
+ */
+ public void copyCasView(String aSrcCasViewName, CAS aTgtCasView, boolean aCopySofa) {
+ copyCasView(getOrCreateView(mSrcCas, aSrcCasViewName), aTgtCasView, aCopySofa);
+ }
+
+ /**
+ * Does a deep copy of the contents of one CAS View into another CAS view,
+ * with a possibly different name.
+ * All FeatureStructures
+ * (except for those dropped because the target type system doesn't have the needed type) that are indexed
* in the source CAS view will become indexed in the target view.
+ * Cross-view references may result in creating additional views in the destination CAS;
+ * for these views, any Sofa data in the source is *not* copied. Any views created because
+ * of cross-view references will have the same view name as in the source.
*
* @param aSrcCasView
* the CAS to copy from
* @param aCopySofa
* if true, the sofa data and mimeType will be copied. If false they will not.
*/
- public void copyCasView(CAS aSrcCasView, boolean aCopySofa) {
- // get or create the target view
- CAS targetView = getOrCreateView(mDestCas, aSrcCasView.getViewName());
-
+ public void copyCasView(CAS aSrcCasView, CAS aTgtCasView, boolean aCopySofa) {
+ if (aSrcCasView == aTgtCasView) {
+ throw new UIMARuntimeException(UIMARuntimeException.ILLEGAL_CAS_COPY_TO_SAME_CAS_SAME_VIEW, null);
+ }
+
+ mSrcCas = aSrcCasView;
+ mSrcCasViewName = aSrcCasView.getViewName();
+
+ mDestCas = aTgtCasView;
+ mTgtCasViewName = aTgtCasView.getViewName();
+
+ mLowLevelDestCas = mDestCas.getLowLevelCAS();
+
+ // The top level sofa associated with this view is copied (or not)
+
if (aCopySofa) {
// can't copy the SofaFS - just copy the sofa data and mime type
SofaFS sofa = aSrcCasView.getSofa();
if (null != sofa) {
+ // if the sofa doesn't exist in the target, these calls will create it
+ // (view can exist without Sofa, at least for the initial view)
String sofaMime = sofa.getSofaMime();
if (aSrcCasView.getDocumentText() != null) {
- targetView.setSofaDataString(aSrcCasView.getDocumentText(), sofaMime);
+ aTgtCasView.setSofaDataString(aSrcCasView.getDocumentText(), sofaMime);
} else if (aSrcCasView.getSofaDataURI() != null) {
- targetView.setSofaDataURI(aSrcCasView.getSofaDataURI(), sofaMime);
+ aTgtCasView.setSofaDataURI(aSrcCasView.getSofaDataURI(), sofaMime);
} else if (aSrcCasView.getSofaDataArray() != null) {
- targetView.setSofaDataArray(copyFs(aSrcCasView.getSofaDataArray()), sofaMime);
+ aTgtCasView.setSofaDataArray(copyFs2(aSrcCasView.getSofaDataArray()), sofaMime);
}
}
}
// now copy indexed FS, but keep track so we don't index anything more than once
+ // Note: mFsMap might be used for this, but it doesn't index several kinds of FSs
+ // see the javadoc for this field for details
+ // NOTE: FeatureStructure hashcode / equals use the int "address" of the FS in the heap.
+
Set<FeatureStructure> indexedFs = new HashSet<FeatureStructure>();
+
+ // We don't clear the map here, in order to skip actually copying the
+ // FSs when doing a full CAS copy with multiple views - the 2nd and subsequent
+ // views don't copy, but they do index.
+
Iterator<FSIndex<FeatureStructure>> indexes = aSrcCasView.getIndexRepository().getIndexes();
while (indexes.hasNext()) {
FSIndex<FeatureStructure> index = indexes.next();
@@ -206,7 +311,7 @@ public class CasCopier {
while (iter.hasNext()) {
FeatureStructure fs = iter.next();
if (!indexedFs.contains(fs)) {
- FeatureStructure copyOfFs = copyFs(fs);
+ FeatureStructure copyOfFs = copyFs2(fs);
// If the lenient option is used, it's possible that no FS was
// created (e.g., FS is not defined in the target CAS. So ignore
// this FS in the source CAS and move on to the next FS.
@@ -219,15 +324,15 @@ public class CasCopier {
// if the annotations were created with the Low Level CAS API. If the
// Sofa reference isn't set, attempting to add the FS to the indexes
// will fail.
- if (fs instanceof AnnotationFS) {
- FeatureStructure sofa = ((AnnotationFS) copyOfFs).getFeatureValue(mDestSofaFeature);
+ if (fs instanceof AnnotationBaseFS) {
+ FeatureStructure sofa = ((AnnotationBaseFS) copyOfFs).getFeatureValue(mDestSofaFeature);
if (sofa == null) {
- copyOfFs.setFeatureValue(mDestSofaFeature, targetView.getSofa());
+ copyOfFs.setFeatureValue(mDestSofaFeature, aTgtCasView.getSofa());
}
}
// also don't index the DocumentAnnotation (it's indexed by default)
if (!isDocumentAnnotation(copyOfFs)) {
- targetView.addFsToIndexes(copyOfFs);
+ aTgtCasView.addFsToIndexes(copyOfFs);
}
indexedFs.add(fs);
}
@@ -250,7 +355,35 @@ public class CasCopier {
*
*/
+ /**
+ * Copy 1 feature structure to a new Cas View. No indexing of the new FS is done.
+ * If the FS has been copied previously (using this CasCopier instance) the
+ * same identical copy will be returned rather than making another copy.
+ *
+ * @param aFS
+ * @return
+ */
+
public FeatureStructure copyFs(FeatureStructure aFS) {
+ // note these variables are null if copyFs is called after
+ // creating an instance of this class
+ if (null == mSrcCasViewName) {
+ mSrcCasViewName = mSrcCas.getViewName();
+ }
+
+ if (null == mTgtCasViewName) {
+ mTgtCasViewName = mDestCas.getViewName();
+ }
+
+ if (null == mLowLevelDestCas) {
+ mLowLevelDestCas = mDestCas.getLowLevelCAS();
+ }
+
+ return copyFs2(aFS);
+ }
+
+ private FeatureStructure copyFs2(FeatureStructure aFS) {
+
FeatureStructure copy = copyFsInner(aFS); // doesn't copy the slot values, but enqueues them
while (!fsToDo.isEmpty()) {
FeatureStructure copyToFillSlots = fsToDo.remove(fsToDo.size()-1);
@@ -268,7 +401,7 @@ public class CasCopier {
* the FS to copy. Must be contained within the source CAS.
* @return the copy of <code>aFS</code> in the target CAS.
*/
- public FeatureStructure copyFsInner(FeatureStructure aFS) {
+ private FeatureStructure copyFsInner(FeatureStructure aFS) {
// FS must be in the source CAS
assert ((CASImpl) aFS.getCAS()).getBaseCAS() == ((CASImpl) mSrcCas).getBaseCAS();
@@ -285,17 +418,23 @@ public class CasCopier {
// Sofa - cannot be created by normal methods. Instead, we return the Sofa with the
// same Sofa ID in the target CAS. If it does not exist it will be created.
if (aFS instanceof SofaFS) {
- String sofaId = ((SofaFS) aFS).getSofaID();
- return getOrCreateView(mDestCas, sofaId).getSofa();
+ String destSofaId = getDestSofaId(((SofaFS) aFS).getSofaID());
+ return getOrCreateView(mDestCas, destSofaId).getSofa();
}
// DocumentAnnotation - instead of creating a new instance, reuse the automatically created
// instance in the destination view.
if (isDocumentAnnotation(aFS)) {
- String viewName = ((AnnotationFS) aFS).getView().getViewName();
- CAS destView = mDestCas.getView(viewName);
+ String destViewName = getDestSofaId(((AnnotationFS) aFS).getView().getViewName());
+
+ // the DocumentAnnotation could be indexed in a different view than the one being copied
+ // Note: The view might not exist in the target
+ // but this is unlikely. To have this case this would require
+ // indexing some other feature structure in this view, which, in turn,
+ // has a reference to the DocumentAnnotation FS belonging to another view
+ CAS destView = getOrCreateView(mDestCas, destViewName);
FeatureStructure destDocAnnot = destView.getDocumentAnnotation();
- if (destDocAnnot != null) {
+ if (destDocAnnot != null) { // Note: is always non-null, getDocumentAnnotation creates if not exist
copyFeatures(aFS, destDocAnnot);
}
return destDocAnnot;
@@ -325,9 +464,10 @@ public class CasCopier {
// CAS.createFS() call doesn't allow us to create subtypes of AnnotationBase from
// a base CAS. In any case we don't need the Sofa reference to be automatically
// set because we'll set it manually when in the copyFeatures method.
+
int typeCode = mLowLevelDestCas.ll_getTypeSystem().ll_getCodeForType(destType);
int destFsAddr = mLowLevelDestCas.ll_createFS(typeCode);
- FeatureStructure destFs = mDestCas.getLowLevelCAS().ll_getFSForRef(destFsAddr);
+ FeatureStructure destFs = mLowLevelDestCas.ll_getFSForRef(destFsAddr);
// add to map so we don't try to copy this more than once
mFsMap.put(aFS, destFs);
@@ -337,6 +477,10 @@ public class CasCopier {
return destFs;
}
+ private String getDestSofaId(String id) {
+ return mSrcCasViewName.equals(id) ? mTgtCasViewName : id;
+ }
+
/**
* Copy feature values from one FS to another. For reference-valued features, this does a deep
* copy.
@@ -393,6 +537,9 @@ public class CasCopier {
}
/**
+ * Note: if lenient is in effect, this method will return false for
+ * FSs which are not copied because the target doesn't have that type.
+ * It also returns false for sofa FSs and the documentAnnotation FS.
* @param aFS a feature structure
* @return true if the given FS has already been copied using this CasCopier.
*/
Modified: uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties?rev=1494286&r1=1494285&r2=1494286&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties (original)
+++ uima/uimaj/trunk/uimaj-core/src/main/resources/org/apache/uima/UIMAException_Messages.properties Tue Jun 18 20:25:39 2013
@@ -39,6 +39,8 @@ define_cas_pool_called_twice = The metho
unsupported_cas_interface = Unsupported CAS interface {0}.
+illegal_copy_same_cas_same_view = CAS Copying of the same view to the same CAS with the same view name is not allowed.
+
type_not_found_during_cas_copy = Attempted to copy a FeatureStructure of type "{0}", which is not defined in the type system of the destination CAS.
feature_not_found_during_cas_copy = Attempted to copy a Feature "{0}", which is not defined in the type system of the destination CAS.
Added: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/CasComparerViewChange.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/CasComparerViewChange.java?rev=1494286&view=auto
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/CasComparerViewChange.java (added)
+++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/CasComparerViewChange.java Tue Jun 18 20:25:39 2013
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.cas_data.impl;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.Assert;
+import static junit.framework.Assert.*;
+
+import org.apache.uima.cas.ArrayFS;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.Feature;
+import org.apache.uima.cas.FeatureStructure;
+import org.apache.uima.cas.FloatArrayFS;
+import org.apache.uima.cas.IntArrayFS;
+import org.apache.uima.cas.SofaFS;
+import org.apache.uima.cas.StringArrayFS;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.impl.CASImpl;
+import org.apache.uima.cas.text.AnnotationFS;
+
+/**
+ * A non-perfect CAS equality checker for JUnit with different views
+ * for testing copyCasView
+ *
+ */
+public class CasComparerViewChange {
+
+ private final CAS view1;
+ private final CAS view2;
+ private final String view1Name;
+ private final String view2Name;
+
+ private final Set<FeatureStructure> visited = new HashSet<FeatureStructure>();
+
+ public CasComparerViewChange(CAS view1, CAS view2) {
+ this.view1 = view1;
+ this.view2 = view2;
+ view1Name = view1.getViewName();
+ view2Name = view2.getViewName();
+ }
+
+ public void assertEqualViews() {
+ visited.clear();
+ FSIterator<FeatureStructure> it1 = view1.getIndexRepository().getAllIndexedFS(view1.getTypeSystem().getTopType());
+ FSIterator<FeatureStructure> it2 = view2.getIndexRepository().getAllIndexedFS(view2.getTypeSystem().getTopType());
+ while (it1.isValid()) {
+ assertTrue(it2.isValid());
+
+ FeatureStructure fs1 = it1.get();
+ FeatureStructure fs2 = it2.get();
+ assertFsEqual(fs1, fs2);
+
+ it1.moveToNext();
+ it2.moveToNext();
+ }
+ }
+
+ private void assertFsEqual(FeatureStructure fs1, FeatureStructure fs2) {
+ if (fs1 == null) {
+ assertNull(fs2);
+ } else {
+ assertNotNull(fs2);
+ }
+
+ if (visited.contains(fs1) || null == fs1) {
+ return;
+ }
+ visited.add(fs1);
+
+ // System.out.println("Comparing " + fs1.getType().getName());
+ assertEquals(fs1.getType().getName(), fs2.getType().getName());
+
+ if (fs1 instanceof SofaFS &&
+ ((SofaFS)fs1).getSofaID().equals(view1Name) &&
+ ((SofaFS)fs2).getSofaID().equals(view2Name)) {
+ return;
+ }
+
+ List<Feature> features1 = fs1.getType().getFeatures();
+ List<Feature> features2 = fs2.getType().getFeatures();
+ for (int i = 0; i < features1.size(); i++) {
+ Feature feat1 = features1.get(i);
+ Feature feat2 = features2.get(i);
+ // System.out.println("Comparing " + feat1.getName());
+ Type rangeType1 = feat1.getRange();
+ Type rangeType2 = feat2.getRange();
+ Assert.assertEquals(rangeType1.getName(), rangeType2.getName());
+ // System.out.println("Range type " + rangeType1);
+ String rangeTypeName = rangeType1.getName();
+
+ if (fs1.getCAS().getTypeSystem().subsumes(
+ fs1.getCAS().getTypeSystem().getType(CAS.TYPE_NAME_STRING), rangeType1)) {
+ assertEquals(fs1.getStringValue(feat1), fs2.getStringValue(feat2));
+ } else if (CAS.TYPE_NAME_INTEGER.equals(rangeTypeName)) {
+ assertEquals(fs1.getIntValue(feat1), fs2.getIntValue(feat2));
+ } else if (CAS.TYPE_NAME_FLOAT.equals(rangeTypeName)) {
+ assertEquals(fs1.getFloatValue(feat1), fs2.getFloatValue(feat2), 0);
+ } else if (CAS.TYPE_NAME_STRING_ARRAY.equals(rangeTypeName)) {
+ StringArrayFS arrayFS1 = (StringArrayFS) fs1.getFeatureValue(feat1);
+ StringArrayFS arrayFS2 = (StringArrayFS) fs2.getFeatureValue(feat2);
+ if ((arrayFS1 == null) && (arrayFS2 == null)) {
+ // ok
+ } else {
+ Assert.assertEquals(arrayFS1.size(), arrayFS2.size());
+ for (int j = 0; j < arrayFS1.size(); j++) {
+ // Temporary workaround for UIMA-2490 - null and "" string values
+ String s1 = arrayFS1.get(j);
+ String s2 = arrayFS2.get(j);
+ if ((s1 == null) && (s2 != null) && (s2.length() == 0)) {
+ continue;
+ }
+ if ((s2 == null) && (s1 != null) && (s1.length() == 0)) {
+ continue;
+ }
+ assertEquals(arrayFS1.get(j), arrayFS2.get(j));
+ }
+ }
+ } else if (CAS.TYPE_NAME_INTEGER_ARRAY.equals(rangeTypeName)) {
+ IntArrayFS arrayFS1 = (IntArrayFS) fs1.getFeatureValue(feat1);
+ IntArrayFS arrayFS2 = (IntArrayFS) fs2.getFeatureValue(feat2);
+ if ((arrayFS1 == null) && (arrayFS2 == null)) {
+ // ok
+ } else {
+ assertEquals(arrayFS1.size(), arrayFS2.size());
+ for (int j = 0; j < arrayFS1.size(); j++) {
+ assertEquals(arrayFS1.get(j), arrayFS2.get(j));
+ }
+ }
+ } else if (CAS.TYPE_NAME_FLOAT_ARRAY.equals(rangeTypeName)) {
+ FloatArrayFS arrayFS1 = (FloatArrayFS) fs1.getFeatureValue(feat1);
+ FloatArrayFS arrayFS2 = (FloatArrayFS) fs2.getFeatureValue(feat2);
+ if ((arrayFS1 == null) && (arrayFS2 == null)) {
+ // ok
+ } else {
+ assertEquals(arrayFS1.size(), arrayFS2.size());
+ for (int j = 0; j < arrayFS1.size(); j++) {
+ assertEquals(arrayFS1.get(j), arrayFS2.get(j), 0);
+ }
+ }
+ } else if (CAS.TYPE_NAME_FS_ARRAY.equals(rangeTypeName)) {
+ ArrayFS arrayFS1 = (ArrayFS) fs1.getFeatureValue(feat1);
+ ArrayFS arrayFS2 = (ArrayFS) fs2.getFeatureValue(feat2);
+ if ((arrayFS1 == null) && (arrayFS2 == null)) {
+ // ok
+ } else {
+ assertEquals(arrayFS1.size(), arrayFS2.size());
+ for (int j = 0; j < arrayFS1.size(); j++) {
+ assertFsEqual(arrayFS1.get(j), arrayFS2.get(j));
+ }
+ }
+ } else // single feature value
+ {
+ FeatureStructure fsVal1 = fs1.getFeatureValue(feat1);
+ FeatureStructure fsVal2 = fs2.getFeatureValue(feat2);
+ assertFsEqual(fsVal1, fsVal2);
+ }
+ }
+ }
+
+}
Propchange: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/CasComparerViewChange.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/CasCopierTest.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/CasCopierTest.java?rev=1494286&r1=1494285&r2=1494286&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/CasCopierTest.java (original)
+++ uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/util/CasCopierTest.java Tue Jun 18 20:25:39 2013
@@ -35,6 +35,7 @@ import org.apache.uima.cas.impl.LowLevel
import org.apache.uima.cas.impl.XCASDeserializer;
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.cas_data.impl.CasComparer;
+import org.apache.uima.cas_data.impl.CasComparerViewChange;
import org.apache.uima.resource.metadata.FsIndexDescription;
import org.apache.uima.resource.metadata.TypeDescription;
import org.apache.uima.resource.metadata.TypeSystemDescription;
@@ -159,6 +160,18 @@ public class CasCopierTest extends TestC
// verify copy
CasComparer.assertEquals(srcCas, destCas);
+
+ // do the copy to a different view
+ // create a destination CAS
+ destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes);
+
+ // do the copy
+ copier = new CasCopier(srcCas, destCas);
+ copier.copyCasView(srcCas, "aNewView", true);
+
+ // verify copy
+ (new CasComparerViewChange(srcCas, destCas.getView("aNewView"))).assertEqualViews();
+
}
public void testCopyFs() throws Exception {