/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/xml5.py

  • Committer: John Arbash Meinel
  • Date: 2006-07-18 18:57:54 UTC
  • mto: This revision was merged to the branch mainline in revision 1868.
  • Revision ID: john@arbash-meinel.com-20060718185754-4007745748e28db9
Commit timestamp restricted to 1ms precision.

The old code would restrict to 1s resolution if the timestamp was
supplied, while it preserved full resolution if the timestamp was
auto generated. Now both paths preserve only 1ms resolution.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
 
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
 
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
 
 
18
from bzrlib.xml_serializer import SubElement, Element, Serializer
 
19
from bzrlib.inventory import ROOT_ID, Inventory, InventoryEntry
 
20
import bzrlib.inventory as inventory
 
21
from bzrlib.revision import Revision
 
22
from bzrlib.errors import BzrError
 
23
 
 
24
 
 
25
class Serializer_v5(Serializer):
 
26
    """Version 5 serializer
 
27
 
 
28
    Packs objects into XML and vice versa.
 
29
    """
 
30
    
 
31
    __slots__ = []
 
32
    
 
33
    def _pack_inventory(self, inv):
 
34
        """Convert to XML Element"""
 
35
        e = Element('inventory',
 
36
                    format='5')
 
37
        e.text = '\n'
 
38
        if inv.root.file_id not in (None, ROOT_ID):
 
39
            e.set('file_id', inv.root.file_id)
 
40
        if inv.revision_id is not None:
 
41
            e.set('revision_id', inv.revision_id)
 
42
        for path, ie in inv.iter_entries():
 
43
            e.append(self._pack_entry(ie))
 
44
        return e
 
45
 
 
46
    def _pack_entry(self, ie):
 
47
        """Convert InventoryEntry to XML element"""
 
48
        # TODO: should just be a plain assertion
 
49
        if not InventoryEntry.versionable_kind(ie.kind):
 
50
            raise AssertionError('unsupported entry kind %s' % ie.kind)
 
51
        e = Element(ie.kind)
 
52
        e.set('name', ie.name)
 
53
        e.set('file_id', ie.file_id)
 
54
 
 
55
        if ie.text_size != None:
 
56
            e.set('text_size', '%d' % ie.text_size)
 
57
 
 
58
        for f in ['text_sha1', 'revision', 'symlink_target']:
 
59
            v = getattr(ie, f)
 
60
            if v != None:
 
61
                e.set(f, v)
 
62
 
 
63
        if ie.executable:
 
64
            e.set('executable', 'yes')
 
65
 
 
66
        # to be conservative, we don't externalize the root pointers
 
67
        # for now, leaving them as null in the xml form.  in a future
 
68
        # version it will be implied by nested elements.
 
69
        if ie.parent_id != ROOT_ID:
 
70
            assert isinstance(ie.parent_id, basestring)
 
71
            e.set('parent_id', ie.parent_id)
 
72
        e.tail = '\n'
 
73
        return e
 
74
 
 
75
    def _pack_revision(self, rev):
 
76
        """Revision object -> xml tree"""
 
77
        root = Element('revision',
 
78
                       committer = rev.committer,
 
79
                       timestamp = '%.9f' % rev.timestamp,
 
80
                       revision_id = rev.revision_id,
 
81
                       inventory_sha1 = rev.inventory_sha1,
 
82
                       format='5',
 
83
                       )
 
84
        if rev.timezone:
 
85
            root.set('timezone', str(rev.timezone))
 
86
        root.text = '\n'
 
87
        msg = SubElement(root, 'message')
 
88
        msg.text = rev.message
 
89
        msg.tail = '\n'
 
90
        if rev.parent_ids:
 
91
            pelts = SubElement(root, 'parents')
 
92
            pelts.tail = pelts.text = '\n'
 
93
            for parent_id in rev.parent_ids:
 
94
                assert isinstance(parent_id, basestring)
 
95
                p = SubElement(pelts, 'revision_ref')
 
96
                p.tail = '\n'
 
97
                p.set('revision_id', parent_id)
 
98
        if rev.properties:
 
99
            self._pack_revision_properties(rev, root)
 
100
        return root
 
101
 
 
102
 
 
103
    def _pack_revision_properties(self, rev, under_element):
 
104
        top_elt = SubElement(under_element, 'properties')
 
105
        for prop_name, prop_value in sorted(rev.properties.items()):
 
106
            assert isinstance(prop_name, basestring) 
 
