| /** \file xmlwriter.cpp . |
| ----------------------------------------------------------------------------- |
| |
| |
| * 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. |
| |
| ----------------------------------------------------------------------------- |
| |
| Description: |
| |
| ----------------------------------------------------------------------------- |
| |
| |
| -------------------------------------------------------------------------- */ |
| |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Include dependencies */ |
| /* ----------------------------------------------------------------------- */ |
| #include "uima/pragmas.hpp" |
| |
| #include "uima/xmiwriter.hpp" |
| #include "uima/arrayfs.hpp" |
| #include "uima/listfs.hpp" |
| #include "uima/lowlevel_indexrepository.hpp" |
| #include "uima/lowlevel_indexiterator.hpp" |
| #include "uima/internal_casimpl.hpp" |
| #include "uima/internal_fspromoter.hpp" |
| #include "uima/fsindexrepository.hpp" |
| |
| #include "uima/resmgr.hpp" |
| #include "uima/location.hpp" |
| #include <sstream> |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Constants */ |
| /* ----------------------------------------------------------------------- */ |
| //#define TAB_INCREMENT 0 |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Forward declarations */ |
| /* ----------------------------------------------------------------------- */ |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Types / Classes */ |
| /* ----------------------------------------------------------------------- */ |
| |
| using namespace std; |
| namespace uima { |
| |
| //////////////////////////////////////////////////////////////////////// |
| // XmiWriter |
| |
| XmiWriter::XmiWriter(CAS const & cas, bool addDocument) |
| : XMLWriterABase(cas, addDocument), sharedData(0), |
| iv_stringType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_STRING) ), |
| iv_integerType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_INTEGER) ), |
| iv_floatType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FLOAT) ), |
| iv_byteType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BYTE) ), |
| iv_booleanType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BOOLEAN) ), |
| iv_shortType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SHORT) ), |
| iv_longType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_LONG) ), |
| iv_doubleType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_DOUBLE) ), |
| iv_arrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_ARRAY_BASE) ), |
| iv_stringArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_STRING_ARRAY) ), |
| iv_intArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_INTEGER_ARRAY) ), |
| iv_floatArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FLOAT_ARRAY) ), |
| iv_byteArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BYTE_ARRAY) ), |
| iv_booleanArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BOOLEAN_ARRAY) ), |
| iv_shortArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SHORT_ARRAY) ), |
| iv_longArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_LONG_ARRAY) ), |
| iv_doubleArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_DOUBLE_ARRAY) ), |
| iv_sofaType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SOFA) ) { |
| assert( iv_stringType.isValid()); |
| assert( iv_integerType.isValid()); |
| assert( iv_floatType.isValid()); |
| assert( iv_byteType.isValid()); |
| assert( iv_booleanType.isValid()); |
| assert( iv_shortType.isValid()); |
| assert( iv_longType.isValid()); |
| assert( iv_doubleType.isValid()); |
| assert( iv_stringArrayType.isValid() ); |
| assert( iv_arrayType.isValid() ); |
| assert( iv_intArrayType.isValid()); |
| assert( iv_floatArrayType.isValid()); |
| assert( iv_byteArrayType.isValid()); |
| assert( iv_booleanArrayType.isValid()); |
| assert( iv_shortArrayType.isValid()); |
| assert( iv_longArrayType.isValid()); |
| assert( iv_doubleArrayType.isValid()); |
| assert( iv_sofaType.isValid()); |
| } |
| |
| XmiWriter::XmiWriter(CAS const & cas, bool addDocument, XmiSerializationSharedData * serdata) |
| : XMLWriterABase(cas, addDocument), sharedData(serdata), |
| iv_stringType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_STRING) ), |
| iv_integerType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_INTEGER) ), |
| iv_floatType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FLOAT) ), |
| iv_byteType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BYTE) ), |
| iv_booleanType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BOOLEAN) ), |
| iv_shortType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SHORT) ), |
| iv_longType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_LONG) ), |
| iv_doubleType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_DOUBLE) ), |
| iv_arrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_ARRAY_BASE) ), |
| iv_stringArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_STRING_ARRAY) ), |
| iv_intArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_INTEGER_ARRAY) ), |
| iv_floatArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FLOAT_ARRAY) ), |
| iv_byteArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BYTE_ARRAY) ), |
| iv_booleanArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_BOOLEAN_ARRAY) ), |
| iv_shortArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SHORT_ARRAY) ), |
| iv_longArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_LONG_ARRAY) ), |
| iv_doubleArrayType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_DOUBLE_ARRAY) ), |
| iv_sofaType( cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_SOFA) ) { |
| assert( iv_stringType.isValid()); |
| assert( iv_integerType.isValid()); |
| assert( iv_floatType.isValid()); |
| assert( iv_byteType.isValid()); |
| assert( iv_booleanType.isValid()); |
| assert( iv_shortType.isValid()); |
| assert( iv_longType.isValid()); |
| assert( iv_doubleType.isValid()); |
| assert( iv_stringArrayType.isValid() ); |
| assert( iv_arrayType.isValid() ); |
| assert( iv_intArrayType.isValid()); |
| assert( iv_floatArrayType.isValid()); |
| assert( iv_byteArrayType.isValid()); |
| assert( iv_booleanArrayType.isValid()); |
| assert( iv_shortArrayType.isValid()); |
| assert( iv_longArrayType.isValid()); |
| assert( iv_doubleArrayType.isValid()); |
| assert( iv_sofaType.isValid()); |
| } |
| |
| XmiWriter::~XmiWriter() { |
| for (size_t i = 0; i < enqueuedFS.size(); i++) { |
| vector<int> * indexes = (vector<int>*) enqueuedFS[i]; |
| if (indexes != 0) |
| delete indexes; |
| } |
| for (size_t i = 0; i < xmiTypeNames.size(); i++) { |
| if (xmiTypeNames.at(i) != 0) { |
| delete xmiTypeNames.at(i); |
| } |
| } |
| } |
| |
| /** |
| * Populates nsUriToPrefixMap and xmiTypeNames structures based on CAS type system. |
| */ |
| void XmiWriter::initTypeAndNamespaceMappings() { |
| nsUriToPrefixMap[XMI_NS_URI] = XMI_NS_PREFIX; |
| |
| //Add any namespace prefix mappings used by out of type system data. |
| //Need to do this before the in-typesystem namespaces so that the prefix |
| //used here are reserved and won't be reused for any in-typesystem namespaces. |
| if (this->sharedData != NULL) { |
| vector<OotsElementData*> & ootsElements = this->sharedData->getOutOfTypeSystemElements(); |
| for(size_t i=0;i<ootsElements.size();i++) { |
| OotsElementData * oed = ootsElements.at(i); |
| string nsUri = oed->elementName->nsUri; |
| string qname = oed->elementName->qualifiedName; |
| string localName = oed->elementName->shortName; |
| string prefix = qname.substr(0, oed->elementName->qualifiedName.find_first_of(":")); |
| nsUriToPrefixMap[nsUri] = prefix; |
| nsPrefixesUsed.insert(prefix); |
| } |
| } |
| |
| vector<Type> allTypes; |
| iv_cas.getTypeSystem().getAllTypes(allTypes); |
| xmiTypeNames.resize(allTypes.size() + 1); |
| //leave out 0th element. |
| XmlElementName * invalidType = new XmlElementName("INVALID_TYPE", |
| "INVALID_TYPE", |
| "INVALID_TYPE"); |
| |
| xmiTypeNames[0] = invalidType; |
| |
| for (size_t i = 0; i < allTypes.size() ; i++) { |
| Type type = allTypes.at(i); |
| lowlevel::TyFSType typecode = uima::internal::FSPromoter::demoteType(type); |
| //cout << "Mapping " << type.getName() << endl; |
| UnicodeStringRef name = type.getName(); |
| xmiTypeNames[typecode] = uimaTypeName2XmiElementName(name); |
| // this also populats the nsUriToPrefix map |
| } |
| } |
| |
| /** |
| * Converts a UIMA-style dotted type name to the element name that should be used in the XMI |
| * serialization. The XMI element name consists of three parts - the Namespace URI, the Local |
| * Name, and the QName (qualified name). |
| * |
| * @param uimaTypeName |
| * a UIMA-style dotted type name |
| * @return a data structure holding the three components of the XML element name |
| */ |
| XmlElementName * XmiWriter::uimaTypeName2XmiElementName(UnicodeStringRef & uimaTypeName) { |
| // split uima type name into namespace and short name |
| string nameSpace; |
| string shortName; |
| string nsUri; |
| string qName; |
| string typeName = uimaTypeName.asUTF8(); |
| int lastDotIndex = typeName.find_last_of("."); |
| |
| if (lastDotIndex == -1) // no namespace |
| { |
| shortName = typeName; |
| nsUri = DEFAULT_NAMESPACE_URI; |
| } else { |
| nameSpace = typeName.substr(0, lastDotIndex); |
| shortName = typeName.substr(lastDotIndex + 1); |
| nsUri = "http:///"; |
| nsUri.append(nameSpace); |
| std::replace(nsUri.begin(), nsUri.end(), '.', '/'); |
| nsUri.append(".ecore"); |
| //cout << nsUri << endl; |
| } |
| |
| // determine what namespace prefix to use |
| map<string, string>::iterator ite = nsUriToPrefixMap.find(nsUri); |
| string prefix; |
| if (ite != nsUriToPrefixMap.end()) { |
| prefix = ite->second; |
| } |
| |
| //create a prefix and associate nameSpace with prefix |
| if (prefix.length() == 0) { |
| if (nameSpace.length() != 0) { |
| int secondLastDotIndex = nameSpace.find_last_of("."); |
| //cout << nameSpace << " secondlastdot " << secondLastDotIndex << endl; |
| prefix = nameSpace.substr(secondLastDotIndex + 1); |
| } else { |
| prefix = "noNamespace"; |
| } |
| //cout << "prefix " << prefix << endl; |
| // make sure this prefix hasn't already been used for some other namespace |
| set<string>::iterator prefixIte = nsPrefixesUsed.find(prefix); |
| int num=1; |
| while (prefixIte != nsPrefixesUsed.end()) { |
| num++; |
| stringstream basePrefix; |
| basePrefix << prefix << num << endl; |
| prefixIte = nsPrefixesUsed.find(basePrefix.str()); |
| if (prefixIte == nsPrefixesUsed.end() ) { |
| prefix = basePrefix.str(); |
| break; |
| } |
| } |
| nsPrefixesUsed.insert(prefix); |
| nsUriToPrefixMap[nsUri] = prefix; |
| } |
| qName = prefix; |
| qName.append(":"); |
| qName.append(shortName); |
| return new XmlElementName(nsUri, shortName, qName); |
| |
| } |
| |
| void XmiWriter::writeViews(ostream & os, CAS const & cas) { |
| // Get indexes for each SofaFS in the CAS |
| int numViews = cas.iv_baseCas->iv_sofaCount; |
| //const CAS * baseCas = cas.getBaseCas(); |
| int sofaXmiId=0; |
| lowlevel::TyFS sofaAddr; |
| |
| for (int sofaNum = 1; sofaNum <= numViews; sofaNum++) { |
| vector<lowlevel::TyFS> indexedFS; |
| SofaFS sofa = cas.iv_baseCas->getSofa(sofaNum); |
| |
| lowlevel::IndexRepository * loopIR = cas.iv_baseCas->iv_sofa2indexMap[sofaNum]; |
| |
| if (sofaNum != 1 || cas.iv_baseCas->isInitialSofaCreated()) { |
| sofaAddr = internal::FSPromoter::demoteFS(sofa); |
| sofaXmiId = this->getXmiId(sofaAddr); |
| } |
| if (loopIR != NULL) { |
| loopIR->getIndexedFSs(indexedFS); |
| writeView(os, sofaXmiId, indexedFS); |
| } |
| } |
| } |
| |
| void XmiWriter::writeView(ostream & os,int sofaXmiId, vector<lowlevel::TyFS>& members) { |
| UnicodeString viewType(UnicodeString("uima.cas.View")); |
| UnicodeStringRef uref(viewType.getBuffer(), viewType.length()); |
| XmlElementName * elemName = uimaTypeName2XmiElementName(uref); |
| |
| stringstream membersString; |
| for (size_t i = 0; i < members.size(); i++) { |
| membersString << getXmiId(members.at(i)) << " "; |
| } |
| |
| //check for out-of-typesystem members |
| if (this->sharedData != NULL) { |
| vector<int> ootsMembers; |
| this->sharedData->getOutOfTypeSystemViewMembers(sofaXmiId, ootsMembers); |
| if (ootsMembers.size() != 0) { |
| for (size_t i=0; i < ootsMembers.size(); i++) { |
| membersString << ootsMembers.at(i) << " "; |
| } |
| } |
| } |
| |
| //remove leading and trailing blanks |
| string outstr = membersString.str(); |
| size_t startpos = outstr.find_first_not_of(" "); |
| size_t endpos = outstr.find_last_not_of(" "); |
| if (string::npos != startpos && string::npos != endpos) { |
| outstr = outstr.substr(startpos, endpos-startpos+1); |
| } |
| |
| if (sofaXmiId !=0 || outstr.size() > 0) { |
| os << "<" << elemName->qualifiedName; |
| if (sofaXmiId != 0) { |
| os << " sofa=\"" << sofaXmiId << "\""; |
| } |
| if (outstr.size() > 0) { |
| os << " members=\"" << outstr << "\""; |
| } |
| os << "/>"; |
| } |
| delete elemName; |
| } |
| |
| bool XmiWriter::isReferenceType(Type const & t) const { |
| return !( t.getTypeSystem().isPrimitive(uima::internal::FSPromoter::demoteType(t)) ); |
| } |
| |
| void XmiWriter::writeFeatureValue(ostream & os, FeatureStructure const & fs, Feature const & f) { |
| assert( fs.isValid() ); |
| assert( f.isValid() ); |
| Type t; |
| f.getRangeType(t); |
| assert( t.isValid() ); |
| if ( t == iv_stringType || t.isStringSubType() ) { |
| if (!fs.isUntouchedFSValue(f) ) { |
| UnicodeStringRef ref = fs.getStringValue(f); |
| if (ref.getBuffer() != NULL) { |
| icu::UnicodeString us; |
| normalize( ref, us ); |
| os << " " << f.getName() << "=\""; |
| os << us << "\""; |
| } |
| } |
| } else if (t == iv_integerType) { |
| os << " " << f.getName() << "=\""; |
| os << fs.getIntValue(f) << "\""; |
| } else if (t == iv_floatType) { |
| os << " " << f.getName() << "=\""; |
| os << fs.getFloatValue(f) << "\""; |
| } else if (t == iv_byteType) { |
| os << " " << f.getName() << "=\""; |
| int val = fs.getByteValue(f); |
| os << val << "\""; |
| } else if (t == iv_booleanType) { |
| os << " " << f.getName() << "=\""; |
| if (fs.getBooleanValue(f)) |
| os << "true" << "\""; |
| else |
| os << "false" << "\""; |
| } else if (t == iv_shortType) { |
| os << " " << f.getName() << "=\""; |
| os << fs.getShortValue(f) << "\""; |
| } else if (t == iv_longType) { |
| os << " " << f.getName() << "=\""; |
| os << fs.getLongValue(f) << "\""; |
| } else if (t == iv_doubleType) { |
| os << " " << f.getName() << "=\""; |
| stringstream s; |
| s << fs.getDoubleValue(f); |
| os << s.str() << "\""; |
| } else { |
| |
| FeatureStructure referencedFS = fs.getFSValue(f); |
| uima::lowlevel::TyFS lolFS = uima::internal::FSPromoter::demoteFS(referencedFS); |
| if (lolFS != uima::lowlevel::FSHeap::INVALID_FS) { |
| os << " " ; |
| os << f.getName() << "=\""; |
| //ptrdiff_t val = uima::internal::CASImpl::promoteCAS(iv_cas).getHeap().getUniqueID(lolFS); |
| int val = getXmiId(lolFS); |
| os << val << "\""; |
| } |
| } |
| } |
| |
| template<class Array> |
| void writeArray(ostream & os, Array const & array, char const * tag, int xmiid) { |
| size_t i; |
| if (array.size() > 0) { |
| //XCAS os << " size=\"" << array.size() << "\">" << endl; |
| os << " <" << tag; |
| os << " " << XmiWriter::ID_ATTR_NAME << "=\"" << xmiid << "\""; |
| os << " elements=\"" ; |
| os << arrayToString(array, tag); |
| os << "\"/>" << endl; |
| } else { |
| //XCAS os << " size=\"0\"/>" << endl; |
| } |
| } |
| |
| void XmiWriter::writeArray(ostream & os, |
| FeatureStructure const & array, |
| char const * tag, int xmiid) { |
| os << " <" << tag; |
| os << " " << ID_ATTR_NAME << "=\"" << xmiid << "\""; |
| os << " elements=\"" ; |
| os << arrayToString(array, tag); |
| os << "\"/>" << endl; |
| } |
| |
| string XmiWriter::arrayToString(FeatureStructure const & fs, char const * tag) { |
| stringstream str; |
| |
| int typecode = internal::FSPromoter::demoteType(fs.getType()); |
| switch (typecode) { |
| case internal::gs_tyIntArrayType: { |
| IntArrayFS arrayfs(fs); |
| size_t n = arrayfs.size(); |
| for (size_t i=0; i < n;i++) { |
| str << arrayfs.get(i); |
| if (i+1 < n) { |
| str << " "; |
| } |
| } |
| break; |
| } |
| case internal::gs_tyFloatArrayType: { |
| FloatArrayFS arrayfs(fs); |
| size_t n = arrayfs.size(); |
| for (size_t i=0; i < n;i++) { |
| str << arrayfs.get(i); |
| if (i+1 < n) { |
| str << " "; |
| } |
| } |
| break; |
| } |
| case internal::gs_tyBooleanArrayType: { |
| BooleanArrayFS arrayfs(fs); |
| size_t n = arrayfs.size(); |
| for (size_t i=0; i < n;i++) { |
| if (arrayfs.get(i)) { |
| str << "true"; |
| } else { |
| str << "false"; |
| } |
| if (i+1 < n) { |
| str << " "; |
| } |
| } |
| break; |
| } |
| case internal::gs_tyByteArrayType: { |
| ByteArrayFS arrayfs(fs); |
| size_t n = arrayfs.size(); |
| char * out = new char[3]; |
| memset(out,0,3); |
| for (size_t i=0; i < n;i++) { |
| sprintf(out,"%02X",0xFF & arrayfs.get(i)); |
| //printf ("itoahexadecimal: %d %d\n",i, arrayfs.get(i)); |
| str << out[0] << out[1]; |
| } |
| delete[] out; |
| break; |
| } |
| case internal::gs_tyShortArrayType: { |
| ShortArrayFS arrayfs(fs); |
| size_t n = arrayfs.size(); |
| for (size_t i=0; i < n;i++) { |
| str << arrayfs.get(i); |
| if (i+1 < n) { |
| str << " "; |
| } |
| } |
| break; |
| } |
| case internal::gs_tyLongArrayType: { |
| LongArrayFS arrayfs(fs); |
| size_t n = arrayfs.size(); |
| for (size_t i=0; i < n;i++) { |
| str << arrayfs.get(i); |
| if (i+1 < n) { |
| str << " "; |
| } |
| } |
| break; |
| } |
| case internal::gs_tyDoubleArrayType: { |
| DoubleArrayFS arrayfs(fs); |
| size_t n = arrayfs.size(); |
| for (size_t i=0; i < n;i++) { |
| str << arrayfs.get(i); |
| if (i+1 < n) { |
| str << " "; |
| } |
| } |
| break; |
| } |
| case internal::gs_tyFSArrayType: { |
| ArrayFS arrayfs(fs); |
| size_t size = arrayfs.size(); |
| |
| vector<XmiArrayElement*> * ootsList = NULL; |
| if (this->sharedData != NULL) { |
| ootsList = this->sharedData->getOutOfTypeSystemArrayElements(internal::FSPromoter::demoteFS(arrayfs)); |
| } |
| size_t ootsIndex = 0; |
| for (size_t j=0; j < size; j++) { |
| int xmiId = getXmiId(uima::internal::FSPromoter::demoteFS(arrayfs.get(j)));//convert to xmiid; 0 if not set |
| if (xmiId == 0) { //if 0 check if its an Oots FS |
| // However, this null array element might have been a reference to an |
| //out-of-typesystem FS, so check the ootsArrayElementsList |
| if (ootsList != NULL) { |
| while (ootsIndex < ootsList->size()) { |
| XmiArrayElement * arel = ootsList->at(ootsIndex++); |
| if (arel->index == j) { |
| str << arel->xmiId; |
| break; |
| } |
| } |
| } |
| } else { |
| str << xmiId; |
| } |
| if (j+1 < size) { |
| str << " "; |
| } |
| } |
| break; |
| } |
| case internal::gs_tyStringArrayType: { |
| StringArrayFS arrayfs(fs); |
| size_t n = arrayfs.size(); |
| UnicodeString ustr; |
| for (size_t i=0; i < n;i++) { |
| ustr.setTo(""); |
| normalize( arrayfs.get(i), ustr ); |
| str << "<" << tag << ">" << ustr << "</" << tag << ">"; |
| |
| } |
| break; |
| } |
| default: { |
| cerr << "arrayToString() type not supported " << typecode << endl; |
| ErrorInfo errInfo; |
| errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED); |
| ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR); |
| msg.addParam("arrayToString() type not supported."); |
| msg.addParam(typecode); |
| errInfo.setMessage(msg); |
| errInfo.setSeverity(ErrorInfo::unrecoverable); |
| ExcIllFormedInputError exc(errInfo); |
| throw exc; |
| } |
| } |
| return str.str(); |
| } |
| |
| void XmiWriter::writeBooleanArray(ostream & os, BooleanArrayFS const & array, char const * tag, int xmiid) { |
| |
| if (array.size() > 0) { |
| os << " <" << tag; |
| os << " " << ID_ATTR_NAME << "=\"" << xmiid << "\""; |
| os << " elements=\"" ; |
| os << arrayToString(array, tag).c_str(); |
| os << "\"/>" << endl; |
| } |
| } |
| |
| void XmiWriter::writeStringArray(ostream & os, StringArrayFS const & array, char const * tag, int xmiid) { |
| if (array.size() > 0) { |
| //XCAS os << " size=\"" << array.size() << "\">" << endl; |
| os << " <" << tag; |
| os << " " << ID_ATTR_NAME << "=\"" << xmiid << "\">"; |
| os << arrayToString(array, "elements").c_str(); |
| os << "</" << tag << ">" << endl; |
| } |
| } |
| |
| void XmiWriter::writeFSFlat(ostream & os, |
| FeatureStructure const & fs, |
| vector<int>* indexInfo) { |
| uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(iv_cas); |
| assert( fs.isValid() ); |
| Type t = fs.getType(); |
| lowlevel::TyFSType typecode = uima::internal::FSPromoter::demoteType(t); |
| XmlElementName * xmlElementName = xmiTypeNames[typecode]; |
| bool insidelist = fs.getCAS().getTypeSystem().isListType(typecode); |
| int xmiId = /**crCASImpl.getHeap().getUniqueID**/ |
| getXmiId( uima::internal::FSPromoter::demoteFS(fs) ); |
| |
| // if array |
| if ( iv_arrayType.subsumes(t) ) { |
| const CAS* ccasp = &iv_cas; |
| CAS* casp = const_cast<CAS*> (ccasp); |
| if (casp->getHeap()->getArraySize(internal::FSPromoter::demoteFS(fs)) >0) { |
| if ( t == iv_intArrayType ) { |
| writeArray( os, IntArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId); |
| } else if ( t == iv_floatArrayType ) { |
| writeArray( os, FloatArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId); |
| } else if ( t == iv_stringArrayType ) { |
| //cout << "got a string array " << endl; |
| writeStringArray( os, StringArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId); |
| } else if ( t == iv_byteArrayType ) { |
| writeArray(os, ByteArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId); |
| } else if ( t == iv_booleanArrayType ) { |
| writeArray( os, BooleanArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId); |
| } else if ( t == iv_shortArrayType ) { |
| writeArray( os, ShortArrayFS(fs),xmlElementName->qualifiedName.c_str(), xmiId ); |
| } else if ( t == iv_longArrayType ) { |
| writeArray( os, LongArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId); |
| } else if ( t == iv_doubleArrayType ) { |
| writeArray( os, DoubleArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId); |
| } else { |
| assert( t == iv_cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FS_ARRAY) ); |
| if (internal::FSPromoter::demoteType(t) == internal::gs_tyFSArrayType) { |
| writeArray( os, ArrayFS(fs), xmlElementName->qualifiedName.c_str(), xmiId); |
| } else { |
| cerr << "writeFSFlat unknown array type " << t.getName() << endl; |
| } |
| } |
| } |
| } else { |
| vector<Feature> features; |
| fs.getType().getAppropriateFeatures(features); |
| size_t i; |
| stringstream strcontent; |
| os << " <" << xmlElementName->qualifiedName; |
| os << " " << ID_ATTR_NAME << "=\"" << getXmiId( uima::internal::FSPromoter::demoteFS(fs) ) << "\""; |
| bool containsElements=false; |
| for (i=0; i<features.size(); ++i) { |
| uima::Feature const & f = features[i]; |
| Type range; |
| f.getRangeType(range); |
| int typecode = internal::FSPromoter::demoteType(range); |
| //cout << "writeFSFlat() " << range.getName() << endl; |
| switch (typecode) { |
| case internal::gs_tyBooleanType: |
| case internal::gs_tyByteType: |
| case internal::gs_tyIntegerType: |
| case internal::gs_tyFloatType: |
| case internal::gs_tyStringType: |
| case internal::gs_tyShortType: |
| case internal::gs_tyLongType: |
| case internal::gs_tyDoubleType: { |
| writeFeatureValue(os, fs, f); |
| break; |
| } |
| case internal::gs_tyStringArrayType: { |
| if (f.isMultipleReferencesAllowed() ) { |
| writeFeatureValue(os, fs, f); |
| } else { |
| StringArrayFS arrayFS = fs.getStringArrayFSValue(f); |
| if (arrayFS.isValid() && arrayFS.size() > 0) { |
| strcontent << arrayToString(arrayFS, f.getName().asUTF8().c_str()); |
| } |
| } |
| break; |
| } |
| case internal::gs_tyIntArrayType: |
| case internal::gs_tyFloatArrayType: |
| case internal::gs_tyByteArrayType: |
| case internal::gs_tyBooleanArrayType: |
| case internal::gs_tyShortArrayType: |
| case internal::gs_tyLongArrayType: |
| case internal::gs_tyDoubleArrayType: |
| case internal::gs_tyFSArrayType: { |
| if (f.isMultipleReferencesAllowed() ) { |
| writeFeatureValue(os, fs, f); |
| } else { |
| if (fs.getFSValue(f).isValid()) { |
| string str = arrayToString(fs.getFSValue(f), f.getName().asUTF8().c_str()); |
| os << " " << f.getName() << "=\"" << str << "\" "; |
| } |
| } |
| break; |
| } |
| case internal::gs_tyIntListType: |
| case internal::gs_tyEIntListType: |
| case internal::gs_tyNEIntListType: |
| case internal::gs_tyFloatListType: |
| case internal::gs_tyEFloatListType: |
| case internal::gs_tyNEFloatListType: |
| case internal::gs_tyFSListType: { |
| if (f.isMultipleReferencesAllowed() || insidelist) { |
| writeFeatureValue(os, fs, f); |
| } else { |
| if (fs.getFSValue(f).isValid()) { |
| string str = listToString(fs.getFSValue(f), f.getName().asUTF8().c_str()); |
| os << " " << f.getName() << "=\"" << str << "\" "; |
| //cout << " " << range.getName() << str << endl; |
| } |
| } |
| break; |
| } |
| case internal::gs_tyStringListType: |
| case internal::gs_tyEStringListType: |
| case internal::gs_tyNEStringListType: { |
| FeatureStructure listFS = fs.getFSValue(f); |
| if (listFS.isValid()) { |
| if (f.isMultipleReferencesAllowed() ) { |
| writeFeatureValue(os, fs, f); |
| } else { |
| if (fs.getFSValue(f).isValid()) { |
| string str = listToString(fs.getFSValue(f), f.getName().asUTF8().c_str()); |
| if (listFS.isValid() && str.length() > 0) { |
| strcontent << str; |
| } |
| } |
| } |
| } |
| break; |
| } |
| default: { |
| writeFeatureValue(os, fs, f); |
| break; |
| } |
| } |
| } |
| |
| //add out-of-typesystem features, if any |
| if (this->sharedData != NULL) { |
| int fsaddr = internal::FSPromoter::demoteFS(fs); |
| OotsElementData * oed = this->sharedData->getOutOfTypeSystemFeatures(fsaddr); |
| if (oed != NULL) { |
| //attributes |
| for (size_t a=0; a < oed->attributes.size(); a++) { |
| XmlAttribute * attr = oed->attributes.at(a); |
| icu::UnicodeString us; |
| icu::UnicodeString av(attr->value.c_str()); |
| normalize( av, us ); |
| os << " " << attr->name << "=\"" << us << "\""; |
| } |
| //child elements |
| map<string,vector<string>*>::iterator ite ; |
| for (ite = oed->childElements.begin(); |
| ite != oed->childElements.end(); ite++) { |
| vector<string> * values = ite->second; |
| for (size_t v=0; v < values->size();v++) { |
| icu::UnicodeString us; |
| icu::UnicodeString av(values->at(v).c_str()); |
| normalize( av, us ); |
| strcontent << " <" << ite->first |
| << ">" << us |
| << "</" << ite->first << ">"; |
| } |
| } |
| } |
| } |
| // write stringArray and/or stringList Features if any |
| if (strcontent.str().length() > 0) { |
| os << ">" << strcontent.str(); |
| os << "</" << xmlElementName->qualifiedName << ">" << endl; |
| strcontent.clear(); |
| } else { |
| os << "/>" << endl; |
| } |
| } |
| } |
| |
| |
| void XmiWriter::findReferencedFSs(FeatureStructure const & fs, bool check) { |
| |
| |
| if (! fs.isValid() ) { |
| return; |
| } |
| if (check) { |
| if (! enqueueUnindexed(fs)) { |
| // already been processed |
| return; |
| } |
| } |
| Type t = fs.getType(); |
| //cout << "findReferencedFSs() " << t.getName() << endl; |
| int tcode = internal::FSPromoter::demoteType(t); |
| bool insideListNode=fs.getCAS().getTypeSystem().isListType(tcode); |
| assert( t.isValid() ); |
| size_t i; |
| if ( iv_arrayType.subsumes(t) ) { |
| if ( t == iv_cas.getTypeSystem().getType(uima::CAS::TYPE_NAME_FS_ARRAY) ) { |
| ArrayFS array(fs); |
| for (i=0; i<array.size(); ++i) { |
| findReferencedFSs(array.get(i)); |
| } |
| } |
| } |
| else { |
| vector<Feature> features; |
| fs.getType().getAppropriateFeatures(features); |
| |
| for (i=0; i<features.size(); ++i) { |
| uima::Feature const & f = features[i]; |
| Type range; |
| f.getRangeType(range); |
| if (isReferenceType(range)) { |
| //cout << __LINE__ << "a referenced feature " << |
| // f.getName() << endl; |
| int typecode = internal::FSPromoter::demoteType(range); |
| switch (typecode) { |
| case internal::gs_tyFSArrayType: { |
| findReferencedFSs(fs.getFSValue(f)); |
| break; |
| } |
| case internal::gs_tyFSListType: { |
| // we only enqueue lists as first-class objects if the feature has |
| // multipleReferencesAllowed = true |
| // OR if we're already inside a list node (this handles the tail feature correctly) |
| if (f.isMultipleReferencesAllowed() || insideListNode) { |
| findReferencedFSs(fs.getFSValue(f)); |
| } else { |
| // enqueue any FSs reachable from an FSList |
| enqueueFSListElements(fs.getFSValue(f)); |
| } |
| break; |
| } |
| case internal::gs_tyBooleanArrayType: |
| case internal::gs_tyByteArrayType: |
| case internal::gs_tyIntArrayType: |
| case internal::gs_tyFloatArrayType: |
| case internal::gs_tyStringArrayType: |
| case internal::gs_tyShortArrayType: |
| case internal::gs_tyLongArrayType: |
| case internal::gs_tyDoubleArrayType: { |
| if (f.isMultipleReferencesAllowed ()) { |
| findReferencedFSs(fs.getFSValue(f)); |
| } |
| break; |
| } |
| case internal::gs_tyIntListType: |
| case internal::gs_tyFloatListType: |
| case internal::gs_tyStringListType: { |
| if (f.isMultipleReferencesAllowed () || insideListNode) { |
| findReferencedFSs(fs.getFSValue(f)); |
| } |
| break; |
| } |
| default: { //FS Ref |
| findReferencedFSs(fs.getFSValue(f)); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| void XmiWriter::write(ostream & os) { |
| |
| //build xmlTypeNames and nsUri to prefix mapping |
| initTypeAndNamespaceMappings(); |
| //enqueue every FS that was deserialized into this CAS |
| enqueueIncoming(); |
| const uima::lowlevel::IndexRepository * ixRep; |
| const CAS* ccasp = &iv_cas; |
| CAS* casp = const_cast<CAS*> (ccasp); |
| CAS* tcas; |
| uima::internal::CASImpl const & crCASImpl = uima::internal::CASImpl::promoteCAS(*casp->getBaseCas()); |
| ixRep = &crCASImpl.getIndexRepository(); |
| |
| int numViews = casp->getNumViews(); |
| set<FeatureStructure> referencedFSs; |
| for (int view=0; view<=numViews; view++) { |
| if (view==0) { |
| // First time through is for base CAS |
| sofa = 0; |
| } else { |
| // for all Sofa found in the CAS, get new IndexRepository |
| tcas = casp->getViewBySofaNum(view); |
| sofa = tcas->getSofaNum(); |
| uima::internal::CASImpl & crTCASImpl = uima::internal::CASImpl::promoteCAS(*tcas); |
| ixRep = &crTCASImpl.getIndexRepository(); |
| } |
| |
| // enqueue indexed FSs in known indexes |
| vector<FeatureStructure> indexedFSs; |
| vector<icu::UnicodeString> indexIDs = ixRep->getAllIndexIDs(); |
| size_t i; |
| for (i=0; i<indexIDs.size(); ++i) { |
| Type t = ixRep->getTypeForIndex(indexIDs[i]); |
| FSIndex ix = ixRep->getIndex(indexIDs[i], t); |
| FSIterator it = ix.iterator(); |
| for (it.moveToFirst(); it.isValid(); it.moveToNext()) { |
| FeatureStructure fs = it.get(); |
| enqueueIndexed(fs, sofa); |
| } |
| } |
| |
| // enqueue the undefined index FSs |
| for (size_t i=0;i < ixRep->iv_undefinedindex.size(); i++ ) { |
| FeatureStructure fs = internal::FSPromoter::promoteFS(ixRep->iv_undefinedindex[i], iv_cas); |
| enqueueIndexed(fs, sofa); |
| } |
| } |
| |
| os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; |
| /////XCAS os << "<CAS>" << endl; |
| os << "<xmi:XMI " ; |
| //write nsURI and prefix |
| map<string, string>::iterator ite; |
| for (ite=nsUriToPrefixMap.begin(); ite != nsUriToPrefixMap.end(); ite++) { |
| os << "xmlns:" << ite->second << "=\"" << ite->first << "\" " ; |
| } |
| os << " xmi:version=\"2.0\">"; |
| // TODO: add schemaLocation if specified |
| |
| //Write a special instance of dummy type uima.cas.NULL, having xmi:id=0. |
| //This is needed to represent nulls in multi-valued references, which |
| //aren't natively supported in Ecore. |
| //?? XmlElementName * nullElement = uimaTypeName2XmiElementName("uima.cas.NULL"); //? |
| os << "<cas:NULL xmi:id=\"0\"/>"; |
| |
| // write out all enqueued FS |
| map<int, vector<int>*>::iterator it; |
| for (it = enqueuedFS.begin(); it != enqueuedFS.end(); it++) { |
| FeatureStructure fs = internal::FSPromoter::promoteFS((*it).first, iv_cas); |
| writeFSFlat(os, fs, (*it).second); |
| } |
| serializeOutOfTypeSystemElements(os); //encodes sharedData.getOutOfTypeSystemElements().size() elements |
| writeViews(os,iv_cas); |
| os << "</xmi:XMI>" << endl; |
| } |
| |
| // return true if the fs was not previously enqueued |
| bool XmiWriter::enqueueUnindexed(FeatureStructure const &fs) { |
| |
| vector<int> * indexes; |
| size_t tyfs = uima::internal::FSPromoter::demoteFS(fs); |
| indexes = enqueuedFS[tyfs]; |
| if (NULL != indexes) { |
| return false; |
| } |
| //cout << "enqueue new fs " << tyfs << " " << fs.getType().getName() << endl; |
| // new FS, enqueue it |
| indexes = new vector<int>; |
| enqueuedFS[tyfs] = indexes; |
| return true; |
| } |
| |
| |
| // return true if the fs was not previously enqueued |
| bool XmiWriter::enqueueUnindexed(int id) { |
| |
| vector<int> * indexes; |
| indexes = enqueuedFS[id]; |
| if (NULL != indexes) { |
| return false; |
| } |
| //cout << "enqueue new fs " << tyfs << " " << fs.getType().getName() << endl; |
| // new FS, enqueue it |
| indexes = new vector<int>; |
| enqueuedFS[id] = indexes; |
| return true; |
| } |
| |
| // return true if the fs was not previously enqueued |
| bool XmiWriter::enqueueIndexed(FeatureStructure const &fs, int sofa) { |
| vector<int> * indexes; |
| size_t tyfs = uima::internal::FSPromoter::demoteFS(fs); |
| indexes = enqueuedFS[tyfs]; |
| if (NULL != indexes) { |
| for (size_t i=0; i<indexes->size(); i++) { |
| if (sofa == indexes->at(i)) { |
| return false; |
| } |
| } |
| indexes->push_back(sofa); |
| enqueuedFS[tyfs] = indexes; |
| // and look for references |
| // currently this is done for every FS. |
| // This could be done more efficiently |
| // when enqueueing the incoming FS. |
| findReferencedFSs(fs, false); |
| return false; |
| } |
| // new FS, enqueue it and note the indexed Sofa |
| indexes = new vector<int>; |
| indexes->push_back(sofa); |
| enqueuedFS[tyfs] = indexes; |
| // and look for references |
| findReferencedFSs(fs, false); |
| return true; |
| } |
| |
| /** |
| * Enqueues all FS that are stored in the XmiSerializationSharedData's id map. |
| * This map is populated during the previous deserialization. This method |
| * is used to make sure that all incoming FS are echoed in the next |
| * serialization. |
| */ |
| void XmiWriter::enqueueIncoming() { |
| if (this->sharedData == NULL) |
| return; |
| vector<int> fsAddrs; |
| this->sharedData->getAllFsAddressesInIdMap(fsAddrs); |
| for (size_t i = 0; i < fsAddrs.size(); i++) { |
| enqueueUnindexed(fsAddrs.at(i)); |
| } |
| } |
| |
| /** |
| * Get the XMI ID to use for an FS. |
| * |
| * @param addr |
| * address of FS |
| * @return XMI ID. If addr == CASImpl.NULL, returns null |
| */ |
| int XmiWriter::getXmiId(int addr) { |
| |
| if (addr == 0) return 0; |
| if (sharedData != NULL) { |
| return this->sharedData->getXmiId(addr); |
| } else { |
| return addr; // in the absence of outside information, just use the FS address |
| } |
| } |
| |
| void XmiWriter::enqueueFSListElements(FeatureStructure const & fs) { |
| if (!fs.isValid()) { |
| return; |
| } |
| |
| ListFS curNode(fs); |
| map<int,int> visited; |
| while (!curNode.isEmpty()) { |
| int addr = internal::FSPromoter::demoteFS(curNode); |
| if (visited[addr] == addr) { |
| cerr << "Found Cycle truncating " << endl; |
| ResourceManager::getInstance().getLogger().logWarning("Found cycle in FSlist. Truncating."); |
| break; |
| } |
| visited[addr] = addr; |
| FeatureStructure head = curNode.getHead(); |
| if (head.isValid()) { |
| this->findReferencedFSs(head); |
| } |
| |
| curNode = curNode.getTail(); |
| } |
| } |
| |
| |
| string XmiWriter::listToString(FeatureStructure const & fs, char const * tag) { |
| stringstream str; |
| map<int,int> visited; |
| if (!fs.isValid()) { |
| return str.str(); |
| } |
| int typecode = internal::FSPromoter::demoteType(fs.getType()); |
| //cout << __LINE__ << " listToString() " << fs.getType().getName() << endl; |
| switch (typecode) { |
| case internal::gs_tyNEIntListType: { |
| IntListFS curNode(fs); |
| while (!curNode.isEmpty()) { |
| int head = curNode.getHead(); |
| str << head; |
| curNode = curNode.getTail(); |
| int addr = internal::FSPromoter::demoteFS(curNode); |
| if (visited[addr] == addr) { |
| cerr << "Found Cycle truncating " << endl; |
| ResourceManager::getInstance().getLogger().logWarning("Found cycle in Intlist. Truncating."); |
| break; |
| } |
| visited[addr] = addr; |
| if ( !curNode.isEmpty() ) { |
| str << " " ; |
| } |
| } |
| //cout << "intList contents " << str.str() << endl; |
| break; |
| } |
| case internal::gs_tyNEFloatListType: { |
| FloatListFS curNode(fs); |
| while (!curNode.isEmpty()) { |
| str << curNode.getHead(); |
| curNode = curNode.getTail(); |
| int addr = internal::FSPromoter::demoteFS(curNode); |
| if (visited[addr] == addr) { |
| cerr << "Found Cycle truncating " << endl; |
| ResourceManager::getInstance().getLogger().logWarning("Found cycle in FloatListFS. Truncating."); |
| break; |
| } |
| visited[addr] = addr; |
| if ( !curNode.isEmpty() ) { |
| str << " " ; |
| } |
| } |
| break; |
| } |
| case internal::gs_tyEListType: { |
| //cout << "listToString() Empty FSList SKIP" << endl; |
| break; |
| } |
| case internal::gs_tyFSListType: { |
| //cout << "listToString() FSList SKIP" << endl; |
| break; |
| } |
| case internal::gs_tyNEListType: { |
| //cout << "listToString() NonEmpty FSList" << endl; |
| ListFS curNode(fs); |
| while (!curNode.isEmpty()) { |
| int head = internal::FSPromoter::demoteFS(curNode.getHead()); |
| if (head == 0) { |
| //null value in list. Represent with "0". |
| // this may be null because the element was originally a reference to an |
| // out-of-typesystem FS, so chck the XmiSerializationSharedData |
| if (sharedData != NULL) { |
| int addr = internal::FSPromoter::demoteFS(curNode); |
| OotsElementData * oed = sharedData->getOutOfTypeSystemFeatures(addr); |
| if (oed != NULL) { |
| assert(oed->attributes.size() == 1); //only the head feature can possibly be here |
| XmlAttribute * attr = oed->attributes.at(0); |
| assert(attr->name.compare(CAS::FEATURE_BASE_NAME_HEAD)==0); |
| str << attr->value; |
| } |
| } else { |
| str << head; |
| } |
| } else { |
| int addr = internal::FSPromoter::demoteFS(curNode); |
| if (visited[addr] == addr) { |
| cerr << "Found Cycle truncating " << endl; |
| ResourceManager::getInstance().getLogger().logWarning("Found cycle in NEListFS. Truncating."); |
| break; |
| } |
| visited[addr] = addr; |
| str << getXmiId(head); |
| } |
| |
| curNode = curNode.getTail(); |
| if ( !curNode.isEmpty() ) { |
| str << " " ; |
| } |
| } |
| //cout << "FSListType content " << str.str() << endl; |
| break; |
| } |
| case internal::gs_tyNEStringListType: { |
| StringListFS curNode(fs); |
| UnicodeString ustr; |
| while (!curNode.isEmpty()) { |
| ///string head = curNode.getHead().asUTF8(); |
| ustr.setTo(""); |
| normalize(curNode.getHead(), ustr); |
| str << "<" << tag << ">" << ustr << "</" << tag << ">"; |
| curNode = curNode.getTail(); |
| int addr = internal::FSPromoter::demoteFS(curNode); |
| if (visited[addr] == addr) { |
| cerr << "Found Cycle truncating " << endl; |
| ResourceManager::getInstance().getLogger().logWarning("Found cycle in StringListFS. Truncating."); |
| break; |
| } |
| visited[addr] = addr; |
| if ( !curNode.isEmpty() ) { |
| str << " " ; |
| } |
| } |
| break; |
| } |
| default: { |
| cerr << "listToString() Invalid type " << fs.getType().getName() << endl; |
| ErrorInfo errInfo; |
| errInfo.setErrorId((TyErrorId)UIMA_ERR_RESOURCE_CORRUPTED); |
| ErrorMessage msg(UIMA_MSG_ID_EXC_XML_SAXPARSE_FATALERROR); |
| msg.addParam("listToString Invalid List type."); |
| msg.addParam(tag); |
| errInfo.setMessage(msg); |
| errInfo.setSeverity(ErrorInfo::unrecoverable); |
| ExcIllFormedInputError exc(errInfo); |
| throw exc; |
| } |
| } |
| return str.str(); |
| } |
| |
| |
| /** |
| * Serializes all of the out-of-typesystem elements that were recorded |
| * in the XmiSerializationSharedData during the last deserialization. |
| */ |
| void XmiWriter::serializeOutOfTypeSystemElements(ostream & os) { |
| if (this->sharedData == NULL) |
| return; |
| vector<OotsElementData*> & ootsList = this->sharedData->getOutOfTypeSystemElements(); |
| for (size_t i=0; i < ootsList.size();i++) { |
| OotsElementData * oed = ootsList.at(i); |
| os << " <" << oed->elementName->qualifiedName; |
| os << " " << ID_ATTR_NAME << "=\"" << oed->xmiId << "\""; |
| // Add other attributes |
| for (size_t a=0; a < oed->attributes.size();a++) { |
| XmlAttribute * attr = oed->attributes.at(a); |
| icu::UnicodeString us; |
| icu::UnicodeString av(attr->value.c_str()); |
| normalize( av, us ); |
| os << " " << attr->name << "=\"" << us << "\""; |
| } |
| if (oed->childElements.size() > 0) { |
| os << ">"; |
| //serialize features encoded as child elements |
| map<string, vector<string>*>::iterator ite; |
| for (ite = oed->childElements.begin(); ite != oed->childElements.end();ite++ ) { |
| vector<string> * values = ite->second; |
| for (size_t v=0; v < values->size(); v++) { |
| icu::UnicodeString us; |
| icu::UnicodeString av(values->at(v).c_str()); |
| normalize( av, us ); |
| os << " <" << ite->first << ">"; |
| os << us; |
| os << "</" << ite->first << ">"; |
| } |
| } |
| os << "</" << oed->elementName->qualifiedName << ">"; |
| } else { |
| os << "/>"; |
| } |
| } |
| |
| } |
| |
| char const * XmiWriter::XMI_NS_URI = "http://www.omg.org/XMI"; |
| char const * XmiWriter::XMI_NS_PREFIX = "xmi"; |
| char const * XmiWriter::DEFAULT_NAMESPACE_URI = "http:///uima/noNamespace.ecore"; |
| |
| char const * XmiWriter::XSI_NS_URI= "http://www.w3.org/2001/XMLSchema-instance"; |
| char const * XmiWriter::XMI_TAG_LOCAL_NAME = "XMI"; |
| char const * XmiWriter::XMI_TAG_QNAME = "xmi:XMI"; |
| char const * XmiWriter::INDEXED_ATTR_NAME = "_indexed"; |
| char const * XmiWriter::ID_ATTR_NAME = "xmi:id"; |
| char const * XmiWriter::XMI_VERSION_LOCAL_NAME = "version"; |
| char const * XmiWriter::XMI_VERSION_QNAME = "xmi:version"; |
| char const * XmiWriter::XMI_VERSION_VALUE = "2.0"; |
| |
| } |
| |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Implementation */ |
| /* ----------------------------------------------------------------------- */ |
| |
| |
| /* ----------------------------------------------------------------------- */ |
| |
| |
| |
| |
| |
| |
| |
| |