~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/decorator.py

  • Committer: Alexander Belchenko
  • Date: 2006-07-30 16:43:12 UTC
  • mto: (1711.2.111 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 1906.
  • Revision ID: bialix@ukr.net-20060730164312-b025fd3ff0cee59e
rename  gpl.txt => COPYING.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Implementation of Transport that decorates another transport.
18
18
 
19
 
This does not change the transport behaviour at all, but provides all the
 
19
This does not change the transport behaviour at all, but provides all the 
20
20
stub functions to allow other decorators to be written easily.
21
21
"""
22
22
 
23
 
from bzrlib import transport
24
 
 
25
 
 
26
 
class TransportDecorator(transport.Transport):
 
23
from bzrlib.transport import get_transport, Transport, Server
 
24
 
 
25
 
 
26
class TransportDecorator(Transport):
27
27
    """A no-change decorator for Transports.
28
28
 
29
29
    Subclasses of this are new transports that are based on an
30
 
    underlying transport and can override or intercept some
31
 
    behavior.  For example ReadonlyTransportDecorator prevents
32
 
    all write attempts, and FakeNFSTransportDecorator simulates
 
30
    underlying transport and can override or intercept some 
 
31
    behavior.  For example ReadonlyTransportDecorator prevents 
 
32
    all write attempts, and FakeNFSTransportDecorator simulates 
33
33
    some NFS quirks.
34
34
 
35
35
    This decorator class is not directly usable as a decorator:
37
37
    method to return the url prefix for the subclass.
38
38
    """
39
39
 
40
 
    def __init__(self, url, _decorated=None, _from_transport=None):
41
 
        """Set the 'base' path of the transport.
42
 
 
43
 
        :param _decorated: A private parameter for cloning.
44
 
        :param _from_transport: Is available for subclasses that
45
 
            need to share state across clones.
46
 
        """
 
40
    def __init__(self, url, _decorated=None):
 
41
        """Set the 'base' path where files will be stored.
 
42
        
 
43
        _decorated is a private parameter for cloning."""
47
44
        prefix = self._get_url_prefix()
48
 
        if not url.startswith(prefix):
49
 
            raise ValueError("url %r doesn't start with decorator prefix %r" %
50
 
                             (url, prefix))
51
 
        not_decorated_url = url[len(prefix):]
 
45
        assert url.startswith(prefix), \
 
46
                "url %r doesn't start with decorator prefix %r" % \
 
47
                (url, prefix)
 
48
        decorated_url = url[len(prefix):]
52
49
        if _decorated is None:
53
 
            self._decorated = transport.get_transport(not_decorated_url)
 
50
            self._decorated = get_transport(decorated_url)
54
51
        else:
55
52
            self._decorated = _decorated
56
 
        super(TransportDecorator, self).__init__(prefix + self._decorated.base)
 
53
        super(TransportDecorator, self).__init__(
 
54
            prefix + self._decorated.base)
57
55
 
58
56
    def abspath(self, relpath):
59
57
        """See Transport.abspath()."""
60
58
        return self._get_url_prefix() + self._decorated.abspath(relpath)
61
59
 
62
 
    def append_file(self, relpath, f, mode=None):
63
 
        """See Transport.append_file()."""
64
 
        return self._decorated.append_file(relpath, f, mode=mode)
65
 
 
66
 
    def append_bytes(self, relpath, bytes, mode=None):
67
 
        """See Transport.append_bytes()."""
68
 
        return self._decorated.append_bytes(relpath, bytes, mode=mode)
69
 
 
70
 
    def _can_roundtrip_unix_modebits(self):
71
 
        """See Transport._can_roundtrip_unix_modebits()."""
72
 
        return self._decorated._can_roundtrip_unix_modebits()
 
60
    def append(self, relpath, f, mode=None):
 
61
        """See Transport.append()."""
 
62
        return self._decorated.append(relpath, f, mode=mode)
73
63
 
74
64
    def clone(self, offset=None):
75
65
        """See Transport.clone()."""
76
66
        decorated_clone = self._decorated.clone(offset)
77
67
        return self.__class__(
78
 
            self._get_url_prefix() + decorated_clone.base, decorated_clone,
79
 
            self)
 
68
            self._get_url_prefix() + decorated_clone.base, decorated_clone)
80
69
 
81
70
    def delete(self, relpath):
82
71
        """See Transport.delete()."""
86
75
        """See Transport.delete_tree()."""
87
76
        return self._decorated.delete_tree(relpath)
88
77
 
89
 
    def external_url(self):
90
 
        """See bzrlib.transport.Transport.external_url."""
91
 
        # while decorators are in-process only, they
92
 
        # can be handed back into bzrlib safely, so
93
 
        # its just the base.
94
 
        return self.base
95
 
 
96
78
    @classmethod
97
79
    def _get_url_prefix(self):
98
80
        """Return the URL prefix of this decorator."""
102
84
        """See Transport.get()."""
103
85
        return self._decorated.get(relpath)
104
86
 
105
 
    def get_smart_client(self):
106
 
        return self._decorated.get_smart_client()
107
 
 
108
87
    def has(self, relpath):
109
88
        """See Transport.has()."""
110
89
        return self._decorated.has(relpath)
117
96
        """See Transport.mkdir()."""
118
97
        return self._decorated.mkdir(relpath, mode)
119
98
 
120
 
    def open_write_stream(self, relpath, mode=None):
121
 
        """See Transport.open_write_stream."""
122
 
        return self._decorated.open_write_stream(relpath, mode=mode)
123
 
 
124
 
    def put_file(self, relpath, f, mode=None):
125
 
        """See Transport.put_file()."""
126
 
        return self._decorated.put_file(relpath, f, mode)
127
 
 
128
 
    def put_bytes(self, relpath, bytes, mode=None):
129
 
        """See Transport.put_bytes()."""
130
 
        return self._decorated.put_bytes(relpath, bytes, mode)
131
 
 
 
99
    def put(self, relpath, f, mode=None):
 
100
        """See Transport.put()."""
 
101
        return self._decorated.put(relpath, f, mode)
 
102
    
132
103
    def listable(self):
133
104
        """See Transport.listable."""
134
105
        return self._decorated.listable()
136
107
    def iter_files_recursive(self):
137
108
        """See Transport.iter_files_recursive()."""
138
109
        return self._decorated.iter_files_recursive()
139
 
 
 
110
    
140
111
    def list_dir(self, relpath):
141
112
        """See Transport.list_dir()."""
142
113
        return self._decorated.list_dir(relpath)
143
114
 
144
 
    def _readv(self, relpath, offsets):
145
 
        """See Transport._readv."""
146
 
        return self._decorated._readv(relpath, offsets)
147
 
 
148
 
    def recommended_page_size(self):
149
 
        """See Transport.recommended_page_size()."""
150
 
        return self._decorated.recommended_page_size()
151
 
 
152
115
    def rename(self, rel_from, rel_to):
153
116
        return self._decorated.rename(rel_from, rel_to)
154
 
 
 
117
    
155
118
    def rmdir(self, relpath):
156
119
        """See Transport.rmdir."""
157
120
        return self._decorated.rmdir(relpath)
158
121
 
 
122
    def should_cache(self):
 
123
        """See Transport.should_cache()."""
 
124
        return self._decorated.should_cache()
 
125
 
159
126
    def stat(self, relpath):
160
127
        """See Transport.stat()."""
161
128
        return self._decorated.stat(relpath)
168
135
        """See Transport.lock_write."""
169
136
        return self._decorated.lock_write(relpath)
170
137
 
171
 
    def _redirected_to(self, source, target):
172
 
        redirected = self._decorated._redirected_to(source, target)
173
 
        if redirected is not None:
174
 
            return self.__class__(self._get_url_prefix() + redirected.base,
175
 
                                  redirected)
 
138
 
 
139
class DecoratorServer(Server):
 
140
    """Server for the TransportDecorator for testing with.
 
141
    
 
142
    To use this when subclassing TransportDecorator, override override the
 
143
    get_decorator_class method.
 
144
    """
 
145
 
 
146
    def setUp(self, server=None):
 
147
        """See bzrlib.transport.Server.setUp.
 
148
 
 
149
        :server: decorate the urls given by server. If not provided a
 
150
        LocalServer is created.
 
151
        """
 
152
        if server is not None:
 
153
            self._made_server = False
 
154
            self._server = server
176
155
        else:
177
 
            return None
 
156
            from bzrlib.transport.local import LocalRelpathServer
 
157
            self._made_server = True
 
158
            self._server = LocalRelpathServer()
 
159
            self._server.setUp()
 
160
 
 
161
    def tearDown(self):
 
162
        """See bzrlib.transport.Server.tearDown."""
 
163
        if self._made_server:
 
164
            self._server.tearDown()
 
165
 
 
166
    def get_decorator_class(self):
 
167
        """Return the class of the decorators we should be constructing."""
 
168
        raise NotImplementedError(self.get_decorator_class)
 
169
 
 
170
    def get_url_prefix(self):
 
171
        """What URL prefix does this decorator produce?"""
 
172
        return self.get_decorator_class()._get_url_prefix()
 
173
 
 
174
    def get_bogus_url(self):
 
175
        """See bzrlib.transport.Server.get_bogus_url."""
 
176
        return self.get_url_prefix() + self._server.get_bogus_url()
 
177
 
 
178
    def get_url(self):
 
179
        """See bzrlib.transport.Server.get_url."""
 
180
        return self.get_url_prefix() + self._server.get_url()
178
181
 
179
182
 
180
183
def get_test_permutations():
181
184
    """Return the permutations to be used in testing.
182
 
 
 
185
    
183
186
    The Decorator class is not directly usable, and testing it would not have
184
187
    any benefit - its the concrete classes which need to be tested.
185
188
    """