1 /* $Id: moduleset.cpp 545959 2017-09-12 17:04:06Z gouriano $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Eugene Vasilchenko
27 *
28 * File Description:
29 * Set of modules: equivalent of ASN.1 source file
30 *
31 */
32
33 #include <ncbi_pch.hpp>
34 #include <corelib/ncbiapp.hpp>
35 #include <corelib/ncbiargs.hpp>
36 #include <corelib/ncbifile.hpp>
37 #include <typeinfo>
38 #include "moduleset.hpp"
39 #include "module.hpp"
40 #include "type.hpp"
41 #include "exceptions.hpp"
42 #include "fileutil.hpp"
43 #include <serial/error_codes.hpp>
44
45
46 #define NCBI_USE_ERRCODE_X Serial_Modules
47
48 BEGIN_NCBI_SCOPE
49
CFileModules(const string & name)50 CFileModules::CFileModules(const string& name)
51 : m_SourceFileName(name)
52 {
53 }
54
AddModule(const AutoPtr<CDataTypeModule> & module)55 void CFileModules::AddModule(const AutoPtr<CDataTypeModule>& module)
56 {
57 module->SetModuleContainer(this);
58 CDataTypeModule*& mptr = m_ModulesByName[module->GetName()];
59 if ( mptr ) {
60 ERR_POST_X(4, GetSourceFileName() << ": duplicate module: " <<
61 module->GetName());
62 }
63 else {
64 mptr = module.get();
65 m_Modules.push_back(module);
66 }
67 }
68
Check(void) const69 bool CFileModules::Check(void) const
70 {
71 bool ok = true;
72 ITERATE ( TModules, mi, m_Modules ) {
73 if ( !(*mi)->Check() )
74 ok = false;
75 }
76 return ok;
77 }
78
CheckNames(void) const79 bool CFileModules::CheckNames(void) const
80 {
81 bool ok = true;
82 ITERATE ( TModules, mi, m_Modules ) {
83 if ( !(*mi)->CheckNames() )
84 ok = false;
85 }
86 return ok;
87 }
88
PrintSampleDEF(const string & rootdir) const89 void CFileModules::PrintSampleDEF(const string& rootdir) const
90 {
91 ITERATE ( TModules, mi, m_Modules ) {
92 string fileName = MakeAbsolutePath(
93 Path(rootdir, Path(GetFileNamePrefix(), (*mi)->GetName() + "._sample_def")));
94 CNcbiOfstream out(fileName.c_str());
95 (*mi)->PrintSampleDEF(out);
96 if ( !out )
97 ERR_POST_X(5, Fatal << "Cannot write to file "<<fileName);
98 }
99 }
100
PrintASN(CNcbiOstream & out) const101 void CFileModules::PrintASN(CNcbiOstream& out) const
102 {
103 ITERATE ( TModules, mi, m_Modules ) {
104 PrintASNRefInfo(out);
105 (*mi)->PrintASN(out);
106 }
107 m_LastComments.PrintASN(out, 0, CComments::eMultiline);
108 }
109
PrintSpecDump(CNcbiOstream & out) const110 void CFileModules::PrintSpecDump(CNcbiOstream& out) const
111 {
112 ITERATE ( TModules, mi, m_Modules ) {
113 out << "M," << mi->get()->GetSourceLine() << ',';
114 out << CDirEntry(m_SourceFileName).GetName() << ':'
115 << (*mi)->GetName();
116 (*mi)->PrintSpecDump(out);
117 }
118 }
119
PrintJSONSchema(CNcbiOstream & out) const120 void CFileModules::PrintJSONSchema(CNcbiOstream& out) const
121 {
122 ITERATE ( TModules, mi, m_Modules ) {
123 (*mi)->PrintJSONSchema(out);
124 }
125 }
126
127 // XML schema generator submitted by
128 // Marc Dumontier, Blueprint initiative, dumontier@mshri.on.ca
PrintXMLSchema(CNcbiOstream & out) const129 void CFileModules::PrintXMLSchema(CNcbiOstream& out) const
130 {
131 BeginXMLSchema(out);
132 ITERATE ( TModules, mi, m_Modules ) {
133 (*mi)->PrintXMLSchema(out);
134 }
135 m_LastComments.PrintDTD(out, CComments::eMultiline);
136 EndXMLSchema(out);
137 }
138
GetRefInfo(list<string> & info) const139 void CFileModules::GetRefInfo(list<string>& info) const
140 {
141 info.clear();
142 string s, h("::DATATOOL:: ");
143 s = h + "Generated from \"" + GetSourceFileName() + "\"";
144 info.push_back(s);
145 s = h + "by application DATATOOL version ";
146 s += CNcbiApplication::Instance()->GetVersion().Print();
147 info.push_back(s);
148 s = h + "on " + CTime(CTime::eCurrent).AsString();
149 info.push_back(s);
150 }
151
PrintASNRefInfo(CNcbiOstream & out) const152 void CFileModules::PrintASNRefInfo(CNcbiOstream& out) const
153 {
154 list<string> info;
155 GetRefInfo(info);
156 out << "-- ============================================\n";
157 ITERATE(list<string>, i, info) {
158 out << "-- " << *i << "\n";
159 }
160 out << "-- ============================================\n\n";
161 }
162
PrintXMLRefInfo(CNcbiOstream & out) const163 void CFileModules::PrintXMLRefInfo(CNcbiOstream& out) const
164 {
165 list<string> info;
166 GetRefInfo(info);
167 out << "<!-- ============================================\n";
168 ITERATE(list<string>, i, info) {
169 out << " " << *i << "\n";
170 }
171 out << " ============================================ -->\n\n";
172 }
173
PrintDTD(CNcbiOstream & out) const174 void CFileModules::PrintDTD(CNcbiOstream& out) const
175 {
176 ITERATE ( TModules, mi, m_Modules ) {
177 PrintXMLRefInfo(out);
178 (*mi)->PrintDTD(out);
179 }
180 m_LastComments.PrintDTD(out, CComments::eMultiline);
181 }
182
PrintDTDModular(void) const183 void CFileModules::PrintDTDModular(void) const
184 {
185 ITERATE ( TModules, mi, m_Modules ) {
186 string fileNameBase = MakeAbsolutePath(
187 (*mi)->GetDTDFileNameBase() + (*mi)->GetModuleFileSuffix());
188 {
189 string fileName = fileNameBase + ".mod.dtd";
190 CNcbiOfstream out(fileName.c_str());
191 PrintXMLRefInfo(out);
192 (*mi)->PrintDTD(out);
193 if ( !out )
194 ERR_POST_X(5, Fatal << "Cannot write to file "<<fileName);
195 }
196 {
197 string fileName = fileNameBase + ".dtd";
198 CNcbiOfstream out(fileName.c_str());
199 PrintXMLRefInfo(out);
200 (*mi)->PrintDTDModular(out);
201 if ( !out )
202 ERR_POST_X(6, Fatal << "Cannot write to file "<<fileName);
203 }
204 }
205 }
206
PrintXMLSchemaModular(void) const207 void CFileModules::PrintXMLSchemaModular(void) const
208 {
209 ITERATE ( TModules, mi, m_Modules ) {
210 string fileNameBase = MakeAbsolutePath(
211 (*mi)->GetDTDFileNameBase() + (*mi)->GetModuleFileSuffix());
212 {
213 string fileName = fileNameBase + ".mod.xsd";
214 CNcbiOfstream out(fileName.c_str());
215 if ( !out )
216 ERR_POST_X(7, Fatal << "Cannot write to file "<<fileName);
217 BeginXMLSchema(out);
218 (*mi)->PrintXMLSchema(out);
219 EndXMLSchema(out);
220 }
221 {
222 string fileName = fileNameBase + ".xsd";
223 CNcbiOfstream out(fileName.c_str());
224 if ( !out )
225 ERR_POST_X(8, Fatal << "Cannot write to file "<<fileName);
226 BeginXMLSchema(out);
227 (*mi)->PrintXMLSchemaModular(out);
228 EndXMLSchema(out);
229 }
230 }
231 }
232
BeginXMLSchema(CNcbiOstream & out) const233 void CFileModules::BeginXMLSchema(CNcbiOstream& out) const
234 {
235 string nsName("http://www.ncbi.nlm.nih.gov");
236 string nsNcbi(nsName);
237 string elementForm("qualified");
238 string attributeForm("unqualified");
239 if (!m_Modules.empty()) {
240 const CDataTypeModule::TDefinitions& defs =
241 m_Modules.front()->GetDefinitions();
242 if (!defs.empty()) {
243 const string& ns = defs.front().second->GetNamespaceName();
244 if (!ns.empty()) {
245 nsName = ns;
246 }
247 if (defs.front().second->IsNsQualified() == eNSUnqualified) {
248 elementForm = "unqualified";
249 }
250 }
251 }
252 const CArgs& args = CNcbiApplication::Instance()->GetArgs();
253 if ( const CArgValue& px_ns = args["xmlns"] ) {
254 nsName = px_ns.AsString();
255 }
256 out << "<?xml version=\"1.0\" ?>\n";
257 PrintXMLRefInfo(out);
258 out << "<xs:schema\n"
259 << " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n"
260 << " xmlns:ncbi=\"" << nsNcbi << "\"\n";
261 if (!nsName.empty()) {
262 out << " xmlns=\"" << nsName << "\"\n"
263 << " targetNamespace=\"" << nsName << "\"\n";
264 }
265 out << " elementFormDefault=\"" << elementForm << "\"\n"
266 << " attributeFormDefault=\"" << attributeForm << "\">\n\n";
267 }
268
EndXMLSchema(CNcbiOstream & out) const269 void CFileModules::EndXMLSchema(CNcbiOstream& out) const
270 {
271 out << "</xs:schema>\n";
272 }
273
GetSourceFileName(void) const274 const string& CFileModules::GetSourceFileName(void) const
275 {
276 return m_SourceFileName;
277 }
278
GetFileNamePrefix(void) const279 string CFileModules::GetFileNamePrefix(void) const
280 {
281 if ( MakeFileNamePrefixFromSourceFileName() ) {
282 if ( m_PrefixFromSourceFileName.empty() ) {
283 m_PrefixFromSourceFileName = DirName(m_SourceFileName);
284 if ( !IsLocalPath(m_PrefixFromSourceFileName) ) {
285 // path absent or non local
286 m_PrefixFromSourceFileName.erase();
287 return GetModuleContainer().GetFileNamePrefix();
288 }
289 }
290 _TRACE("file " << m_SourceFileName << ": \"" << m_PrefixFromSourceFileName << "\"");
291 if ( UseAllFileNamePrefixes() ) {
292 return Path(GetModuleContainer().GetFileNamePrefix(),
293 m_PrefixFromSourceFileName);
294 }
295 else {
296 return m_PrefixFromSourceFileName;
297 }
298 }
299 return GetModuleContainer().GetFileNamePrefix();
300 }
301
ExternalResolve(const string & moduleName,const string & typeName,bool allowInternal) const302 CDataType* CFileModules::ExternalResolve(const string& moduleName,
303 const string& typeName,
304 bool allowInternal) const
305 {
306 // find module definition
307 TModulesByName::const_iterator mi = m_ModulesByName.find(moduleName);
308 if ( mi == m_ModulesByName.end() ) {
309 // no such module
310 NCBI_THROW(CNotFoundException,eModule,
311 "module not found: "+moduleName+" for type "+typeName);
312 }
313 return mi->second->ExternalResolve(typeName, allowInternal);
314 }
315
ResolveInAnyModule(const string & typeName,bool allowInternal) const316 CDataType* CFileModules::ResolveInAnyModule(const string& typeName,
317 bool allowInternal) const
318 {
319 CResolvedTypeSet types(typeName);
320 ITERATE ( TModules, i, m_Modules ) {
321 try {
322 types.Add((*i)->ExternalResolve(typeName, allowInternal));
323 }
324 catch ( CAmbiguiousTypes& exc ) {
325 types.Add(exc);
326 }
327 catch ( CNotFoundException& /* ignored */) {
328 }
329 }
330 return types.GetType();
331 }
332
CollectAllTypeinfo(set<TTypeInfo> & types) const333 void CFileModules::CollectAllTypeinfo(set<TTypeInfo>& types) const
334 {
335 ITERATE ( TModules, i, m_Modules ) {
336 (*i)->CollectAllTypeinfo(types);
337 }
338 }
339
AddFile(const AutoPtr<CFileModules> & moduleSet)340 void CFileSet::AddFile(const AutoPtr<CFileModules>& moduleSet)
341 {
342 moduleSet->SetModuleContainer(this);
343 m_ModuleSets.push_back(moduleSet);
344 }
345
PrintSampleDEF(const string & rootdir) const346 void CFileSet::PrintSampleDEF(const string& rootdir) const
347 {
348 ITERATE ( TModuleSets, i, m_ModuleSets ) {
349 (*i)->PrintSampleDEF(rootdir);
350 }
351 }
352
PrintASN(CNcbiOstream & out) const353 void CFileSet::PrintASN(CNcbiOstream& out) const
354 {
355 ITERATE ( TModuleSets, i, m_ModuleSets ) {
356 (*i)->PrintASN(out);
357 }
358 }
359
PrintSpecDump(CNcbiOstream & out) const360 void CFileSet::PrintSpecDump(CNcbiOstream& out) const
361 {
362 ITERATE ( TModuleSets, i, m_ModuleSets ) {
363 (*i)->PrintSpecDump(out);
364 }
365 }
366
PrintJSONSchema(CNcbiOstream & out) const367 void CFileSet::PrintJSONSchema(CNcbiOstream& out) const
368 {
369 ITERATE ( TModuleSets, i, m_ModuleSets ) {
370 (*i)->PrintJSONSchema(out);
371 }
372 }
373
374 // XML schema generator submitted by
375 // Marc Dumontier, Blueprint initiative, dumontier@mshri.on.ca
PrintXMLSchema(CNcbiOstream & out) const376 void CFileSet::PrintXMLSchema(CNcbiOstream& out) const
377 {
378 ITERATE ( TModuleSets, i, m_ModuleSets ) {
379 (*i)->PrintXMLSchema(out);
380 }
381 }
382
PrintDTD(CNcbiOstream & out) const383 void CFileSet::PrintDTD(CNcbiOstream& out) const
384 {
385 #if 0
386 out <<
387 "<!-- ======================== -->\n"
388 "<!-- NCBI DTD -->\n"
389 "<!-- NCBI ASN.1 mapped to XML -->\n"
390 "<!-- ======================== -->\n"
391 "\n"
392 "<!-- Entities used to give specificity to #PCDATA -->\n"
393 "<!ENTITY % INTEGER '#PCDATA'>\n"
394 "<!ENTITY % ENUM 'EMPTY'>\n"
395 "<!ENTITY % BOOLEAN 'EMPTY'>\n"
396 "<!ENTITY % NULL 'EMPTY'>\n"
397 "<!ENTITY % REAL '#PCDATA'>\n"
398 "<!ENTITY % OCTETS '#PCDATA'>\n"
399 "<!-- ============================================ -->\n"
400 "\n";
401 #endif
402 ITERATE ( TModuleSets, i, m_ModuleSets ) {
403 (*i)->PrintDTD(out);
404 }
405 }
406
PrintDTDModular(void) const407 void CFileSet::PrintDTDModular(void) const
408 {
409 ITERATE ( TModuleSets, i, m_ModuleSets ) {
410 (*i)->PrintDTDModular();
411 }
412 }
413
PrintXMLSchemaModular(void) const414 void CFileSet::PrintXMLSchemaModular(void) const
415 {
416 ITERATE ( TModuleSets, i, m_ModuleSets ) {
417 (*i)->PrintXMLSchemaModular();
418 }
419 }
420
ExternalResolve(const string & module,const string & name,bool allowInternal) const421 CDataType* CFileSet::ExternalResolve(const string& module, const string& name,
422 bool allowInternal) const
423 {
424 CResolvedTypeSet types(module, name);
425 ITERATE ( TModuleSets, i, m_ModuleSets ) {
426 try {
427 types.Add((*i)->ExternalResolve(module, name, allowInternal));
428 }
429 catch ( CAmbiguiousTypes& exc ) {
430 types.Add(exc);
431 }
432 catch ( CNotFoundException& /* ignored */) {
433 }
434 }
435 return types.GetType();
436 }
437
ResolveInAnyModule(const string & name,bool allowInternal) const438 CDataType* CFileSet::ResolveInAnyModule(const string& name,
439 bool allowInternal) const
440 {
441 CResolvedTypeSet types(name);
442 ITERATE ( TModuleSets, i, m_ModuleSets ) {
443 try {
444 types.Add((*i)->ResolveInAnyModule(name, allowInternal));
445 }
446 catch ( CAmbiguiousTypes& exc ) {
447 types.Add(exc);
448 }
449 catch ( CNotFoundException& /* ignored */) {
450 }
451 }
452 return types.GetType();
453 }
454
Check(void) const455 bool CFileSet::Check(void) const
456 {
457 bool ok = true;
458 ITERATE ( TModuleSets, mi, m_ModuleSets ) {
459 if ( !(*mi)->Check() )
460 ok = false;
461 }
462 return ok;
463 }
464
CheckNames(void) const465 bool CFileSet::CheckNames(void) const
466 {
467 bool ok = true;
468 ITERATE ( TModuleSets, mi, m_ModuleSets ) {
469 if ( !(*mi)->CheckNames() )
470 ok = false;
471 }
472 return ok;
473 }
474
CollectAllTypeinfo(set<TTypeInfo> & types) const475 void CFileSet::CollectAllTypeinfo(set<TTypeInfo>& types) const
476 {
477 ITERATE ( TModuleSets, i, m_ModuleSets ) {
478 (*i)->CollectAllTypeinfo(types);
479 }
480 }
481
482 END_NCBI_SCOPE
483