1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """A package to manipulate elements from the Advene model.
20 """
21
22 import os
23 import sys
24 import urllib
25 import re
26
27 import xml.sax
28
29 import util.uri
30
31 from util.auto_properties import auto_properties
32
33 import advene.core.config as config
34 import _impl
35 import advene.model.annotation as annotation
36 import advene.model.modeled as modeled
37 import advene.model.query as query
38 import advene.model.schema as schema
39 import advene.model.view as view
40 import advene.model.viewable as viewable
41 from advene.model.zippackage import ZipPackage
42 from advene.util.expat import PyExpat
43
44 from advene.model.bundle import StandardXmlBundle, ImportBundle, InverseDictBundle, SumBundle
45 from advene.model.constants import *
46 from advene.model.exception import AdveneException
47
48
49
50
51
52 _get_from_uri = object()
53
54 -class Package(modeled.Modeled, viewable.Viewable.withClass('package'),
55 _impl.Authored, _impl.Dated, _impl.Titled,
56 annotation.AnnotationFactory,
57 annotation.RelationFactory,
58 schema.SchemaFactory,
59 query.QueryFactory,
60 view.ViewFactory,
61 ):
62
63 """A package is the container of all the elements of an annotation
64 (schemas, types, annotations, relations, views, queries). It
65 provides factory methods to create attached annotations, views, ..."""
66
67 __metaclass__ = auto_properties
68
70 """Calling the constructor with just a URI tries to read the package
71 from this URI. This can be overidden by providing explicitly the
72 source parameter (a URL or a stream).
73 Providing None for the source parameter creates a new Package.
74 """
75 self.meta_cache={}
76 if isinstance(uri, unicode):
77 uri=uri.encode(sys.getfilesystemencoding())
78 if re.match('[a-zA-Z]:', uri):
79
80
81 uri=urllib.pathname2url(uri)
82 self.__uri = uri
83 self.__importer = importer
84
85 self.__zip = None
86 abs_uri = self.getUri (absolute=True)
87
88 if importer:
89 importer.__pkg_cache[abs_uri] = self
90 self.__pkg_cache = importer.__pkg_cache
91 else:
92 self.__pkg_cache = {abs_uri:self}
93
94 element = None
95 if source is None:
96 element = self._make_model()
97 else:
98 reader = PyExpat.Reader()
99 if source is _get_from_uri:
100
101
102 if abs_uri.lower().endswith('.azp') or abs_uri.endswith('/'):
103
104 self.__zip = ZipPackage(abs_uri)
105 f=urllib.pathname2url(self.__zip.getContentsFile())
106 element = reader.fromUri("file://" + f).documentElement
107 else:
108 element = reader.fromUri(abs_uri).documentElement
109 elif hasattr(source, 'read'):
110 element = reader.fromStream(source).documentElement
111 else:
112 if re.match('[a-zA-Z]:', source):
113
114
115 source=urllib.pathname2url(source)
116 source_uri = util.uri.urljoin (
117 'file:%s/' % urllib.pathname2url (os.getcwd ()),
118 str(source)
119 )
120
121 if source_uri.lower().endswith('.azp') or source_uri.endswith('/'):
122
123 self.__zip = ZipPackage(source_uri)
124 f=urllib.pathname2url(self.__zip.getContentsFile())
125 element = reader.fromUri("file://" + f).documentElement
126 else:
127 element = reader.fromUri(source_uri).documentElement
128
129 modeled.Modeled.__init__(self, element, None)
130
131 self.__imports = None
132 self.__annotations = None
133 self.__queries = None
134 self.__relations = None
135 self.__schemas = None
136 self.__views = None
137
139 if self.__zip:
140 self.__zip.close()
141 return
142
144 """Return a nice string representation of the object."""
145 return "Package (%s)" % self.__uri
146
148 """Build a new empty annotation model"""
149 di = xml.dom.DOMImplementation.DOMImplementation()
150 doc = di.createDocument(adveneNS, "package", None)
151
152 elt = doc.documentElement
153 elt.setAttributeNS(xmlNS, "xml:base", unicode(self.__uri))
154 elt.setAttributeNS(xmlnsNS, "xmlns", adveneNS)
155 elt.setAttributeNS(xmlnsNS, "xmlns:xlink", xlinkNS)
156 elt.setAttributeNS(xmlnsNS, "xmlns:dc", dcNS)
157 elt.setAttributeNS(dcNS, "dc:creator", "")
158
159 elt.appendChild(doc.createElementNS(adveneNS, "imports"))
160 elt.appendChild(doc.createElementNS(adveneNS, "annotations"))
161 elt.appendChild(doc.createElementNS(adveneNS, "queries"))
162 elt.appendChild(doc.createElementNS(adveneNS, "schemas"))
163 elt.appendChild(doc.createElementNS(adveneNS, "views"))
164 return elt
165
167 """Return a cached version of the package designated by "uri" """
168 return self.__pkg_cache.get(uri, None)
169
171 """Return this package. Used for breaking recursivity in the parenthood tree."""
172 return self
173
175 if self.__importer:
176 r = list(self.__importer.getAccessPath())
177 r.append(self)
178 return tuple(r)
179 else:
180 return (self,)
181
183 if self.__importer:
184 return self.__importer.getRootPackage()
185 else:
186 return self
187
188 - def getUri(self, absolute=True, context=None):
189 """
190 Return the URI of the package.
191
192 Parameter if _absolute_ is _True_, the URI will be forced absolute.
193 If not, and if _context_ is _None_, the URI will be resolved with
194 respect to the root package URI, whatever its stored form (absolute or
195 relative).
196 If context is given and is a (direct or indirect) importer package,
197 the URI will be resolved with respect to the context URI, whatever its
198 stored form (absolute or relative).
199
200 You would probably rather use the uri read-only property, unless you
201 want to set the parameter _absolute_.
202 """
203 uri = self.__uri
204
205 if not absolute and context is self:
206 return ''
207
208 importer = self.__importer
209 if importer is not None:
210 uri =