svn: Fixed "TreeConflictRefreshablePanel" disposing
[idea/community.git] / plugins / svn4idea / src / org / jetbrains / idea / svn / difftool / SvnChangeDiffViewerProvider.java
1 package org.jetbrains.idea.svn.difftool;
2
3 import com.intellij.diff.chains.DiffRequestProducerException;
4 import com.intellij.diff.impl.DiffViewerWrapper;
5 import com.intellij.diff.requests.DiffRequest;
6 import com.intellij.openapi.diagnostic.Logger;
7 import com.intellij.openapi.progress.ProcessCanceledException;
8 import com.intellij.openapi.progress.ProgressIndicator;
9 import com.intellij.openapi.project.Project;
10 import com.intellij.openapi.util.UserDataHolder;
11 import com.intellij.openapi.util.text.StringUtil;
12 import com.intellij.openapi.vcs.VcsException;
13 import com.intellij.openapi.vcs.changes.Change;
14 import com.intellij.openapi.vcs.changes.ContentRevision;
15 import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProducer;
16 import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffViewerWrapperProvider;
17 import com.intellij.util.ThreeState;
18 import org.jetbrains.annotations.NotNull;
19 import org.jetbrains.annotations.Nullable;
20 import org.jetbrains.idea.svn.SvnBundle;
21 import org.jetbrains.idea.svn.SvnChangeProvider;
22 import org.jetbrains.idea.svn.difftool.properties.SvnPropertiesDiffRequest;
23 import org.jetbrains.idea.svn.history.PropertyRevision;
24 import org.jetbrains.idea.svn.properties.PropertyData;
25
26 import java.util.List;
27 import java.util.Map;
28
29 public class SvnChangeDiffViewerProvider implements ChangeDiffViewerWrapperProvider {
30   private static final Logger LOG = Logger.getInstance(SvnChangeDiffViewerProvider.class);
31
32   @NotNull
33   @Override
34   public ThreeState isEquals(@NotNull Change change1, @NotNull Change change2) {
35     Change layer1 = getSvnChangeLayer(change1);
36     Change layer2 = getSvnChangeLayer(change2);
37     if (layer1 != null || layer2 != null) {
38       if (layer1 == null || layer2 == null) return ThreeState.NO;
39     }
40     return ThreeState.UNSURE;
41   }
42
43   @Override
44   public boolean canCreate(@Nullable Project project, @NotNull Change change) {
45     return getSvnChangeLayer(change) != null; // TODO: do not show, if no properties are set in both revisions ?
46   }
47
48   @NotNull
49   @Override
50   public DiffViewerWrapper process(@NotNull ChangeDiffRequestProducer presentable,
51                                    @NotNull UserDataHolder context,
52                                    @NotNull ProgressIndicator indicator) throws DiffRequestProducerException, ProcessCanceledException {
53     // TODO: support properties conflict for three-way-diff
54
55     DiffRequest propertyRequest = createPropertyRequest(presentable.getChange(), indicator);
56     return new SvnDiffViewerWrapper(propertyRequest);
57   }
58
59   @NotNull
60   private static SvnPropertiesDiffRequest createPropertyRequest(@NotNull Change change, @NotNull ProgressIndicator indicator)
61     throws DiffRequestProducerException {
62     try {
63       Change propertiesChange = getSvnChangeLayer(change);
64       if (propertiesChange == null) throw new DiffRequestProducerException(SvnBundle.getString("diff.cant.get.properties.changes"));
65
66       ContentRevision bRevRaw = propertiesChange.getBeforeRevision();
67       ContentRevision aRevRaw = propertiesChange.getAfterRevision();
68
69       if (bRevRaw != null && !(bRevRaw instanceof PropertyRevision)) {
70         LOG.warn("Before change is not PropertyRevision");
71         throw new DiffRequestProducerException(SvnBundle.getString("diff.cant.get.properties.changes"));
72       }
73       if (aRevRaw != null && !(aRevRaw instanceof PropertyRevision)) {
74         LOG.warn("After change is not PropertyRevision");
75         throw new DiffRequestProducerException(SvnBundle.getString("diff.cant.get.properties.changes"));
76       }
77
78       PropertyRevision bRev = (PropertyRevision)bRevRaw;
79       PropertyRevision aRev = (PropertyRevision)aRevRaw;
80
81       indicator.checkCanceled();
82       List<PropertyData> bContent = bRev != null ? bRev.getProperties() : null;
83
84       indicator.checkCanceled();
85       List<PropertyData> aContent = aRev != null ? aRev.getProperties() : null;
86
87       if (aRev == null && bRev == null) throw new DiffRequestProducerException(SvnBundle.getString("diff.cant.get.properties.changes"));
88
89       ContentRevision bRevMain = change.getBeforeRevision();
90       ContentRevision aRevMain = change.getAfterRevision();
91       String title1 = bRevMain != null ? StringUtil.nullize(bRevMain.getRevisionNumber().asString()) : null;
92       String title2 = aRevMain != null ? StringUtil.nullize(aRevMain.getRevisionNumber().asString()) : null;
93
94       return new SvnPropertiesDiffRequest(bContent, aContent, title1, title2);
95     }
96     catch (VcsException e) {
97       throw new DiffRequestProducerException(e);
98     }
99   }
100
101   @Nullable
102   private static Change getSvnChangeLayer(@NotNull Change change) {
103     for (Map.Entry<String, Change> entry : change.getOtherLayers().entrySet()) {
104       if (SvnChangeProvider.PROPERTY_LAYER.equals(entry.getKey())) {
105         if (change.getOtherLayers().size() != 1) LOG.warn("Some of change layers ignored");
106         return entry.getValue();
107       }
108     }
109     return null;
110   }
111 }