PageRenderTime 58ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/netbeans-7.3/maven/src/org/netbeans/modules/maven/customizer/CustomizerProviderImpl.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 483 lines | 358 code | 49 blank | 76 comment | 51 complexity | 9f8f91f226e46d32c1e31cb4e701648e MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * If you wish your version of this file to be governed by only the CDDL
  28. * or only the GPL Version 2, indicate your decision by adding
  29. * "[Contributor] elects to include this software in this distribution
  30. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  31. * single choice of license, a recipient has the option to distribute
  32. * your version of this file under either the CDDL, the GPL Version 2 or
  33. * to extend the choice of license to its licensees as provided above.
  34. * However, if you add GPL Version 2 code and therefore, elected the GPL
  35. * Version 2 license, then the option applies only if the new code is
  36. * made subject to such option by the copyright holder.
  37. *
  38. * Contributor(s):
  39. *
  40. * Portions Copyrighted 2008 Sun Microsystems, Inc.
  41. */
  42. package org.netbeans.modules.maven.customizer;
  43. import java.awt.Dialog;
  44. import java.awt.event.ActionEvent;
  45. import java.awt.event.ActionListener;
  46. import java.io.*;
  47. import java.util.ArrayList;
  48. import java.util.HashMap;
  49. import java.util.List;
  50. import java.util.Map;
  51. import java.util.TreeMap;
  52. import java.util.logging.Level;
  53. import java.util.logging.Logger;
  54. import org.apache.maven.project.MavenProject;
  55. import org.codehaus.plexus.util.IOUtil;
  56. import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
  57. import org.jdom.DefaultJDOMFactory;
  58. import org.jdom.Document;
  59. import org.jdom.JDOMException;
  60. import org.jdom.JDOMFactory;
  61. import org.jdom.input.SAXBuilder;
  62. import org.jdom.output.Format;
  63. import org.netbeans.api.project.Project;
  64. import org.netbeans.api.project.ProjectUtils;
  65. import org.netbeans.api.project.ui.ProjectProblems;
  66. import org.netbeans.modules.maven.MavenProjectPropsImpl;
  67. import org.netbeans.modules.maven.NbMavenProjectImpl;
  68. import org.netbeans.modules.maven.api.NbMavenProject;
  69. import org.netbeans.modules.maven.api.customizer.ModelHandle;
  70. import org.netbeans.modules.maven.api.customizer.ModelHandle2;
  71. import org.netbeans.modules.maven.api.problem.ProblemReport;
  72. import org.netbeans.modules.maven.configurations.M2ConfigProvider;
  73. import org.netbeans.modules.maven.configurations.M2Configuration;
  74. import org.netbeans.modules.maven.execute.model.ActionToGoalMapping;
  75. import org.netbeans.modules.maven.execute.model.NetbeansActionMapping;
  76. import org.netbeans.modules.maven.execute.model.io.jdom.NetbeansBuildActionJDOMWriter;
  77. import org.netbeans.modules.maven.execute.model.io.xpp3.NetbeansBuildActionXpp3Reader;
  78. import org.netbeans.modules.maven.model.Utilities;
  79. import org.netbeans.modules.maven.model.pom.POMModel;
  80. import org.netbeans.modules.maven.model.pom.POMModelFactory;
  81. import org.netbeans.modules.maven.problems.ProblemReporterImpl;
  82. import org.netbeans.modules.xml.xam.Model.State;
  83. import org.netbeans.modules.xml.xam.ModelSource;
  84. import org.netbeans.spi.project.AuxiliaryConfiguration;
  85. import org.netbeans.spi.project.ProjectServiceProvider;
  86. import org.netbeans.spi.project.ui.CustomizerProvider;
  87. import org.netbeans.spi.project.ui.support.ProjectCustomizer;
  88. import org.openide.DialogDisplayer;
  89. import org.openide.NotifyDescriptor;
  90. import org.openide.filesystems.FileLock;
  91. import org.openide.filesystems.FileObject;
  92. import org.openide.filesystems.FileSystem;
  93. import org.openide.filesystems.FileUtil;
  94. import org.openide.util.Exceptions;
  95. import org.openide.util.HelpCtx;
  96. import org.openide.util.Lookup;
  97. import org.openide.util.lookup.Lookups;
  98. import static org.netbeans.modules.maven.customizer.Bundle.*;
  99. import org.openide.util.NbBundle.Messages;
  100. /**
  101. * maven implementation of CustomizerProvider, handles the general workflow,
  102. *for panel creation delegates to M2CustomizerPanelProvider instances.
  103. * @author Milos Kleint
  104. */
  105. @ProjectServiceProvider(service={CustomizerProvider.class, CustomizerProviderImpl.class}, projectType="org-netbeans-modules-maven")
  106. public class CustomizerProviderImpl implements CustomizerProvider {
  107. private final Project project;
  108. private ModelHandle handle;
  109. private ModelHandle2 handle2;
  110. private static final String BROKEN_NBACTIONS = "BROKENNBACTIONS"; //NOI18N
  111. public CustomizerProviderImpl(Project project) {
  112. this.project = project;
  113. }
  114. @Override
  115. public void showCustomizer() {
  116. showCustomizer( null );
  117. }
  118. public void showCustomizer( String preselectedCategory ) {
  119. showCustomizer( preselectedCategory, null );
  120. }
  121. @Messages({
  122. "TIT_Project_Properties=Project Properties - {0}",
  123. "ERR_MissingPOM=Project's pom.xml file contains invalid xml content. Please fix the file before proceeding.",
  124. "TXT_Unloadable=Project is unloadable, you have to fix the problems before accessing the project properties dialog. Show Problem Resolution dialog?",
  125. "TIT_Unloadable=Project unlodable"
  126. })
  127. public void showCustomizer( String preselectedCategory, String preselectedSubCategory ) {
  128. if (project.getLookup().lookup(NbMavenProject.class).isUnloadable()) {
  129. NotifyDescriptor.Confirmation nd = new NotifyDescriptor.Confirmation(TXT_Unloadable(), TIT_Unloadable());
  130. nd.setOptionType(NotifyDescriptor.YES_NO_OPTION);
  131. if (DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.YES_OPTION) {
  132. ProjectProblems.showCustomizer(project);
  133. }
  134. return;
  135. }
  136. try {
  137. POMModel mdl = init();
  138. //#171958 start
  139. if (!mdl.getState().equals(State.VALID)) {
  140. NotifyDescriptor nd = new NotifyDescriptor.Message(ERR_MissingPOM(), NotifyDescriptor.ERROR_MESSAGE);
  141. DialogDisplayer.getDefault().notify(nd);
  142. return;
  143. }
  144. //#171958 end
  145. // handle.getPOMModel().startTransaction();
  146. // project.getLookup().lookup(MavenProjectPropsImpl.class).startTransaction();
  147. OptionListener listener = new OptionListener();
  148. Lookup context = Lookups.fixed(new Object[] { project, handle, handle2});
  149. Dialog dialog = ProjectCustomizer.createCustomizerDialog("Projects/org-netbeans-modules-maven/Customizer", //NOI18N
  150. context,
  151. preselectedCategory,
  152. new ActionListener() {
  153. @Override
  154. public void actionPerformed(ActionEvent ae) {
  155. //noop
  156. }
  157. }, listener, new HelpCtx("maven_settings"));
  158. //QualitasCorpus.class: Created due to compilation errors
  159. //dialog.setTitle( TIT_Project_Properties(ProjectUtils.getInformation(project).getDisplayName()));
  160. dialog.setModal(true);
  161. dialog.setVisible(true);
  162. } catch (FileNotFoundException ex) {
  163. if ("No pom file exists.".equals(ex.getMessage())) { //NOI18N
  164. //#157020
  165. return;
  166. }
  167. Logger.getLogger(CustomizerProviderImpl.class.getName()).log(Level.SEVERE, "Cannot show project customizer", ex);
  168. } catch (IOException ex) {
  169. Logger.getLogger(CustomizerProviderImpl.class.getName()).log(Level.SEVERE, "Cannot show project customizer", ex);
  170. } catch (XmlPullParserException ex) {
  171. Logger.getLogger(CustomizerProviderImpl.class.getName()).log(Level.SEVERE, "Cannot show project customizer", ex);
  172. }
  173. }
  174. private String TIT_Unloadable() {
  175. // TODO Auto-generated method stub
  176. return null;
  177. }
  178. private Object ERR_MissingPOM() {
  179. // TODO Auto-generated method stub
  180. return null;
  181. }
  182. private Object TXT_Unloadable() {
  183. // TODO Auto-generated method stub
  184. return null;
  185. }
  186. private POMModel init() throws XmlPullParserException, IOException {
  187. FileObject pom = FileUtil.toFileObject(project.getLookup().lookup(NbMavenProjectImpl.class).getPOMFile());
  188. if (pom == null || !pom.isValid()) {
  189. throw new FileNotFoundException("No pom file exists."); //NOI18N
  190. }
  191. ModelSource source = Utilities.createModelSource(pom);
  192. POMModel model = POMModelFactory.getDefault().createFreshModel(source);
  193. Map<String, ActionToGoalMapping> mapps = new HashMap<String, ActionToGoalMapping>();
  194. NetbeansBuildActionXpp3Reader reader = new NetbeansBuildActionXpp3Reader();
  195. List<ModelHandle.Configuration> configs = new ArrayList<ModelHandle.Configuration>();
  196. ModelHandle.Configuration active = null;
  197. M2ConfigProvider provider = project.getLookup().lookup(M2ConfigProvider.class);
  198. M2Configuration act = provider.getActiveConfiguration();
  199. M2Configuration defconfig = provider.getDefaultConfig();
  200. mapps.put(defconfig.getId(), reader.read(new StringReader(defconfig.getRawMappingsAsString())));
  201. ModelHandle.Configuration c = ModelHandle.createDefaultConfiguration();
  202. configs.add(c);
  203. if (act.equals(defconfig)) {
  204. active = c;
  205. }
  206. for (M2Configuration config : provider.getSharedConfigurations()) {
  207. mapps.put(config.getId(), reader.read(new StringReader(config.getRawMappingsAsString())));
  208. c = ModelHandle.createCustomConfiguration(config.getId());
  209. c.setActivatedProfiles(config.getActivatedProfiles());
  210. c.setProperties(config.getProperties());
  211. c.setShared(true);
  212. configs.add(c);
  213. if (act.equals(config)) {
  214. active = c;
  215. }
  216. }
  217. for (M2Configuration config : provider.getNonSharedConfigurations()) {
  218. mapps.put(config.getId(), reader.read(new StringReader(config.getRawMappingsAsString())));
  219. c = ModelHandle.createCustomConfiguration(config.getId());
  220. c.setActivatedProfiles(config.getActivatedProfiles());
  221. c.setProperties(config.getProperties());
  222. c.setShared(false);
  223. configs.add(c);
  224. if (act.equals(config)) {
  225. active = c;
  226. }
  227. }
  228. for (M2Configuration config : provider.getProfileConfigurations()) {
  229. mapps.put(config.getId(), reader.read(new StringReader(config.getRawMappingsAsString())));
  230. c = ModelHandle.createProfileConfiguration(config.getId());
  231. configs.add(c);
  232. if (act.equals(config)) {
  233. active = c;
  234. }
  235. }
  236. if (active == null) { //#152706
  237. active = configs.get(0); //default if current not found..
  238. }
  239. handle = ACCESSOR.createHandle(model,
  240. project.getLookup().lookup(NbMavenProject.class).getMavenProject(), mapps, configs, active,
  241. project.getLookup().lookup(MavenProjectPropsImpl.class));
  242. handle2 = ACCESSOR2.createHandle(model,
  243. project.getLookup().lookup(NbMavenProject.class).getMavenProject(), mapps, new ArrayList<ModelHandle2.Configuration>(configs), active,
  244. project.getLookup().lookup(MavenProjectPropsImpl.class));
  245. return model;
  246. }
  247. public static ModelAccessor ACCESSOR = null;
  248. public static ModelAccessor2 ACCESSOR2 = null;
  249. static {
  250. // invokes static initializer of ModelHandle.class
  251. // that will assign value to the ACCESSOR field above
  252. Class c = ModelHandle.class;
  253. try {
  254. Class.forName(c.getName(), true, c.getClassLoader());
  255. } catch (Exception ex) {
  256. ex.printStackTrace();
  257. }
  258. c = ModelHandle2.class;
  259. try {
  260. Class.forName(c.getName(), true, c.getClassLoader());
  261. } catch (Exception ex) {
  262. ex.printStackTrace();
  263. }
  264. }
  265. public static abstract class ModelAccessor {
  266. public abstract ModelHandle createHandle(POMModel model, MavenProject proj, Map<String, ActionToGoalMapping> mapp,
  267. List<ModelHandle.Configuration> configs, ModelHandle.Configuration active, MavenProjectPropsImpl auxProps);
  268. }
  269. public static abstract class ModelAccessor2 {
  270. public abstract ModelHandle2 createHandle(POMModel model, MavenProject proj, Map<String, ActionToGoalMapping> mapp,
  271. List<ModelHandle2.Configuration> configs, ModelHandle2.Configuration active, MavenProjectPropsImpl auxProps);
  272. public abstract TreeMap<String, String> getModifiedAuxProps(ModelHandle2 handle, boolean shared);
  273. public abstract boolean isConfigurationModified(ModelHandle2 handle);
  274. public abstract boolean isModified(ModelHandle2 handle, ActionToGoalMapping mapp);
  275. }
  276. /** Listens to the actions on the Customizer's option buttons
  277. ONLY STORE listener now.
  278. */
  279. private class OptionListener implements ActionListener {
  280. OptionListener() {
  281. }
  282. // Listening to OK button ----------------------------------------------
  283. @Override
  284. public void actionPerformed( ActionEvent e ) {
  285. final FileObject pom = FileUtil.toFileObject(project.getLookup().lookup(NbMavenProjectImpl.class).getPOMFile());
  286. if (pom == null || !pom.isValid()) {
  287. return; //TODO
  288. }
  289. try {
  290. writeAll(handle2, project.getLookup().lookup(NbMavenProjectImpl.class));
  291. } catch (IOException ex) {
  292. Exceptions.printStackTrace(ex);
  293. //TODO error reporting on wrong model save
  294. }
  295. }
  296. }
  297. static interface SubCategoryProvider {
  298. public void showSubCategory(String name);
  299. }
  300. static void writeAll(ModelHandle2 handle, NbMavenProjectImpl project) throws IOException {
  301. //save configs before pom, to save reloads in case both pom and configs were changed.
  302. boolean performConfigsInvokedReload = false;
  303. M2ConfigProvider prv = project.getLookup().lookup(M2ConfigProvider.class);
  304. if (ACCESSOR2.isConfigurationModified(handle)) {
  305. List<M2Configuration> shared = new ArrayList<M2Configuration>();
  306. List<M2Configuration> nonshared = new ArrayList<M2Configuration>();
  307. for (ModelHandle2.Configuration mdlConf : handle.getConfigurations()) {
  308. if (!mdlConf.isDefault() && !mdlConf.isProfileBased()) {
  309. M2Configuration c = new M2Configuration(mdlConf.getId(), project.getProjectDirectory());
  310. c.setActivatedProfiles(mdlConf.getActivatedProfiles());
  311. c.setProperties(mdlConf.getProperties());
  312. if (mdlConf.isShared()) {
  313. shared.add(c);
  314. } else {
  315. nonshared.add(c);
  316. }
  317. }
  318. }
  319. prv.setConfigurations(shared, nonshared, true);
  320. performConfigsInvokedReload = true;
  321. }
  322. final FileObject pom = FileUtil.toFileObject(project.getLookup().lookup(NbMavenProjectImpl.class).getPOMFile());
  323. Utilities.performPOMModelOperations(pom, handle.getPOMOperations());
  324. AuxiliaryConfiguration aux = project.getLookup().lookup(AuxiliaryConfiguration.class);
  325. if (!ACCESSOR2.getModifiedAuxProps(handle, true).isEmpty()) {
  326. MavenProjectPropsImpl.writeAuxiliaryData(aux, ACCESSOR2.getModifiedAuxProps(handle, true), true);
  327. }
  328. if (!ACCESSOR2.getModifiedAuxProps(handle, false).isEmpty()) {
  329. MavenProjectPropsImpl.writeAuxiliaryData(aux, ACCESSOR2.getModifiedAuxProps(handle, false), false);
  330. }
  331. if (ACCESSOR2.isModified(handle, handle.getActionMappings())) {
  332. writeNbActionsModel(project, handle.getActionMappings(), M2Configuration.getFileNameExt(M2Configuration.DEFAULT));
  333. }
  334. //TODO we need to set the configurations for the case of non profile configs
  335. String id = handle.getActiveConfiguration() != null ? handle.getActiveConfiguration().getId() : M2Configuration.DEFAULT;
  336. for (M2Configuration m2 : prv.getConfigurations()) {
  337. if (id.equals(m2.getId())) {
  338. prv.setActiveConfiguration(m2);
  339. }
  340. }
  341. //save action mappings for configurations..
  342. for (ModelHandle2.Configuration c : handle.getConfigurations()) {
  343. if (ACCESSOR2.isModified(handle,handle.getActionMappings(c))) {
  344. writeNbActionsModel(project, handle.getActionMappings(c), M2Configuration.getFileNameExt(c.getId()));
  345. }
  346. }
  347. if (performConfigsInvokedReload && handle.getPOMOperations().isEmpty()) { //#only do the reload if no change to po file was done. can be actually figured now with operations
  348. //#174637
  349. NbMavenProject.fireMavenProjectReload(project);
  350. }
  351. }
  352. public static void writeNbActionsModel(final FileObject pomDir, final ActionToGoalMapping mapping, final String path) throws IOException {
  353. writeNbActionsModel(null, pomDir, mapping, path);
  354. }
  355. public static void writeNbActionsModel(final Project project, final ActionToGoalMapping mapping, final String path) throws IOException {
  356. writeNbActionsModel(project, project.getProjectDirectory(), mapping, path);
  357. }
  358. @Messages({"TXT_Problem_Broken_Actions=Broken nbactions.xml file.", "DESC_Problem_Broken_Actions=Cannot parse the $project_basedir/nbactions.xml file. The information contained in the file will be ignored until fixed. This affects several features in the IDE that will not work properly as a result.\n\n Parsing exception:\n{0}"})
  359. private static void writeNbActionsModel(final Project project, final FileObject pomDir, final ActionToGoalMapping mapping, final String path) throws IOException {
  360. pomDir.getFileSystem().runAtomicAction(new FileSystem.AtomicAction() {
  361. @Override
  362. public void run() throws IOException {
  363. JDOMFactory factory = new DefaultJDOMFactory();
  364. InputStream inStr = null;
  365. FileLock lock = null;
  366. OutputStreamWriter outStr = null;
  367. try {
  368. Document doc;
  369. if (mapping.getActions().isEmpty()) { //#224450 don't write emtpy nbactions.xml files
  370. FileObject fo = pomDir.getFileObject(path);
  371. if (fo != null) {
  372. fo.delete();
  373. }
  374. return;
  375. }
  376. FileObject fo = pomDir.getFileObject(path);
  377. if (fo == null) {
  378. fo = pomDir.createData(path);
  379. doc = factory.document(factory.element("actions")); //NOI18N
  380. } else {
  381. //TODO..
  382. inStr = fo.getInputStream();
  383. SAXBuilder builder = new SAXBuilder();
  384. doc = builder.build(inStr);
  385. inStr.close();
  386. inStr = null;
  387. }
  388. lock = fo.lock();
  389. NetbeansBuildActionJDOMWriter writer = new NetbeansBuildActionJDOMWriter();
  390. String encoding = mapping.getModelEncoding() != null ? mapping.getModelEncoding() : "UTF-8"; //NOI18N
  391. outStr = new OutputStreamWriter(fo.getOutputStream(lock), encoding);
  392. Format form = Format.getRawFormat().setEncoding(encoding);
  393. form = form.setLineSeparator(System.getProperty("line.separator")); //NOI18N
  394. List<NetbeansActionMapping> maps = mapping.getActions();
  395. //no packaging elements make sense in nbactions files.
  396. for (NetbeansActionMapping m : maps) {
  397. m.setPackagings(null);
  398. }
  399. writer.write(mapping, doc, outStr, form);
  400. } catch (JDOMException exc){
  401. //throw (IOException) new IOException("Cannot parse the nbactions.xml by JDOM.").initCause(exc); //NOI18N
  402. //TODO this would need it's own problem provider, but how to access it in project lookup if all are merged into one?
  403. NbMavenProjectImpl prj = project != null ? project.getLookup().lookup(NbMavenProjectImpl.class) : null;
  404. ProblemReporterImpl impl = prj != null ? prj.getProblemReporter() : null;
  405. if (impl != null && !impl.hasReportWithId(BROKEN_NBACTIONS)) {
  406. ProblemReport rep = new ProblemReport(ProblemReport.SEVERITY_MEDIUM,
  407. TXT_Problem_Broken_Actions(),
  408. DESC_Problem_Broken_Actions(exc.getMessage()),
  409. ProblemReporterImpl.createOpenFileAction(pomDir.getFileObject(path)));
  410. rep.setId(BROKEN_NBACTIONS);
  411. impl.addReport(rep);
  412. }
  413. Logger.getLogger(CustomizerProviderImpl.class.getName()).log(Level.INFO, exc.getMessage(), exc);
  414. } finally {
  415. IOUtil.close(inStr);
  416. IOUtil.close(outStr);
  417. if (lock != null) {
  418. lock.releaseLock();
  419. }
  420. }
  421. }
  422. //QualitasCorpus.class: Created due to compilation errors
  423. private String DESC_Problem_Broken_Actions(String message) {
  424. // TODO Auto-generated method stub
  425. return null;
  426. }
  427. //QualitasCorpus.class: Created due to compilation errors
  428. private String TXT_Problem_Broken_Actions() {
  429. // TODO Auto-generated method stub
  430. return null;
  431. }
  432. });
  433. }
  434. }