~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/xml4.py

  • Committer: Robert Collins
  • Date: 2005-10-16 00:22:17 UTC
  • mto: This revision was merged to the branch mainline in revision 1457.
  • Revision ID: robertc@lifelesslap.robertcollins.net-20051016002217-aa38f9c1eb13ee48
Plugins are now loaded under bzrlib.plugins, not bzrlib.plugin.

Plugins are also made available for other plugins to use by making them 
accessible via import bzrlib.plugins.NAME. You should not import other
plugins during the __init__ of your plugin though, as no ordering is
guaranteed, and the plugins directory is not on the python path.

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
 
 
26
 
 
27
 
 
28
 
 
29
class _Serializer_v4(Serializer):
 
30
    """Version 0.0.4 serializer
 
31
 
 
32
    You should use the serialzer_v4 singleton."""
 
33
    
 
34
    __slots__ = []
 
35
    
 
36
    def _pack_inventory(self, inv):
 
37
        """Convert to XML Element"""
 
38
        e = Element('inventory')
 
39
        e.text = '\n'
 
40
        if inv.root.file_id not in (None, ROOT_ID):
 
41
            e.set('file_id', inv.root.file_id)
 
42
        for path, ie in inv.iter_entries():
 
43
            e.append(self._pack_entry(ie))
 
44
        return e
 
45
 
 
46
 
 
47
    def _pack_entry(self, ie):
 
48
        """Convert InventoryEntry to XML element"""
 
49
        e = Element('entry')
 
50
        e.set('name', ie.name)
 
51
        e.set('file_id', ie.file_id)
 
52
        e.set('kind', ie.kind)
 
53
 
 
54
        if ie.text_size != None:
 
55
            e.set('text_size', '%d' % ie.text_size)
 
56
 
 
57
        for f in ['text_id', 'text_sha1', 'symlink_target']:
 
58
            v = getattr(ie, f)
 
59
            if v != None:
 
60
                e.set(f, v)
 
61
 
 
62
        # to be conservative, we don't externalize the root pointers
 
63
        # for now, leaving them as null in the xml form.  in a future
 
64
        # version it will be implied by nested elements.
 
65
        if ie.parent_id != ROOT_ID:
 
66
            assert isinstance(ie.parent_id, basestring)
 
67
            e.set('parent_id', ie.parent_id)
 
68
 
 
69
        e.tail = '\n'
 
70
 
 
71
        return e
 
72
 
 
73
 
 
74
    def _unpack_inventory(self, elt):
 
75
        """Construct from XML Element
 
76
        """
 
77
        assert elt.tag == 'inventory'
 
78
        root_id = elt.get('file_id') or ROOT_ID
 
79
        inv = Inventory(root_id)
 
80
        for e in elt:
 
81
            ie = self._unpack_entry(e)
 
82
            if ie.parent_id == ROOT_ID:
 
83
                ie.parent_id = root_id
 
84
            inv.add(ie)
 
85
        return inv
 
86
 
 
87
 
 
88
    def _unpack_entry(self, elt):
 
89
        assert elt.tag == 'entry'
 
90
 
 
91
        ## original format inventories don't have a parent_id for
 
92
        ## nodes in the root directory, but it's cleaner to use one
 
93
        ## internally.
 
94
        parent_id = elt.get('parent_id')
 
95
        if parent_id == None:
 
96
            parent_id = ROOT_ID
 
97
 
 
98
        kind = elt.get('kind')
 
99
        if kind == 'directory':
 
100
            ie = inventory.InventoryDirectory(elt.get('file_id'),
 
101
                                              elt.get('name'),
 
102
                                              parent_id)
 
103
        elif kind == 'file':
 
104
            ie = inventory.InventoryFile(elt.get('file_id'),
 
105
                                         elt.get('name'),
 
106
                                         parent_id)
 
107
            ie.text_id = elt.get('text_id')
 
