File indexing completed on 2024-11-10 06:40:39
0001 /* 0002 SPDX-FileCopyrightText: 2007-2011 Aaron Seigo <aseigo@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef KPACKAGE_PACKAGE_H 0008 #define KPACKAGE_PACKAGE_H 0009 0010 #include <QCryptographicHash> 0011 #include <QMetaType> 0012 #include <QStringList> 0013 #include <QUrl> 0014 0015 #include <KPluginMetaData> 0016 0017 #include <kpackage/package_export.h> 0018 0019 #include <KJob> 0020 0021 namespace KPackage 0022 { 0023 /** 0024 * @class Package kpackage/package.h <KPackage/Package> 0025 * 0026 * @short object representing an installed package 0027 * 0028 * Package defines what is in a package and provides easy access to the contents. 0029 * 0030 * To define a package, one might write the following code: 0031 * 0032 @code 0033 Package package; 0034 0035 package.addDirectoryDefinition("images", "pics/"); 0036 package.setMimeTypes("images", QStringList{"image/svg", "image/png", "image/jpeg"}); 0037 0038 package.addDirectoryDefinition("scripts", "code/"); 0039 package.setMimeTypes("scripts", QStringList{"text/\*"}); 0040 0041 package.addFileDefinition("mainscript", "code/main.js"); 0042 package.setRequired("mainscript", true); 0043 @endcode 0044 * One may also choose to create a subclass of PackageStructure and include the setup 0045 * in the constructor. 0046 * 0047 * Either way, Package creates a self-documenting contract between the packager and 0048 * the application without exposing package internals such as actual on-disk structure 0049 * of the package or requiring that all contents be explicitly known ahead of time. 0050 * 0051 * Subclassing PackageStructure does have provide a number of potential const benefits: 0052 * * the package can be notified of path changes via the virtual pathChanged() method 0053 * * the subclass may implement mechanisms to install and remove packages using the 0054 * virtual install and uninstall methods 0055 * * subclasses can be compiled as plugins for easy re-use 0056 **/ 0057 // TODO: write documentation on USING a package 0058 0059 class PackagePrivate; 0060 class PackageStructure; 0061 0062 class KPACKAGE_EXPORT Package 0063 { 0064 public: 0065 /** 0066 * Default constructor 0067 * 0068 * @param structure if a null pointer is passed in, this will creates an empty (invalid) Package; 0069 * otherwise the structure is allowed to set up the Package's initial layout 0070 */ 0071 explicit Package(PackageStructure *structure = nullptr); 0072 0073 /** 0074 * Copy constructor 0075 */ 0076 Package(const Package &other); 0077 0078 virtual ~Package(); 0079 0080 /** 0081 * Assignment operator 0082 */ 0083 Package &operator=(const Package &rhs); 0084 0085 /** 0086 * @return true if this package has a valid PackageStructure associatedw it with it. 0087 * A package may not be valid, but have a valid structure. Useful when dealing with 0088 * Package objects in a semi-initialized state (e.g. before calling setPath()) 0089 * @since 5.1 0090 */ 0091 bool hasValidStructure() const; 0092 0093 /** 0094 * @return true if all the required components exist 0095 **/ 0096 bool isValid() const; 0097 0098 /** 0099 * Sets the path to the root of this package 0100 * @param path an absolute path, or a relative path to the default package root 0101 */ 0102 void setPath(const QString &path); 0103 0104 /** 0105 * @return the path to the root of this particular package 0106 */ 0107 const QString path() const; 0108 0109 /** 0110 * Get the path to a given file based on the key and an optional filename. 0111 * Example: finding the main script in a scripting package: 0112 * filePath("mainscript") 0113 * 0114 * Example: finding a specific image in the images directory: 0115 * filePath("images", "myimage.png") 0116 * 0117 * @param key the key of the file type to look for, 0118 * @param filename optional name of the file to locate within the package 0119 * @return path to the file on disk. QString() if not found. 0120 **/ 0121 QString filePath(const QByteArray &key, const QString &filename = QString()) const; 0122 0123 /** 0124 * Get the url to a given file based on the key and an optional filename, is the file:// or qrc:// format 0125 * Example: finding the main script in a scripting package: 0126 * filePath("mainscript") 0127 * 0128 * Example: finding a specific image in the images directory: 0129 * filePath("images", "myimage.png") 0130 * 0131 * @param key the key of the file type to look for, 0132 * @param filename optional name of the file to locate within the package 0133 * @return path to the file on disk. QUrl() if not found. 0134 * @since 5.41 0135 **/ 0136 QUrl fileUrl(const QByteArray &key, const QString &filename = QString()) const; 0137 0138 /** 0139 * Get the list of files of a given type. 0140 * 0141 * @param fileType the type of file to look for, as defined in the 0142 * package structure. 0143 * @return list of files by name, suitable for passing to filePath 0144 **/ 0145 QStringList entryList(const QByteArray &key) const; 0146 0147 /** 0148 * @return true if the item at path exists and is required 0149 **/ 0150 bool isRequired(const QByteArray &key) const; 0151 0152 /** 0153 * @return the mimeTypes associated with the path, if any 0154 **/ 0155 QStringList mimeTypes(const QByteArray &key) const; 0156 0157 /** 0158 * @return the prefix paths inserted between the base path and content entries, in order of priority. 0159 * When searching for a file, all paths will be tried in order. 0160 */ 0161 QStringList contentsPrefixPaths() const; 0162 0163 /** 0164 * @return preferred package root. This defaults to kpackage/generic/ 0165 */ 0166 QString defaultPackageRoot() const; 0167 0168 /** 0169 * @return true if paths/symlinks outside the package itself should be followed. 0170 * By default this is set to false for security reasons. 0171 */ 0172 bool allowExternalPaths() const; 0173 0174 /** 0175 * Sets the metadata for the KPackage. This overwrites the current metadata. 0176 * This should be used in case a kpackage gets loaded by name, based 0177 * on the path a C++ plugin which has embedded metadata. 0178 * @since 5.88 0179 */ 0180 void setMetadata(const KPluginMetaData &data); 0181 0182 /** 0183 * @return the package metadata object. 0184 */ 0185 KPluginMetaData metadata() const; 0186 0187 /** 0188 * @return a hash digest of the contents of the package in hexadecimal form 0189 * @since 5.21 0190 */ 0191 QByteArray cryptographicHash(QCryptographicHash::Algorithm algorithm) const; 0192 0193 /** 0194 * Adds a directory to the structure of the package. It is added as 0195 * a not-required element with no associated mimeTypes. 0196 * If an entry with the given key already exists, the path 0197 * is added to it as a search alternative. 0198 * 0199 * @param key used as an internal label for this directory 0200 * @param path the path within the package for this directory 0201 */ 0202 void addDirectoryDefinition(const QByteArray &key, const QString &path); 0203 0204 /** 0205 * Adds a file to the structure of the package. It is added as 0206 * a not-required element with no associated mimeTypes. 0207 * If an entry with the given key already exists, the path 0208 * is added to it as a search alternative. 0209 * 0210 * @param key used as an internal label for this file 0211 * @param path the path within the package for this file 0212 */ 0213 void addFileDefinition(const QByteArray &key, const QString &path); 0214 0215 /** 0216 * Removes a definition from the structure of the package. 0217 * @param key the internal label of the file or directory to remove 0218 */ 0219 void removeDefinition(const QByteArray &key); 0220 0221 /** 0222 * Sets whether or not a given part of the structure is required or not. 0223 * The path must already have been added using addDirectoryDefinition 0224 * or addFileDefinition. 0225 * 0226 * @param key the entry within the package 0227 * @param required true if this entry is required, false if not 0228 */ 0229 void setRequired(const QByteArray &key, bool required); 0230 0231 /** 0232 * Defines the default mimeTypes for any definitions that do not have 0233 * associated mimeTypes. Handy for packages with only one or predominantly 0234 * one file type. 0235 * 0236 * @param mimeTypes a list of mimeTypes 0237 **/ 0238 void setDefaultMimeTypes(const QStringList &mimeTypes); 0239 0240 /** 0241 * Define mimeTypes for a given part of the structure 0242 * The path must already have been added using addDirectoryDefinition 0243 * or addFileDefinition. 0244 * 0245 * @param key the entry within the package 0246 * @param mimeTypes a list of mimeTypes 0247 **/ 0248 void setMimeTypes(const QByteArray &key, const QStringList &mimeTypes); 0249 0250 /** 0251 * Sets the prefixes that all the contents in this package should 0252 * appear under. This defaults to "contents/" and is added automatically 0253 * between the base path and the entries as defined by the package 0254 * structure. Multiple entries can be added. 0255 * In this case each file request will be searched in all prefixes in order, 0256 * and the first found will be returned. 0257 * 0258 * @param prefix paths the directory prefix to use 0259 */ 0260 void setContentsPrefixPaths(const QStringList &prefixPaths); 0261 0262 /** 0263 * Sets whether or not external paths/symlinks can be followed by a package 0264 * @param allow true if paths/symlinks outside of the package should be followed, 0265 * false if they should be rejected. 0266 */ 0267 void setAllowExternalPaths(bool allow); 0268 0269 /** 0270 * Sets preferred package root. 0271 */ 0272 void setDefaultPackageRoot(const QString &packageRoot); 0273 0274 /** 0275 * Sets the fallback package root path 0276 * If a file won't be found in this package, it will search it in the package 0277 * with the same structure identified by path 0278 * It is intended to be used by the packageStructure 0279 * @param path package root path @see setPath 0280 */ 0281 void setFallbackPackage(const KPackage::Package &package); 0282 0283 /** 0284 * @return The fallback package root path 0285 */ 0286 KPackage::Package fallbackPackage() const; 0287 0288 // Content structure description methods 0289 /** 0290 * @return all directories registered as part of this Package's structure 0291 */ 0292 QList<QByteArray> directories() const; 0293 0294 /** 0295 * @return all directories registered as part of this Package's required structure 0296 */ 0297 QList<QByteArray> requiredDirectories() const; 0298 0299 /** 0300 * @return all files registered as part of this Package's structure 0301 */ 0302 QList<QByteArray> files() const; 0303 0304 /** 0305 * @return all files registered as part of this Package's required structure 0306 */ 0307 QList<QByteArray> requiredFiles() const; 0308 0309 private: 0310 QExplicitlySharedDataPointer<PackagePrivate> d; 0311 friend class PackagePrivate; 0312 }; 0313 0314 } 0315 0316 Q_DECLARE_METATYPE(KPackage::Package) 0317 #endif