]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/parts/NodeVersionHistoryPage.java
Fix char array comparison
[lgpl/argeo-commons.git] / org.argeo.cms.ui.workbench / src / org / argeo / cms / ui / workbench / internal / jcr / parts / NodeVersionHistoryPage.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.cms.ui.workbench.internal.jcr.parts;
17
18 import java.text.DateFormat;
19 import java.text.SimpleDateFormat;
20 import java.util.ArrayList;
21 import java.util.Calendar;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.jcr.Node;
26 import javax.jcr.Property;
27 import javax.jcr.PropertyType;
28 import javax.jcr.RepositoryException;
29 import javax.jcr.Value;
30 import javax.jcr.nodetype.NodeType;
31 import javax.jcr.version.Version;
32 import javax.jcr.version.VersionHistory;
33 import javax.jcr.version.VersionIterator;
34 import javax.jcr.version.VersionManager;
35
36 import org.argeo.cms.ui.workbench.WorkbenchUiPlugin;
37 import org.argeo.cms.ui.workbench.internal.WorkbenchConstants;
38 import org.argeo.cms.ui.workbench.internal.jcr.FullVersioningTreeContentProvider;
39 import org.argeo.cms.ui.workbench.internal.jcr.JcrDClickListener;
40 import org.argeo.cms.ui.workbench.internal.jcr.VersionLabelProvider;
41 import org.argeo.eclipse.ui.EclipseUiException;
42 import org.argeo.jcr.JcrUtils;
43 import org.argeo.jcr.PropertyDiff;
44 import org.argeo.jcr.VersionDiff;
45 import org.eclipse.jface.viewers.ITreeContentProvider;
46 import org.eclipse.jface.viewers.TreeViewer;
47 import org.eclipse.swt.SWT;
48 import org.eclipse.swt.layout.GridData;
49 import org.eclipse.swt.layout.GridLayout;
50 import org.eclipse.swt.widgets.Composite;
51 import org.eclipse.swt.widgets.Text;
52 import org.eclipse.ui.forms.AbstractFormPart;
53 import org.eclipse.ui.forms.IManagedForm;
54 import org.eclipse.ui.forms.editor.FormEditor;
55 import org.eclipse.ui.forms.editor.FormPage;
56 import org.eclipse.ui.forms.widgets.FormToolkit;
57 import org.eclipse.ui.forms.widgets.ScrolledForm;
58 import org.eclipse.ui.forms.widgets.Section;
59 import org.eclipse.ui.forms.widgets.TableWrapData;
60 import org.eclipse.ui.forms.widgets.TableWrapLayout;
61
62 /**
63 * Offers two main sections : one to display a text area with a summary of all
64 * variations between a version and its predecessor and one tree view that
65 * enable browsing
66 */
67 public class NodeVersionHistoryPage extends FormPage implements WorkbenchConstants {
68 // private final static Log log = LogFactory
69 // .getLog(NodeVersionHistoryPage.class);
70
71 // Utils
72 protected DateFormat timeFormatter = new SimpleDateFormat(DATE_TIME_FORMAT);
73
74 // business objects
75 private Node currentNode;
76
77 // this page UI components
78 private FullVersioningTreeContentProvider nodeContentProvider;
79 private TreeViewer nodesViewer;
80 private FormToolkit tk;
81
82 public NodeVersionHistoryPage(FormEditor editor, String title, Node currentNode) {
83 super(editor, "NodeVersionHistoryPage", title);
84 this.currentNode = currentNode;
85 }
86
87 protected void createFormContent(IManagedForm managedForm) {
88 ScrolledForm form = managedForm.getForm();
89 form.setText(WorkbenchUiPlugin.getMessage("nodeVersionHistoryPageTitle"));
90 tk = managedForm.getToolkit();
91 Composite innerBox = form.getBody();
92 // Composite innerBox = new Composite(body, SWT.NO_FOCUS);
93 GridLayout twt = new GridLayout(1, false);
94 twt.marginWidth = twt.marginHeight = 5;
95 innerBox.setLayout(twt);
96 try {
97 if (!currentNode.isNodeType(NodeType.MIX_VERSIONABLE)) {
98 tk.createLabel(innerBox, WorkbenchUiPlugin.getMessage("warningUnversionableNode"));
99 } else {
100 createHistorySection(innerBox);
101 createTreeSection(innerBox);
102 }
103 } catch (RepositoryException e) {
104 throw new EclipseUiException("Unable to check if node is versionable", e);
105 }
106 }
107
108 protected void createTreeSection(Composite parent) {
109 Section section = tk.createSection(parent, Section.TWISTIE);
110 section.setLayoutData(new GridData(GridData.FILL_BOTH));
111 section.setText(WorkbenchUiPlugin.getMessage("versionTreeSectionTitle"));
112
113 Composite body = tk.createComposite(section, SWT.FILL);
114 section.setClient(body);
115 section.setExpanded(true);
116 body.setLayoutData(new GridData(GridData.FILL_BOTH));
117 body.setLayout(new GridLayout());
118
119 nodeContentProvider = new FullVersioningTreeContentProvider();
120 nodesViewer = createNodeViewer(body, nodeContentProvider);
121 nodesViewer.setInput(currentNode);
122 }
123
124 protected TreeViewer createNodeViewer(Composite parent, final ITreeContentProvider nodeContentProvider) {
125
126 final TreeViewer tmpNodeViewer = new TreeViewer(parent, SWT.MULTI);
127
128 tmpNodeViewer.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
129
130 tmpNodeViewer.setContentProvider(nodeContentProvider);
131 tmpNodeViewer.setLabelProvider(new VersionLabelProvider());
132 tmpNodeViewer.addDoubleClickListener(new JcrDClickListener(tmpNodeViewer));
133 return tmpNodeViewer;
134 }
135
136 protected void createHistorySection(Composite parent) {
137
138 // Section Layout
139 Section section = tk.createSection(parent, Section.TWISTIE);
140 section.setLayoutData(new GridData(TableWrapData.FILL_GRAB));
141 TableWrapLayout twt = new TableWrapLayout();
142 section.setLayout(twt);
143
144 // Set title of the section
145 section.setText(WorkbenchUiPlugin.getMessage("versionHistorySectionTitle"));
146
147 final Text styledText = tk.createText(section, "",
148 SWT.FULL_SELECTION | SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
149 section.setClient(styledText);
150 styledText.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB));
151 refreshHistory(styledText);
152 styledText.setEditable(false);
153 section.setExpanded(false);
154
155 AbstractFormPart part = new AbstractFormPart() {
156 public void commit(boolean onSave) {
157 }
158
159 public void refresh() {
160 super.refresh();
161 refreshHistory(styledText);
162 }
163 };
164 getManagedForm().addPart(part);
165 }
166
167 protected void refreshHistory(Text styledText) {
168 try {
169 List<VersionDiff> lst = listHistoryDiff();
170 StringBuffer main = new StringBuffer("");
171
172 for (int i = lst.size() - 1; i >= 0; i--) {
173 if (i == 0)
174 main.append("Creation (");
175 else
176 main.append("Update " + i + " (");
177
178 if (lst.get(i).getUserId() != null)
179 main.append("UserId : " + lst.get(i).getUserId());
180
181 if (lst.get(i).getUserId() != null && lst.get(i).getUpdateTime() != null)
182 main.append(", ");
183
184 if (lst.get(i).getUpdateTime() != null)
185 main.append("Date : " + timeFormatter.format(lst.get(i).getUpdateTime().getTime()) + ")\n");
186
187 StringBuffer buf = new StringBuffer("");
188 Map<String, PropertyDiff> diffs = lst.get(i).getDiffs();
189 for (String prop : diffs.keySet()) {
190 PropertyDiff pd = diffs.get(prop);
191 // String propName = pd.getRelPath();
192 Value refValue = pd.getReferenceValue();
193 Value newValue = pd.getNewValue();
194 String refValueStr = "";
195 String newValueStr = "";
196
197 if (refValue != null) {
198 if (refValue.getType() == PropertyType.DATE) {
199 refValueStr = timeFormatter.format(refValue.getDate().getTime());
200 } else
201 refValueStr = refValue.getString();
202 }
203 if (newValue != null) {
204 if (newValue.getType() == PropertyType.DATE) {
205 newValueStr = timeFormatter.format(newValue.getDate().getTime());
206 } else
207 newValueStr = newValue.getString();
208 }
209
210 if (pd.getType() == PropertyDiff.MODIFIED) {
211 buf.append(prop).append(": ");
212 buf.append(refValueStr);
213 buf.append(" > ");
214 buf.append(newValueStr);
215 buf.append("\n");
216 } else if (pd.getType() == PropertyDiff.ADDED && !"".equals(newValueStr)) {
217 // we don't list property that have been added with an
218 // empty string as value
219 buf.append(prop).append(": ");
220 buf.append(" + ");
221 buf.append(newValueStr);
222 buf.append("\n");
223 } else if (pd.getType() == PropertyDiff.REMOVED) {
224 buf.append(prop).append(": ");
225 buf.append(" - ");
226 buf.append(refValueStr);
227 buf.append("\n");
228 }
229 }
230 buf.append("\n");
231 main.append(buf);
232 }
233 styledText.setText(main.toString());
234 } catch (RepositoryException e) {
235 throw new EclipseUiException("Cannot generate history for node", e);
236 }
237 }
238
239 public List<VersionDiff> listHistoryDiff() {
240 try {
241 List<VersionDiff> res = new ArrayList<VersionDiff>();
242 VersionManager versionManager = currentNode.getSession().getWorkspace().getVersionManager();
243 VersionHistory versionHistory = versionManager.getVersionHistory(currentNode.getPath());
244
245 VersionIterator vit = versionHistory.getAllLinearVersions();
246 while (vit.hasNext()) {
247 Version version = vit.nextVersion();
248 Node node = version.getFrozenNode();
249 Version predecessor = null;
250 try {
251 predecessor = version.getLinearPredecessor();
252 } catch (Exception e) {
253 // no predecessor seems to throw an exception even if it
254 // shouldn't...
255 }
256 if (predecessor == null) {// original
257 } else {
258 Map<String, PropertyDiff> diffs = JcrUtils.diffProperties(predecessor.getFrozenNode(), node);
259 if (!diffs.isEmpty()) {
260 String lastUserName = null;
261 Calendar lastUpdate = null;
262 try {
263 if (currentNode.isNodeType(NodeType.MIX_LAST_MODIFIED)) {
264 lastUserName = node.getProperty(Property.JCR_LAST_MODIFIED_BY).getString();
265 lastUpdate = node.getProperty(Property.JCR_LAST_MODIFIED).getDate();
266 } else
267 lastUpdate = version.getProperty(Property.JCR_CREATED).getDate();
268
269 } catch (Exception e) {
270 // Silent that info is optional
271 }
272 VersionDiff vd = new VersionDiff(lastUserName, lastUpdate, diffs);
273 res.add(vd);
274 }
275 }
276 }
277 return res;
278 } catch (RepositoryException e) {
279 throw new EclipseUiException("Cannot generate history for node ");
280 }
281
282 }
283
284 @Override
285 public void setActive(boolean active) {
286 super.setActive(active);
287 }
288 }