1 package org
.argeo
.jackrabbit
;
3 import java
.io
.InputStreamReader
;
7 import javax
.jcr
.Session
;
9 import org
.apache
.commons
.io
.IOUtils
;
10 import org
.apache
.commons
.logging
.Log
;
11 import org
.apache
.commons
.logging
.LogFactory
;
12 import org
.apache
.jackrabbit
.commons
.cnd
.CndImporter
;
13 import org
.apache
.jackrabbit
.core
.config
.RepositoryConfig
;
14 import org
.argeo
.ArgeoException
;
15 import org
.argeo
.jcr
.ArgeoNames
;
16 import org
.argeo
.jcr
.JcrCallback
;
17 import org
.argeo
.jcr
.JcrUtils
;
18 import org
.springframework
.core
.io
.Resource
;
20 /** Migrate the data in a Jackrabbit repository. */
21 public class JackrabbitDataModelMigration
implements
22 Comparable
<JackrabbitDataModelMigration
> {
23 private final static Log log
= LogFactory
24 .getLog(JackrabbitDataModelMigration
.class);
26 private String dataModelNodePath
;
27 private String targetVersion
;
28 private Resource migrationCnd
;
29 private JcrCallback dataModification
;
32 * Expects an already started repository with the old data model to migrate.
33 * Expects to be run with admin rights (Repository.login() will be used).
35 * @return true if a migration was performed and the repository needs to be
36 * restarted and its caches cleared.
38 public Boolean
migrate(Session session
) {
39 long begin
= System
.currentTimeMillis();
42 // check if already migrated
43 if (!session
.itemExists(dataModelNodePath
)) {
44 log
.warn("Node " + dataModelNodePath
45 + " does not exist: nothing to migrate.");
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.");
59 // apply transitional CND
60 if (migrationCnd
!= null) {
61 reader
= new InputStreamReader(migrationCnd
.getInputStream());
62 CndImporter
.registerNodeTypes(reader
, session
, true);
64 log
.info("Registered migration node types from " + migrationCnd
);
68 dataModification
.execute(session
);
73 long duration
= System
.currentTimeMillis() - begin
;
74 log
.info("Migration of data model " + dataModelNodePath
+ " to "
75 + targetVersion
+ " performed in " + duration
+ "ms");
77 } catch (Exception e
) {
78 JcrUtils
.discardQuietly(session
);
79 throw new ArgeoException("Migration of data model "
80 + dataModelNodePath
+ " to " + targetVersion
+ " failed.",
83 JcrUtils
.logoutQuietly(session
);
84 IOUtils
.closeQuietly(reader
);
88 protected static int compareVersions(String version1
, String version2
) {
89 // TODO do a proper version analysis and comparison
90 return version1
.compareTo(version2
);
93 /** To be called on a stopped repository. */
94 public static void clearRepositoryCaches(RepositoryConfig repositoryConfig
) {
96 String customeNodeTypesPath
= "/nodetypes/custom_nodetypes.xml";
97 repositoryConfig
.getFileSystem().deleteFile(customeNodeTypesPath
);
98 if (log
.isDebugEnabled())
99 log
.debug("Cleared " + customeNodeTypesPath
);
100 } catch (Exception e
) {
101 throw new ArgeoException("Cannot clear caches", e
);
104 // File customNodeTypes = new File(home.getPath()
105 // + "/repository/nodetypes/custom_nodetypes.xml");
106 // if (customNodeTypes.exists()) {
107 // customNodeTypes.delete();
108 // if (log.isDebugEnabled())
109 // log.debug("Cleared " + customNodeTypes);
111 // log.warn("File " + customNodeTypes + " not found.");
116 * FOR USE IN (SORTED) SETS
119 public int compareTo(JackrabbitDataModelMigration dataModelMigration
) {
120 // TODO make ordering smarter
121 if (dataModelNodePath
.equals(dataModelMigration
.dataModelNodePath
))
122 return compareVersions(targetVersion
,
123 dataModelMigration
.targetVersion
);
125 return dataModelNodePath
126 .compareTo(dataModelMigration
.dataModelNodePath
);
130 public boolean equals(Object obj
) {
131 if (!(obj
instanceof JackrabbitDataModelMigration
))
133 JackrabbitDataModelMigration dataModelMigration
= (JackrabbitDataModelMigration
) obj
;
134 return dataModelNodePath
.equals(dataModelMigration
.dataModelNodePath
)
135 && targetVersion
.equals(dataModelMigration
.targetVersion
);
139 public int hashCode() {
140 return targetVersion
.hashCode();
143 public void setDataModelNodePath(String dataModelNodePath
) {
144 this.dataModelNodePath
= dataModelNodePath
;
147 public void setTargetVersion(String targetVersion
) {
148 this.targetVersion
= targetVersion
;
151 public void setMigrationCnd(Resource migrationCnd
) {
152 this.migrationCnd
= migrationCnd
;
155 public void setDataModification(JcrCallback dataModification
) {
156 this.dataModification
= dataModification
;
159 public String
getDataModelNodePath() {
160 return dataModelNodePath
;
163 public String
getTargetVersion() {
164 return targetVersion
;