107
            assert isinstance(prop_value, basestring) 
 
108
            prop_elt = SubElement(top_elt, 'property')
 
109
            prop_elt.set('name', prop_name)
 
110
            prop_elt.text = prop_value
 
111
            prop_elt.tail = '\n'
 
112
        top_elt.tail = '\n'
 
113
 
 
114
 
 
115
    def _unpack_inventory(self, elt):
 
116
        """Construct from XML Element
 
117
        """
 
118
        assert elt.tag == 'inventory'
 
119
        root_id = elt.get('file_id') or ROOT_ID
 
120
        format = elt.get('format')
 
121
        if format is not None:
 
122
            if format != '5':
 
123
                raise BzrError("invalid format version %r on inventory"
 
124
                                % format)
 
125
        revision_id = elt.get('revision_id')
 
126
        inv = Inventory(root_id, revision_id=revision_id)
 
127
        for e in elt:
 
128
            ie = self._unpack_entry(e)
 
129
            if ie.parent_id == ROOT_ID:
 
130
                ie.parent_id = root_id
 
131
            inv.add(ie)
 
132
        return inv
 
133
 
 
134
 
 
135
    def _unpack_entry(self, elt):
 
136
        kind = elt.tag
 
137
        if not InventoryEntry.versionable_kind(kind):
 
138
            raise AssertionError('unsupported entry kind %s' % kind)
 
139
 
 
140
        parent_id = elt.get('parent_id')
 
141
        if parent_id == None:
 
142
            parent_id = ROOT_ID
 
143
 
 
144
        if kind == 'directory':
 
145
            ie = inventory.InventoryDirectory(elt.get('file_id'),
 
146
                                              elt.get('name'),
 
147
                                              parent_id)
 
148
        elif kind == 'file':
 
149
            ie = inventory.InventoryFile(elt.get('file_id'),
 
150
                                         elt.get('name'),
 
151
                                         parent_id)
 
152
            ie.text_sha1 = elt.get('text_sha1')
 
153
            if elt.get('executable') == 'yes':
 
154
                ie.executable = True
 
155
            v = elt.get('text_size')
 
156
            ie.text_size = v and int(v)
 
157
        elif kind == 'symlink':
 
158
            ie = inventory.InventoryLink(elt.get('file_id'),
 
159
                                         elt.get('name'),
 
160
                                         parent_id)
 
161
            ie.symlink_target = elt.get('symlink_target')
 
162
        else:
 
163
            raise BzrError("unknown kind %r" % kind)
 
164
        ie.revision = elt.get('revision')
 
165
 
 
166
        return ie
 
167
 
 
168
 
 
169
    def _unpack_revision(self, elt):
 
170
        """XML Element -> Revision object"""
 
171
        assert elt.tag == 'revision'
 
172
        format = elt.get('format')
 
173
        if format is not None:
 
174
            if format != '5':
 
175
                raise BzrError("invalid format version %r on inventory"
 
176
                                % format)
 
177
        rev = Revision(committer = elt.get('committer'),
 
178
                       timestamp = float(elt.get('timestamp')),
 
179
                       revision_id = elt.get('revision_id'),
 
180
                       inventory_sha1 = elt.get('inventory_sha1')
 
181
                       )
 
182
        parents = elt.find('parents') or []
 
183
        for p in parents:
 
184
            assert p.tag == 'revision_ref', \
 
185
                   "bad parent node tag %r" % p.tag
 
186
            rev.parent_ids.append(p.get('revision_id'))
 
187
        self._unpack_revision_properties(elt, rev)
 
188
        v = elt.get('timezone')
 
189
        rev.timezone = v and int(v)
 
190
        rev.message = elt.findtext('message') # text of <message>
 
191
        return rev
 
192
 
 
193
 
 
194
    def _unpack_revision_properties(self, elt, rev):
 
195
        """Unpack properties onto a revision."""
 
196
        props_elt = elt.find('properties')
 
197
        assert len(rev.properties) == 0
 
198
        if not props_elt:
 
199
            return
 
200
        for prop_elt in props_elt:
 
201
            assert prop_elt.tag == 'property', \
 
202
                "bad tag under properties list: %r" % prop_elt.tag
 
203
            name = prop_elt.get('name')
 
204
            value = prop_elt.text
 
205
            assert name not in rev.properties, \
 
206
                "repeated property %r" % name
 
207
            rev.properties[name] = value
 
208
 
 
209
 
 
210
serializer_v5 = Serializer_v5()