You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by jo...@apache.org on 2009/05/05 12:52:21 UTC
svn commit: r771663 - in /incubator/uima/uimaj/trunk: uimaj-core/
uimaj-core/src/main/java/org/apache/uima/ecore/ uimaj-ep-runtime/
uimaj-examples/src/main/java/org/apache/uima/examples/xmi/
Author: joern
Date: Tue May 5 10:52:19 2009
New Revision: 771663
URL: http://svn.apache.org/viewvc?rev=771663&view=rev
Log:
UIMA-1326: Moved ecore classes from uimaj-core to uimaj-examples and removed uimaj-examples dependency from uimaj-ep-runtime plugin.
Added:
incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/Ecore2UimaTypeSystem.java (with props)
incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/UimaTypeSystem2Ecore.java (with props)
Removed:
incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/ecore/
Modified:
incubator/uima/uimaj/trunk/uimaj-core/pom.xml
incubator/uima/uimaj/trunk/uimaj-ep-runtime/pom.xml
incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/XmiEcoreCasConsumer.java
Modified: incubator/uima/uimaj/trunk/uimaj-core/pom.xml
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/pom.xml?rev=771663&r1=771662&r2=771663&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/pom.xml (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/pom.xml Tue May 5 10:52:19 2009
@@ -51,24 +51,6 @@
<scope>compile</scope>
</dependency>
<dependency>
- <groupId>org.eclipse.emf</groupId>
- <artifactId>common</artifactId>
- <version>2.1.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.emf</groupId>
- <artifactId>ecore</artifactId>
- <version>2.1.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.eclipse.emf</groupId>
- <artifactId>ecore-xmi</artifactId>
- <version>2.1.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>org.apache.uima</groupId>
<artifactId>uimaj-test-util</artifactId>
<version>${uimaj-release-version}</version>
Modified: incubator/uima/uimaj/trunk/uimaj-ep-runtime/pom.xml
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-ep-runtime/pom.xml?rev=771663&r1=771662&r2=771663&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-ep-runtime/pom.xml (original)
+++ incubator/uima/uimaj/trunk/uimaj-ep-runtime/pom.xml Tue May 5 10:52:19 2009
@@ -71,13 +71,6 @@
<dependency>
<groupId>org.apache.uima</groupId>
- <artifactId>uimaj-examples</artifactId>
- <version>${uimaj-release-version}</version>
- <scope>compile</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.uima</groupId>
<artifactId>uimaj-adapter-vinci</artifactId>
<version>${uimaj-release-version}</version>
<scope>compile</scope>
@@ -128,7 +121,6 @@
alternative to the jars - but might have a
versioning / control issue -->
<_exportcontents>
- example,
org.apache.uima,
org.apache.uima.adapter.vinci,
org.apache.uima.adapter.vinci.util,
@@ -167,14 +159,6 @@
org.apache.uima.collection.impl.metadata,
org.apache.uima.collection.impl.metadata.cpe,
org.apache.uima.collection.metadata,
- org.apache.uima.ecore,
- org.apache.uima.examples,
- org.apache.uima.examples.cas,
- org.apache.uima.examples.casMultiplier,
- org.apache.uima.examples.cpe,
- org.apache.uima.examples.flow,
- org.apache.uima.examples.tokenizer,
- org.apache.uima.examples.xmi,
org.apache.uima.flow,
org.apache.uima.flow.impl,
org.apache.uima.impl,
@@ -209,13 +193,6 @@
org.apache.uima.tools.util.gui,
org.apache.uima.tools.util.htmlview,
org.apache.uima.tools.viewer,
- org.apache.uima.tutorial,
- org.apache.uima.tutorial.ex1,
- org.apache.uima.tutorial.ex2,
- org.apache.uima.tutorial.ex3,
- org.apache.uima.tutorial.ex4,
- org.apache.uima.tutorial.ex5,
- org.apache.uima.tutorial.ex6,
org.apache.uima.uimacpp,
org.apache.uima.util,
org.apache.uima.util.impl,
Added: incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/Ecore2UimaTypeSystem.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/Ecore2UimaTypeSystem.java?rev=771663&view=auto
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/Ecore2UimaTypeSystem.java (added)
+++ incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/Ecore2UimaTypeSystem.java Tue May 5 10:52:19 2009
@@ -0,0 +1,526 @@
+/*
+ * 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.examples.xmi;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.uima.ResourceSpecifierFactory;
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.UIMARuntimeException;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.impl.XmiCasSerializer;
+import org.apache.uima.resource.metadata.AllowedValue;
+import org.apache.uima.resource.metadata.FeatureDescription;
+import org.apache.uima.resource.metadata.FsIndexDescription;
+import org.apache.uima.resource.metadata.TypeDescription;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.util.CasCreationUtils;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EEnumLiteral;
+import org.eclipse.emf.ecore.ENamedElement;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
+
+/**
+ * Converts an Ecore model to a UIMA TypeSystemDescription.
+ */
+public class Ecore2UimaTypeSystem {
+ /**
+ * Configures the handling of multi-valued properties in the Ecore model. If set to Boolean.FALSE
+ * (the default), UIMA array types (e.g. FSArray) will be generated. If set to Boolean.TRUE, UIMA
+ * list types (e.g. FSList) will be generated. Note that for primitive types that have no
+ * corresponding list type (Byte, Short, Long, Double, and Boolean), array types will always be
+ * used.
+ */
+ public static final String OPTION_GENERATE_UIMA_LIST_TYPES = "OPTION_GENERATE_UIMA_LIST_TYPES";
+
+ /**
+ * Configures the assignment of supertypes to EClasses that have no declared supertype. If set to
+ * Boolean.TRUE (the default), if such an EClass has "begin" and "end" properties of type EInt,
+ * the superclass will be set to uima.tcas.Annotation. If set to Boolean.FALSE, all EClasses with
+ * no declared supertype will have their supertype set to uima.cas.TOP.
+ */
+ public static final String OPTION_CREATE_ANNOTATION_SUBTYPES = "OPTION_CREATE_ANNOTATION_SUBTYPES";
+
+ private static ResourceSpecifierFactory uimaFactory = UIMAFramework.getResourceSpecifierFactory();
+
+ /**
+ * Converts an Ecore model to a UIMA TypeSytemDescription.
+ *
+ * @param aEcoreFilePath
+ * file path to a .ecore model file
+ * @param aOptions
+ * a Map defining options for the conversion. Valid keys for this map are defined as
+ * constants on this class.
+ *
+ * @return The UIMA TypeSystemDescription corresponding to the Ecore model
+ * @throws URISyntaxException
+ * if there is a problem finding or reading the .ecore file
+ */
+ public static TypeSystemDescription ecore2UimaTypeSystem(String aEcoreFilePath, Map aOptions)
+ throws URISyntaxException {
+ // register default resource factory
+ Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("*",
+ new XMIResourceFactoryImpl());
+ // create resource set to hold the resource we're loading and its dependent resources
+ ResourceSet resourceSet = new ResourceSetImpl();
+ // convert file path to absolute path -- seems to be required for propery proxy resolution
+ File inputFile = new File(aEcoreFilePath);
+ URI absoluteInputURI = URI.createFileURI(inputFile.getAbsolutePath());
+ // load the resource
+ Resource resource = resourceSet.getResource(absoluteInputURI, true);
+ // convert to UIMA TypeSystem
+ return ecore2UimaTypeSystem(resource, aOptions);
+ }
+
+ /**
+ * Converts an Ecore model to a UIMA TypeSytemDescription.
+ *
+ * @param aEcoreResource
+ * An EMF Resource containing the Ecore model
+ * @param aOptions
+ * a Map defining options for the conversion. Valid keys for this map are defined as
+ * constants on this class.
+ *
+ * @return The UIMA TypeSystemDescription corresponding to the Ecore model
+ * @throws URISyntaxException
+ * if there is a problem reading from the resource
+ */
+ public static TypeSystemDescription ecore2UimaTypeSystem(Resource aEcoreResource, Map aOptions)
+ throws URISyntaxException {
+ if (aOptions == null) {
+ aOptions = Collections.EMPTY_MAP;
+ }
+
+ TypeSystemDescription tsDesc = uimaFactory.createTypeSystemDescription();
+
+ // try to get descriptive info from EAnnotation with NS "http://uima.apache.org",
+ // on the first EPackage in the Resource
+ EPackage ePackage = (EPackage) aEcoreResource.getContents().get(0);
+ EAnnotation eannot = ePackage.getEAnnotation("http://uima.apache.org");
+ if (eannot != null) {
+ tsDesc.setName((String) eannot.getDetails().get("name"));
+ tsDesc.setDescription((String) eannot.getDetails().get("description"));
+ tsDesc.setVendor((String) eannot.getDetails().get("vendor"));
+ tsDesc.setVersion((String) eannot.getDetails().get("version"));
+ }
+
+ // convert types
+ List types = new ArrayList();
+ Iterator iter = aEcoreResource.getContents().iterator();
+ while (iter.hasNext()) {
+ Object obj = iter.next();
+ if (obj instanceof EPackage) {
+ ePackage2UimaTypes((EPackage) obj, types, aOptions);
+ }
+ }
+ TypeDescription[] typeArr = new TypeDescription[types.size()];
+ types.toArray(typeArr);
+ tsDesc.setTypes(typeArr);
+ return tsDesc;
+ }
+
+ private static void ePackage2UimaTypes(EPackage aEPackage, List aResultTypes, Map aOptions)
+ throws URISyntaxException {
+ String nsUri = aEPackage.getNsURI();
+ String uimaNamespace = namespaceUri2UimaNamespace(nsUri);
+ // skip the uima.cas package, since it contains only feature-final built-ins
+ if ("uima.cas".equals(uimaNamespace)) {
+ return;
+ }
+
+ Iterator iter = aEPackage.getEClassifiers().iterator();
+ while (iter.hasNext()) {
+ Object classifier = iter.next();
+ if (classifier instanceof EClass) {
+ EClass eclass = (EClass) classifier;
+ TypeDescription type = eclass2UimaType(eclass, uimaNamespace, aOptions);
+ // skip uima.tcas.Annotation, since it is feature-final
+ if (!"uima.tcas.Annotation".equals(type.getName())) {
+ aResultTypes.add(type);
+ }
+ } else if (classifier instanceof EEnum) {
+ EEnum eenum = (EEnum) classifier;
+ TypeDescription type = eenum2UimaType(eenum, uimaNamespace, aOptions);
+ aResultTypes.add(type);
+ }
+ }
+ // now process nested subpckages
+ iter = aEPackage.getESubpackages().iterator();
+ while (iter.hasNext()) {
+ ePackage2UimaTypes((EPackage) iter.next(), aResultTypes, aOptions);
+ }
+ }
+
+ private static TypeDescription eclass2UimaType(EClass aEClass, String aUimaNamespace, Map aOptions)
+ throws URISyntaxException {
+ TypeDescription type = uimaFactory.createTypeDescription();
+ // set name
+ if (aUimaNamespace != null) {
+ type.setName(aUimaNamespace + "." + aEClass.getName());
+ } else {
+ type.setName(aEClass.getName());
+ }
+ // try to get desecription from EAnnotation
+ EAnnotation eannot = aEClass.getEAnnotation("http://uima.apache.org");
+ if (eannot != null) {
+ type.setDescription((String) eannot.getDetails().get("description"));
+ }
+ // set supertype
+ EList supertypes = aEClass.getESuperTypes();
+ if (supertypes.isEmpty()) // supertype not defined in the Ecore model
+ {
+ if (aOptions.get(OPTION_CREATE_ANNOTATION_SUBTYPES) == Boolean.FALSE) {
+ type.setSupertypeName(CAS.TYPE_NAME_TOP);
+ } else {
+ // if this class has "begin" and "end" attributes of type EInt, make it a subtype of
+ // annotation
+ EStructuralFeature begin = aEClass.getEStructuralFeature("begin");
+ EStructuralFeature end = aEClass.getEStructuralFeature("end");
+ if (begin != null && end != null && begin.getEType() == EcorePackage.eINSTANCE.getEInt()
+ && end.getEType() == EcorePackage.eINSTANCE.getEInt()) {
+ type.setSupertypeName(CAS.TYPE_NAME_ANNOTATION);
+ } else {
+ type.setSupertypeName(CAS.TYPE_NAME_TOP);
+ }
+ }
+ } else {
+ EClass supertype = (EClass) supertypes.get(0);
+ // if the supertype is EObject, translate that to uima.cas.TOP
+ if (supertype.equals(EcorePackage.eINSTANCE.getEObject())) {
+ type.setSupertypeName(CAS.TYPE_NAME_TOP);
+ }
+ // otherwise translate the name according to our conventions
+ String uimaSupertypeName = getUimaTypeName(supertype, false, aOptions);
+ type.setSupertypeName(uimaSupertypeName);
+
+ // if there are multiple supertypes, the first one is arbitrarily chosen
+ // as the single supertype for the UIMA type. Other features are copied-down.
+ if (supertypes.size() > 1) {
+ System.err.println("Warning: EClass " + aEClass.getName()
+ + " defines multiple supertypes. " + "The UIMA supertype will be "
+ + type.getSupertypeName()
+ + "; features inherited from other supertypes will be copied down.");
+ }
+ }
+ // set features
+ EList eFeatures = aEClass.getEStructuralFeatures();
+ Iterator iter = eFeatures.iterator();
+ List uimaFeatures = new ArrayList();
+ while (iter.hasNext()) {
+ EStructuralFeature eFeat = (EStructuralFeature) iter.next();
+ FeatureDescription uimaFeat = eStructuralFeature2UimaFeature(eFeat, aOptions);
+ uimaFeatures.add(uimaFeat);
+ }
+ // copy down features from additional supertypes
+ for (int i = 1; i < supertypes.size(); i++) {
+ EClass copyFrom = (EClass) supertypes.get(i);
+ EList copyFeatures = copyFrom.getEStructuralFeatures();
+ Iterator iter2 = copyFeatures.iterator();
+ while (iter2.hasNext()) {
+ EStructuralFeature eFeat = (EStructuralFeature) iter2.next();
+ // do not copy if this feature is a duplicate of one defined on the class
+ // or inherited from its primary supertype
+ EList locallyDefinedFeatures = aEClass.getEStructuralFeatures();
+ EList firstSupertypesFeatures = ((EClass) supertypes.get(0)).getEAllStructuralFeatures();
+ if (!containsNamedElement(locallyDefinedFeatures, eFeat.getName())
+ && !containsNamedElement(firstSupertypesFeatures, eFeat.getName())) {
+ FeatureDescription uimaFeat = eStructuralFeature2UimaFeature(eFeat, aOptions);
+ uimaFeatures.add(uimaFeat);
+ }
+ }
+ }
+
+ FeatureDescription[] featureArr = new FeatureDescription[uimaFeatures.size()];
+ uimaFeatures.toArray(featureArr);
+ type.setFeatures(featureArr);
+ return type;
+ }
+
+ private static boolean containsNamedElement(EList locallyDefinedFeatures, String name) {
+ Iterator iter = locallyDefinedFeatures.iterator();
+ while (iter.hasNext()) {
+ Object obj = iter.next();
+ if (obj instanceof ENamedElement) {
+ if (name.equals(((ENamedElement) obj).getName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static TypeDescription eenum2UimaType(EEnum aEEnum, String aUimaNamespace, Map aOptions)
+ throws URISyntaxException {
+ TypeDescription type = uimaFactory.createTypeDescription();
+ // set name
+ if (aUimaNamespace != null) {
+ type.setName(aUimaNamespace + "." + aEEnum.getName());
+ } else {
+ type.setName(aEEnum.getName());
+ }
+ // set supetype to String
+ type.setSupertypeName(CAS.TYPE_NAME_STRING);
+ // try to get desecription from EAnnotation
+ EAnnotation eannot = aEEnum.getEAnnotation("http://uima.apache.org");
+ if (eannot != null) {
+ type.setDescription((String) eannot.getDetails().get("description"));
+ }
+ // set allowed values
+ EList literals = aEEnum.getELiterals();
+ AllowedValue[] vals = new AllowedValue[literals.size()];
+ for (int i = 0; i < literals.size(); i++) {
+ EEnumLiteral literal = (EEnumLiteral) literals.get(i);
+ vals[i] = uimaFactory.createAllowedValue();
+ vals[i].setString(literal.getName());
+ EAnnotation literalAnnot = literal.getEAnnotation("http://uima.apache.org");
+ if (literalAnnot != null) {
+ vals[i].setDescription((String) literalAnnot.getDetails().get("description"));
+ }
+ }
+ type.setAllowedValues(vals);
+ return type;
+ }
+
+ /**
+ * @param attr
+ * @return
+ */
+ private static FeatureDescription eStructuralFeature2UimaFeature(
+ EStructuralFeature aStructuralFeature, Map aOptions) throws URISyntaxException {
+ FeatureDescription feat = uimaFactory.createFeatureDescription();
+ feat.setName(aStructuralFeature.getName());
+ String rangeTypeName = null;
+ String elementTypeName = null;
+ EAnnotation eannot = aStructuralFeature.getEAnnotation("http://uima.apache.org");
+ if (eannot != null) {
+ feat.setDescription((String) eannot.getDetails().get("description"));
+ // the UIMA type name to use may be recorded as an EAnnotation; this is
+ // particularly important for arrays and lists, since Ecore doesn't distinguish between
+ // these two possible implementations for a multi-valued property
+ rangeTypeName = (String) eannot.getDetails().get("uimaType");
+ // the elemnt type may also be specified as an EAnnotation; this is
+ // used for the case where an FSArray or FSList is NOT represented
+ // as a multi-valued property
+ elementTypeName = (String) eannot.getDetails().get("elementType");
+ }
+ EClassifier attrRangeType = aStructuralFeature.getEType();
+
+ // if range type wasn't specified in an EAnnotation, compute it ourselves
+ if (rangeTypeName == null) {
+ rangeTypeName = getUimaTypeName(attrRangeType, aStructuralFeature.isMany(), aOptions);
+ }
+ feat.setRangeTypeName(rangeTypeName);
+
+ if (aStructuralFeature.isMany()) {
+ // set the element type of the array/list to the EType of the structural feature
+ // (except primitive, or TOP, which are assumed)
+ String uimaElementType = getUimaTypeName(attrRangeType, false, aOptions);
+ if (!CAS.TYPE_NAME_INTEGER.equals(uimaElementType)
+ && !CAS.TYPE_NAME_FLOAT.equals(uimaElementType)
+ && !CAS.TYPE_NAME_STRING.equals(uimaElementType)
+ && !CAS.TYPE_NAME_TOP.equals(uimaElementType)
+ && !CAS.TYPE_NAME_BYTE.equals(uimaElementType)
+ && !CAS.TYPE_NAME_SHORT.equals(uimaElementType)
+ && !CAS.TYPE_NAME_LONG.equals(uimaElementType)
+ && !CAS.TYPE_NAME_DOUBLE.equals(uimaElementType)
+ && !CAS.TYPE_NAME_BOOLEAN.equals(uimaElementType)) {
+ feat.setElementType(uimaElementType);
+ }
+ } else if (!aStructuralFeature.getEType().equals(EcorePackage.eINSTANCE.getEByteArray())) {
+ // if in Ecore we have a single-valued property whose range type is an array or list,
+ // we need to set "multiple references allowed" to true in the UIMA type system
+ // (exception: don't do this for the EByteArray data type, which is implicilty a
+ // multi-valued type)
+ if (isArrayOrList(rangeTypeName)) {
+ feat.setMultipleReferencesAllowed(Boolean.TRUE);
+ // also, set element type if one was contained in the EAnnotation
+ feat.setElementType(elementTypeName);
+ }
+ }
+ return feat;
+ }
+
+ private static boolean isArrayOrList(String rangeTypeName) {
+ return CAS.TYPE_NAME_FS_LIST.equals(rangeTypeName)
+ || CAS.TYPE_NAME_INTEGER_LIST.equals(rangeTypeName)
+ || CAS.TYPE_NAME_FLOAT_LIST.equals(rangeTypeName)
+ || CAS.TYPE_NAME_STRING_LIST.equals(rangeTypeName)
+ || CAS.TYPE_NAME_FS_ARRAY.equals(rangeTypeName)
+ || CAS.TYPE_NAME_INTEGER_ARRAY.equals(rangeTypeName)
+ || CAS.TYPE_NAME_FLOAT_ARRAY.equals(rangeTypeName)
+ || CAS.TYPE_NAME_STRING_ARRAY.equals(rangeTypeName)
+ || CAS.TYPE_NAME_BYTE_ARRAY.equals(rangeTypeName)
+ || CAS.TYPE_NAME_SHORT_ARRAY.equals(rangeTypeName)
+ || CAS.TYPE_NAME_LONG_ARRAY.equals(rangeTypeName)
+ || CAS.TYPE_NAME_DOUBLE_ARRAY.equals(rangeTypeName)
+ || CAS.TYPE_NAME_BOOLEAN_ARRAY.equals(rangeTypeName);
+
+ }
+
+ private static String getUimaTypeName(EClassifier aEcoreType, boolean aMultiValued, Map aOptions)
+ throws URISyntaxException {
+ boolean useUimaLists = Boolean.TRUE.equals(aOptions.get(OPTION_GENERATE_UIMA_LIST_TYPES));
+
+ if (aEcoreType.eIsProxy()) {
+ // try to resolve
+ aEcoreType = (EClassifier) EcoreUtil.resolve(aEcoreType, aEcoreType);
+ if (aEcoreType.eIsProxy()) {
+ throw new UIMARuntimeException(UIMARuntimeException.ECORE_UNRESOLVED_PROXY,
+ new Object[] { aEcoreType.toString() });
+ }
+ }
+
+ if (aEcoreType instanceof EClass || aEcoreType instanceof EEnum) {
+ // maps to non-primitive UIMA type
+ if (aMultiValued) {
+ // UIMA doesn't have typed arrays or lists of nonprimitives
+ return useUimaLists ? CAS.TYPE_NAME_FS_LIST : CAS.TYPE_NAME_FS_ARRAY;
+ }
+
+ // Derive type name from package name
+ EPackage epackage = aEcoreType.getEPackage();
+ if (epackage != null) {
+ String uimaNamespace = namespaceUri2UimaNamespace(epackage.getNsURI());
+ if (uimaNamespace != null)
+ return uimaNamespace + '.' + aEcoreType.getName();
+ else
+ return aEcoreType.getName();
+ } else {
+ return aEcoreType.getName();
+ }
+ } else // primitive type
+ {
+ if (aEcoreType.equals(EcorePackage.eINSTANCE.getEInt())) {
+ return aMultiValued ? (useUimaLists ? CAS.TYPE_NAME_INTEGER_LIST
+ : CAS.TYPE_NAME_INTEGER_ARRAY) : CAS.TYPE_NAME_INTEGER;
+ } else if (aEcoreType.equals(EcorePackage.eINSTANCE.getEShort())) {
+ return aMultiValued ? CAS.TYPE_NAME_SHORT_ARRAY : CAS.TYPE_NAME_SHORT;
+ } else if (aEcoreType.equals(EcorePackage.eINSTANCE.getELong())) {
+ return aMultiValued ? CAS.TYPE_NAME_LONG_ARRAY : CAS.TYPE_NAME_LONG;
+ } else if (aEcoreType.equals(EcorePackage.eINSTANCE.getEByte())) {
+ return aMultiValued ? CAS.TYPE_NAME_BYTE_ARRAY : CAS.TYPE_NAME_BYTE;
+ } else if (aEcoreType.equals(EcorePackage.eINSTANCE.getEFloat())) {
+ return aMultiValued ? (useUimaLists ? CAS.TYPE_NAME_FLOAT_LIST : CAS.TYPE_NAME_FLOAT_ARRAY)
+ : CAS.TYPE_NAME_FLOAT;
+ } else if (aEcoreType.equals(EcorePackage.eINSTANCE.getEDouble())) {
+ return aMultiValued ? CAS.TYPE_NAME_DOUBLE_ARRAY : CAS.TYPE_NAME_DOUBLE;
+ } else if (aEcoreType.equals(EcorePackage.eINSTANCE.getEBoolean())) {
+ return aMultiValued ? CAS.TYPE_NAME_BOOLEAN_ARRAY : CAS.TYPE_NAME_BOOLEAN;
+ }
+ // Ecore has a special type EByteArray that we use instead of a
+ // multi-valued EByte property. This gives a slightly more efficient
+ // serialization
+ else if (aEcoreType.equals(EcorePackage.eINSTANCE.getEByteArray())) {
+ return CAS.TYPE_NAME_BYTE_ARRAY;
+ } else // any other datatype maps to String
+ {
+ if (!aEcoreType.equals(EcorePackage.eINSTANCE.getEString())) {
+ System.err.println("Warning: unknown EDataType " + aEcoreType.getName()
+ + " being mapped to uima.cas.String.");
+ }
+ return aMultiValued ? (useUimaLists ? CAS.TYPE_NAME_STRING_LIST
+ : CAS.TYPE_NAME_STRING_ARRAY) : CAS.TYPE_NAME_STRING;
+ }
+ }
+ }
+
+ private static String namespaceUri2UimaNamespace(String nsUri) throws URISyntaxException {
+ // Check for the special "no namespace URI", which maps to the null UIMA namespace
+ if (XmiCasSerializer.DEFAULT_NAMESPACE_URI.equals(nsUri)) {
+ return null;
+ }
+ // Our convention is that the UIMA namespace is the URI path, with leading slashes
+ // removed, trailing ".ecore" removed, and internal slashes converted to dots
+ java.net.URI uri = new java.net.URI(nsUri);
+ String uimaNs = uri.getPath();
+ if (uimaNs == null) {
+ // The URI is a URN
+ uimaNs = uri.getSchemeSpecificPart();
+ uimaNs = uimaNs.replace(':', '.');
+ } else {
+ // The URI is a URL
+ while (uimaNs.startsWith("/")) {
+ uimaNs = uimaNs.substring(1);
+ }
+ if (uimaNs.endsWith(".ecore")) {
+ uimaNs = uimaNs.substring(0, uimaNs.length() - 6);
+ }
+ uimaNs = uimaNs.replace('/', '.');
+ }
+ uimaNs = uimaNs.replace('-', '_');
+ return uimaNs;
+ }
+
+ /**
+ * Main program. Takes two arguments: the filename of an input .ecore file and the filename of the
+ * UIMA TypeSystem file to generate.
+ */
+ public static void main(String[] args) throws Exception {
+ if (args.length != 2) {
+ System.err.println("Usage: java " + Ecore2UimaTypeSystem.class.getName()
+ + " <ecore filename> <filename of UIMA TypeSystem file to generate>");
+ return;
+ }
+ if (!new File(args[0]).exists()) {
+ System.err.println("File " + args[0] + " does not exist");
+ return;
+ }
+
+ Map options = new HashMap();
+ // options.put(OPTION_GENERATE_UIMA_LIST_TYPES, Boolean.TRUE);
+ TypeSystemDescription tsDesc = ecore2UimaTypeSystem(args[0], options);
+
+ FileOutputStream os = new FileOutputStream(args[1]);
+ try {
+ tsDesc.toXML(os);
+ } finally {
+ os.close();
+ }
+
+ // test creating a CAS
+ try {
+ CasCreationUtils.createCas(tsDesc, null, new FsIndexDescription[0]);
+ } catch (Exception e) {
+ System.err
+ .println("Warning: CAS could not be created from the output type system. The following problem occurred:");
+ System.err.println(e.getMessage());
+ }
+ }
+}
Propchange: incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/Ecore2UimaTypeSystem.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/UimaTypeSystem2Ecore.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/UimaTypeSystem2Ecore.java?rev=771663&view=auto
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/UimaTypeSystem2Ecore.java (added)
+++ incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/UimaTypeSystem2Ecore.java Tue May 5 10:52:19 2009
@@ -0,0 +1,503 @@
+/*
+ * 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.examples.xmi;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.UIMARuntimeException;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.impl.XmiCasSerializer;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.AllowedValue;
+import org.apache.uima.resource.metadata.FeatureDescription;
+import org.apache.uima.resource.metadata.TypeDescription;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.util.CasCreationUtils;
+import org.apache.uima.util.InvalidXMLException;
+import org.apache.uima.util.XMLInputSource;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EEnumLiteral;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
+
+/**
+ * Converts a UIMA TypeSystemDescription to an Ecore model.
+ */
+public class UimaTypeSystem2Ecore {
+ /**
+ * Converts a UIMA TypeSystem descriptor to an Ecore model
+ *
+ * @param aUimaTypeSystemFilePath
+ * file path to UIMA TypeSystem descritpor
+ * @param aOutputResource
+ * An EMF Resource to be populated with the Ecore model
+ * @param aOptions
+ * a Map defining options for the conversion. Valid keys for this map are defined as
+ * constants on this class.
+ *
+ * @throws InvalidXMLException
+ * if the TypeSystem descriptor, or one of its imports, is not valid or if there are
+ * duplicate, inconsistent definitions of the same type.
+ * @throws IOException
+ * if an failure occur while reading the descriptor file
+ */
+ public static void uimaTypeSystem2Ecore(String aUimaTypeSystemFilePath, Resource aOutputResource,
+ Map aOptions) throws InvalidXMLException, IOException {
+ TypeSystemDescription tsDesc = UIMAFramework.getXMLParser().parseTypeSystemDescription(
+ new XMLInputSource(aUimaTypeSystemFilePath));
+ uimaTypeSystem2Ecore(tsDesc, aOutputResource, aOptions);
+ }
+
+ /**
+ * Converts a UIMA TypeSystemDescription to an Ecore model
+ *
+ * @param aTypeSystem
+ * UIMA TypeSystemDescription object to convert
+ * @param aOutputResource
+ * An EMF Resource to be populated with the Ecore model
+ * @param aOptions
+ * a Map defining options for the conversion. Valid keys for this map are defined as
+ * constants on this class.
+ *
+ * @throws InvalidXMLException
+ * if the TypeSystem descriptor imports another descriptor that could not be
+ * successfully parsed, or if there are duplicate, inconsistent definitions of the same
+ * type.
+ */
+ public static void uimaTypeSystem2Ecore(TypeSystemDescription aTypeSystem,
+ Resource aOutputResource, Map aOptions) throws InvalidXMLException {
+ uimaTypeSystem2Ecore(aTypeSystem, aOutputResource, aOptions, null);
+ }
+
+ /**
+ * Converts a UIMA TypeSystemDescription to an Ecore model
+ *
+ * @param aTypeSystem
+ * UIMA TypeSystemDescription object to convert
+ * @param aOutputResource
+ * An EMF Resource to be populated with the Ecore model
+ * @param aOptions
+ * a Map defining options for the conversion. Valid keys for this map are defined as
+ * constants on this class.
+ * @param aSchemaLocationMap
+ * optional parameter - if non-null, this map will be populated with (Namespace URI,
+ * Schema Location) pairs, suitable for inclusion in the "schemaLocation" attribute of
+ * XMI instance documents.
+ */
+ public static void uimaTypeSystem2Ecore(TypeSystemDescription aTypeSystem,
+ Resource aOutputResource, Map aOptions, Map aSchemaLocationMap)
+ throws InvalidXMLException {
+ // Add the default definition of uima.tcas.DocumentAnnotation. If the
+ // user also defines this type (with additional features), it will be merged
+ // with this. First clone the aTypeSystem object so user won't notice
+ // we have added a new type definition to their TypeSystemDescription.
+ aTypeSystem = (TypeSystemDescription) aTypeSystem.clone();
+ TypeDescription docAnnotType = aTypeSystem.addType("uima.tcas.DocumentAnnotation", "",
+ "uima.tcas.Annotation");
+ docAnnotType.addFeature("language", "", "uima.cas.String");
+
+ // resolve imports
+ aTypeSystem.resolveImports();
+
+ // merge, to eliminate duplicate type definitions
+ try {
+ aTypeSystem = CasCreationUtils.mergeTypeSystems(Arrays.asList(new Object[] { aTypeSystem }));
+ } catch (ResourceInitializationException e) {
+ throw new InvalidXMLException(e);
+ }
+
+ if (aOptions == null) {
+ aOptions = Collections.EMPTY_MAP;
+ }
+
+ // load Ecore model for the UIMA Built-in types
+ ResourceSet resSet = aOutputResource.getResourceSet();
+ if (resSet == null) {
+ resSet = new ResourceSetImpl();
+ resSet.getResources().add(aOutputResource);
+ }
+ loadUimaBuiltinsEcore(resSet, aSchemaLocationMap);
+
+ // Do this in two passes. First pass creates EPackages, EClasses, and EEnums (for string
+ // subtypes)
+ // Second pass sets supertypes and creates EStructuralFeatures
+ TypeDescription[] types = aTypeSystem.getTypes();
+ EPackage firstPackage = null;
+ for (int i = 0; i < types.length; i++) {
+ TypeDescription type = types[i];
+ EClassifier eclassifier = uimaType2EClassifier(type, aOptions);
+ // EPackages may also have been created. Add the root EPackage to the resource.
+ EPackage rootPackage = eclassifier.getEPackage();
+ while (rootPackage.getESuperPackage() != null)
+ rootPackage = rootPackage.getESuperPackage();
+ aOutputResource.getContents().add(rootPackage);
+ if (aSchemaLocationMap != null) {
+ String schemaLoc = aOutputResource.getURI() + "#"
+ + aOutputResource.getURIFragment(eclassifier.getEPackage());
+ aSchemaLocationMap.put(eclassifier.getEPackage().getNsURI(), schemaLoc);
+ }
+ if (firstPackage == null) {
+ firstPackage = eclassifier.getEPackage();
+ }
+ }
+
+ // Now make second pass to set supertype and create feautres
+ for (int i = 0; i < types.length; i++) {
+ TypeDescription type = types[i];
+ EClassifier eclassifier = lookupEClassifierForType(type.getName());
+ if (eclassifier instanceof EClass) {
+ EClass eclass = (EClass) eclassifier;
+ // set supertype
+ String supertypeName = type.getSupertypeName();
+ EClassifier superclass = lookupEClassifierForType(supertypeName); // creates EClass if not
+ // already existing
+ eclass.getESuperTypes().add(superclass);
+
+ // set features
+ FeatureDescription[] features = type.getFeatures();
+ for (int j = 0; j < features.length; j++) {
+ eclass.getEStructuralFeatures()
+ .add(uimaFeature2EStructuralFeature(features[j], aOptions));
+ }
+ }
+ }
+
+ // add descriptive type system attributes as EAnnotations on first package
+ EAnnotation eannot = EcoreFactory.eINSTANCE.createEAnnotation();
+ eannot.setSource("http://uima.apache.org");
+ if (aTypeSystem.getName() != null && aTypeSystem.getName().length() > 0)
+ eannot.getDetails().put("name", aTypeSystem.getName());
+ if (aTypeSystem.getDescription() != null && aTypeSystem.getDescription().length() > 0)
+ eannot.getDetails().put("description", aTypeSystem.getDescription());
+ if (aTypeSystem.getVersion() != null && aTypeSystem.getVersion().length() > 0)
+ eannot.getDetails().put("version", aTypeSystem.getVersion());
+ if (aTypeSystem.getVendor() != null && aTypeSystem.getVendor().length() > 0)
+ eannot.getDetails().put("vendor", aTypeSystem.getVendor());
+ firstPackage.getEAnnotations().add(eannot);
+ }
+
+ private static Resource loadUimaBuiltinsEcore(ResourceSet resourceSet, Map aSchemaLocationMap) {
+ // load Ecore model for UIMA built-in types (use classloader to locate)
+ URL uimaEcoreUrl = UimaTypeSystem2Ecore.class.getResource("/uima.ecore");
+ if (uimaEcoreUrl == null) {
+ throw new UIMARuntimeException(UIMARuntimeException.UIMA_ECORE_NOT_FOUND, new Object[0]);
+ }
+ Resource uimaEcoreResource = resourceSet.getResource(URI.createURI(uimaEcoreUrl.toString()),
+ true);
+ // register core UIMA packages (I'm surprised I need to do this manually)
+ TreeIterator iter = uimaEcoreResource.getAllContents();
+ while (iter.hasNext()) {
+ Object current = iter.next();
+ if (current instanceof EPackage) {
+ EPackage pkg = (EPackage) current;
+ EPackage.Registry.INSTANCE.put(pkg.getNsURI(), pkg);
+ if (aSchemaLocationMap != null) {
+ String schemaLoc = uimaEcoreResource.getURI() + "#"
+ + uimaEcoreResource.getURIFragment(pkg);
+ aSchemaLocationMap.put(pkg.getNsURI(), schemaLoc);
+ }
+ }
+ }
+ return uimaEcoreResource;
+ }
+
+ private static EClassifier uimaType2EClassifier(TypeDescription aType, Map aOptions) {
+ // separate name into package name and class name
+ String fullTypeName = aType.getName();
+ String uimaNamespace, shortTypeName;
+ int lastDot = fullTypeName.lastIndexOf('.');
+ if (lastDot <= 0) {
+ uimaNamespace = null;
+ shortTypeName = fullTypeName;
+ } else {
+ uimaNamespace = fullTypeName.substring(0, lastDot);
+ shortTypeName = fullTypeName.substring(lastDot + 1);
+ }
+
+ // does EPackage already exist for this URI?
+ EPackage ePackage = uimaNamespace2EPackage(uimaNamespace);
+
+ EClassifier eclassifier;
+ // if aType is a "subtype" of uima.cas.String, create an EEnum for it
+ if (CAS.TYPE_NAME_STRING.equals(aType.getSupertypeName())) {
+ eclassifier = EcoreFactory.eINSTANCE.createEEnum();
+ AllowedValue[] vals = aType.getAllowedValues();
+ for (int i = 0; i < vals.length; i++) {
+ EEnumLiteral literal = EcoreFactory.eINSTANCE.createEEnumLiteral();
+ literal.setValue(i);
+ literal.setName(vals[i].getString());
+ if (vals[i].getDescription() != null && vals[i].getDescription().length() > 0) {
+ EAnnotation eannot = EcoreFactory.eINSTANCE.createEAnnotation();
+ eannot.setSource("http://uima.apache.org");
+ eannot.getDetails().put("description", vals[i].getDescription());
+ literal.getEAnnotations().add(eannot);
+ }
+ ((EEnum) eclassifier).getELiterals().add(literal);
+ }
+ } else {
+ // create EClass
+ eclassifier = EcoreFactory.eINSTANCE.createEClass();
+ }
+
+ // set name of EClassifier
+ eclassifier.setName(shortTypeName);
+ // add to package
+ ePackage.getEClassifiers().add(eclassifier);
+ // set description as EAnnotation
+ if (aType.getDescription() != null && aType.getDescription().length() > 0) {
+ EAnnotation eannot = EcoreFactory.eINSTANCE.createEAnnotation();
+ eannot.setSource("http://uima.apache.org");
+ eannot.getDetails().put("description", aType.getDescription());
+ eclassifier.getEAnnotations().add(eannot);
+ }
+ return eclassifier;
+ }
+
+ private static EStructuralFeature uimaFeature2EStructuralFeature(FeatureDescription aFeature,
+ Map aOptions) {
+ String range = aFeature.getRangeTypeName();
+ boolean multiRefAllowed = aFeature.getMultipleReferencesAllowed() == null ? false : aFeature
+ .getMultipleReferencesAllowed().booleanValue();
+ EStructuralFeature efeat;
+ // map primitive types to EAttributes
+ if (CAS.TYPE_NAME_STRING.equals(range)) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEString());
+ } else if (CAS.TYPE_NAME_INTEGER.equals(range)) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEInt());
+ } else if (CAS.TYPE_NAME_FLOAT.equals(range)) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEFloat());
+ } else if (CAS.TYPE_NAME_BYTE.equals(range)) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEByte());
+ } else if (CAS.TYPE_NAME_SHORT.equals(range)) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEShort());
+ } else if (CAS.TYPE_NAME_LONG.equals(range)) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getELong());
+ } else if (CAS.TYPE_NAME_DOUBLE.equals(range)) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEDouble());
+ } else if (CAS.TYPE_NAME_BOOLEAN.equals(range)) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEBoolean());
+ }
+ // map arrays and lists to multivalued EAttributes if multiple references not allowed
+ else if ((CAS.TYPE_NAME_STRING_ARRAY.equals(range) || CAS.TYPE_NAME_STRING_LIST.equals(range))
+ && !multiRefAllowed) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEString());
+ efeat.setUpperBound(-1);
+ } else if ((CAS.TYPE_NAME_INTEGER_ARRAY.equals(range) || CAS.TYPE_NAME_INTEGER_LIST
+ .equals(range))
+ && !multiRefAllowed) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEInt());
+ efeat.setUpperBound(-1);
+ } else if ((CAS.TYPE_NAME_FLOAT_ARRAY.equals(range) || CAS.TYPE_NAME_FLOAT_LIST.equals(range))
+ && !multiRefAllowed) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEFloat());
+ efeat.setUpperBound(-1);
+ } else if (CAS.TYPE_NAME_SHORT_ARRAY.equals(range) && !multiRefAllowed) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEShort());
+ efeat.setUpperBound(-1);
+ } else if (CAS.TYPE_NAME_LONG_ARRAY.equals(range) && !multiRefAllowed) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getELong());
+ efeat.setUpperBound(-1);
+ } else if (CAS.TYPE_NAME_DOUBLE_ARRAY.equals(range) && !multiRefAllowed) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEDouble());
+ efeat.setUpperBound(-1);
+ } else if (CAS.TYPE_NAME_BOOLEAN_ARRAY.equals(range) && !multiRefAllowed) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEBoolean());
+ efeat.setUpperBound(-1);
+ }
+ // Ecore has a special type EByteArray that we use instead of a
+ // multi-valued EByte property. This gives a slightly more efficient
+ // serialization.
+ else if (CAS.TYPE_NAME_BYTE_ARRAY.equals(range) && !multiRefAllowed) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ efeat.setEType(EcorePackage.eINSTANCE.getEByteArray());
+ }
+ // FSArrays and FSLists map to multivalued references if multiple references not allowed
+ else if ((CAS.TYPE_NAME_FS_ARRAY.equals(range) || CAS.TYPE_NAME_FS_LIST.equals(range))
+ && !multiRefAllowed) {
+ efeat = EcoreFactory.eINSTANCE.createEReference();
+ String elementType = aFeature.getElementType();
+ if (elementType == null) {
+ elementType = CAS.TYPE_NAME_TOP;
+ }
+ efeat.setEType(lookupEClassifierForType(elementType));
+ efeat.setUpperBound(-1);
+ } else // non-primitive, non-array, non-list type.
+ // map to EAttribute if it's an EEnum, otherwise map to EReference
+ {
+ EClassifier etype = lookupEClassifierForType(range);
+ if (etype instanceof EEnum) {
+ efeat = EcoreFactory.eINSTANCE.createEAttribute();
+ } else {
+ efeat = EcoreFactory.eINSTANCE.createEReference();
+ }
+ efeat.setEType(etype);
+ }
+
+ efeat.setName(aFeature.getName());
+
+ // use EAnnotation to record:
+ // - the description of the feature
+ // - for multi-valued properties, the name of the UIMA type used to
+ // implement it (to distinguish between array and list)
+ // - for FSList or FSArray that are NOT represented by multi-valued
+ // properties, the element type
+ if ((aFeature.getDescription() != null && aFeature.getDescription().length() > 0)
+ || efeat.isMany() || aFeature.getElementType() != null) {
+ EAnnotation eannot = EcoreFactory.eINSTANCE.createEAnnotation();
+ eannot.setSource("http://uima.apache.org");
+ if (aFeature.getDescription() != null && aFeature.getDescription().length() > 0) {
+ eannot.getDetails().put("description", aFeature.getDescription());
+ }
+ if (efeat.isMany()) {
+ eannot.getDetails().put("uimaType", aFeature.getRangeTypeName());
+ }
+ if (!efeat.isMany() && aFeature.getElementType() != null) {
+ eannot.getDetails().put("elementType", aFeature.getElementType());
+ }
+ efeat.getEAnnotations().add(eannot);
+ }
+ return efeat;
+ }
+
+ private static EClassifier lookupEClassifierForType(String aFullTypeName) {
+ // separate name into package name and class name
+ String uimaNamespace, shortTypeName;
+ int lastDot = aFullTypeName.lastIndexOf('.');
+ if (lastDot <= 0) {
+ uimaNamespace = null;
+ shortTypeName = aFullTypeName;
+ } else {
+ uimaNamespace = aFullTypeName.substring(0, lastDot);
+ shortTypeName = aFullTypeName.substring(lastDot + 1);
+ }
+ String nsUri = uimaNamespace2NamespaceUri(uimaNamespace);
+
+ // does EPackage already exist for this URI?
+ EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(nsUri);
+ if (ePackage == null) {
+ return null;
+ }
+ return ePackage.getEClassifier(shortTypeName);
+ }
+
+ /**
+ * Gets or creates an EPackage for a UIMA namespace. Actually will create a whole chain of nested
+ * EPackages, one for each component of the UIMA namespace, but only the leaf node of the chain
+ * will be returned.
+ *
+ * @param uimaNamespace
+ * UIMA namespace
+ * @return EPackage corresponding to this namespace.
+ */
+ private static EPackage uimaNamespace2EPackage(String uimaNamespace) {
+ // convert UIMA namespace (dotted string) to namespace URI
+ String nsUri = uimaNamespace2NamespaceUri(uimaNamespace);
+ // see if package already exists for this URI
+ EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(nsUri);
+ if (ePackage == null) {
+ // package name is last component of namespace.
+ // all other components form the parent namespace
+ String parentNamespace = null;
+ String packageName;
+ if (uimaNamespace != null) {
+ int lastDot = uimaNamespace.lastIndexOf('.');
+ packageName = uimaNamespace.substring(lastDot + 1);
+ if (lastDot > 0) {
+ parentNamespace = uimaNamespace.substring(0, lastDot);
+ }
+ } else {
+ packageName = "noNamespace";
+ }
+
+ // create Package
+ ePackage = EcoreFactory.eINSTANCE.createEPackage();
+ ePackage.setNsURI(nsUri);
+ ePackage.setName(packageName);
+ EPackage.Registry.INSTANCE.put(nsUri, ePackage);
+
+ // get or create SuperPackage if any
+ if (parentNamespace != null) {
+ EPackage superPackage = uimaNamespace2EPackage(parentNamespace);
+ superPackage.getESubpackages().add(ePackage);
+ }
+ }
+ return ePackage;
+ }
+
+ private static String uimaNamespace2NamespaceUri(String uimaNamespace) {
+ if (uimaNamespace == null || uimaNamespace.length() == 0) {
+ return XmiCasSerializer.DEFAULT_NAMESPACE_URI;
+ }
+ // Our convention is that the Namespace URI is "http:///", followed by the UIMA namespace, with
+ // dots converted to slashes, and with ".ecore" appended. (This is EMF's convention for
+ // constructing a namespace URI from a Java package name.)
+ return "http:///" + uimaNamespace.replace('.', '/') + ".ecore";
+ }
+
+ /**
+ * Main program. Takes two arguments: the filename of an input TypeSystem descriptor file and the
+ * filename of the Ecore/XMI file to generate.
+ */
+ public static void main(String[] args) throws Exception {
+ // register default resource factory
+ Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("*",
+ new XMIResourceFactoryImpl());
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+ URI outputURI = URI.createFileURI(args[1]);
+ Resource outputResource = resourceSet.createResource(outputURI);
+ Map options = new HashMap();
+ // options.put(OPTION_PRESERVE_UIMA_LIST_TYPES, Boolean.TRUE);
+ uimaTypeSystem2Ecore(args[0], outputResource, options);
+ outputResource.save(null);
+ }
+}
Propchange: incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/UimaTypeSystem2Ecore.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/XmiEcoreCasConsumer.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/XmiEcoreCasConsumer.java?rev=771663&r1=771662&r2=771663&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/XmiEcoreCasConsumer.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-examples/src/main/java/org/apache/uima/examples/xmi/XmiEcoreCasConsumer.java Tue May 5 10:52:19 2009
@@ -33,7 +33,6 @@
import org.apache.uima.cas.FSIterator;
import org.apache.uima.cas.impl.XmiCasSerializer;
import org.apache.uima.collection.CasConsumer_ImplBase;
-import org.apache.uima.ecore.UimaTypeSystem2Ecore;
import org.apache.uima.examples.SourceDocumentInformation;
import org.apache.uima.jcas.JCas;
import org.apache.uima.resource.ResourceInitializationException;
@@ -82,6 +81,7 @@
private Map schemaLocationMap = null;
+ @Override
public void initialize() throws ResourceInitializationException {
mDocNum = 0;
mOutputDir = new File((String) getConfigParameterValue(PARAM_OUTPUTDIR));