| 1 | // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. |
| 2 | // |
| 3 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 4 | |
| 5 | #include "mavenprojectgenerator.h" |
| 6 | #include "mavenasynparse.h" |
| 7 | #include "maven/project/properties/mavenconfigpropertywidget.h" |
| 8 | |
| 9 | #include "services/window/windowservice.h" |
| 10 | #include "services/builder/builderservice.h" |
| 11 | |
| 12 | #include "common/dialog/propertiesdialog.h" |
| 13 | #include "properties/mavenconfigutil.h" |
| 14 | #include "common/util/custompaths.h" |
| 15 | #include "common/util/environment.h" |
| 16 | #include "common/supportfile/dapconfig.h" |
| 17 | #include "services/project/projectservice.h" |
| 18 | |
| 19 | #include <QtXml> |
| 20 | #include <QFileIconProvider> |
| 21 | |
| 22 | using namespace mavenConfig; |
| 23 | using namespace dpfservice; |
| 24 | class MavenProjectGeneratorPrivate |
| 25 | { |
| 26 | friend class MavenProjectGenerator; |
| 27 | QStandardItem* configureRootItem {nullptr}; |
| 28 | QMenu * {nullptr}; |
| 29 | QHash<QStandardItem*, MavenAsynParse*> projectParses {}; |
| 30 | }; |
| 31 | |
| 32 | MavenProjectGenerator::MavenProjectGenerator() |
| 33 | : d(new MavenProjectGeneratorPrivate()) |
| 34 | { |
| 35 | using namespace dpfservice; |
| 36 | auto &ctx = dpfInstance.serviceContext(); |
| 37 | BuilderService *builderService = ctx.service<BuilderService>(BuilderService::name()); |
| 38 | if (!builderService) { |
| 39 | qCritical() << "Failed, not found service : builderService" ; |
| 40 | abort(); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | MavenProjectGenerator::~MavenProjectGenerator() |
| 45 | { |
| 46 | qInfo() << __FUNCTION__; |
| 47 | |
| 48 | if (d) |
| 49 | delete d; |
| 50 | } |
| 51 | |
| 52 | QStringList MavenProjectGenerator::supportLanguages() |
| 53 | { |
| 54 | return {dpfservice::MWMFA_JAVA}; |
| 55 | } |
| 56 | |
| 57 | QStringList MavenProjectGenerator::supportFileNames() |
| 58 | { |
| 59 | return {"pom.xml" }; |
| 60 | } |
| 61 | |
| 62 | QDialog *MavenProjectGenerator::configureWidget(const QString &language, |
| 63 | const QString &workspace) |
| 64 | { |
| 65 | // get config result. |
| 66 | ProjectInfo projectInfo; |
| 67 | projectInfo.setLanguage(language); |
| 68 | projectInfo.setKitName(MavenProjectGenerator::toolKitName()); |
| 69 | projectInfo.setWorkspaceFolder(workspace); |
| 70 | |
| 71 | // refresh config. |
| 72 | restoreRuntimeCfg(projectInfo); |
| 73 | configure(projectInfo); |
| 74 | |
| 75 | return nullptr; |
| 76 | } |
| 77 | |
| 78 | bool MavenProjectGenerator::configure(const dpfservice::ProjectInfo &info) |
| 79 | { |
| 80 | dpfservice::ProjectGenerator::configure(info); |
| 81 | |
| 82 | auto root = createRootItem(info); |
| 83 | using namespace dpfservice; |
| 84 | auto &ctx = dpfInstance.serviceContext(); |
| 85 | ProjectService *projectService = ctx.service<ProjectService>(ProjectService::name()); |
| 86 | if (projectService && root) { |
| 87 | projectService->projectView.addRootItem(root); |
| 88 | projectService->projectView.expandedDepth(root, 1); |
| 89 | } |
| 90 | |
| 91 | return true; |
| 92 | } |
| 93 | |
| 94 | QStandardItem *MavenProjectGenerator::createRootItem(const dpfservice::ProjectInfo &info) |
| 95 | { |
| 96 | using namespace dpfservice; |
| 97 | QStandardItem *rootItem = ProjectGenerator::createRootItem(info); |
| 98 | dpfservice::ProjectInfo::set(rootItem, info); |
| 99 | d->projectParses[rootItem] = new MavenAsynParse(); |
| 100 | QObject::connect(d->projectParses[rootItem], &MavenAsynParse::itemsModified, |
| 101 | this, &MavenProjectGenerator::itemModified); |
| 102 | QMetaObject::invokeMethod(d->projectParses[rootItem], "parseProject" , |
| 103 | Q_ARG(const dpfservice::ProjectInfo &, info)); |
| 104 | return rootItem; |
| 105 | } |
| 106 | |
| 107 | void MavenProjectGenerator::removeRootItem(QStandardItem *root) |
| 108 | { |
| 109 | if (!root) |
| 110 | return; |
| 111 | auto parser = d->projectParses[root]; |
| 112 | |
| 113 | while (root->hasChildren()) { |
| 114 | root->takeRow(0); |
| 115 | } |
| 116 | d->projectParses.remove(root); |
| 117 | |
| 118 | delete root; |
| 119 | |
| 120 | if (parser) |
| 121 | delete parser; |
| 122 | } |
| 123 | |
| 124 | QMenu *MavenProjectGenerator::createItemMenu(const QStandardItem *item) |
| 125 | { |
| 126 | if (item->parent()) |
| 127 | return nullptr; |
| 128 | |
| 129 | QMenu * = new QMenu(); |
| 130 | if (!d->mavenMenu) { |
| 131 | d->mavenMenu = new QMenu("Maven" , menu); |
| 132 | QObject::connect(d->mavenMenu, &QMenu::destroyed, |
| 133 | [=](){ |
| 134 | d->mavenMenu = nullptr; |
| 135 | }); |
| 136 | } |
| 137 | |
| 138 | menu->addMenu(d->mavenMenu); |
| 139 | |
| 140 | // asyn parse |
| 141 | using namespace dpfservice; |
| 142 | |
| 143 | QStandardItem *itemTemp = const_cast<QStandardItem *>(item); |
| 144 | if (!itemTemp) |
| 145 | return d->mavenMenu; |
| 146 | |
| 147 | auto parse = d->projectParses[itemTemp]; |
| 148 | if (!parse) |
| 149 | return d->mavenMenu; |
| 150 | |
| 151 | ProjectInfo info = ProjectInfo::get(item); |
| 152 | if (info.isEmpty()) |
| 153 | return d->mavenMenu; |
| 154 | |
| 155 | // add menu generat call back |
| 156 | QObject::connect(parse, &MavenAsynParse::parsedActions, |
| 157 | this, &MavenProjectGenerator::doAddMavenMeue, |
| 158 | Qt::UniqueConnection); |
| 159 | // execute logic |
| 160 | parse->parseActions(info); |
| 161 | |
| 162 | QAction *action = new QAction(tr("Properties" )); |
| 163 | menu->addAction(action); |
| 164 | QObject::connect(action, &QAction::triggered, [=](){ |
| 165 | actionProperties(info, itemTemp); |
| 166 | }); |
| 167 | |
| 168 | return menu; |
| 169 | } |
| 170 | |
| 171 | void MavenProjectGenerator::itemModified(const QList<QStandardItem *> &items) |
| 172 | { |
| 173 | MavenAsynParse *parse = qobject_cast<MavenAsynParse*>(sender()); |
| 174 | if (parse) { |
| 175 | auto root = d->projectParses.key(parse); |
| 176 | emit itemChanged(root, items); |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | void MavenProjectGenerator::(const dpfservice::ProjectActionInfos &infos) |
| 181 | { |
| 182 | if (d->mavenMenu) { |
| 183 | for (auto actionInfo : infos) { |
| 184 | QAction *action = new QAction(actionInfo.displyText, d->mavenMenu); |
| 185 | dpfservice::ProjectMenuActionInfo::set(action, actionInfo); |
| 186 | d->mavenMenu->addAction(action); |
| 187 | QObject::connect(action, &QAction::triggered, |
| 188 | this, &MavenProjectGenerator::doActionTriggered, |
| 189 | Qt::UniqueConnection); |
| 190 | } |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | void MavenProjectGenerator::doActionTriggered() |
| 195 | { |
| 196 | QAction *action = qobject_cast<QAction*>(sender()); |
| 197 | if (action) { |
| 198 | auto value = dpfservice::ProjectMenuActionInfo::get(action); |
| 199 | |
| 200 | auto &ctx = dpfInstance.serviceContext(); |
| 201 | auto builderService = ctx.service<dpfservice::BuilderService>(dpfservice::BuilderService::name()); |
| 202 | if (builderService) { |
| 203 | BuildCommandInfo commandInfo; |
| 204 | commandInfo.kitName = toolKitName(); |
| 205 | commandInfo.program = value.buildProgram; |
| 206 | commandInfo.arguments = value.buildArguments; |
| 207 | commandInfo.workingDir = QFileInfo(value.workingDirectory).path(); |
| 208 | builderService->interface.builderCommand({commandInfo}, false); |
| 209 | } |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | void MavenProjectGenerator::actionProperties(const dpfservice::ProjectInfo &info, QStandardItem *item) |
| 214 | { |
| 215 | PropertiesDialog dlg; |
| 216 | MavenConfigPropertyWidget *property = new MavenConfigPropertyWidget(info, item); |
| 217 | dlg.insertPropertyPanel("Config" , property); |
| 218 | dlg.exec(); |
| 219 | } |
| 220 | |
| 221 | void MavenProjectGenerator::restoreRuntimeCfg(dpfservice::ProjectInfo &projectInfo) |
| 222 | { |
| 223 | // get project config. |
| 224 | ConfigureParam *cfgParams = ConfigUtil::instance()->getConfigureParamPointer(); |
| 225 | ConfigUtil::instance()->readConfig(ConfigUtil::instance()->getConfigPath(projectInfo.workspaceFolder()), *cfgParams); |
| 226 | |
| 227 | // get global config. |
| 228 | QString arch = ProcessUtil::localPlatform(); |
| 229 | QString dapSupportFilePath = support_file::DapSupportConfig::globalPath(); |
| 230 | QString configHomePath = env::pkg::native::path();// CustomPaths::user(CustomPaths::Configures) + QDir::separator(); |
| 231 | support_file::JavaDapPluginConfig javaDapPluginConfig; |
| 232 | bool ret = support_file::DapSupportConfig::readFromSupportFile(dapSupportFilePath, arch, javaDapPluginConfig, configHomePath); |
| 233 | if (!ret) { |
| 234 | qDebug("Read dapconfig.support failed, please check the file and retry." ); |
| 235 | return; |
| 236 | } |
| 237 | |
| 238 | // use global config when project config is null. |
| 239 | auto setPropertyParams = [&](QString &projectProperty, const QString &key, const QString &globalPropery){ |
| 240 | if (projectProperty.isEmpty()) { |
| 241 | // use global propery. |
| 242 | projectInfo.setProperty(key, globalPropery); |
| 243 | projectProperty = globalPropery; |
| 244 | } else { |
| 245 | // use project propery. |
| 246 | projectInfo.setProperty(key, projectProperty); |
| 247 | } |
| 248 | }; |
| 249 | setPropertyParams(cfgParams->jrePath, kJrePath, javaDapPluginConfig.jrePath); |
| 250 | setPropertyParams(cfgParams->jreExecute, kJreExecute, javaDapPluginConfig.jreExecute); |
| 251 | setPropertyParams(cfgParams->launchConfigPath, kLaunchConfigPath, javaDapPluginConfig.launchConfigPath); |
| 252 | setPropertyParams(cfgParams->launchPackageFile, kLaunchPackageFile, javaDapPluginConfig.launchPackageFile); |
| 253 | setPropertyParams(cfgParams->dapPackageFile, kDapPackageFile, javaDapPluginConfig.dapPackageFile); |
| 254 | projectInfo.setDetailInformation(cfgParams->detailInfo); |
| 255 | } |
| 256 | |