Project

General

Profile

Statistics
| Branch: | Revision:

root / src / nedxml / nedresourcecache.h @ c87b95b0

History | View | Annotate | Download (8.15 KB)

1
//==========================================================================
2
// NEDRESOURCECACHE.H -
3
//
4
//                     OMNeT++/OMNEST
5
//            Discrete System Simulation in C++
6
//
7
//==========================================================================
8

    
9
/*--------------------------------------------------------------*
10
  Copyright (C) 2002-2008 Andras Varga
11
  Copyright (C) 2006-2008 OpenSim Ltd.
12

13
  This file is distributed WITHOUT ANY WARRANTY. See the file
14
  `license' for details on this and other legal matters.
15
*--------------------------------------------------------------*/
16

    
17

    
18
#ifndef __NEDRESOURCECACHE_H
19
#define __NEDRESOURCECACHE_H
20

    
21
#include <map>
22
#include <vector>
23
#include <string>
24
#include "nedelements.h"
25
#include "nedtypeinfo.h"
26

    
27
NAMESPACE_BEGIN
28

    
29

    
30
/**
31
 * Context of NED type lookup
32
 */
33
struct NEDLookupContext
34
{
35
    NEDElement *element;  // compound module or NED file
36
    std::string qname;    // fully qualified name, or (for NED files) package name
37
    NEDLookupContext(NEDElement *e, const char *q) {element=e;qname=q;}
38
};
39

    
40
/**
41
 * Stores loaded NED files, and keeps track of components in them.
42
 *
43
 * This class can be turned into a cache (discarding and reloading
44
 * NED files on demand) if such need arises.
45
 *
46
 * @ingroup NEDResources
47
 */
