Lines 45-58
Link Here
|
45 |
import java.awt.Dialog; |
45 |
import java.awt.Dialog; |
46 |
import java.awt.event.ActionEvent; |
46 |
import java.awt.event.ActionEvent; |
47 |
import java.awt.event.ActionListener; |
47 |
import java.awt.event.ActionListener; |
48 |
import java.awt.event.WindowAdapter; |
|
|
49 |
import java.awt.event.WindowEvent; |
50 |
import java.io.*; |
48 |
import java.io.*; |
51 |
import java.text.MessageFormat; |
49 |
import java.text.MessageFormat; |
52 |
import java.util.ArrayList; |
50 |
import java.util.ArrayList; |
53 |
import java.util.HashMap; |
51 |
import java.util.HashMap; |
54 |
import java.util.List; |
52 |
import java.util.List; |
55 |
import java.util.Map; |
53 |
import java.util.Map; |
|
|
54 |
import java.util.TreeMap; |
56 |
import java.util.logging.Level; |
55 |
import java.util.logging.Level; |
57 |
import java.util.logging.Logger; |
56 |
import java.util.logging.Logger; |
58 |
import javax.swing.AbstractAction; |
57 |
import javax.swing.AbstractAction; |
Lines 73-78
Link Here
|
73 |
import org.netbeans.modules.maven.NbMavenProjectImpl; |
72 |
import org.netbeans.modules.maven.NbMavenProjectImpl; |
74 |
import org.netbeans.modules.maven.api.NbMavenProject; |
73 |
import org.netbeans.modules.maven.api.NbMavenProject; |
75 |
import org.netbeans.modules.maven.api.customizer.ModelHandle; |
74 |
import org.netbeans.modules.maven.api.customizer.ModelHandle; |
|
|
75 |
import org.netbeans.modules.maven.api.customizer.ModelHandle2; |
76 |
import org.netbeans.modules.maven.api.problem.ProblemReport; |
76 |
import org.netbeans.modules.maven.api.problem.ProblemReport; |
77 |
import org.netbeans.modules.maven.configurations.M2ConfigProvider; |
77 |
import org.netbeans.modules.maven.configurations.M2ConfigProvider; |
78 |
import org.netbeans.modules.maven.configurations.M2Configuration; |
78 |
import org.netbeans.modules.maven.configurations.M2Configuration; |
Lines 86-91
Link Here
|
86 |
import org.netbeans.modules.maven.problems.ProblemReporterImpl; |
86 |
import org.netbeans.modules.maven.problems.ProblemReporterImpl; |
87 |
import org.netbeans.modules.xml.xam.Model.State; |
87 |
import org.netbeans.modules.xml.xam.Model.State; |
88 |
import org.netbeans.modules.xml.xam.ModelSource; |
88 |
import org.netbeans.modules.xml.xam.ModelSource; |
|
|
89 |
import org.netbeans.spi.project.AuxiliaryConfiguration; |
89 |
import org.netbeans.spi.project.ProjectServiceProvider; |
90 |
import org.netbeans.spi.project.ProjectServiceProvider; |
90 |
import org.netbeans.spi.project.ui.CustomizerProvider; |
91 |
import org.netbeans.spi.project.ui.CustomizerProvider; |
91 |
import org.netbeans.spi.project.ui.support.ProjectCustomizer; |
92 |
import org.netbeans.spi.project.ui.support.ProjectCustomizer; |
Lines 103-112
Link Here
|
103 |
import org.openide.util.Lookup; |
104 |
import org.openide.util.Lookup; |
104 |
import org.openide.util.NbBundle; |
105 |
import org.openide.util.NbBundle; |
105 |
import org.openide.util.lookup.Lookups; |
106 |
import org.openide.util.lookup.Lookups; |
|
|
107 |
import static org.netbeans.modules.maven.customizer.Bundle.*; |
108 |
import org.openide.util.NbBundle.Messages; |
106 |
|
109 |
|
107 |
/** |
110 |
/** |
108 |
* maven implementation of CustomizerProvider, handles the general workflow, |
111 |
* maven implementation of CustomizerProvider, handles the general workflow, |
109 |
*for panel creation depegates to M2CustomizerPanelProvider instances. |
112 |
*for panel creation delegates to M2CustomizerPanelProvider instances. |
110 |
* @author Milos Kleint |
113 |
* @author Milos Kleint |
111 |
*/ |
114 |
*/ |
112 |
@ProjectServiceProvider(service={CustomizerProvider.class, CustomizerProviderImpl.class}, projectType="org-netbeans-modules-maven") |
115 |
@ProjectServiceProvider(service={CustomizerProvider.class, CustomizerProviderImpl.class}, projectType="org-netbeans-modules-maven") |
Lines 114-119
Link Here
|
114 |
|
117 |
|
115 |
private final Project project; |
118 |
private final Project project; |
116 |
private ModelHandle handle; |
119 |
private ModelHandle handle; |
|
|
120 |
private ModelHandle2 handle2; |
117 |
|
121 |
|
118 |
private static final String BROKEN_NBACTIONS = "BROKENNBACTIONS"; //NOI18N |
122 |
private static final String BROKEN_NBACTIONS = "BROKENNBACTIONS"; //NOI18N |
119 |
|
123 |
|
Lines 131-164
Link Here
|
131 |
showCustomizer( preselectedCategory, null ); |
135 |
showCustomizer( preselectedCategory, null ); |
132 |
} |
136 |
} |
133 |
|
137 |
|
|
|
138 |
@Messages({ |
139 |
"TIT_Project_Properties=Project Properties - {0}", |
140 |
"ERR_MissingPOM=Project's pom.xml file contains invalid xml content. Please fix the file before proceeding."}) |
134 |
public void showCustomizer( String preselectedCategory, String preselectedSubCategory ) { |
141 |
public void showCustomizer( String preselectedCategory, String preselectedSubCategory ) { |
135 |
try { |
142 |
try { |
136 |
init(); |
143 |
POMModel mdl = init(); |
137 |
//#171958 start |
144 |
//#171958 start |
138 |
try { |
145 |
if (!mdl.getState().equals(State.VALID)) { |
139 |
handle.getPOMModel().sync(); |
146 |
NotifyDescriptor nd = new NotifyDescriptor.Message(ERR_MissingPOM(), NotifyDescriptor.ERROR_MESSAGE); |
140 |
} catch (IOException ex) { |
|
|
141 |
Logger.getLogger(CustomizerProviderImpl.class.getName()).log(Level.INFO, "Error while syncing the editor document with model for pom.xml file", ex); //NOI18N |
142 |
} |
143 |
if (!handle.getPOMModel().getState().equals(State.VALID)) { |
144 |
NotifyDescriptor nd = new NotifyDescriptor.Message(NbBundle.getMessage(CustomizerProviderImpl.class, "ERR_MissingPOM"), NotifyDescriptor.ERROR_MESSAGE); |
145 |
DialogDisplayer.getDefault().notify(nd); |
147 |
DialogDisplayer.getDefault().notify(nd); |
146 |
return; |
148 |
return; |
147 |
} |
149 |
} |
148 |
//#171958 end |
150 |
//#171958 end |
149 |
|
151 |
|
150 |
handle.getPOMModel().startTransaction(); |
152 |
// handle.getPOMModel().startTransaction(); |
151 |
project.getLookup().lookup(MavenProjectPropsImpl.class).startTransaction(); |
153 |
// project.getLookup().lookup(MavenProjectPropsImpl.class).startTransaction(); |
152 |
OptionListener listener = new OptionListener(); |
154 |
OptionListener listener = new OptionListener(); |
153 |
Lookup context = Lookups.fixed(new Object[] { project, handle}); |
155 |
Lookup context = Lookups.fixed(new Object[] { project, handle, handle2}); |
154 |
Dialog dialog = ProjectCustomizer.createCustomizerDialog("Projects/org-netbeans-modules-maven/Customizer", //NOI18N |
156 |
Dialog dialog = ProjectCustomizer.createCustomizerDialog("Projects/org-netbeans-modules-maven/Customizer", //NOI18N |
155 |
context, |
157 |
context, |
156 |
preselectedCategory, listener, listener, new HelpCtx("maven_settings")); |
158 |
preselectedCategory, |
157 |
dialog.addWindowListener( listener ); |
159 |
new ActionListener() { |
158 |
listener.setDialog(dialog); |
160 |
@Override |
159 |
dialog.setTitle( MessageFormat.format( |
161 |
public void actionPerformed(ActionEvent ae) { |
160 |
org.openide.util.NbBundle.getMessage(CustomizerProviderImpl.class, "TIT_Project_Properties"), |
162 |
//noop |
161 |
new Object[] { ProjectUtils.getInformation(project).getDisplayName() } ) ); |
163 |
} |
|
|
164 |
}, listener, new HelpCtx("maven_settings")); |
165 |
dialog.setTitle( TIT_Project_Properties(ProjectUtils.getInformation(project).getDisplayName())); |
162 |
dialog.setModal(true); |
166 |
dialog.setModal(true); |
163 |
dialog.setVisible(true); |
167 |
dialog.setVisible(true); |
164 |
} catch (FileNotFoundException ex) { |
168 |
} catch (FileNotFoundException ex) { |
Lines 174-186
Link Here
|
174 |
} |
178 |
} |
175 |
} |
179 |
} |
176 |
|
180 |
|
177 |
private void init() throws XmlPullParserException, IOException { |
181 |
private POMModel init() throws XmlPullParserException, IOException { |
178 |
FileObject pom = FileUtil.toFileObject(project.getLookup().lookup(NbMavenProjectImpl.class).getPOMFile()); |
182 |
FileObject pom = FileUtil.toFileObject(project.getLookup().lookup(NbMavenProjectImpl.class).getPOMFile()); |
179 |
if (pom == null || !pom.isValid()) { |
183 |
if (pom == null || !pom.isValid()) { |
180 |
throw new FileNotFoundException("No pom file exists."); //NOI18N |
184 |
throw new FileNotFoundException("No pom file exists."); //NOI18N |
181 |
} |
185 |
} |
182 |
ModelSource source = Utilities.createModelSource(pom); |
186 |
ModelSource source = Utilities.createModelSource(pom); |
183 |
POMModel model = POMModelFactory.getDefault().getModel(source); |
187 |
POMModel model = POMModelFactory.getDefault().createFreshModel(source); |
|
|
188 |
|
184 |
Map<String, ActionToGoalMapping> mapps = new HashMap<String, ActionToGoalMapping>(); |
189 |
Map<String, ActionToGoalMapping> mapps = new HashMap<String, ActionToGoalMapping>(); |
185 |
NetbeansBuildActionXpp3Reader reader = new NetbeansBuildActionXpp3Reader(); |
190 |
NetbeansBuildActionXpp3Reader reader = new NetbeansBuildActionXpp3Reader(); |
186 |
List<ModelHandle.Configuration> configs = new ArrayList<ModelHandle.Configuration>(); |
191 |
List<ModelHandle.Configuration> configs = new ArrayList<ModelHandle.Configuration>(); |
Lines 230-238
Link Here
|
230 |
handle = ACCESSOR.createHandle(model, |
235 |
handle = ACCESSOR.createHandle(model, |
231 |
project.getLookup().lookup(NbMavenProject.class).getMavenProject(), mapps, configs, active, |
236 |
project.getLookup().lookup(NbMavenProject.class).getMavenProject(), mapps, configs, active, |
232 |
project.getLookup().lookup(MavenProjectPropsImpl.class)); |
237 |
project.getLookup().lookup(MavenProjectPropsImpl.class)); |
|
|
238 |
handle2 = ACCESSOR2.createHandle(model, |
239 |
project.getLookup().lookup(NbMavenProject.class).getMavenProject(), mapps, new ArrayList<ModelHandle2.Configuration>(configs), active, |
240 |
project.getLookup().lookup(MavenProjectPropsImpl.class)); |
241 |
return model; |
233 |
} |
242 |
} |
234 |
|
243 |
|
235 |
public static ModelAccessor ACCESSOR = null; |
244 |
public static ModelAccessor ACCESSOR = null; |
|
|
245 |
public static ModelAccessor2 ACCESSOR2 = null; |
236 |
|
246 |
|
237 |
static { |
247 |
static { |
238 |
// invokes static initializer of ModelHandle.class |
248 |
// invokes static initializer of ModelHandle.class |
Lines 243-249
Link Here
|
243 |
} catch (Exception ex) { |
253 |
} catch (Exception ex) { |
244 |
ex.printStackTrace(); |
254 |
ex.printStackTrace(); |
245 |
} |
255 |
} |
|
|
256 |
c = ModelHandle2.class; |
257 |
try { |
258 |
Class.forName(c.getName(), true, c.getClassLoader()); |
259 |
} catch (Exception ex) { |
260 |
ex.printStackTrace(); |
246 |
} |
261 |
} |
|
|
262 |
} |
247 |
|
263 |
|
248 |
|
264 |
|
249 |
public static abstract class ModelAccessor { |
265 |
public static abstract class ModelAccessor { |
Lines 252-347
Link Here
|
252 |
List<ModelHandle.Configuration> configs, ModelHandle.Configuration active, MavenProjectPropsImpl auxProps); |
268 |
List<ModelHandle.Configuration> configs, ModelHandle.Configuration active, MavenProjectPropsImpl auxProps); |
253 |
|
269 |
|
254 |
} |
270 |
} |
255 |
/** Listens to the actions on the Customizer's option buttons */ |
|
|
256 |
private class OptionListener extends WindowAdapter implements ActionListener { |
257 |
private Dialog dialog; |
258 |
private boolean weAreSaving = false; |
259 |
|
271 |
|
260 |
OptionListener() { |
272 |
public static abstract class ModelAccessor2 { |
|
|
273 |
|
274 |
public abstract ModelHandle2 createHandle(POMModel model, MavenProject proj, Map<String, ActionToGoalMapping> mapp, |
275 |
List<ModelHandle2.Configuration> configs, ModelHandle2.Configuration active, MavenProjectPropsImpl auxProps); |
276 |
|
277 |
public abstract TreeMap<String, String> getModifiedAuxProps(ModelHandle2 handle, boolean shared); |
278 |
|
279 |
public abstract boolean isConfigurationModified(ModelHandle2 handle); |
280 |
|
281 |
public abstract boolean isModified(ModelHandle2 handle, ActionToGoalMapping mapp); |
282 |
|
261 |
} |
283 |
} |
262 |
|
284 |
|
263 |
void setDialog(Dialog dlg) { |
285 |
/** Listens to the actions on the Customizer's option buttons |
264 |
dialog = dlg; |
286 |
ONLY STORE listener now. |
|
|
287 |
*/ |
288 |
private class OptionListener implements ActionListener { |
289 |
|
290 |
OptionListener() { |
265 |
} |
291 |
} |
266 |
|
292 |
|
|
|
293 |
|
267 |
// Listening to OK button ---------------------------------------------- |
294 |
// Listening to OK button ---------------------------------------------- |
268 |
|
295 |
|
269 |
@Override |
296 |
@Override |
270 |
public void actionPerformed( ActionEvent e ) { |
297 |
public void actionPerformed( ActionEvent e ) { |
271 |
if (SwingUtilities.isEventDispatchThread()) { // OK option listener |
298 |
final FileObject pom = FileUtil.toFileObject(project.getLookup().lookup(NbMavenProjectImpl.class).getPOMFile()); |
272 |
if ( dialog != null ) { |
299 |
if (pom == null || !pom.isValid()) { |
273 |
dialog.setVisible(false); |
300 |
return; //TODO |
274 |
dialog.dispose(); |
|
|
275 |
dialog = null; |
276 |
weAreSaving = true; |
277 |
} |
301 |
} |
278 |
} else { // store listener |
302 |
|
279 |
//we need to finish transactions in the same thread we initiated them, doh.. |
|
|
280 |
// but #189854: this cannot be while holding project mutex |
281 |
// and #192051: must happen before the other stuff |
282 |
SwingUtilities.invokeLater(new Runnable() { |
283 |
public @Override void run() { |
284 |
if (handle.getPOMModel().isIntransaction()) { |
285 |
if (handle.isModified(handle.getPOMModel())) { |
286 |
handle.getPOMModel().endTransaction(); |
287 |
} else { |
288 |
handle.getPOMModel().rollbackTransaction(); |
289 |
} |
290 |
} |
291 |
try { |
303 |
try { |
292 |
project.getProjectDirectory().getFileSystem().runAtomicAction(new FileSystem.AtomicAction() { |
304 |
writeAll(handle2, project.getLookup().lookup(NbMavenProjectImpl.class)); |
293 |
@Override |
|
|
294 |
public void run() throws IOException { |
295 |
project.getLookup().lookup(MavenProjectPropsImpl.class).commitTransaction(); |
296 |
writeAll(handle, project.getLookup().lookup(NbMavenProjectImpl.class)); |
297 |
} |
298 |
}); |
299 |
} catch (IOException ex) { |
305 |
} catch (IOException ex) { |
300 |
Exceptions.printStackTrace(ex); |
306 |
Exceptions.printStackTrace(ex); |
301 |
//TODO error reporting on wrong model save |
307 |
//TODO error reporting on wrong model save |
302 |
} |
308 |
} |
303 |
} |
309 |
} |
304 |
}); |
|
|
305 |
} |
310 |
} |
306 |
} |
|
|
307 |
|
311 |
|
308 |
// Listening to window events ------------------------------------------ |
|
|
309 |
|
310 |
@Override |
311 |
public void windowClosed( WindowEvent e) { |
312 |
if (!weAreSaving) { |
313 |
//TODO where to put elsewhere? |
314 |
project.getLookup().lookup(MavenProjectPropsImpl.class).cancelTransaction(); |
315 |
if (handle.getPOMModel().isIntransaction()) { |
316 |
handle.getPOMModel().rollbackTransaction(); |
317 |
} |
318 |
assert !handle.getPOMModel().isIntransaction(); |
319 |
} |
320 |
} |
321 |
|
322 |
@Override |
323 |
public void windowClosing(WindowEvent e) { |
324 |
if ( dialog != null ) { |
325 |
dialog.setVisible(false); |
326 |
dialog.dispose(); |
327 |
dialog = null; |
328 |
} |
329 |
} |
330 |
|
331 |
} |
332 |
|
333 |
static interface SubCategoryProvider { |
312 |
static interface SubCategoryProvider { |
334 |
public void showSubCategory(String name); |
313 |
public void showSubCategory(String name); |
335 |
} |
314 |
} |
336 |
|
315 |
|
337 |
public static void writeAll(ModelHandle handle, NbMavenProjectImpl project) throws IOException { |
316 |
static void writeAll(ModelHandle2 handle, NbMavenProjectImpl project) throws IOException { |
338 |
//save configs before pom, to save reloads in case both pom and configs were changed. |
317 |
//save configs before pom, to save reloads in case both pom and configs were changed. |
339 |
boolean performConfigsInvokedReload = false; |
318 |
boolean performConfigsInvokedReload = false; |
340 |
M2ConfigProvider prv = project.getLookup().lookup(M2ConfigProvider.class); |
319 |
M2ConfigProvider prv = project.getLookup().lookup(M2ConfigProvider.class); |
341 |
if (handle.isModified(handle.getConfigurations())) { |
320 |
if (ACCESSOR2.isConfigurationModified(handle)) { |
342 |
List<M2Configuration> shared = new ArrayList<M2Configuration>(); |
321 |
List<M2Configuration> shared = new ArrayList<M2Configuration>(); |
343 |
List<M2Configuration> nonshared = new ArrayList<M2Configuration>(); |
322 |
List<M2Configuration> nonshared = new ArrayList<M2Configuration>(); |
344 |
for (ModelHandle.Configuration mdlConf : handle.getConfigurations()) { |
323 |
for (ModelHandle2.Configuration mdlConf : handle.getConfigurations()) { |
345 |
if (!mdlConf.isDefault() && !mdlConf.isProfileBased()) { |
324 |
if (!mdlConf.isDefault() && !mdlConf.isProfileBased()) { |
346 |
M2Configuration c = new M2Configuration(mdlConf.getId(), project); |
325 |
M2Configuration c = new M2Configuration(mdlConf.getId(), project); |
347 |
c.setActivatedProfiles(mdlConf.getActivatedProfiles()); |
326 |
c.setActivatedProfiles(mdlConf.getActivatedProfiles()); |
Lines 355-363
Link Here
|
355 |
prv.setConfigurations(shared, nonshared, true); |
334 |
prv.setConfigurations(shared, nonshared, true); |
356 |
performConfigsInvokedReload = true; |
335 |
performConfigsInvokedReload = true; |
357 |
} |
336 |
} |
|
|
337 |
final FileObject pom = FileUtil.toFileObject(project.getLookup().lookup(NbMavenProjectImpl.class).getPOMFile()); |
338 |
Utilities.performPOMModelOperations(pom, handle.getPOMOperations()); |
358 |
|
339 |
|
359 |
Utilities.saveChanges(handle.getPOMModel()); |
340 |
AuxiliaryConfiguration aux = project.getLookup().lookup(AuxiliaryConfiguration.class); |
360 |
if (handle.isModified(handle.getActionMappings())) { |
341 |
if (!ACCESSOR2.getModifiedAuxProps(handle, true).isEmpty()) { |
|
|
342 |
MavenProjectPropsImpl.writeAuxiliaryData(aux, ACCESSOR2.getModifiedAuxProps(handle, true), true); |
343 |
} |
344 |
if (!ACCESSOR2.getModifiedAuxProps(handle, false).isEmpty()) { |
345 |
MavenProjectPropsImpl.writeAuxiliaryData(aux, ACCESSOR2.getModifiedAuxProps(handle, false), false); |
346 |
} |
347 |
|
348 |
if (ACCESSOR2.isModified(handle, handle.getActionMappings())) { |
361 |
writeNbActionsModel(project, handle.getActionMappings(), M2Configuration.getFileNameExt(M2Configuration.DEFAULT)); |
349 |
writeNbActionsModel(project, handle.getActionMappings(), M2Configuration.getFileNameExt(M2Configuration.DEFAULT)); |
362 |
} |
350 |
} |
363 |
|
351 |
|
Lines 369-380
Link Here
|
369 |
} |
357 |
} |
370 |
} |
358 |
} |
371 |
//save action mappings for configurations.. |
359 |
//save action mappings for configurations.. |
372 |
for (ModelHandle.Configuration c : handle.getConfigurations()) { |
360 |
for (ModelHandle2.Configuration c : handle.getConfigurations()) { |
373 |
if (handle.isModified(handle.getActionMappings(c))) { |
361 |
if (ACCESSOR2.isModified(handle,handle.getActionMappings(c))) { |
374 |
writeNbActionsModel(project, handle.getActionMappings(c), M2Configuration.getFileNameExt(c.getId())); |
362 |
writeNbActionsModel(project, handle.getActionMappings(c), M2Configuration.getFileNameExt(c.getId())); |
375 |
} |
363 |
} |
376 |
} |
364 |
} |
377 |
if (performConfigsInvokedReload) { |
365 |
if (performConfigsInvokedReload && handle.getPOMOperations().isEmpty()) { //#only do the reload if no change to po file was done. can be actually figured now with operations |
378 |
//#174637 |
366 |
//#174637 |
379 |
NbMavenProject.fireMavenProjectReload(project); |
367 |
NbMavenProject.fireMavenProjectReload(project); |
380 |
} |
368 |
} |