108
            ie.text_sha1 = elt.get('text_sha1')
 
109
            v = elt.get('text_size')
 
110
            ie.text_size = v and int(v)
 
111
        elif kind == 'symlink':
 
112
            ie = inventory.InventoryLink(elt.get('file_id'),
 
113
                                         elt.get('name'),
 
114
                                         parent_id)
 
115
            ie.symlink_target = elt.get('symlink_target')
 
116
        else:
 
117
            raise BzrError("unknown kind %r" % kind)
 
118
 
 
119
        ## mutter("read inventoryentry: %r" % (elt.attrib))
 
120
 
 
121
        return ie
 
122
 
 
123
 
 
124
    def _pack_revision(self, rev):
 
125
        """Revision object -> xml tree"""
 
126
        root = Element('revision',
 
127
                       committer = rev.committer,
 
128
                       timestamp = '%.9f' % rev.timestamp,
 
129
                       revision_id = rev.revision_id,
 
130
                       inventory_id = rev.inventory_id,
 
131
                       inventory_sha1 = rev.inventory_sha1,
 
132
                       )
 
133
        if rev.timezone:
 
134
            root.set('timezone', str(rev.timezone))
 
135
        root.text = '\n'
 
136
 
 
137
        msg = SubElement(root, 'message')
 
138
        msg.text = rev.message
 
139
        msg.tail = '\n'
 
140
 
 
141
        if rev.parents:
 
142
            pelts = SubElement(root, 'parents')
 
143
            pelts.tail = pelts.text = '\n'
 
144
            for i, parent_id in enumerate(rev.parents):
 
145
                p = SubElement(pelts, 'revision_ref')
 
146
                p.tail = '\n'
 
147
                assert parent_id
 
148
                p.set('revision_id', parent_id)
 
149
                if i < len(rev.parent_sha1s):
 
150
                    p.set('revision_sha1', rev.parent_sha1s[i])
 
151
        return root
 
152
 
 
153
    
 
154
    def _unpack_revision(self, elt):
 
155
        """XML Element -> Revision object"""
 
156
        
 
157
        # <changeset> is deprecated...
 
158
        if elt.tag not in ('revision', 'changeset'):
 
159
            raise BzrError("unexpected tag in revision file: %r" % elt)
 
160
 
 
161
        rev = Revision(committer = elt.get('committer'),
 
162
                       timestamp = float(elt.get('timestamp')),
 
163
                       revision_id = elt.get('revision_id'),
 
164
                       inventory_id = elt.get('inventory_id'),
 
165
                       inventory_sha1 = elt.get('inventory_sha1')
 
166
                       )
 
167
 
 
168
        precursor = elt.get('precursor')
 
169
        precursor_sha1 = elt.get('precursor_sha1')
 
170
 
 
171
        pelts = elt.find('parents')
 
172
 
 
173
        if pelts:
 
174
            for p in pelts:
 
175
                assert p.tag == 'revision_ref', \
 
176
                       "bad parent node tag %r" % p.tag
 
177
                rev.parent_ids.append(p.get('revision_id'))
 
178
                rev.parent_sha1s.append(p.get('revision_sha1'))
 
179
            if precursor:
 
180
                # must be consistent
 
181
                prec_parent = rev.parent_ids[0]
 
182
                assert prec_parent == precursor
 
183
        elif precursor:
 
184
            # revisions written prior to 0.0.5 have a single precursor
 
185
            # give as an attribute
 
186
            rev.parent_ids.append(precursor)
 
187
            rev.parent_sha1s.append(precursor_sha1)
 
188
 
 
189
        v = elt.get('timezone')
 
190
        rev.timezone = v and int(v)
 
191
 
 
192
        rev.message = elt.findtext('message') # text of <message>
 
193
        return rev
 
194
 
 
195
 
 
196
 
 
197
 
 
198
"""singleton instance"""
 
199
serializer_v4 = _Serializer_v4()
 
200