1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
5 |
|
|
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
|
10 |
|
|
11 |
|
|
12 |
|
|
13 |
|
|
14 |
|
|
15 |
|
|
16 |
|
|
17 |
|
|
18 |
|
|
19 |
|
|
20 |
|
package com.xpn.xwiki.internal.objects.classes; |
21 |
|
|
22 |
|
import java.util.List; |
23 |
|
|
24 |
|
import javax.inject.Inject; |
25 |
|
import javax.inject.Named; |
26 |
|
import javax.inject.Provider; |
27 |
|
|
28 |
|
import org.slf4j.Logger; |
29 |
|
import org.xwiki.model.EntityType; |
30 |
|
import org.xwiki.model.reference.ClassPropertyReference; |
31 |
|
import org.xwiki.model.reference.DocumentReferenceResolver; |
32 |
|
import org.xwiki.model.reference.EntityReference; |
33 |
|
import org.xwiki.model.reference.EntityReferenceSerializer; |
34 |
|
import org.xwiki.observation.AbstractEventListener; |
35 |
|
import org.xwiki.observation.event.Event; |
36 |
|
import org.xwiki.query.Query; |
37 |
|
import org.xwiki.query.QueryException; |
38 |
|
import org.xwiki.query.QueryManager; |
39 |
|
|
40 |
|
import com.xpn.xwiki.XWikiContext; |
41 |
|
import com.xpn.xwiki.XWikiException; |
42 |
|
import com.xpn.xwiki.doc.XWikiDocument; |
43 |
|
import com.xpn.xwiki.internal.event.XClassPropertyUpdatedEvent; |
44 |
|
import com.xpn.xwiki.internal.store.PropertyConverter; |
45 |
|
import com.xpn.xwiki.objects.BaseObject; |
46 |
|
import com.xpn.xwiki.objects.BaseProperty; |
47 |
|
import com.xpn.xwiki.objects.classes.PropertyClass; |
48 |
|
|
49 |
|
|
50 |
|
|
51 |
|
|
52 |
|
@link |
53 |
|
|
54 |
|
@version |
55 |
|
@since |
56 |
|
|
57 |
|
|
58 |
|
|
|
|
| 88.3% |
Uncovered Elements: 7 (60) |
Complexity: 14 |
Complexity Density: 0.32 |
|
59 |
|
public class XClassMigratorListener extends AbstractEventListener |
60 |
|
{ |
61 |
|
@Inject |
62 |
|
@Named("local") |
63 |
|
private EntityReferenceSerializer<String> localSerializer; |
64 |
|
|
65 |
|
@Inject |
66 |
|
private DocumentReferenceResolver<String> resolver; |
67 |
|
|
68 |
|
@Inject |
69 |
|
private QueryManager queryManager; |
70 |
|
|
71 |
|
@Inject |
72 |
|
private Provider<XWikiContext> xcontextProvider; |
73 |
|
|
74 |
|
|
75 |
|
|
76 |
|
|
77 |
|
@Inject |
78 |
|
private PropertyConverter propertyConverter; |
79 |
|
|
80 |
|
@Inject |
81 |
|
private Logger logger; |
82 |
|
|
83 |
|
|
84 |
|
|
85 |
|
|
|
|
| 100% |
Uncovered Elements: 0 (1) |
Complexity: 1 |
Complexity Density: 1 |
|
86 |
186 |
public XClassMigratorListener()... |
87 |
|
{ |
88 |
186 |
super(XClassMigratorListener.class.getName(), new XClassPropertyUpdatedEvent()); |
89 |
|
} |
90 |
|
|
|
|
| 87.5% |
Uncovered Elements: 2 (16) |
Complexity: 5 |
Complexity Density: 0.42 |
|
91 |
6 |
@Override... |
92 |
|
public void onEvent(Event event, Object source, Object data) |
93 |
|
{ |
94 |
6 |
XClassPropertyUpdatedEvent propertyEvent = (XClassPropertyUpdatedEvent) event; |
95 |
6 |
XWikiDocument newDocument = (XWikiDocument) source; |
96 |
6 |
XWikiDocument previousDocument = newDocument.getOriginalDocument(); |
97 |
|
|
98 |
6 |
PropertyClass newPropertyClass = |
99 |
|
(PropertyClass) newDocument.getXClass().getField(propertyEvent.getReference().getName()); |
100 |
6 |
PropertyClass previousPropertyClass = |
101 |
|
(PropertyClass) previousDocument.getXClass().getField(propertyEvent.getReference().getName()); |
102 |
|
|
103 |
6 |
if (newPropertyClass != null && previousPropertyClass != null) { |
104 |
6 |
BaseProperty newProperty = newPropertyClass.newProperty(); |
105 |
6 |
BaseProperty previousProperty = previousPropertyClass.newProperty(); |
106 |
|
|
107 |
|
|
108 |
6 |
if (newProperty.getClass() != previousProperty.getClass()) { |
109 |
1 |
try { |
110 |
1 |
migrate(newPropertyClass); |
111 |
|
} catch (QueryException e) { |
112 |
0 |
this.logger.error("Failed to migrate XClass property [{}]", newPropertyClass.getReference(), e); |
113 |
|
} |
114 |
|
} |
115 |
|
} |
116 |
|
} |
117 |
|
|
|
|
| 88.9% |
Uncovered Elements: 2 (18) |
Complexity: 3 |
Complexity Density: 0.19 |
|
118 |
1 |
private void migrate(PropertyClass newPropertyClass) throws QueryException... |
119 |
|
{ |
120 |
1 |
ClassPropertyReference propertyReference = newPropertyClass.getReference(); |
121 |
1 |
EntityReference classReference = propertyReference.extractReference(EntityType.DOCUMENT); |
122 |
1 |
EntityReference wikiReference = propertyReference.extractReference(EntityType.WIKI); |
123 |
|
|
124 |
|
|
125 |
1 |
Query query = |
126 |
|
this.queryManager.createQuery("from doc.object(" + this.localSerializer.serialize(classReference) |
127 |
|
+ ") as obj", Query.XWQL); |
128 |
1 |
query.setWiki(wikiReference.getName()); |
129 |
|
|
130 |
1 |
List<String> documents = query.execute(); |
131 |
|
|
132 |
1 |
if (!documents.isEmpty()) { |
133 |
1 |
XWikiContext xcontext = this.xcontextProvider.get(); |
134 |
|
|
135 |
1 |
String currentWikiId = xcontext.getWikiId(); |
136 |
1 |
try { |
137 |
|
|
138 |
1 |
xcontext.setWikiId(wikiReference.getName()); |
139 |
|
|
140 |
1 |
for (String documentName : documents) { |
141 |
1 |
try { |
142 |
1 |
migrate(newPropertyClass, documentName, xcontext); |
143 |
|
} catch (XWikiException e) { |
144 |
0 |
this.logger.error("Failed to migrate property [{}] in document [{}]", propertyReference, |
145 |
|
documentName, xcontext); |
146 |
|
} |
147 |
|
} |
148 |
|
} finally { |
149 |
|
|
150 |
1 |
xcontext.setWikiId(currentWikiId); |
151 |
|
} |
152 |
|
} |
153 |
|
} |
154 |
|
|
|
|
| 85.7% |
Uncovered Elements: 3 (21) |
Complexity: 5 |
Complexity Density: 0.33 |
|
155 |
1 |
private void migrate(PropertyClass newPropertyClass, String documentName, XWikiContext xcontext)... |
156 |
|
throws XWikiException |
157 |
|
{ |
158 |
1 |
BaseProperty newProperty = newPropertyClass.newProperty(); |
159 |
|
|
160 |
1 |
ClassPropertyReference propertyReference = newPropertyClass.getReference(); |
161 |
1 |
EntityReference classReference = propertyReference.extractReference(EntityType.DOCUMENT); |
162 |
|
|
163 |
1 |
XWikiDocument document = |
164 |
|
xcontext.getWiki().getDocument(this.resolver.resolve(documentName, classReference), xcontext); |
165 |
|
|
166 |
1 |
boolean modified = false; |
167 |
|
|
168 |
1 |
for (BaseObject xobject : document.getXObjects(classReference)) { |
169 |
1 |
BaseProperty property = (BaseProperty) xobject.getField(propertyReference.getName()); |
170 |
|
|
171 |
|
|
172 |
1 |
if (property != null && property.getClass() != newProperty.getClass()) { |
173 |
1 |
BaseProperty<?> convertedProperty = this.propertyConverter.convertProperty(property, newPropertyClass); |
174 |
|
|
175 |
|
|
176 |
1 |
if (convertedProperty != null) { |
177 |
|
|
178 |
1 |
xobject.removeField(propertyReference.getName()); |
179 |
|
|
180 |
|
|
181 |
1 |
xobject.safeput(propertyReference.getName(), convertedProperty); |
182 |
|
|
183 |
1 |
modified = true; |
184 |
|
} |
185 |
|
} |
186 |
|
} |
187 |
|
|
188 |
|
|
189 |
1 |
if (modified) { |
190 |
1 |
xcontext.getWiki().saveDocument( |
191 |
|
document, |
192 |
|
"Migrated property [" + propertyReference.getName() + "] from class [" |
193 |
|
+ this.localSerializer.serialize(classReference) + "]", xcontext); |
194 |
|
} |
195 |
|
} |
196 |
|
} |