1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.importexport;
35
36 import info.magnolia.cms.core.Content;
37 import info.magnolia.cms.core.HierarchyManager;
38 import info.magnolia.cms.core.ItemType;
39 import info.magnolia.cms.core.NodeData;
40 import info.magnolia.cms.util.ContentUtil;
41 import info.magnolia.cms.util.OrderedProperties;
42
43 import java.io.ByteArrayInputStream;
44 import java.io.IOException;
45 import java.io.InputStream;
46 import java.util.Calendar;
47 import java.util.Collection;
48 import java.util.Properties;
49 import java.util.Set;
50
51 import javax.jcr.PropertyType;
52 import javax.jcr.RepositoryException;
53 import javax.jcr.Value;
54
55 import org.apache.commons.beanutils.ConvertUtils;
56 import org.apache.commons.lang3.StringUtils;
57 import org.apache.jackrabbit.util.ISO8601;
58
59
60
61
62
63
64
65
66
67
68 @Deprecated
69 public class PropertiesImportExport {
70
71 public void createContent(Content root, InputStream propertiesStream) throws IOException, RepositoryException {
72 Properties properties = new OrderedProperties();
73
74 properties.load(propertiesStream);
75
76 properties = keysToInnerFormat(properties);
77
78 for (Object o : properties.keySet()) {
79 String key = (String) o;
80 String valueStr = properties.getProperty(key);
81
82 String propertyName = StringUtils.substringAfterLast(key, ".");
83 String path = StringUtils.substringBeforeLast(key, ".");
84
85 String type = null;
86 if (propertyName.equals("@type")) {
87 type = valueStr;
88 } else if (properties.containsKey(path + ".@type")) {
89 type = properties.getProperty(path + ".@type");
90 }
91
92 type = StringUtils.defaultIfEmpty(type, ItemType.CONTENTNODE.getSystemName());
93 Content c = ContentUtil.createPath(root, path, new ItemType(type));
94 populateContent(c, propertyName, valueStr);
95 }
96 }
97
98
99
100
101 private Properties keysToInnerFormat(Properties properties) {
102 Properties cleaned = new OrderedProperties();
103
104 for (Object o : properties.keySet()) {
105 String orgKey = (String) o;
106
107
108 String newKey = orgKey;
109
110
111 newKey = StringUtils.replace(newKey, "@", ".@");
112
113 newKey = StringUtils.replace(newKey, "..@", ".@");
114
115 String propertyName = StringUtils.substringAfterLast(newKey, ".");
116 String keySuffix = StringUtils.substringBeforeLast(newKey, ".");
117 String path = StringUtils.replace(keySuffix, ".", "/");
118 path = StringUtils.removeStart(path, "/");
119
120
121 if (StringUtils.isEmpty(propertyName)) {
122
123 if (StringUtils.isEmpty(properties.getProperty(orgKey))) {
124
125 if (!properties.containsKey(orgKey + "@type")) {
126 cleaned.put(path + ".@type", ItemType.CONTENTNODE.getSystemName());
127 }
128 continue;
129 }
130 propertyName = StringUtils.substringAfterLast(path, "/");
131 path = StringUtils.substringBeforeLast(path, "/");
132 }
133 cleaned.put(path + "." + propertyName, properties.get(orgKey));
134 }
135 return cleaned;
136 }
137
138 protected void populateContent(Content c, String name, String valueStr) throws RepositoryException {
139 if (StringUtils.isEmpty(name) && StringUtils.isEmpty(valueStr)) {
140
141 return;
142 }
143 if (name.equals("@type")) {
144
145 } else if (name.equals("@uuid")) {
146 throw new UnsupportedOperationException("Can't see UUIDs on real node. Use MockUtil if you are using MockContent instances.");
147 } else {
148 Object valueObj = convertNodeDataStringToObject(valueStr);
149 c.setNodeData(name, valueObj);
150 }
151 }
152
153 protected Object convertNodeDataStringToObject(String valueStr) {
154 if (contains(valueStr, ':')) {
155 final String type = StringUtils.substringBefore(valueStr, ":");
156 final String value = StringUtils.substringAfter(valueStr, ":");
157
158
159 if (type.equalsIgnoreCase("date")) {
160 return ISO8601.parse(value);
161 } else if (type.equalsIgnoreCase("binary")) {
162 return new ByteArrayInputStream(value.getBytes());
163 } else {
164 try {
165 final Class<?> typeCl;
166 if (type.equals("int")) {
167 typeCl = Integer.class;
168 } else {
169 typeCl = Class.forName("java.lang." + StringUtils.capitalize(type));
170 }
171 return ConvertUtils.convert(value, typeCl);
172 } catch (ClassNotFoundException e) {
173
174 return valueStr;
175 }
176 }
177 }
178
179 return valueStr;
180 }
181
182
183
184
185
186
187
188
189
190
191
192 @Deprecated
193 public static Properties toProperties(HierarchyManager hm) throws Exception {
194 return toProperties(hm.getRoot());
195 }
196
197
198
199
200 public static Properties toProperties(Content rootContent) throws Exception {
201 return toProperties(rootContent, ContentUtil.EXCLUDE_META_DATA_CONTENT_FILTER, true);
202 }
203
204
205
206
207 public static Properties contentToProperties(HierarchyManager hm) throws Exception {
208 return contentToProperties(hm.getRoot());
209 }
210
211
212
213
214 public static Properties contentToProperties(Content rootContent) throws Exception {
215 return toProperties(rootContent, ContentUtil.EXCLUDE_META_DATA_CONTENT_FILTER, false);
216 }
217
218
219
220
221 public static Properties contentToProperties(Content rootContent, Content.ContentFilter filter) throws Exception {
222 return toProperties(rootContent, filter, false);
223 }
224
225
226
227
228
229
230
231
232
233
234
235
236 private static Properties toProperties(Content rootContent, Content.ContentFilter contentFilter, final boolean legacyMode) throws Exception {
237 final Properties out = new OrderedProperties();
238 ContentUtil.visit(rootContent, new ContentUtil.Visitor() {
239 @Override
240 public void visit(Content node) throws Exception {
241 if (!legacyMode) {
242 appendNodeTypeAndUUID(node, out, true);
243 }
244 appendNodeProperties(node, out);
245 }
246 }, contentFilter);
247 return out;
248 }
249
250 private static void appendNodeTypeAndUUID(Content node, Properties out, final boolean dumpMetaData) throws RepositoryException {
251 String path = getExportPath(node);
252
253 if (path.equals("/jcr:root")) {
254 return;
255 }
256
257 String nodeTypeName = node.getNodeTypeName();
258 if (nodeTypeName != null && StringUtils.isNotEmpty(nodeTypeName)) {
259 out.put(path + "@type", nodeTypeName);
260 }
261 String nodeUUID = node.getUUID();
262 if (nodeUUID != null && StringUtils.isNotEmpty(nodeUUID)) {
263 out.put(path + "@uuid", node.getUUID());
264 }
265 }
266
267 public static void appendNodeProperties(Content node, Properties out) {
268 final Collection<NodeData> props = node.getNodeDataCollection();
269 for (NodeData prop : props) {
270 final String path = getExportPath(node) + "." + prop.getName();
271
272 String propertyValue = getPropertyString(prop);
273
274 if (propertyValue != null) {
275 out.setProperty(path, propertyValue);
276 }
277 }
278 }
279
280 private static String getExportPath(Content node) {
281 return node.getHandle();
282 }
283
284 private static String getPropertyString(NodeData prop) {
285 int propType = prop.getType();
286
287 switch (propType) {
288 case (PropertyType.STRING): {
289 return prop.getString();
290 }
291 case (PropertyType.BOOLEAN): {
292 return convertBooleanToExportString(prop.getBoolean());
293 }
294 case (PropertyType.BINARY): {
295 return convertBinaryToExportString(prop.getValue());
296 }
297 case (PropertyType.PATH): {
298 return prop.getString();
299 }
300 case (PropertyType.DATE): {
301 return convertCalendarToExportString(prop.getDate());
302 }
303 case (PropertyType.LONG): {
304 return "" + prop.getLong();
305 }
306 case (PropertyType.DOUBLE): {
307 return "" + prop.getDouble();
308 }
309 default: {
310 return prop.getString();
311 }
312 }
313 }
314
315 private static String convertBooleanToExportString(boolean b) {
316 return "boolean:" + (b ? "true" : "false");
317 }
318
319 private static String convertBinaryToExportString(Value value) {
320 return "binary:" + ConvertUtils.convert(value);
321 }
322
323 private static String convertCalendarToExportString(Calendar calendar) {
324 return "date:" + ISO8601.format(calendar);
325 }
326
327
328
329
330
331 public static String dumpPropertiesToString(Content content, Content.ContentFilter filter) throws Exception {
332 Properties properties = PropertiesImportExport.contentToProperties(content, filter);
333 return dumpPropertiesToString(properties);
334 }
335
336 public static String dumpPropertiesToString(Properties properties) {
337 final StringBuilder sb = new StringBuilder();
338 final Set<Object> propertyNames = properties.keySet();
339 for (Object propertyKey : propertyNames) {
340 final String name = propertyKey.toString();
341 final String value = properties.getProperty(name);
342 sb.append(name);
343 sb.append("=");
344 sb.append(value);
345 sb.append("\n");
346 }
347 return sb.toString();
348 }
349
350 private static boolean contains(String s, char ch) {
351 return s.indexOf(ch) > -1;
352 }
353 }