blob: 7615e93410a87638b53c6d908e347e0fb6b6d74c [file] [log] [blame]
/** \file dottypesystemwriter.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:
-----------------------------------------------------------------------------
09/20/2002 Initial creation
-------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Include dependencies */
/* ----------------------------------------------------------------------- */
#include "uima/pragmas.hpp"
#include "uima/dottypesystemwriter.hpp"
#include "uima/timedatetools.hpp"
#include "unicode/ustring.h"
#include "uima/unistrref.hpp"
#include "uima/typesystem.hpp"
#include "uima/cas.hpp"
#include <time.h>
#ifdef _MSC_VER
#include <minmax.h> // for min
#endif
/* ----------------------------------------------------------------------- */
/* Constants */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Forward declarations */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */
/* Types / Classes */
/* ----------------------------------------------------------------------- */
using namespace std;
namespace uima {
const size_t cuiINDENT = 3;
std::string
currDateString() {
time_t ltime;
(void)time(&ltime); //get time, ignore return value
const size_t uiMAXSTR = 64;
char pszDate[uiMAXSTR];
strftime(pszDate, uiMAXSTR, "%x", localtime(&ltime));
string t(pszDate);
return t; //time string
}
UnicodeStringRef adjustTypeName(UnicodeStringRef ulstrName) {
icu::UnicodeString ustrTypePfx( "uima" ); // Our namespace
ustrTypePfx.append( (UChar) uima::TypeSystem::NAMESPACE_SEPARATOR );
if (u_strncmp(ulstrName.getBuffer(), ustrTypePfx.getBuffer(), min(ulstrName.length(), ustrTypePfx.length())) == 0) {
ulstrName = UnicodeStringRef(ulstrName.getBuffer() + ustrTypePfx.length(),
ulstrName.length()- ustrTypePfx.length());
}
return ulstrName;
}
UnicodeStringRef adjustFeatName(UnicodeStringRef ulstrName) {
return ulstrName;
}
DotTypeSystemWriter::DotTypeSystemWriter(CAS const & crCAS, bool bNoCASTypes, bool bOnlyCASTypes ) :
iv_crCAS(crCAS),
iv_bNoCASTypes(bNoCASTypes),
iv_bOnlyCASTypes(bOnlyCASTypes) {}
static inline bool isCasType(uima::Type const & crType) {
return crType.getName().startsWith(icu::UnicodeString("uima.cas." ))
|| crType.getName().startsWith(icu::UnicodeString("uima.tcas."));
}
void DotTypeSystemWriter::writeType(ostream & os, uima::Type const & crType, size_t uiIndent) const {
if (iv_bOnlyCASTypes &&
(crType != crType.getTypeSystem().getTopType()) && (!isCasType(crType))) {
return;
}
if (iv_bNoCASTypes && isCasType(crType)) {
return;
}
string strIndentString(uiIndent, ' ');
os << strIndentString;
os << adjustTypeName(crType.getName())
<< "[label=\"" << adjustTypeName(crType.getName());
vector<Feature> features;
crType.getAppropriateFeatures(features);
size_t i;
for (i=0; i<features.size(); ++i) {
assert( features[i].isValid());
// print only features which are introduced at this type
Type introType;
features[i].getIntroType(introType);
assert( introType.isValid() );
if (introType == crType) {
Type range;
features[i].getRangeType(range);
assert( range.isValid());
os << "|{" << adjustFeatName(features[i].getName()) << ": " << adjustTypeName(range.getName()) << "}";
}
}
os << "\"];" << endl;
vector<Type> subTypes;
crType.getDirectSubTypes(subTypes);
if (subTypes.size() > 0) {
// print <typename> -> {<sub-type1>, <sub-type2>, ...};
os << strIndentString;
os << adjustTypeName(crType.getName()) << " -> {";
size_t uiTypesWritten = 0;
for (i=0; i<subTypes.size(); ++i) {
if (iv_bOnlyCASTypes && !isCasType(subTypes[i]) ) {
continue;
}
if (iv_bNoCASTypes && isCasType(subTypes[i]) ) {
continue;
}
if (uiTypesWritten > 0 ) {
os << "; ";
}
os << adjustTypeName(subTypes[i].getName());
++uiTypesWritten;
}
os << "};" << endl;
}
for (i=0; i<subTypes.size(); ++i) {
writeType(os, subTypes[i], uiIndent+cuiINDENT);
}
}
void DotTypeSystemWriter::write(std::ostream & os) const {
os << "digraph G {\n"
" graph [rankdir=LR];\n"
" label=\" Type\\n Hierarchy\\n " <<
currDateString() << "\";\n";
os << " fontsize=24;\n"
" fontname=Helvetica;\n"
" color=white;\n"
" node [shape=Mrecord, /*style=bold, */ fontsize=10, width=2.4, height=.28];\n";
Type top = iv_crCAS.getTypeSystem().getTopType();
writeType(os, top, cuiINDENT);
os << "}" << endl;
}
} // namespace uima
/* ----------------------------------------------------------------------- */
/* Implementation */
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */