1/*
2 SPDX-FileCopyrightText: 2007-2011 Aaron Seigo <aseigo@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#ifndef KPACKAGE_PACKAGE_H
8#define KPACKAGE_PACKAGE_H
9
10#include <QCryptographicHash>
11#include <QMetaType>
12#include <QStringList>
13#include <QUrl>
14
15#include <KPluginMetaData>
16
17#include <kpackage/package_export.h>
18
19#include <KJob>
20
21namespace KPackage
22{
23/**
24 * @class Package kpackage/package.h <KPackage/Package>
25 *
26 * @short object representing an installed package
27 *
28 * Package defines what is in a package and provides easy access to the contents.
29 *
30 * To define a package, one might write the following code:
31 *
32 @code
33 Package package;
34
35 package.addDirectoryDefinition("images", "pics/");
36 package.setMimeTypes("images", QStringList{"image/svg", "image/png", "image/jpeg"});
37
38 package.addDirectoryDefinition("scripts", "code/");
39 package.setMimeTypes("scripts", QStringList{"text/\*"});
40
41 package.addFileDefinition("mainscript", "code/main.js");
42 package.setRequired("mainscript", true);
43 @endcode
44 * One may also choose to create a subclass of PackageStructure and include the setup
45 * in the constructor.
46 *
47 * Either way, Package creates a self-documenting contract between the packager and
48 * the application without exposing package internals such as actual on-disk structure
49 * of the package or requiring that all contents be explicitly known ahead of time.
50 *
51 * Subclassing PackageStructure does have provide a number of potential const benefits:
52 * * the package can be notified of path changes via the virtual pathChanged() method
53 * * the subclass may implement mechanisms to install and remove packages using the
54 * virtual install and uninstall methods
55 * * subclasses can be compiled as plugins for easy re-use
56 **/
57// TODO: write documentation on USING a package
58
59class PackagePrivate;
60class PackageStructure;
61
62class KPACKAGE_EXPORT Package
63{
64public:
65 /**
66 * Default constructor
67 *
68 * @param structure if a null pointer is passed in, this will creates an empty (invalid) Package;
69 * otherwise the structure is allowed to set up the Package's initial layout
70 */
71 explicit Package(PackageStructure *structure = nullptr);
72
73 /**
74 * Copy constructor
75 */
76 Package(const Package &other);
77
78 virtual ~Package();
79
80 /**
81 * Assignment operator
82 */
83 Package &operator=(const Package &rhs);
84
85 /**
86 * @return true if this package has a valid PackageStructure associatedw it with it.
87 * A package may not be valid, but have a valid structure. Useful when dealing with
88 * Package objects in a semi-initialized state (e.g. before calling setPath())
89 * @since 5.1
90 */
91 bool hasValidStructure() const;
92
93 /**
94 * @return true if all the required components exist
95 **/
96 bool isValid() const;
97
98 /**
99 * Sets the path to the root of this package
100 * @param path an absolute path, or a relative path to the default package root
101 */
102 void setPath(const QString &path);
103
104 /**
105 * @return the path to the root of this particular package
106 */
107 const QString path() const;
108
109 /**
110 * Get the path to a given file based on the key and an optional filename.
111 * Example: finding the main script in a scripting package:
112 * filePath("mainscript")
113 *
114 * Example: finding a specific image in the images directory:
115 * filePath("images", "myimage.png")
116 *
117 * @param key the key of the file type to look for,
118 * @param filename optional name of the file to locate within the package
119 * @return path to the file on disk. QString() if not found.
120 **/
121 QString filePath(const QByteArray &key, const QString &filename = QString()) const;
122
123 /**
124 * Get the url to a given file based on the key and an optional filename, is the file:// or qrc:// format
125 * Example: finding the main script in a scripting package:
126 * filePath("mainscript")
127 *
128 * Example: finding a specific image in the images directory:
129 * filePath("images", "myimage.png")
130 *
131 * @param key the key of the file type to look for,
132 * @param filename optional name of the file to locate within the package
133 * @return path to the file on disk. QUrl() if not found.
134 * @since 5.41
135 **/
136 QUrl fileUrl(const QByteArray &key, const QString &filename = QString()) const;
137
138 /**
139 * Get the list of files of a given type.
140 *
141 * @param fileType the type of file to look for, as defined in the
142 * package structure.
143 * @return list of files by name, suitable for passing to filePath
144 **/
145 QStringList entryList(const QByteArray &key) const;
146
147 /**
148 * @return true if the item at path exists and is required
149 **/
150 bool isRequired(const QByteArray &key) const;
151
152 /**
153 * @return the mimeTypes associated with the path, if any
154 **/
155 QStringList mimeTypes(const QByteArray &key) const;
156
157 /**
158 * @return the prefix paths inserted between the base path and content entries, in order of priority.
159 * When searching for a file, all paths will be tried in order.
160 */
161 QStringList contentsPrefixPaths() const;
162
163 /**
164 * @return preferred package root. This defaults to kpackage/generic/
165 */
166 QString defaultPackageRoot() const;
167
168 /**
169 * @return true if paths/symlinks outside the package itself should be followed.
170 * By default this is set to false for security reasons.
171 */
172 bool allowExternalPaths() const;
173
174 /**
175 * Sets the metadata for the KPackage. This overwrites the current metadata.
176 * This should be used in case a kpackage gets loaded by name, based
177 * on the path a C++ plugin which has embedded metadata.
178 * @since 5.88
179 */
180 void setMetadata(const KPluginMetaData &data);
181
182 /**
183 * @return the package metadata object.
184 */
185 KPluginMetaData metadata() const;
186
187 /**
188 * @return a hash digest of the contents of the package in hexadecimal form
189 * @since 5.21
190 */
191 QByteArray cryptographicHash(QCryptographicHash::Algorithm algorithm) const;
192
193 /**
194 * Adds a directory to the structure of the package. It is added as
195 * a not-required element with no associated mimeTypes.
196 * If an entry with the given key already exists, the path
197 * is added to it as a search alternative.
198 *
199 * @param key used as an internal label for this directory
200 * @param path the path within the package for this directory
201 */
202 void addDirectoryDefinition(const QByteArray &key, const QString &path);
203
204 /**
205 * Adds a file to the structure of the package. It is added as
206 * a not-required element with no associated mimeTypes.
207 * If an entry with the given key already exists, the path
208 * is added to it as a search alternative.
209 *
210 * @param key used as an internal label for this file
211 * @param path the path within the package for this file
212 */
213 void addFileDefinition(const QByteArray &key, const QString &path);
214
215 /**
216 * Removes a definition from the structure of the package.
217 * @param key the internal label of the file or directory to remove
218 */
219 void removeDefinition(const QByteArray &key);
220
221 /**
222 * Sets whether or not a given part of the structure is required or not.
223 * The path must already have been added using addDirectoryDefinition
224 * or addFileDefinition.
225 *
226 * @param key the entry within the package
227 * @param required true if this entry is required, false if not
228 */
229 void setRequired(const QByteArray &key, bool required);
230
231 /**
232 * Defines the default mimeTypes for any definitions that do not have
233 * associated mimeTypes. Handy for packages with only one or predominantly
234 * one file type.
235 *
236 * @param mimeTypes a list of mimeTypes
237 **/
238 void setDefaultMimeTypes(const QStringList &mimeTypes);
239
240 /**
241 * Define mimeTypes for a given part of the structure
242 * The path must already have been added using addDirectoryDefinition
243 * or addFileDefinition.
244 *
245 * @param key the entry within the package
246 * @param mimeTypes a list of mimeTypes
247 **/
248 void setMimeTypes(const QByteArray &key, const QStringList &mimeTypes);
249
250 /**
251 * Sets the prefixes that all the contents in this package should
252 * appear under. This defaults to "contents/" and is added automatically
253 * between the base path and the entries as defined by the package
254 * structure. Multiple entries can be added.
255 * In this case each file request will be searched in all prefixes in order,
256 * and the first found will be returned.
257 *
258 * @param prefix paths the directory prefix to use
259 */
260 void setContentsPrefixPaths(const QStringList &prefixPaths);
261
262 /**
263 * Sets whether or not external paths/symlinks can be followed by a package
264 * @param allow true if paths/symlinks outside of the package should be followed,
265 * false if they should be rejected.
266 */
267 void setAllowExternalPaths(bool allow);
268
269 /**
270 * Sets preferred package root.
271 */
272 void setDefaultPackageRoot(const QString &packageRoot);
273
274 /**
275 * Sets the fallback package root path
276 * If a file won't be found in this package, it will search it in the package
277 * with the same structure identified by path
278 * It is intended to be used by the packageStructure
279 * @param path package root path @see setPath
280 */
281 void setFallbackPackage(const KPackage::Package &package);
282
283 /**
284 * @return The fallback package root path
285 */
286 KPackage::Package fallbackPackage() const;
287
288 // Content structure description methods
289 /**
290 * @return all directories registered as part of this Package's structure
291 */
292 QList<QByteArray> directories() const;
293
294 /**
295 * @return all directories registered as part of this Package's required structure
296 */
297 QList<QByteArray> requiredDirectories() const;
298
299 /**
300 * @return all files registered as part of this Package's structure
301 */
302 QList<QByteArray> files() const;
303
304 /**
305 * @return all files registered as part of this Package's required structure
306 */
307 QList<QByteArray> requiredFiles() const;
308
309private:
310 QExplicitlySharedDataPointer<PackagePrivate> d;
311 friend class PackagePrivate;
312};
313
314}
315
316Q_DECLARE_METATYPE(KPackage::Package)
317#endif
318

source code of kpackage/src/kpackage/package.h