summaryrefslogtreecommitdiffstats
path: root/kio/kio/forwardingslavebase.h
blob: 49d01f4e2c76ee2f2b8272cf19edec15fe5daf10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/* This file is part of the KDE project
   Copyright (c) 2004 Kevin Ottens <ervin ipsquad net>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#ifndef _FORWARDING_SLAVE_BASE_H_
#define _FORWARDING_SLAVE_BASE_H_

#include <kio/slavebase.h>
#include <kio/jobclasses.h>

#include <tqobject.h>

namespace TDEIO
{

class ForwardingSlaveBasePrivate;

/**
 * This class should be used as a base for ioslaves acting as a
 * forwarder to other ioslaves. It has been designed to support only
 * local filesystem like ioslaves.
 *
 * If the resulting ioslave should be a simple proxy, you only need
 * to implement the ForwardingSlaveBase::rewriteURL() method.
 * 
 * For more advanced behavior, the classic ioslave methods should
 * be reimplemented, because their default behavior in this class
 * is to forward using the ForwardingSlaveBase::rewriteURL() method.
 * 
 * A possible code snippet for an advanced stat() behavior would look
 * like this in the child class:
 * 
 * \code
 *     void ChildProtocol::stat(const KURL &url)
 *     {
 *         bool is_special = false;
 *         
 *         // Process the URL to see if it should have
 *         // a special treatment
 *         
 *         if ( is_special )
 *         {
 *             // Handle the URL ourselves
 *             TDEIO::UDSEntry entry;
 *             // Fill entry with UDSAtom instances
 *             statEntry(entry);
 *             finished();
 *         }
 *         else
 *         {
 *             // Setup the ioslave internal state if
 *             // required by ChildProtocol::rewriteURL()
 *             ForwardingSlaveBase::stat(url);
 *         }
 *     }
 * \endcode
 * 
 * Of course in this case, you surely need to reimplement listDir()
 * and get() accordingly.
 * 
 * If you want view on directories to be correctly refreshed when
 * something changes on a forwarded URL, you'll need a companion kded
 * module to emit the KDirNotify Files*() DCOP signals.
 * 
 * This class was initially used for media:/ ioslave. This ioslave code
 * and the MediaDirNotify class of its companion kded module can be a
 * good source of inspiration.
 * 
 * @see ForwardingSlaveBase::rewriteURL()
 * @since 3.4
 * @author Kevin Ottens <ervin@ipsquad.net>
 */
class KIO_EXPORT ForwardingSlaveBase : public TQObject, public SlaveBase
{
Q_OBJECT
public:
    ForwardingSlaveBase(const TQCString &protocol,
                        const TQCString &poolSocket,
                        const TQCString &appSocket);
    virtual ~ForwardingSlaveBase();

    virtual void get(const KURL &url);

    virtual void put(const KURL &url, int permissions,
                     bool overwrite, bool resume);

    virtual void stat(const KURL &url);

    virtual void mimetype(const KURL &url);

    virtual void listDir(const KURL &url);

    virtual void mkdir(const KURL &url, int permissions);

    virtual void rename(const KURL &src, const KURL &dest, bool overwrite);

    virtual void symlink(const TQString &target, const KURL &dest,
                         bool overwrite);

    virtual void chmod(const KURL &url, int permissions);

    virtual void copy(const KURL &src, const KURL &dest,
                      int permissions, bool overwrite);

    virtual void del(const KURL &url, bool isfile);

    virtual void localURL(const KURL& remoteURL);

protected:
    /**
     * Rewrite an url to it's forwarded counterpart. It should return
     * true if everything was ok, and false otherwise.
     *
     * If a problem is detected it's up to this method to trigger error()
     * before returning. Returning false silently cancel the current
     * slave operation.
     *
     * @param url The URL as given during the slave call
     * @param newURL The new URL to forward the slave call to
     * @return true if the given url could be correctly rewritten
     */
    virtual bool rewriteURL(const KURL &url, KURL &newURL)=0;
    
    /**
     * Allow to modify a UDSEntry before it's sent to the ioslave enpoint.
     * This is the default implementation working in most case, but sometimes
     * you could make use of more forwarding black magic (for example
     * dynamically transform any desktop file into a fake directory...)
     *
     * @param entry the UDSEntry to post-process
     * @param listing indicate if this entry it created during a listDir
     *                operation
     */
    virtual void prepareUDSEntry(TDEIO::UDSEntry &entry,
                                 bool listing=false) const;
    
    /**
     * Return the URL being processed by the ioslave
     * Only access it inside prepareUDSEntry()
     */
    KURL processedURL() const { return m_processedURL; }

    /**
     * Return the URL asked to the ioslave
     * Only access it inside prepareUDSEntry()
     */
    KURL requestedURL() const { return m_requestedURL; }

private:
    KURL m_processedURL;
    KURL m_requestedURL;
    ForwardingSlaveBasePrivate *d;
    
    bool internalRewriteURL(const KURL &url, KURL &newURL);
    
    void connectJob(Job *job);
    void connectSimpleJob(SimpleJob *job);
    void connectListJob(ListJob *job);
    void connectTransferJob(TransferJob *job);
    void connectLocalURLJob(LocalURLJob *job);

private slots:
    // TDEIO::Job
    void slotResult(TDEIO::Job *job);
    void slotWarning(TDEIO::Job *job, const TQString &msg);
    void slotInfoMessage(TDEIO::Job *job, const TQString &msg);
    void slotTotalSize(TDEIO::Job *job, TDEIO::filesize_t size);
    void slotProcessedSize(TDEIO::Job *job, TDEIO::filesize_t size);
    void slotSpeed(TDEIO::Job *job, unsigned long bytesPerSecond);

    // TDEIO::SimpleJob subclasses
    void slotRedirection(TDEIO::Job *job, const KURL &url);

    // TDEIO::ListJob
    void slotEntries(TDEIO::Job *job, const TDEIO::UDSEntryList &entries);

    // TDEIO::TransferJob
    void slotData(TDEIO::Job *job, const TQByteArray &data);
    void slotDataReq(TDEIO::Job *job, TQByteArray &data);
    void slotMimetype (TDEIO::Job *job, const TQString &type);
    void slotCanResume (TDEIO::Job *job, TDEIO::filesize_t offset);

    // TDEIO::LocalURLJob
    void slotLocalURL(TDEIO::Job *, const KURL&, bool);
};

}

#endif