1 package org
.argeo
.jackrabbit
;
3 import java
.awt
.geom
.CubicCurve2D
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStreamReader
;
9 import javax
.jcr
.RepositoryException
;
10 import javax
.jcr
.Session
;
12 import org
.apache
.commons
.io
.IOUtils
;
13 import org
.apache
.commons
.logging
.Log
;
14 import org
.apache
.commons
.logging
.LogFactory
;
15 import org
.apache
.jackrabbit
.commons
.cnd
.CndImporter
;
16 import org
.apache
.jackrabbit
.commons
.cnd
.ParseException
;
17 import org
.apache
.jackrabbit
.core
.config
.RepositoryConfig
;
18 import org
.apache
.jackrabbit
.core
.fs
.FileSystemException
;
19 import org
.argeo
.jcr
.JcrCallback
;
20 import org
.argeo
.jcr
.JcrException
;
21 import org
.argeo
.jcr
.JcrUtils
;
23 /** Migrate the data in a Jackrabbit repository. */
25 public class JackrabbitDataModelMigration
implements Comparable
<JackrabbitDataModelMigration
> {
26 private final static Log log
= LogFactory
.getLog(JackrabbitDataModelMigration
.class);
28 private String dataModelNodePath
;
29 private String targetVersion
;
30 private URL migrationCnd
;
31 private JcrCallback dataModification
;
34 * Expects an already started repository with the old data model to migrate.
35 * Expects to be run with admin rights (Repository.login() will be used).
37 * @return true if a migration was performed and the repository needs to be
38 * restarted and its caches cleared.
40 public Boolean
migrate(Session session
) {
41 long begin
= System
.currentTimeMillis();
44 // check if already migrated
45 if (!session
.itemExists(dataModelNodePath
)) {
46 // log.warn("Node " + dataModelNodePath + " does not exist: nothing to migrate.");
49 // Node dataModelNode = session.getNode(dataModelNodePath);
50 // if (dataModelNode.hasProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION)) {
51 // String currentVersion = dataModelNode.getProperty(
52 // ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
53 // if (compareVersions(currentVersion, targetVersion) >= 0) {
54 // log.info("Data model at version " + currentVersion
55 // + ", no need to migrate.");
60 // apply transitional CND
61 if (migrationCnd
!= null) {
62 reader
= new InputStreamReader(migrationCnd
.openStream());
63 CndImporter
.registerNodeTypes(reader
, session
, true);
65 // log.info("Registered migration node types from " + migrationCnd);
69 dataModification
.execute(session
);
74 long duration
= System
.currentTimeMillis() - begin
;
75 // log.info("Migration of data model " + dataModelNodePath + " to " + targetVersion + " performed in "
76 // + duration + "ms");
78 } catch (RepositoryException e
) {
79 JcrUtils
.discardQuietly(session
);
80 throw new JcrException("Migration of data model " + dataModelNodePath
+ " to " + targetVersion
+ " failed.",
82 } catch (ParseException
| IOException e
) {
83 JcrUtils
.discardQuietly(session
);
84 throw new RuntimeException(
85 "Migration of data model " + dataModelNodePath
+ " to " + targetVersion
+ " failed.", e
);
87 JcrUtils
.logoutQuietly(session
);
88 IOUtils
.closeQuietly(reader
);
92 protected static int compareVersions(String version1
, String version2
) {
93 // TODO do a proper version analysis and comparison
94 return version1
.compareTo(version2
);
97 /** To be called on a stopped repository. */
98 public static void clearRepositoryCaches(RepositoryConfig repositoryConfig
) {
100 String customeNodeTypesPath
= "/nodetypes/custom_nodetypes.xml";
101 // FIXME causes weird error in Eclipse
102 repositoryConfig
.getFileSystem().deleteFile(customeNodeTypesPath
);
103 if (log
.isDebugEnabled())
104 log
.debug("Cleared " + customeNodeTypesPath
);
105 } catch (RuntimeException e
) {
107 } catch (RepositoryException e
) {
108 throw new JcrException(e
);
109 } catch (FileSystemException e
) {
110 throw new RuntimeException("Cannot clear node types cache.",e
);
113 // File customNodeTypes = new File(home.getPath()
114 // + "/repository/nodetypes/custom_nodetypes.xml");
115 // if (customNodeTypes.exists()) {
116 // customNodeTypes.delete();
117 // if (log.isDebugEnabled())
118 // log.debug("Cleared " + customNodeTypes);
120 // log.warn("File " + customNodeTypes + " not found.");
125 * FOR USE IN (SORTED) SETS
128 public int compareTo(JackrabbitDataModelMigration dataModelMigration
) {
129 // TODO make ordering smarter
130 if (dataModelNodePath
.equals(dataModelMigration
.dataModelNodePath
))
131 return compareVersions(targetVersion
, dataModelMigration
.targetVersion
);
133 return dataModelNodePath
.compareTo(dataModelMigration
.dataModelNodePath
);
137 public boolean equals(Object obj
) {
138 if (!(obj
instanceof JackrabbitDataModelMigration
))
140 JackrabbitDataModelMigration dataModelMigration
= (JackrabbitDataModelMigration
) obj
;
141 return dataModelNodePath
.equals(dataModelMigration
.dataModelNodePath
)
142 && targetVersion
.equals(dataModelMigration
.targetVersion
);
146 public int hashCode() {
147 return targetVersion
.hashCode();
150 public void setDataModelNodePath(String dataModelNodePath
) {
151 this.dataModelNodePath
= dataModelNodePath
;
154 public void setTargetVersion(String targetVersion
) {
155 this.targetVersion
= targetVersion
;
158 public void setMigrationCnd(URL migrationCnd
) {
159 this.migrationCnd
= migrationCnd
;
162 public void setDataModification(JcrCallback dataModification
) {
163 this.dataModification
= dataModification
;
166 public String
getDataModelNodePath() {
167 return dataModelNodePath
;
170 public String
getTargetVersion() {
171 return targetVersion
;