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.dam.app.setup.migration;
35
36 import info.magnolia.dam.jcr.DamConstants;
37 import info.magnolia.dam.jcr.AssetNodeTypes;
38 import info.magnolia.jcr.util.NodeTypes;
39 import info.magnolia.jcr.util.NodeUtil;
40 import info.magnolia.jcr.util.NodeVisitor;
41 import info.magnolia.module.InstallContext;
42 import info.magnolia.module.delta.AbstractRepositoryTask;
43 import info.magnolia.module.delta.TaskExecutionException;
44
45 import java.util.List;
46
47 import javax.jcr.Node;
48 import javax.jcr.Property;
49 import javax.jcr.RepositoryException;
50 import javax.jcr.Session;
51 import javax.jcr.Workspace;
52
53 import org.apache.commons.lang.StringUtils;
54 import org.apache.jackrabbit.JcrConstants;
55 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory;
57
58 import com.google.common.collect.Lists;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 public class MoveDataWorkspaceToDamMigrationTask extends AbstractRepositoryTask {
82
83 private static final Logger log = LoggerFactory.getLogger(MoveDataWorkspaceToDamMigrationTask.class);
84
85 private final List<String> originalPathsList;
86 private final String targetSubPath;
87 private Session damSession;
88 private final String dataRepository;
89 private Session dataSession;
90 private final String originalBinaryName = "document";
91
92
93
94
95 public MoveDataWorkspaceToDamMigrationTask(String taskName, String taskDescription, List<String> originalPathsList, String targetSubPath, String dataRepository) {
96 super(taskName, taskDescription);
97 this.dataRepository = dataRepository;
98 this.originalPathsList = originalPathsList;
99 this.targetSubPath = targetSubPath;
100 }
101
102 @Override
103 public void doExecute(InstallContext ctx) throws TaskExecutionException {
104 log.info("Start to move data from '{}' to DAM repository.", dataRepository);
105 try {
106
107 dataSession = ctx.getJCRSession(dataRepository);
108 damSession = ctx.getJCRSession(DamConstants.WORKSPACE);
109
110 for (String path : this.originalPathsList) {
111 if (!dataSession.nodeExists(path)) {
112 log.warn("Path '{}' does not exist for the repository '{}'. No Data migration will be performed", path, dataRepository);
113 continue;
114 }
115 migrateData(path, this.targetSubPath);
116 }
117
118 } catch (Exception e) {
119 ctx.error("Unable to perform Migration task " + getName(), e);
120 throw new TaskExecutionException(e.getMessage());
121 }
122 log.info("Successfully moved data to DAM repository: ");
123 }
124
125 private void migrateData(String path, String targetSubPath) throws TaskExecutionException {
126 String rootDataPath = StringUtils.isNotBlank(targetSubPath) ? targetSubPath + path : path;
127 copyNodesFromDataRepositoryToDam(path, targetSubPath);
128 convertFoldersToDam(rootDataPath);
129 convertContentNodesToDam(rootDataPath);
130 }
131
132
133
134
135
136
137
138 protected void copyNodesFromDataRepositoryToDam(String dataPath, String targetSubPath) throws TaskExecutionException {
139
140 log.info("Trying to move Data from the following path " + dataPath + " to " + (StringUtils.isNotBlank(targetSubPath) ? targetSubPath + "/" + dataPath : dataPath));
141 try {
142 Workspace workspaceDAM = damSession.getWorkspace();
143 final Node rootData = dataSession.getNode(dataPath);
144 List<Node> rootNodeToMove = null;
145
146 if (rootData.equals(dataSession.getRootNode())) {
147
148 rootNodeToMove = Lists.newArrayList(rootData.getNodes(NodeTypes.Content.NAME));
149 } else {
150 rootNodeToMove = Lists.newArrayList(rootData);
151 }
152
153 for (Node child : rootNodeToMove) {
154 String sourcePath = child.getPath();
155 String destPath = StringUtils.isNotBlank(targetSubPath) ? targetSubPath + sourcePath : "" + sourcePath;
156
157 if (damSession.nodeExists(destPath)) {
158 damSession.removeItem(destPath);
159 damSession.save();
160 log.warn("Destination path already existing in the DAM repository : " + destPath + "- data located in the current path are now removed");
161 }
162 workspaceDAM.clone(dataRepository, sourcePath, destPath, true);
163 log.info("Following " + this.dataRepository + ":" + sourcePath + " moved to dam:" + destPath);
164 damSession.save();
165 }
166 } catch (Exception e) {
167 throw new TaskExecutionException("Could not copy nodes from dms to DAM workspace. ", e);
168 }
169 }
170
171
172
173
174 private void convertFoldersToDam(String newDAMpath) throws TaskExecutionException {
175 try {
176 final Node rootDAM = damSession.getNode(newDAMpath);
177 NodeUtil.visit(rootDAM, createFolderVisitor());
178 damSession.save();
179
180 } catch (RepositoryException e) {
181 throw new TaskExecutionException("Could not convert folders to DAM format. ", e);
182 }
183 }
184
185
186
187
188 private void convertContentNodesToDam(String newDAMpath) throws TaskExecutionException {
189 try {
190 final Node rootDAM = damSession.getNode(newDAMpath);
191 NodeUtil.visit(rootDAM, createDataVisitor());
192 damSession.save();
193 } catch (RepositoryException e) {
194 throw new TaskExecutionException("Could not convert content nodes to DAM format. ", e);
195 }
196 }
197
198 private NodeVisitor createFolderVisitor() {
199 NodeVisitor folderVisitor = new NodeVisitor() {
200 @Override
201 public void visit(Node node) throws RepositoryException {
202 if (isNodeDmsFolder(node)) {
203 if (node.hasProperty(AssetNodeTypes.Asset.TYPE)) {
204 node.getProperty(AssetNodeTypes.Asset.TYPE).remove();
205 }
206 node.setPrimaryType(NodeTypes.Folder.NAME);
207 log.debug("Node primary Type set to NT_FOLDER for dam: " + node.getPath());
208 }
209 }
210 };
211
212 return folderVisitor;
213 }
214
215 private NodeVisitor createDataVisitor() {
216 NodeVisitor dataVisitor = new NodeVisitor() {
217 @Override
218 public void visit(Node node) throws RepositoryException {
219 if (isNodeDmsContent(node)) {
220 log.debug("Handle Node path " + node.getPath());
221 node.setPrimaryType(AssetNodeTypes.Asset.NAME);
222 log.debug("Handle Node path " + node.getPath() + " primary type set to " + AssetNodeTypes.Asset.NAME);
223 log.debug("Change primary type to '" + AssetNodeTypes.Asset.NAME + "' for : " + node.getPath());
224
225 if (node.hasNode(originalBinaryName)) {
226 Node nodeDocument = node.getNode(originalBinaryName);
227 node.getSession().move(nodeDocument.getPath(), nodeDocument.getParent().getPath() + "/" + JcrConstants.JCR_CONTENT);
228 log.debug("Handle Node path " + nodeDocument.getPath() + " renamed to type jcr:content");
229 log.debug("Rename content node to : " + nodeDocument.getPath());
230 if (nodeDocument.hasProperty(AssetNodeTypes.AssetResource.HEIGHT)) {
231 nodeDocument.setProperty(AssetNodeTypes.AssetResource.HEIGHT, Long.parseLong(nodeDocument.getProperty(AssetNodeTypes.AssetResource.HEIGHT).getString()));
232 }
233 if (nodeDocument.hasProperty(AssetNodeTypes.AssetResource.WIDTH)) {
234 nodeDocument.setProperty(AssetNodeTypes.AssetResource.WIDTH, Long.parseLong(nodeDocument.getProperty(AssetNodeTypes.AssetResource.WIDTH).getString()));
235 }
236 if (nodeDocument.hasProperty(AssetNodeTypes.AssetResource.SIZE)) {
237 nodeDocument.setProperty(AssetNodeTypes.AssetResource.SIZE, Long.parseLong(nodeDocument.getProperty(AssetNodeTypes.AssetResource.SIZE).getString()));
238 }
239 }
240 }
241 }
242 };
243
244 return dataVisitor;
245 }
246
247
248
249
250 private boolean isNodeDmsFolder(Node node) throws RepositoryException {
251 if (!NodeUtil.isNodeType(node, NodeTypes.Folder.NAME)) {
252 if (node.hasProperty("type")) {
253 Property type = node.getProperty("type");
254 String typeString = type.getString();
255
256 if ("folder".equals(typeString)) {
257 return true;
258 }
259 }
260 }
261 return false;
262 }
263
264
265
266
267 private boolean isNodeDmsContent(Node node) throws RepositoryException {
268 if (NodeUtil.isNodeType(node, NodeTypes.ContentNode.NAME)) {
269 String id = node.getName();
270
271 if (!"description_files".equals(id)) {
272 return true;
273 }
274 }
275 return false;
276 }
277 }