- removed the old release(bool eject) methods
[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 #include "zypp/base/Deprecated.h"
24
25 #include "zypp/Pathname.h"
26 #include "zypp/PathInfo.h"
27
28 #include "zypp/media/MediaException.h"
29 #include "zypp/media/MediaSource.h"
30
31 #include "zypp/Url.h"
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         friend class MediaManager;
67         friend class MediaManager_Impl;
68
69         AttachedMedia        attachedMedia() const;
70
71         bool                 isSharedMedia() const;
72
73         void                 resetParentId();
74         bool                 dependsOnParent() const;
75         bool                 dependsOnParent(MediaAccessId parentId,
76                                              bool exactIdMatch) const;
77
78     public:
79
80        /**
81         * constructor
82         **/
83         MediaAccess();
84
85         /**
86          * open url. If preferred_attach_point is given,
87          * try to use it as attach point.
88          *
89          * <b>Caution:</b> The medium can choose a different attach point.
90          * Only getAttachPoint() knows the real attach point.
91          *
92          * \throws MediaException
93          *
94          **/
95         void open( const Url& url, const Pathname & preferred_attach_point = "" );
96
97         /**
98          * True if media is open.
99          **/
100         bool isOpen() const { return( _handler != 0 ); }
101
102         /**
103          * Hint if files are downloaded or not.
104          * @return True, if the files are downloaded.
105          */
106         bool        downloads() const;
107
108         /**
109          * Hint if files will be downloaded when using the
110          * specified media \p url.
111          *
112          * @note This hint is based on the \p url scheme
113          * only and does not imply, that the URL is valid.
114          *
115          * @param url The media URL to check.
116          * @return True, if the files are downloaded.
117          */
118         static
119         bool        downloads(const Url &url);
120         /**
121          * Hint whether the media can provide volatile contents
122          *
123          * @note This hint is based on the \p url scheme
124          * only and does not imply, that the URL is valid.
125          *
126          * @param url The media URL to check.
127          * @return True, if the files are downloaded.
128          */
129         static
130         bool        canBeVolatile(const Url &url);
131
132         /**
133          * Used Protocol if media is opened, otherwise 'unknown'.
134          **/
135         std::string protocol() const;
136
137         /**
138          * Url if media is opened, otherwise empty.
139          **/
140         Url url() const;
141
142         /**
143          * close url
144          *
145          * \throws MediaException
146          *
147          **/
148         void close();
149
150     public:
151
152         /**
153          * Use concrete handler to attach the media.
154          *
155          * @param next try next available device in turn until end of device
156          * list is reached (for media which are accessible through multiple
157          * devices like cdroms).
158          *
159          * \throws MediaException
160          *
161          **/
162         void attach(bool next = false);
163
164         /**
165          * True if media is attached.
166          *
167          * \throws MediaException
168          *
169          **/
170         bool isAttached() const;
171         
172         bool hasMoreDevices() const;
173
174         /**
175          * Return the local directory that corresponds to medias url,
176          * no matter if media isAttached or not. Files requested will
177          * be available at 'localRoot() + filename' or better
178          * 'localPath( filename )'.
179          *
180          * If media is not open an empty pathname is returned.
181          **/
182         Pathname localRoot() const;
183
184         /**
185          * Short for 'localRoot() + pathname', but returns an empty
186          * pathname if media is not open.
187          *
188          * Files provided will be available at 'localPath(filename)'.
189          **/
190         Pathname localPath( const Pathname & pathname ) const;
191
192         /**
193           Use concrete handler to disconnect the media.
194
195           This is useful for media which e.g. holds open a connection to a
196           server like FTP. After calling disconnect() the media object still is
197           valid and files are present.
198
199           After calling disconnect() it's not possible to call provideFile() or
200           provideDir() anymore.
201          *
202          * \throws MediaException
203          *
204         */
205         void disconnect();
206
207         /**
208          * Use concrete handler to release the media.
209          * @param ejectDev Device to eject. None if empty.
210          *
211          * \throws MediaException
212          *
213          **/
214         void release( const std::string & ejectDev = "" );
215
216         /**
217          * Use concrete handler to provide file denoted by path below
218          * 'attach point'. Filename is interpreted relative to the
219          * attached url and a path prefix is preserved.
220          *
221          * @param cached  If cached is set to true, the function checks, if
222          *                the file already exists and doesn't download it again
223          *                if it does. Currently only the existence is checked,
224          *                no other file attributes.
225          * @param checkonly If this and 'cached' are set to true only the
226          *                  existence of the file is checked but it's not
227          *                  downloaded. If 'cached' is unset an errer is
228          *                  returned always.
229          *
230          * \throws MediaException
231          *
232          **/
233         void provideFile( const Pathname & filename, bool cached = false, bool checkonly = false ) const;
234
235         /**
236          * Remove filename below attach point IFF handler downloads files
237          * to the local filesystem. Never remove anything from media.
238          *
239          * \throws MediaException
240          *
241          **/
242         void releaseFile( const Pathname & filename ) const;
243
244         /**
245          * Use concrete handler to provide directory denoted
246          * by path below 'attach point' (not recursive!).
247          * 'dirname' is interpreted relative to the
248          * attached url and a path prefix is preserved.
249          *
250          * \throws MediaException
251          *
252          **/
253         void provideDir( const Pathname & dirname ) const;
254
255         /**
256          * Use concrete handler to provide directory tree denoted
257          * by path below 'attach point' (recursive!!).
258          * 'dirname' is interpreted relative to the
259          * attached url and a path prefix is preserved.
260          *
261          * \throws MediaException
262          *
263          **/
264         void provideDirTree( const Pathname & dirname ) const;
265
266         /**
267          * Remove directory tree below attach point IFF handler downloads files
268          * to the local filesystem. Never remove anything from media.
269          *
270          * \throws MediaException
271          *
272          **/
273         void releaseDir( const Pathname & dirname ) const;
274
275         /**
276          * Remove pathname below attach point IFF handler downloads files
277          * to the local filesystem. Never remove anything from media.
278          *
279          * If pathname denotes a directory it is recursively removed.
280          * If pathname is empty or '/' everything below the attachpoint
281          * is recursively removed.
282          *
283          * \throws MediaException
284          *
285          **/
286         void releasePath( const Pathname & pathname ) const;
287
288     public:
289
290         /**
291          * Return content of directory on media via retlist. If dots is false
292          * entries starting with '.' are not reported.
293          *
294          * The request is forwarded to the concrete handler,
295          * which may atempt to retieve the content e.g. via 'readdir'
296          *
297          * <B>Caution:</B> This is not supported by all media types.
298          * Be prepared to handle E_not_supported_by_media.
299          *
300          * \throws MediaException
301          *
302          **/
303         void dirInfo( std::list<std::string> & retlist,
304                          const Pathname & dirname, bool dots = true ) const;
305
306         /**
307          * Basically the same as dirInfo above. The content is returned as
308          * filesystem::DirContent, which includes name and filetype of each directory
309          * entry. Retrieving the filetype usg. requires an additional ::stat call for
310          * each entry, thus it's more expensive than a simple readdir.
311          *
312          * <B>Caution:</B> This is not supported by all media types.
313          * Be prepared to handle E_not_supported_by_media.
314          *
315          * \throws MediaException
316          *
317          **/
318         void dirInfo( filesystem::DirContent & retlist,
319                       const Pathname & dirname, bool dots = true ) const;
320
321         /**
322          * check if a file exists
323          *
324          * Asserted that url is a file and not a dir.
325          *
326          * \throws MediaException
327          *
328          **/
329         bool doesFileExist( const Pathname & filename ) const;
330         
331         /**
332          * Destructor
333          **/
334         virtual ~MediaAccess();
335
336     public:
337
338         virtual std::ostream & dumpOn( std::ostream & str ) const;
339
340     public:
341         /**
342          * Get file from location at specified by URL and copy it to
343          * destination.
344          *
345          * @param from Source URL
346          * @param to   Destination file name
347          *
348          * \throws MediaException
349          *
350          **/
351         void getFile( const Url &from, const Pathname &to );
352
353     public:
354
355       /**
356        * Helper class that provides file on construction
357        * and cleans up on destruction.
358        *
359        * <b>Caution:</b> There's no synchronisation between multiple
360        * FileProvider instances, that provide the same file from the
361        * same media. If the first one goes out of scope, the file is
362        * cleaned. It's just a convenience for 'access and forgett'.
363        *
364        * <b>Caution:</b> We should either store the reference MediaAccess'
365        * MediaHandler here (for this MediaHandler must become a
366        * ref counting pointer class), or we need more info from MediaHandler
367        * (whether he's downloading to the local fs. If not, no releasefile
368        * is necessary).
369        * Currently we can not releaseFile after the media was closed
370        * (it's passed to the handler, which is deleted on close).
371        *
372        * \throws MediaBadFilenameException
373        * \throws MediaException
374        **/
375       class FileProvider {
376         FileProvider( const FileProvider & );             // no copy
377         FileProvider & operator=( const FileProvider & ); // no assign
378         private:
379           MediaAccess::constPtr _media;
380           Pathname              _file;
381           Pathname              _local_file;
382         public:
383           /**
384            * \throws MediaException
385            */
386           FileProvider( MediaAccess::constPtr media_r, const Pathname & file_r )
387             : _media( media_r )
388             , _file( file_r )
389             , _local_file( "" )
390           {
391             if ( _file.empty() ) {
392               ZYPP_THROW(MediaBadFilenameException(_file.asString()));
393             } else if ( _media ) {
394               try {
395                 _media->provideFile( _file );
396                 _local_file = _media->localPath( _file );
397               }
398               catch (const MediaException & excpt_r)
399               {
400                 ZYPP_CAUGHT(excpt_r);
401                 _media = NULL;
402                 ZYPP_RETHROW(excpt_r);
403               }
404             }
405           }
406
407           ~FileProvider() {
408             if ( _media )
409             {
410               try {
411                 _media->releaseFile( _file );
412               }
413               catch (const MediaException &excpt_r)
414               {
415                 ZYPP_CAUGHT(excpt_r);
416               }
417               catch(...) {} // No exception from dtor!
418             }
419           }
420
421         public:
422
423           /**
424            * If no error, expect operator() to return the local
425            * Pathname of the provided file.
426            **/
427           Pathname localFile() const { return _local_file; }
428
429           /**
430            * Return the local Pathname of the provided file or
431            * an empty Pathname on error.
432            **/
433           Pathname operator()() const {
434             if ( _media )
435               return _media->localPath( _file );
436             return Pathname();
437           }
438       };
439     };
440
441     std::ostream & operator<<( std::ostream & str, const MediaAccess & obj );
442
443 ///////////////////////////////////////////////////////////////////
444
445   } // namespace media
446 } // namespace zypp
447
448 #endif // ZYPP_MEDIA_MEDIAACCESS_H
449