- Pathname,PathInfo
[platform/upstream/libzypp.git] / zypp / media / MediaAccess.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaAccess.h
10  *
11 */
12 #ifndef ZYPP_MEDIA_MEDIAACCESS_H
13 #define ZYPP_MEDIA_MEDIAACCESS_H
14
15 #include <iosfwd>
16 #include <map>
17 #include <list>
18 #include <string>
19
20 #include "zypp/base/ReferenceCounted.h"
21 #include "zypp/base/NonCopyable.h"
22 #include "zypp/base/PtrTypes.h"
23
24 #include "zypp/Pathname.h"
25 #include "zypp/PathInfo.h"
26
27 #include "zypp/media/MediaException.h"
28
29 #warning FIXME use real Url class
30 // #include "zypp/@Review/Url.h"
31 typedef std::string Url;
32
33 namespace zypp {
34   namespace media {
35
36     class MediaHandler;
37
38     ///////////////////////////////////////////////////////////////////
39     //
40     //  CLASS NAME : MediaAccess
41     /**
42      * @short Handle access to a medium
43      *
44      * The concrete @ref MediaHandler for a certain url is created
45      * on @ref open and deleted on @close.
46      *
47      * The inteface here basically checks whether the handler exists,
48      * then forwards the request to @ref MediaHandler.
49      **/
50     class MediaAccess : public base::ReferenceCounted, private base::NonCopyable
51     {
52     public:
53         typedef intrusive_ptr<MediaAccess> Ptr;
54         typedef intrusive_ptr<const MediaAccess> constPtr;
55
56     private:
57
58         static const Pathname _noPath;
59
60         /**
61          * handler for 'physical' media
62          * == 0 if not open
63          **/
64         MediaHandler * _handler;
65
66     public:
67
68        /**
69         * constructor
70         **/
71         MediaAccess();
72
73         /**
74          * open url. If preferred_attach_point is given,
75          * try to use it as attach point.
76          *
77          * <b>Caution:</b> The medium can choose a different attach point.
78          * Only getAttachPoint() knows the real attach point.
79          *
80          * \throws MediaException
81          *
82          **/
83         void open( const Url& url, const Pathname & preferred_attach_point = "" );
84
85         /**
86          * True if media is open.
87          **/
88         bool isOpen() const { return( _handler != 0 ); }
89
90         /**
91          * Used Protocol if media is opened, otherwise 'unknown'.
92          **/
93 #warning FIXME uncomment once real Url class is implemented
94 #if 0
95         Url::Protocol protocol() const;
96 #endif
97
98         /**
99          * Url if media is opened, otherwise empty.
100          **/
101         Url url() const;
102
103         /**
104          * close url
105          *
106          * \throws MediaException
107          *
108          **/
109         void close();
110
111     public:
112
113         /**
114          * Use concrete handler to attach the media.
115          *
116          * @param next try next available device in turn until end of device
117          * list is reached (for media which are accessible through multiple
118          * devices like cdroms).
119          *
120          * \throws MediaException
121          *
122          **/
123         void attach(bool next = false);
124
125         /**
126          * True if media is attached.
127          *
128          * \throws MediaException
129          *
130          **/
131         bool isAttached() const;
132
133         /**
134          * Return the local directory that corresponds to medias url,
135          * no matter if media isAttached or not. Files requested will
136          * be available at 'localRoot() + filename' or better
137          * 'localPath( filename )'.
138          *
139          * If media is not open an empty pathname is returned.
140          **/
141         const Pathname & localRoot() const;
142
143         /**
144          * Short for 'localRoot() + pathname', but returns an empty
145          * pathname if media is not open.
146          *
147          * Files provided will be available at 'localPath(filename)'.
148          **/
149         Pathname localPath( const Pathname & pathname ) const;
150
151         /**
152           Use concrete handler to disconnect the media.
153
154           This is useful for media which e.g. holds open a connection to a
155           server like FTP. After calling disconnect() the media object still is
156           valid and files are present.
157
158           After calling disconnect() it's not possible to call provideFile() or
159           provideDir() anymore.
160          *
161          * \throws MediaException
162          *
163         */
164         void disconnect();
165
166         /**
167          * Use concrete handler to release the media.
168          * @param eject if true, physically eject the media * (i.e. CD-ROM)
169          *
170          * \throws MediaException
171          *
172          **/
173         void release( bool eject = false );
174
175         /**
176          * Use concrete handler to provide file denoted by path below
177          * 'attach point'. Filename is interpreted relative to the
178          * attached url and a path prefix is preserved.
179          *
180          * @param cached  If cached is set to true, the function checks, if
181          *                the file already exists and doesn't download it again
182          *                if it does. Currently only the existence is checked,
183          *                no other file attributes.
184          * @param checkonly If this and 'cached' are set to true only the
185          *                  existence of the file is checked but it's not
186          *                  downloaded. If 'cached' is unset an errer is
187          *                  returned always.
188          *
189          * \throws MediaException
190          *
191          **/
192         void provideFile( const Pathname & filename, bool cached = false, bool checkonly = false ) const;
193
194         /**
195          * Remove filename below attach point IFF handler downloads files
196          * to the local filesystem. Never remove anything from media.
197          *
198          * \throws MediaException
199          *
200          **/
201         void releaseFile( const Pathname & filename ) const;
202
203         /**
204          * Use concrete handler to provide directory denoted
205          * by path below 'attach point' (not recursive!).
206          * 'dirname' is interpreted relative to the
207          * attached url and a path prefix is preserved.
208          *
209          * \throws MediaException
210          *
211          **/
212         void provideDir( const Pathname & dirname ) const;
213
214         /**
215          * Use concrete handler to provide directory tree denoted
216          * by path below 'attach point' (recursive!!).
217          * 'dirname' is interpreted relative to the
218          * attached url and a path prefix is preserved.
219          *
220          * \throws MediaException
221          *
222          **/
223         void provideDirTree( const Pathname & dirname ) const;
224
225         /**
226          * Remove directory tree below attach point IFF handler downloads files
227          * to the local filesystem. Never remove anything from media.
228          *
229          * \throws MediaException
230          *
231          **/
232         void releaseDir( const Pathname & dirname ) const;
233
234         /**
235          * Remove pathname below attach point IFF handler downloads files
236          * to the local filesystem. Never remove anything from media.
237          *
238          * If pathname denotes a directory it is recursively removed.
239          * If pathname is empty or '/' everything below the attachpoint
240          * is recursively removed.
241          *
242          * \throws MediaException
243          *
244          **/
245         void releasePath( const Pathname & pathname ) const;
246
247     public:
248
249         /**
250          * Return content of directory on media via retlist. If dots is false
251          * entries starting with '.' are not reported.
252          *
253          * The request is forwarded to the concrete handler,
254          * which may atempt to retieve the content e.g. via 'readdir'
255          *
256          * <B>Caution:</B> This is not supported by all media types.
257          * Be prepared to handle E_not_supported_by_media.
258          *
259          * \throws MediaException
260          *
261          **/
262         void dirInfo( std::list<std::string> & retlist,
263                          const Pathname & dirname, bool dots = true ) const;
264
265         /**
266          * Basically the same as dirInfo above. The content is returned as
267          * filesystem::DirContent, which includes name and filetype of each directory
268          * entry. Retrieving the filetype usg. requires an additional ::stat call for
269          * each entry, thus it's more expensive than a simple readdir.
270          *
271          * <B>Caution:</B> This is not supported by all media types.
272          * Be prepared to handle E_not_supported_by_media.
273          *
274          * \throws MediaException
275          *
276          **/
277         void dirInfo( filesystem::DirContent & retlist,
278                       const Pathname & dirname, bool dots = true ) const;
279
280         /**
281          * Destructor
282          **/
283         virtual ~MediaAccess();
284
285     public:
286
287         virtual std::ostream & dumpOn( std::ostream & str ) const;
288
289     public:
290         /**
291          * Get file from location at specified by URL and copy it to
292          * destination.
293          *
294          * @param from Source URL
295          * @param to   Destination file name
296          *
297          * \throws MediaException
298          *
299          **/
300         void getFile( const Url &from, const Pathname &to );
301
302     public:
303
304       /**
305        * Helper class that provides file on construction
306        * and cleans up on destruction.
307        *
308        * <b>Caution:</b> There's no synchronisation between multiple
309        * FileProvider instances, that provide the same file from the
310        * same media. If the first one goes out of scope, the file is
311        * cleaned. It's just a convenience for 'access and forgett'.
312        *
313        * <b>Caution:</b> We should either store the reference MediaAccess'
314        * MediaHandler here (for this MediaHandler must become a
315        * ref counting pointer class), or we need more info from MediaHandler
316        * (whether he's downloading to the local fs. If not, no releasefile
317        * is necessary).
318        * Currently we can not releaseFile after the media was closed
319        * (it's passed to the handler, which is deleted on close).
320        *
321        * \throws MediaException
322        **/
323       class FileProvider {
324         FileProvider( const FileProvider & );             // no copy
325         FileProvider & operator=( const FileProvider & ); // no assign
326         private:
327           MediaAccess::constPtr _media;
328           Pathname              _file;
329           Pathname              _local_file;
330         public:
331           /**
332            * \throws MediaException
333            */
334           FileProvider( MediaAccess::constPtr media_r, const Pathname & file_r )
335             : _media( media_r )
336             , _file( file_r )
337             , _local_file( "" )
338           {
339             if ( _file.empty() ) {
340               ZYPP_THROW( MediaException, "E_bad_filename");
341             } else if ( _media ) {
342               try {
343                 _media->provideFile( _file );
344                 _local_file = _media->localPath( _file );
345               }
346               catch (const MediaException & excpt_r)
347               {
348                 _media = NULL;
349 #warning FIXME rethrow the exception
350 #if 0
351                 ZYPP_RETHROW(excpt_r);
352 #endif
353               }
354             }
355           }
356
357           ~FileProvider() {
358             if ( _media )
359             {
360               try {
361                 _media->releaseFile( _file );
362               }
363               catch (const MediaException &excpt_r)
364               {
365                 INT << "Exception raised while releasing file" << std::endl;
366               }
367             }
368           }
369
370         public:
371
372           /**
373            * If no error, expect operator() to return the local
374            * Pathname of the provided file.
375            **/
376           Pathname localFile() const { return _local_file; }
377
378           /**
379            * Return the local Pathname of the provided file or
380            * an empty Pathname on error.
381            **/
382           Pathname operator()() const {
383             if ( _media )
384               return _media->localPath( _file );
385             return Pathname();
386           }
387       };
388     };
389
390 ///////////////////////////////////////////////////////////////////
391
392   } // namespace media
393 } // namespace zypp
394
395 #endif // ZYPP_MEDIA_MEDIAACCESS_H
396