~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/xml5.py

  • Committer: Robert Collins
  • Date: 2005-10-16 22:31:25 UTC
  • mto: This revision was merged to the branch mainline in revision 1458.
  • Revision ID: robertc@lifelesslap.robertcollins.net-20051016223125-26d4401cb94b7b82
Branch.relpath has been moved to WorkingTree.relpath.

WorkingTree no no longer takes an inventory, rather it takes an optional branch
parameter, and if None is given will open the branch at basedir implicitly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
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 import ElementTree, 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
        for path, ie in inv.iter_entries():
 
41
            e.append(self._pack_entry(ie))
 
42
        return e
 
43
 
 
44
 
 
45
    def _pack_entry(self, ie):
 
46
        """Convert InventoryEntry to XML element"""
 
47
        if not InventoryEntry.versionable_kind(ie.kind):
 
48
            raise AssertionError('unsupported entry kind %s' % ie.kind)
 
49
        e = Element(ie.kind)
 
50
        e.set('name', ie.name)
 
51
        e.set('file_id', ie.file_id)
 
52
 
 
53
        if ie.text_size != None:
 
54
            e.set('text_size', '%d' % ie.text_size)
 
55
 
 
56
        for f in ['text_sha1', 'revision', 'symlink_target']:
 
57
            v = getattr(ie, f)
 
58
            if v != None:
 
59
                e.set(f, v)
 
60
 
 
61
        if ie.executable:
 
62
            e.set('executable', 'yes')
 
63
 
 
64
        # to be conservative, we don't externalize the root pointers
 
65
        # for now, leaving them as null in the xml form.  in a future
 
66
        # version it will be implied by nested elements.
 
67
        if ie.parent_id != ROOT_ID:
 
68
            assert isinstance(ie.parent_id, basestring)
 
69
            e.set('parent_id', ie.parent_id)
 
70
 
 
71
        e.tail = '\n'
 
72
 
 
73
        return e
 
74
 
 
75
 
 
76
    def _pack_revision(self, rev):
 
77
        """Revision object -> xml tree"""
 
78
        root = Element('revision',
 
79
                       committer = rev.committer,
 
80
                       timestamp = '%.9f' % rev.timestamp,
 
81
                       revision_id = rev.revision_id,
 
82
                       inventory_sha1 = rev.inventory_sha1,
 
83
                       format='5',
 
84
                       )
 
85
        if rev.timezone:
 
86
            root.set('timezone', str(rev.timezone))
 
87
        root.text = '\n'
 
88
        msg = SubElement(root, 'message')
 
89
        msg.text = rev.message
 
90
        msg.tail = '\n'
 
91
        if rev.parent_ids:
 
92
            pelts = SubElement(root, 'parents')
 
93
            pelts.tail = pelts.text = '\n'
 
94
            for parent_id in rev.parent_ids:
 
95
                assert isinstance(parent_id, basestring)
 
96
                p = SubElement(pelts, 'revision_ref')
 
97
                p.tail = '\n'
 
98
                p.set('revision_id', parent_id)
 
99
        if rev.properties:
 
100
            self._pack_revision_properties(rev, root)
 
101
        return root
 
102
 
 
103
 
 
104
    def _pack_revision_properties(self, rev, under_element):
 
105
        top_elt = SubElement(under_element, 'properties')
 
106
        for prop_name, prop_value in sorted(rev.properties.items()):
 
107
            assert isinstance(prop_name, basestring) 
 
108
            assert isinstance(prop_value, basestring) 
 
109
            prop_elt = SubElement(top_elt, 'property')
 
110
            prop_elt.set('name', prop_name)
 
111
            prop_elt.text = prop_value
 
112
            prop_elt.tail = '\n'
 
113
        top_elt.tail = '\n'
 
114
 
 
115
 
 
116
    def _unpack_inventory(self, elt):
 
117
        """Construct from XML Element
 
118
        """
 
119
        assert elt.tag == 'inventory'
 
120
        root_id = elt.get('file_id') or ROOT_ID
 
121
        format = elt.get('format')
 
122
        if format is not None:
 
123
            if format != '5':
 
124
                raise BzrError("invalid format version %r on inventory"
 
125
                                % format)
 
126
        inv = Inventory(root_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" % p.tag
 
203
            name = prop_elt.get('name')
 
204
            value = prop_elt.text
 
205
            assert name not in rev.properties, \
 
206
                "repeated property %r" % p.name
 
207
            rev.properties[name] = value
 
208
 
 
209
 
 
210
serializer_v5 = Serializer_v5()