2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
43
* XMLRefactoringTransaction.java
45
* Created on February 1, 2007, 2:32 PM
47
* To change this template, choose Tools | Template Manager
48
* and open the template in the editor.
51
package org.netbeans.modules.xml.refactoring;
53
import java.io.IOException;
55
import java.net.URISyntaxException;
57
import java.util.ArrayList;
58
import java.util.Collection;
59
import java.util.HashMap;
60
import java.util.HashSet;
61
import java.util.List;
64
import java.util.logging.Level;
65
import java.util.logging.Logger;
66
import javax.swing.event.UndoableEditEvent;
67
import javax.swing.event.UndoableEditListener;
68
import javax.swing.undo.AbstractUndoableEdit;
69
import javax.swing.undo.CannotRedoException;
70
import javax.swing.undo.CannotUndoException;
71
import javax.swing.undo.UndoManager;
72
import javax.swing.undo.UndoableEdit;
73
import javax.swing.undo.UndoableEditSupport;
74
import org.netbeans.api.project.FileOwnerQuery;
75
import org.netbeans.api.project.Project;
76
import org.netbeans.modules.refactoring.api.AbstractRefactoring;
77
import org.netbeans.modules.refactoring.api.MoveRefactoring;
78
import org.netbeans.modules.refactoring.api.RenameRefactoring;
79
import org.netbeans.modules.refactoring.api.SafeDeleteRefactoring;
80
import org.netbeans.modules.refactoring.api.SingleCopyRefactoring;
81
import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation;
82
import org.netbeans.modules.refactoring.spi.Transaction;
83
import org.netbeans.modules.xml.refactoring.impl.UndoRedoProgress;
84
import org.netbeans.modules.xml.refactoring.spi.RefactoringUtil;
85
import org.netbeans.modules.xml.refactoring.spi.SharedUtils;
86
import org.netbeans.modules.xml.retriever.catalog.ProjectCatalogSupport;
87
import org.netbeans.modules.xml.retriever.catalog.Utilities;
88
import org.netbeans.modules.xml.xam.AbstractModel;
89
import org.netbeans.modules.xml.xam.Component;
90
import org.netbeans.modules.xml.xam.EmbeddableRoot;
91
import org.netbeans.modules.xml.xam.Model;
92
import org.netbeans.modules.xml.xam.ModelSource;
93
import org.netbeans.modules.xml.xam.Nameable;
94
import org.netbeans.modules.xml.xam.NamedReferenceable;
95
import org.netbeans.modules.xml.xam.Referenceable;
96
import org.netbeans.modules.xml.xam.dom.AbstractDocumentModel;
97
import org.netbeans.modules.xml.xam.dom.DocumentModel;
98
import org.netbeans.modules.xml.xam.locator.CatalogModel;
99
import org.netbeans.modules.xml.xam.locator.CatalogModelException;
100
import org.openide.DialogDisplayer;
101
import org.openide.NotifyDescriptor;
102
import org.openide.filesystems.FileObject;
103
import org.netbeans.modules.refactoring.spi.BackupFacility;
106
* Single transaction object, ensuring the order of refactoring change across
107
* affected models. Responsible for undo/redo of refactoring
111
public class XMLRefactoringTransaction implements Transaction {
113
AbstractRefactoring request;
114
List<RefactoringElementImplementation> elements;
115
List<XMLRefactoringPlugin> plugins;
116
Referenceable target;
117
private Map<Model,UndoManager> undoManagers;
118
//For delete refactoring we need to save the model since it wont be available after delete for undo/redo
120
boolean isLocal = false;
121
ModelSource movedTargetModelSource;
122
Map<Model, Set<RefactoringElementImplementation>> modelsInRefactoring;
123
private boolean commited = false;
124
private UndoManager genericChangeUndoManager;
125
Map<String, FileObject> targetModelRefs;
126
ArrayList<BackupFacility.Handle> ids = new ArrayList();
127
private boolean useBackupFacility = false;
132
* Creates a new instance of XMLRefactoringTransaction
135
public XMLRefactoringTransaction(Referenceable target, AbstractRefactoring req){
136
this.target = target;
137
this.elements = new ArrayList();
138
this.plugins = new ArrayList();
140
this.targetModel = SharedUtils.getModel(target);
145
* Commits the refactoring changes for all the models
147
public void commit() {
148
//when commit is called, there is no way of knowing if its for refactoring or a redo
149
//since for rename redo, we use undoManagers, keep a flag and call redo when appropriate
150
//System.out.println("COMMIT called");
154
//even if we used BackupFacility, use the genericChangeUndoManager for redo since
155
//move/file rename refactoring involve more than just target rename/move
156
if (genericChangeUndoManager != null && genericChangeUndoManager.canRedo()) {
157
genericChangeUndoManager.redo();
160
for (BackupFacility.Handle id:ids) {
163
} catch (IOException ex) {
164
ex.printStackTrace();
165
throw (RuntimeException) new RuntimeException().initCause(ex);
171
//backup the files before doing refactoring
175
}catch (IOException ioe) {
176
String msg = ioe.getMessage();
177
NotifyDescriptor nd = new NotifyDescriptor.Message(msg, NotifyDescriptor.ERROR_MESSAGE);
178
DialogDisplayer.getDefault().notify(nd);
184
* Rollbacks the refactoring changes for all the models
186
public void rollback() {
188
UndoRedoProgress progress = new UndoRedoProgress();
191
//for target use the genericChangeUndoManager
192
if (genericChangeUndoManager != null && genericChangeUndoManager.canUndo()) {
193
genericChangeUndoManager.undo();
195
for (BackupFacility.Handle id:ids) {
198
} catch (IOException ex) {
199
ex.printStackTrace();
200
throw (RuntimeException) new RuntimeException().initCause(ex);
211
/** Registers the RefactoringElements for each plugin
212
* @param plugin that found the usages
213
* @param list List of refactoring usages
216
public void register(XMLRefactoringPlugin plugin, List<? extends RefactoringElementImplementation> list){
217
elements.addAll(list);
222
private synchronized void process() throws IOException {
224
if(modelsInRefactoring == null)
225
modelsInRefactoring = getModels();
226
Set<Model> models = modelsInRefactoring.keySet();
227
//put this code in shared utils
228
Set<Model> excludedFromSave = RefactoringUtil.getDirtyModels(models, targetModel);
229
GeneralChangeExecutor ce = new GeneralChangeExecutor();
233
if(ce.canChange(request.getClass(), target)) {
234
//if (target instanceof Model && ( (request instanceof RenameRefactoring) || (request instanceof MoveRefactoring)) ) {
236
addUndoableListener(ce);
237
ce.doChange(request);
239
addUndoableRefactorListener(targetModel);
243
for (Model model:models) {
244
addUndoableRefactorListener(model);
247
for (XMLRefactoringPlugin plugin : plugins) {
248
plugin.doRefactoring(elements);
253
//Model model = request.getTargetModel();
254
if (targetModel != null) {
256
addUndoableRefactorListener(targetModel);
257
targetModel.startTransaction();
259
//if the scope is local, then there should be only one plugin with only
260
//the usages in the target model
261
for (XMLRefactoringPlugin plugin : plugins) {
262
plugin.doRefactoring(elements);
266
if (targetModel.isIntransaction()) {
267
targetModel.endTransaction();
276
} catch (RuntimeException t) {
277
//setStatus(Status.CANCELLING);
281
removeRefactorUndoEventListeners();
282
removeUndoableListener(ce);
289
private synchronized void addUndoableRefactorListener(Model model) {
290
if (undoManagers == null) {
291
undoManagers = new HashMap<Model,UndoManager>();
293
// checking against source to eliminate embedded model case
294
FileObject source = (FileObject) model.getModelSource().getLookup().lookup(FileObject.class);
295
if (source == null) {
296
throw new IllegalArgumentException("Could not get source file from provided model"); //NOI18N
298
for (Model m : undoManagers.keySet()) {
299
FileObject s = (FileObject) m.getModelSource().getLookup().lookup(FileObject.class);
300
if (source.equals(s)) {
305
if (undoManagers.get(model) == null) {
306
UndoManager um = new UndoManager();
307
model.addUndoableRefactorListener(um);
308
undoManagers.put(model, um);
312
private synchronized void removeRefactorUndoEventListeners() {
313
if (undoManagers == null) return;
314
for(Model model : undoManagers.keySet()) {
315
model.removeUndoableRefactorListener(undoManagers.get(model));
321
public void doRefactorTarget() throws IOException {
322
if (target instanceof Nameable && request instanceof RenameRefactoring) {
323
SharedUtils.renameTarget((Nameable) target, ((RenameRefactoring)request).getNewName());
324
} else if (target instanceof NamedReferenceable && request instanceof SafeDeleteRefactoring) {
325
SharedUtils.deleteTarget((NamedReferenceable) target);
326
} else if(target instanceof Model) {
332
/** Registers the embedded usages
333
* @param list List of usages
336
public void register(List<? extends RefactoringElementImplementation> list) {
337
if(list != null && list.size()> 0 ){
338
elements.addAll(list);
342
public void setLocalScope() {
346
public boolean isLocal(){
352
public synchronized boolean canUndo() {
353
if (undoManagers == null || undoManagers.isEmpty()) {
356
for (UndoManager um : undoManagers.values()) {
357
if (! um.canUndo()) {
364
private void refactorFile() throws IOException {
365
if(modelsInRefactoring == null)
366
modelsInRefactoring = getModels();
367
Set<Model> all = modelsInRefactoring.keySet();
368
FileObject referencedFO = (FileObject) ((Model)target).getModelSource().getLookup().lookup(FileObject.class);
369
assert referencedFO != null : "Failed to lookup for file object in model source"; //NOI18N
370
RefactoringUtil.saveTargetFile((Model)target, all);
371
if(request instanceof RenameRefactoring ) {
372
referencedFO = SharedUtils.renameFile(referencedFO,((RenameRefactoring)request).getNewName());
373
refreshCatalogModel(referencedFO);
374
} else if (request instanceof MoveRefactoring ) {
375
FileObject targetFolder = SharedUtils.getOrCreateFolder(((MoveRefactoring)request).getTarget().lookup(URL.class));
376
//for move, we do the following
377
//first in the target model, update any references to external models
378
//then move the target model
379
//please note -- we update and then move
380
updateTargetModelReferences(targetModel, targetFolder);
381
RefactoringUtil.saveTargetFile(targetModel, all);
382
referencedFO = SharedUtils.moveFile(referencedFO, targetFolder);
383
if(referencedFO != null) {
384
//we have a new file and new model source
385
//keep a reference since we need this do undo
386
this.movedTargetModelSource = Utilities.getModelSource(referencedFO, true);
387
updateCatalogForTarget(this.movedTargetModelSource);
388
refreshCatalogModel(referencedFO);
390
} else if (request instanceof SingleCopyRefactoring ){
391
FileObject targetFolder = SharedUtils.getOrCreateFolder(((SingleCopyRefactoring)request).getTarget().lookup(URL.class));
393
String newName = ((SingleCopyRefactoring)request).getNewName();
394
FileObject newFobj = SharedUtils.copyFile(referencedFO, targetFolder, newName);
396
this.movedTargetModelSource = Utilities.getModelSource(newFobj, true);
397
//get the model from the plugin since the domain specific factory will create the model
398
Model newModel =null;
399
for(XMLRefactoringPlugin plugin:plugins){
400
newModel = plugin.getModel(movedTargetModelSource);
401
if(newModel != null){
408
//get the file objects from old model
409
Collection<Component> refs = new ArrayList<Component>();
410
for(XMLRefactoringPlugin plugin:plugins){
411
refs.addAll(plugin.getExternalReferences(targetModel));
414
if(refs.size() > 0 ){
415
boolean startTransaction = ! newModel.isIntransaction();
417
//map schemaLocation to components in the new copied model
418
Collection<Component> newRefs = new ArrayList<Component>();
419
for(XMLRefactoringPlugin plugin:plugins){
420
newRefs.addAll(plugin.getExternalReferences(newModel));
423
Map<String, Component> map = new HashMap<String, Component>();
424
for(Component r: newRefs){
425
for(XMLRefactoringPlugin plugin:plugins){
426
String location = plugin.getModelReference(r);
427
if(location != null){
428
map.put(location, r);
434
CatalogModel cat = (CatalogModel) (targetModel).getModelSource().getLookup().lookup(CatalogModel.class);
435
if (startTransaction) {
436
// ((Model)target).startTransaction();
437
newModel.startTransaction();
439
for(Component ref: refs){
442
for(XMLRefactoringPlugin plugin:plugins){
443
String location = plugin.getModelReference(ref);
444
if(location != null){
445
URI uri = new URI(location);
446
ModelSource source = null;
447
FileObject fobj = null;
449
source = cat.getModelSource(uri);
450
fobj = source.getLookup().lookup(FileObject.class);
451
} catch (CatalogModelException e){
452
//this means the model source could be in the same project
453
fobj = SharedUtils.getFileObject(targetModel, uri);
454
//if we have a fobj, we can now have two cases
455
//the refactoring target model is being moved within the same project
456
//or the target model is being moved to a different project
458
flag = SharedUtils.inSameProject(targetFolder, fobj);
463
Component comp = map.get(location);
465
String newLocation = SharedUtils.getReferenceURI(targetFolder, fobj).toString();
467
plugin.setModelReference(comp, newLocation);
470
String newLocation = fobj.getURL().toString();
472
plugin.setModelReference(comp, newLocation);
477
}catch (URISyntaxException e) {
478
//do nothing. dont update this model reference
482
if (startTransaction && (newModel).isIntransaction()) {
483
newModel.endTransaction();
487
RefactoringUtil.saveTargetFile(newModel, all);
493
private void refreshCatalogModel( FileObject referencedFO) {
494
// Map<Model, Set<RefactoringElementImplementation>> modelsInRefactoring = SharedUtils.getModelMap(elements);
495
if(modelsInRefactoring == null)
496
modelsInRefactoring = getModels();
497
boolean addedEntry = false;
498
Set<Model> models = modelsInRefactoring.keySet();
499
for (Model ug : models) {
500
FileObject referencingFO = ug.getModelSource().getLookup().lookup(FileObject.class);
501
ProjectCatalogSupport pcs = SharedUtils.getCatalogSupport(referencingFO);
502
if (pcs == null) continue;
503
Set<RefactoringElementImplementation> elems = modelsInRefactoring.get(ug);
504
for (Component uc : getRefactorComponents(elems)) {
505
String reference = getModelReference(uc);
506
if (reference == null) continue;
508
if (pcs != null && pcs.removeCatalogEntry(new URI(reference))) {
509
pcs.createCatalogEntry(referencingFO, referencedFO);
512
//special case for move/copy refactoring when a referencedFO is being moved to a subproject
513
//in this case, there is no catalogEntry and a new one needs to be created
514
if(pcs != null && !addedEntry){
515
Project targetProject = FileOwnerQuery.getOwner(referencedFO);
516
Project project = FileOwnerQuery.getOwner(referencingFO);
517
if( SharedUtils.getProjectReferences(project).contains(targetProject) ){
518
pcs.createCatalogEntry(referencingFO, referencedFO);
522
} catch(Exception ex) {
523
Logger.getLogger(SharedUtils.class.getName()).log(Level.FINE, ex.getMessage());
529
private List<Component> getRefactorComponents(Set<RefactoringElementImplementation> elementImpls) {
530
List<Component> ret = new ArrayList<Component>();
531
for(RefactoringElementImplementation element:elementImpls){
532
if(element.isEnabled())
533
ret.add( (Component)element.getLookup().lookup(Component.class));
538
private String getModelReference(Component comp){
540
for(XMLRefactoringPlugin plugin:plugins){
541
ref = plugin.getModelReference(comp);
548
private void undoRenameFile() throws IOException {
549
CatalogModel cat = (CatalogModel) ((Model)target).getModelSource().getLookup().lookup(CatalogModel.class);
550
FileObject fo = (FileObject) ((Model)target).getModelSource().getLookup().lookup(FileObject.class);
551
if(request instanceof RenameRefactoring ) {
552
String oldName = request.getContext().lookup(String.class);
553
if(oldName == null || oldName.equals("")) {
554
throw new IOException("Unable to undo refactoring. Cannot retrieve old file name"); //not i118N
556
fo = SharedUtils.renameFile(fo, oldName);
557
refreshCatalogModel(fo);
558
} else if(request instanceof MoveRefactoring) {
559
URL url = ((MoveRefactoring)request).getContext().lookup(URL.class);
561
throw new IOException("Unable to undo refactoring. Cannot retrieve original package location");
562
FileObject origFolder = SharedUtils.getOrCreateFolder(url);
563
//to undo the move, do the following
564
// first get the model for the new file
565
// update the external references, if any, in the new model
566
// move the model back to the original location
567
if(this.movedTargetModelSource != null){
570
//get the model from the plugin since the domain specific factory will create the model
571
for(XMLRefactoringPlugin plugin:plugins){
572
model = plugin.getModel(movedTargetModelSource);
578
//update embedded references to external models
580
if(modelsInRefactoring == null)
581
modelsInRefactoring = getModels();
582
Set<Model> all = modelsInRefactoring.keySet();
583
updateTargetModelReferences(model, origFolder);
584
RefactoringUtil.saveTargetFile(model, all);
587
//finally, move the file
588
FileObject movedFile = movedTargetModelSource.getLookup().lookup(FileObject.class);
589
fo = SharedUtils.moveFile(movedFile, origFolder);
591
ModelSource temp = Utilities.getModelSource(fo, true);
593
//after the file is moved, we need to do one final thing.
594
//for redo, we need to point to the right target model
595
//which is the newly moved file
596
for(XMLRefactoringPlugin plugin:plugins){
597
model = plugin.getModel(temp);
603
refreshCatalogModel(fo);
604
//addUndoableRefactorListener(movedTargetModelSource);
607
throw new IOException("Unable to undo Move Refactoring");
608
} else if(request instanceof SingleCopyRefactoring){
609
FileObject fobj = this.movedTargetModelSource.getLookup().lookup(FileObject.class);
616
public String refactorForPreview(Model model){
618
if(modelsInRefactoring == null )
619
modelsInRefactoring = getModels();
622
//This takes care of WSDL model with embedded schema imports
623
if(model instanceof DocumentModel) {
624
Component c = ((DocumentModel)model).getRootComponent();
625
if(c instanceof EmbeddableRoot) {
626
if( ( (EmbeddableRoot)c).getForeignParent() != null )
627
mod = ( (EmbeddableRoot)c).getForeignParent().getModel();
634
Set<RefactoringElementImplementation> elements = modelsInRefactoring.get(mod);
635
ArrayList<RefactoringElementImplementation> elementsForRefactoring = new ArrayList<RefactoringElementImplementation>(elements);
637
//for file rename, we dont need to refactor the target
638
if( !( (target instanceof Model) && ( (request instanceof RenameRefactoring) || (request instanceof MoveRefactoring))) ) {
639
targetModel.startTransaction();
643
if(targetModel != mod) {
644
mod.startTransaction();
646
for (XMLRefactoringPlugin plugin : plugins) {
647
plugin.doRefactoring(elementsForRefactoring);
650
String refactoredString = ( (AbstractDocumentModel)mod).getAccess().getCurrentDocumentText();
651
if( !(target instanceof Model && request instanceof RenameRefactoring)) {
652
( (AbstractModel)targetModel).rollbackTransaction();
654
((AbstractModel)mod).rollbackTransaction();
656
return refactoredString;
658
} catch (Exception e){
659
String msg = e.getMessage();
667
private Map<Model, Set<RefactoringElementImplementation>> getModels(){
668
Map<Model, Set<RefactoringElementImplementation>> results = new HashMap<Model, Set<RefactoringElementImplementation>>();
669
for(RefactoringElementImplementation element:elements){
670
Component comp = element.getLookup().lookup(Component.class);
672
//First group the RE by Foreign Model, if no Foreign Model, then group by Model
673
//This takes care of WSDL model with embedded schema imports
674
if(comp.getModel() instanceof DocumentModel) {
675
Component c = ((DocumentModel)comp.getModel()).getRootComponent();
676
if(c instanceof EmbeddableRoot) {
677
if( ( (EmbeddableRoot)c).getForeignParent() != null )
678
model = ( (EmbeddableRoot)c).getForeignParent().getModel();
683
model = comp.getModel();
686
Set<RefactoringElementImplementation> elementsInModel = results.get(model);
687
if(elementsInModel == null){
688
elementsInModel = new HashSet<RefactoringElementImplementation>();
689
elementsInModel.add(element);
690
results.put(model, elementsInModel);
692
elementsInModel.add(element);
698
public synchronized void redo() throws CannotRedoException {
700
if(modelsInRefactoring == null)
701
modelsInRefactoring = getModels();
702
Set<Model> models = modelsInRefactoring.keySet();
704
Set<Model> excludedFromSave = RefactoringUtil.getDirtyModels(models, targetModel);
706
if (genericChangeUndoManager != null && genericChangeUndoManager.canRedo()) {
707
genericChangeUndoManager.redo();
710
if(undoManagers != null ){
711
for (UndoManager um : undoManagers.values()) {
712
while (um.canRedo()) {
717
//fix for issue 108512
718
if(undoManagers != null) {
719
Set<Model> mods = undoManagers.keySet();
721
if(m instanceof AbstractDocumentModel)
722
((AbstractDocumentModel)m).getAccess().flush();
727
RefactoringUtil.save(models, targetModel, excludedFromSave);
732
public synchronized boolean canRedo() {
733
if (undoManagers == null || undoManagers.isEmpty()) {
736
for (UndoManager um : undoManagers.values()) {
737
if (! um.canRedo()) {
741
if (genericChangeUndoManager != null && ! genericChangeUndoManager.canRedo()) {
747
private synchronized void addUndoableListener(GeneralChangeExecutor executor) {
748
genericChangeUndoManager = new UndoManager();
749
executor.addUndoableEditListener(genericChangeUndoManager);
752
private synchronized void removeUndoableListener(GeneralChangeExecutor exec) {
753
if (! (exec instanceof GeneralChangeExecutor) ||
754
genericChangeUndoManager == null || exec == null) {
758
exec.removeUndoableEditListener(genericChangeUndoManager);
761
private void updateTargetModelReferences(Model model, FileObject targetFolder)throws IOException {
762
//before moving the targetFile, check if the targetFile has any external model references
763
targetModelRefs = new HashMap<String, FileObject>();
764
Collection<Component> refs = new ArrayList<Component>();
765
for(XMLRefactoringPlugin plugin:plugins){
766
refs.addAll(plugin.getExternalReferences(model));
769
if(refs.size() > 0 ){
770
boolean startTransaction = ! (model).isIntransaction();
771
CatalogModel cat = (CatalogModel) (model).getModelSource().getLookup().lookup(CatalogModel.class);
772
if (startTransaction) {
773
// ((Model)target).startTransaction();
774
model.startTransaction();
776
for(Component ref: refs){
779
for(XMLRefactoringPlugin plugin:plugins){
780
String location = plugin.getModelReference(ref);
781
if(location != null){
782
URI uri = new URI(location);
783
ModelSource source = null;
784
FileObject fobj = null;
786
source = cat.getModelSource(uri);
787
fobj = source.getLookup().lookup(FileObject.class);
788
} catch (Exception e){
789
//this means the model source could be in the same project
790
fobj = SharedUtils.getFileObject(model, uri);
791
//if we have a fobj, we can now have two cases
792
//the refactoring target model is being moved within the same project
793
//or the target model is being moved to a different project
795
flag = SharedUtils.inSameProject(targetFolder, fobj);
802
String newLocation = SharedUtils.getReferenceURI(targetFolder, fobj).toString();
803
plugin.setModelReference(ref, newLocation);
804
if(!SharedUtils.inSameProject(targetFolder, fobj ))
805
targetModelRefs.put(newLocation, fobj);
807
String newLocation = fobj.getURL().toString();
808
plugin.setModelReference(ref, newLocation);
813
}catch (URISyntaxException e) {
814
//do nothing. dont update this model reference
819
if (startTransaction && (model).isIntransaction()) {
820
model.endTransaction();
826
private void updateCatalogForTarget(ModelSource target){
827
FileObject referencingFO = target.getLookup().lookup(FileObject.class);
828
ProjectCatalogSupport pcs = SharedUtils.getCatalogSupport(referencingFO);
829
if (pcs == null)return;
830
if(targetModelRefs == null || targetModelRefs.size() == 0)
832
Set<String> keys = targetModelRefs.keySet();
833
for(String key:keys){
834
FileObject referencedFO = targetModelRefs.get(key);
835
if(referencedFO != null) {
837
pcs.createCatalogEntry(referencingFO, referencedFO);
838
}catch (CatalogModelException e){
840
}catch (IOException e){
841
//do nothing; will result in broken reference
849
private void backup() throws IOException {
850
boolean addedTarget = false;
851
if(modelsInRefactoring == null)
852
modelsInRefactoring = getModels();
853
Set<Model> models = modelsInRefactoring.keySet();
854
for(Model mod:models){
855
FileObject fo = mod.getModelSource().getLookup().lookup(FileObject.class);
856
ids.add(BackupFacility.getDefault().backup(mod.getModelSource().getLookup().lookup(FileObject.class)));
857
//backup facility doesnt keep track of unique file objects. need to do it ourselves
858
if(mod.equals(targetModel))
861
GeneralChangeExecutor ce = new GeneralChangeExecutor();
862
if(!ce.canChange(request.getClass(), target) && !addedTarget) {
863
ids.add(BackupFacility.getDefault().backup(targetModel.getModelSource().getLookup().lookup(FileObject.class)));
868
class GeneralChangeExecutor {
869
private UndoableEditSupport ues;
871
/** Creates a new instance of GenericChangeExecutor */
872
public GeneralChangeExecutor() {
873
ues = new UndoableEditSupport(this);
876
public <T extends AbstractRefactoring> boolean canChange(Class<T> changeType, Referenceable target) {
877
if ( (changeType == RenameRefactoring.class || changeType == MoveRefactoring.class || changeType == SingleCopyRefactoring.class) && target instanceof Model) {
884
* Perform the change specified by the refactor request. Any errors that would
885
* fail the overall refactoring should be reported throught #RefactoringRequest.addError
886
* Implementation should quietly ignore unsupported refactoring type.
888
public void doChange(AbstractRefactoring request) throws IOException {
889
if ((request instanceof RenameRefactoring) || (request instanceof MoveRefactoring) || (request instanceof SingleCopyRefactoring) ) {
891
FileRenameUndoable ue = new FileRenameUndoable(request);
898
public synchronized void addUndoableEditListener(UndoableEditListener l) {
899
ues.addUndoableEditListener(l);
902
public synchronized void removeUndoableEditListener(UndoableEditListener l) {
903
ues.removeUndoableEditListener(l);
906
protected void fireUndoEvent(UndoableEdit edit) {
907
UndoableEditEvent ue = new UndoableEditEvent(this, edit);
908
for (UndoableEditListener l:ues.getUndoableEditListeners()) {
909
l.undoableEditHappened(ue);
913
class FileRenameUndoable extends AbstractUndoableEdit {
914
private static final long serialVersionUID = -1L;
915
private AbstractRefactoring request;
917
public FileRenameUndoable(AbstractRefactoring request) {
918
this.request = request;
921
public void undo() throws CannotUndoException {
925
} catch(IOException ioe) {
926
CannotUndoException cue = new CannotUndoException();
932
public void redo() throws CannotRedoException {
936
} catch(IOException ioe) {
937
CannotUndoException cue = new CannotUndoException();