]> git.argeo.org Git - lgpl/argeo-commons.git/blob - jackrabbit/JackrabbitDataModelMigration.java
Prepare next development cycle
[lgpl/argeo-commons.git] / jackrabbit / JackrabbitDataModelMigration.java
1 package org.argeo.jackrabbit;
2
3 import java.io.IOException;
4 import java.io.InputStreamReader;
5 import java.io.Reader;
6 import java.net.URL;
7
8 import javax.jcr.RepositoryException;
9 import javax.jcr.Session;
10
11 import org.apache.commons.io.IOUtils;
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14 import org.apache.jackrabbit.commons.cnd.CndImporter;
15 import org.apache.jackrabbit.commons.cnd.ParseException;
16 import org.apache.jackrabbit.core.config.RepositoryConfig;
17 import org.apache.jackrabbit.core.fs.FileSystemException;
18 import org.argeo.jcr.JcrCallback;
19 import org.argeo.jcr.JcrException;
20 import org.argeo.jcr.JcrUtils;
21
22 /** Migrate the data in a Jackrabbit repository. */
23 @Deprecated
24 public class JackrabbitDataModelMigration implements Comparable<JackrabbitDataModelMigration> {
25 private final static Log log = LogFactory.getLog(JackrabbitDataModelMigration.class);
26
27 private String dataModelNodePath;
28 private String targetVersion;
29 private URL migrationCnd;
30 private JcrCallback dataModification;
31
32 /**
33 * Expects an already started repository with the old data model to migrate.
34 * Expects to be run with admin rights (Repository.login() will be used).
35 *
36 * @return true if a migration was performed and the repository needs to be
37 * restarted and its caches cleared.
38 */
39 public Boolean migrate(Session session) {
40 long begin = System.currentTimeMillis();
41 Reader reader = null;
42 try {
43 // check if already migrated
44 if (!session.itemExists(dataModelNodePath)) {
45 // log.warn("Node " + dataModelNodePath + " does not exist: nothing to migrate.");
46 return false;
47 }
48 // Node dataModelNode = session.getNode(dataModelNodePath);
49 // if (dataModelNode.hasProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION)) {
50 // String currentVersion = dataModelNode.getProperty(
51 // ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
52 // if (compareVersions(currentVersion, targetVersion) >= 0) {
53 // log.info("Data model at version " + currentVersion
54 // + ", no need to migrate.");
55 // return false;
56 // }
57 // }
58
59 // apply transitional CND
60 if (migrationCnd != null) {
61 reader = new InputStreamReader(migrationCnd.openStream());
62 CndImporter.registerNodeTypes(reader, session, true);
63 session.save();
64 // log.info("Registered migration node types from " + migrationCnd);
65 }
66
67 // modify data
68 dataModification.execute(session);
69
70 // apply changes
71 session.save();
72
73 long duration = System.currentTimeMillis() - begin;
74 // log.info("Migration of data model " + dataModelNodePath + " to " + targetVersion + " performed in "
75 // + duration + "ms");
76 return true;
77 } catch (RepositoryException e) {
78 JcrUtils.discardQuietly(session);
79 throw new JcrException("Migration of data model " + dataModelNodePath + " to " + targetVersion + " failed.",
80 e);
81 } catch (ParseException | IOException e) {
82 JcrUtils.discardQuietly(session);
83 throw new RuntimeException(
84 "Migration of data model " + dataModelNodePath + " to " + targetVersion + " failed.", e);
85 } finally {
86 JcrUtils.logoutQuietly(session);
87 IOUtils.closeQuietly(reader);
88 }
89 }
90
91 protected static int compareVersions(String version1, String version2) {
92 // TODO do a proper version analysis and comparison
93 return version1.compareTo(version2);
94 }
95
96 /** To be called on a stopped repository. */
97 public static void clearRepositoryCaches(RepositoryConfig repositoryConfig) {
98 try {
99 String customeNodeTypesPath = "/nodetypes/custom_nodetypes.xml";
100 // FIXME causes weird error in Eclipse
101 repositoryConfig.getFileSystem().deleteFile(customeNodeTypesPath);
102 if (log.isDebugEnabled())
103 log.debug("Cleared " + customeNodeTypesPath);
104 } catch (RuntimeException e) {
105 throw e;
106 } catch (RepositoryException e) {
107 throw new JcrException(e);
108 } catch (FileSystemException e) {
109 throw new RuntimeException("Cannot clear node types cache.",e);
110 }
111
112 // File customNodeTypes = new File(home.getPath()
113 // + "/repository/nodetypes/custom_nodetypes.xml");
114 // if (customNodeTypes.exists()) {
115 // customNodeTypes.delete();
116 // if (log.isDebugEnabled())
117 // log.debug("Cleared " + customNodeTypes);
118 // } else {
119 // log.warn("File " + customNodeTypes + " not found.");
120 // }
121 }
122
123 /*
124 * FOR USE IN (SORTED) SETS
125 */
126
127 public int compareTo(JackrabbitDataModelMigration dataModelMigration) {
128 // TODO make ordering smarter
129 if (dataModelNodePath.equals(dataModelMigration.dataModelNodePath))
130 return compareVersions(targetVersion, dataModelMigration.targetVersion);
131 else
132 return dataModelNodePath.compareTo(dataModelMigration.dataModelNodePath);
133 }
134
135 @Override
136 public boolean equals(Object obj) {
137 if (!(obj instanceof JackrabbitDataModelMigration))
138 return false;
139 JackrabbitDataModelMigration dataModelMigration = (JackrabbitDataModelMigration) obj;
140 return dataModelNodePath.equals(dataModelMigration.dataModelNodePath)
141 && targetVersion.equals(dataModelMigration.targetVersion);
142 }
143
144 @Override
145 public int hashCode() {
146 return targetVersion.hashCode();
147 }
148
149 public void setDataModelNodePath(String dataModelNodePath) {
150 this.dataModelNodePath = dataModelNodePath;
151 }
152
153 public void setTargetVersion(String targetVersion) {
154 this.targetVersion = targetVersion;
155 }
156
157 public void setMigrationCnd(URL migrationCnd) {
158 this.migrationCnd = migrationCnd;
159 }
160
161 public void setDataModification(JcrCallback dataModification) {
162 this.dataModification = dataModification;
163 }
164
165 public String getDataModelNodePath() {
166 return dataModelNodePath;
167 }
168
169 public String getTargetVersion() {
170 return targetVersion;
171 }
172
173 }