48
class NEDXML_API NEDResourceCache
49
{
50
  public:
51
      /** Interface that enumerates NED types; used by resolveType() */
52
      class INEDTypeNames {
53
        public:
54
          /** Returns true if the given fully qualified name is an existing NED type */
55
          virtual bool contains(const char *qname) const = 0;
56

    
57
          /** Returns the number of NED type names */
58
          virtual int size() const = 0;
59

    
60
          /** Returns the kth fully qualified NED type name */
61
          virtual const char *get(int k) const = 0;
62

    
63
          virtual ~INEDTypeNames() {}  // make the compiler happy
64
      };
65

    
66
      class CachedTypeNames : public INEDTypeNames {
67
        protected:
68
          NEDResourceCache *p;
69
        public:
70
          CachedTypeNames(NEDResourceCache *p) {this->p=p;}
71
          virtual bool contains(const char *qname) const {return p->lookup(qname)!=NULL;}
72
          virtual int size() const {return p->getTypeNames().size();}
73
          virtual const char *get(int k) const {return p->getTypeNames()[k].c_str();}
74
      };
75

    
76
  protected:
77
    typedef std::map<std::string, NEDElement *> NEDFileMap;
78
    typedef std::map<std::string, NEDTypeInfo *> NEDTypeInfoMap;
79

    
80
    // table of loaded NED files; maps file name to NED element.
81
    NEDFileMap files;
82

    
83
    // table of NED type declarations; key is fully qualified name, and
84
    // elements point into the files map
85
    NEDTypeInfoMap nedTypes;
86

    
87
    // cached keys of the nedTypes map, for getTypeNames(); zero size means out of date
88
    mutable std::vector<std::string> nedTypeNames;
89

    
90
    // maps the loaded source NED folders (as absolute paths, canonical representation)
91
    // to package names
92
    typedef std::map<std::string,std::string> StringMap;
93
    StringMap folderPackages;
94

    
95
    struct PendingNedType {
96
        std::string qname;
97
        bool isInnerType;
98
        NEDElement *node;
99
        PendingNedType(const char *q, bool inner, NEDElement *e) {qname=q;isInnerType=inner;node=e;}
100
    };
101

    
102
    // storage for NED components not resolved yet because of missing dependencies
103
    std::vector<PendingNedType> pendingList;
104

    
105
  protected:
106
    virtual void registerBuiltinDeclarations();
107
    virtual int doLoadNedSourceFolder(const char *foldername, const char *expectedPackage);
108
    virtual void doLoadNedFileOrText(const char *nedfname, const char *nedtext, const char *expectedPackage, bool isXML);
109
    virtual NEDElement *parseAndValidateNedFileOrText(const char *nedfname, const char *nedtext, bool isXML);
110
    virtual std::string determineRootPackageName(const char *nedSourceFolderName);
111
    virtual std::string getNedSourceFolderForFolder(const char *folder) const;
112
    virtual void collectNedTypesFrom(NEDElement *node, const std::string& namespacePrefix, bool areInnerTypes);
113
    virtual void collectNedType(const char *qname, bool isInnerType, NEDElement *node);
114
    virtual bool areDependenciesResolved(const char *qname, NEDElement *node);
115
    virtual void registerPendingNedTypes();
116
    virtual void registerNedType(const char *qname, bool isInnerType, NEDElement *node);
117

    
118
  public:
119
    /** Constructor */
120
    NEDResourceCache();
121

    
122
    /** Destructor */
123
    virtual ~NEDResourceCache();
124

    
125
    /**
126
     * Load all NED files from a NED source folder. This involves visiting
127
     * each subdirectory, and loading all "*.ned" files from there.
128
     * The given folder is assumed to be the root of the NED package hierarchy.
129
     * Returns the number of files loaded.
130
     *
131
     * Note: doneLoadingNedFiles() must be called after the last
132
     * loadNedSourceFolder()/loadNedFile()/loadNedText() call.
133
     */
134
    virtual int loadNedSourceFolder(const char *foldername);
135

    
136
    /**
137
     * Load a single NED file. If the expected package is given (non-NULL),
138
     * it should match the package declaration inside the NED file.
139
     *
140
     * Note: doneLoadingNedFiles() must be called after the last
141
     * loadNedSourceFolder()/loadNedFile()/loadNedText() call.
142
     */
143
    virtual void loadNedFile(const char *nedfname, const char *expectedPackage, bool isXML);
144

    
145
    /**
146
     * Parses and loads the NED source code passed in the nedtext argument.
147
     * The name argument will be used as filename in error messages, and
148
     * and should be unique among the files loaded. If the expected package
149
     * is given (non-NULL), it should match the package declaration inside
150
     * the NED file.
151
     *
152
     * Note: doneLoadingNedFiles() must be called after the last
153
     * loadNedSourceFolder()/loadNedFile()/loadNedText() call.
154
     */
155
    virtual void loadNedText(const char *name, const char *nedtext, const char *expectedPackage, bool isXML);
156

    
157
    /**
158
     * To be called after all NED folders / files have been loaded. May be
159
     * redefined to issue errors for components that could not be fully
160
     * resolved because of missing base types or interfaces.
161
     */
162
    virtual void doneLoadingNedFiles();
163

    
164
    /**
165
     * Add a file (parsed into an object tree) to the cache. If the file
166
     * was already added, no processing takes place and the function
167
     * returns false; otherwise it returns true.
168
     */
169
    virtual bool addFile(const char *fname, NEDElement *node);  //XXX make protected?
170

    
171
    /** Get a file (represented as object tree) from the cache */
172
    virtual NEDElement *getFile(const char *fname) const;
173

    
174
    /**
175
     * Given a NED file, returns the package.ned file from the same folder,
176
     * or the nearest ancestor package.ned file. If the file is a package.ned
177
     * file itself, returns the nearest ancestor package.ned file. Returns NULL
178
     * if there is no parent package.ned file.
179
     */
180
    virtual NedFileElement *getParentPackageNedFile(NedFileElement *nedfile) const;
181

    
182
    /** Look up a fully qualified NED type name from the cache. Returns NULL if not found. */
183
    virtual NEDTypeInfo *lookup(const char *qname) const;
184

    
185
    /** Like lookup(), but asserts non-NULL return value */
186
    virtual NEDTypeInfo *getDecl(const char *qname) const;
187

    
188
    /** Resolves the given NED type name in the given context, among the given type names. Returns "" if not found. */
189
    virtual std::string resolveNedType(const NEDLookupContext& context, const char *nedtypename, INEDTypeNames *qnames);
190

    
191
    /** Resolves NED type name, based on the NED files loaded */
192
    virtual std::string resolveNedType(const NEDLookupContext& context, const char *nedtypename) {
193
        NEDResourceCache::CachedTypeNames names(this);
194
        return NEDResourceCache::resolveNedType(context, nedtypename, &names);
195
    }
196

    
197
    /** Available NED type names */
198
    virtual const std::vector<std::string>& getTypeNames() const;
199

    
200
    /**
201
     * Returns the NED package that corresponds to the given folder. Returns ""
202
     * for the default package, and "-" if the folder is outside all NED folders.
203
     */
204
    virtual std::string getNedPackageForFolder(const char *folder) const;
205

    
206
    /**
207
     * Utility method, useful with resolveNedType()/resolveComponentType()
208
     */
209
    static NEDLookupContext getParentContextOf(const char *qname, NEDElement *node);
210

    
211
};
212

    
213
NAMESPACE_END
214

    
215

    
216
#endif
217