1 package org
.argeo
.jackrabbit
;
3 import java
.io
.IOException
;
4 import java
.io
.InputStreamReader
;
8 import javax
.jcr
.RepositoryException
;
9 import javax
.jcr
.Session
;
11 import org
.apache
.commons
.io
.IOUtils
;
12 import org
.apache
.jackrabbit
.commons
.cnd
.CndImporter
;
13 import org
.apache
.jackrabbit
.commons
.cnd
.ParseException
;
14 import org
.apache
.jackrabbit
.core
.config
.RepositoryConfig
;
15 import org
.apache
.jackrabbit
.core
.fs
.FileSystemException
;
16 import org
.argeo
.api
.cms
.CmsLog
;
17 import org
.argeo
.jcr
.JcrCallback
;
18 import org
.argeo
.jcr
.JcrException
;
19 import org
.argeo
.jcr
.JcrUtils
;
21 /** Migrate the data in a Jackrabbit repository. */
23 public class JackrabbitDataModelMigration
implements Comparable
<JackrabbitDataModelMigration
> {
24 private final static CmsLog log
= CmsLog
.getLog(JackrabbitDataModelMigration
.class);
26 private String dataModelNodePath
;
27 private String targetVersion
;
28 private URL 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 + " does not exist: nothing to migrate.");
47 // Node dataModelNode = session.getNode(dataModelNodePath);
48 // if (dataModelNode.hasProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION)) {
49 // String currentVersion = dataModelNode.getProperty(
50 // ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
51 // if (compareVersions(currentVersion, targetVersion) >= 0) {
52 // log.info("Data model at version " + currentVersion
53 // + ", no need to migrate.");
58 // apply transitional CND
59 if (migrationCnd
!= null) {
60 reader
= new InputStreamReader(migrationCnd
.openStream());
61 CndImporter
.registerNodeTypes(reader
, session
, true);
63 // log.info("Registered migration node types from " + migrationCnd);
67 dataModification
.execute(session
);
72 long duration
= System
.currentTimeMillis() - begin
;
73 // log.info("Migration of data model " + dataModelNodePath + " to " + targetVersion + " performed in "
74 // + duration + "ms");
76 } catch (RepositoryException e
) {
77 JcrUtils
.discardQuietly(session
);
78 throw new JcrException("Migration of data model " + dataModelNodePath
+ " to " + targetVersion
+ " failed.",
80 } catch (ParseException
| IOException e
) {
81 JcrUtils
.discardQuietly(session
);
82 throw new RuntimeException(
83 "Migration of data model " + dataModelNodePath
+ " to " + targetVersion
+ " failed.", e
);
85 JcrUtils
.logoutQuietly(session
);
86 IOUtils
.closeQuietly(reader
);
90 protected static int compareVersions(String version1
, String version2
) {
91 // TODO do a proper version analysis and comparison
92 return version1
.compareTo(version2
);
95 /** To be called on a stopped repository. */
96 public static void clearRepositoryCaches(RepositoryConfig repositoryConfig
) {
98 String customeNodeTypesPath
= "/nodetypes/custom_nodetypes.xml";
99 // FIXME causes weird error in Eclipse
100 repositoryConfig
.getFileSystem().deleteFile(customeNodeTypesPath
);
101 if (log
.isDebugEnabled())
102 log
.debug("Cleared " + customeNodeTypesPath
);
103 } catch (RuntimeException e
) {
105 } catch (RepositoryException e
) {
106 throw new JcrException(e
);
107 } catch (FileSystemException e
) {
108 throw new RuntimeException("Cannot clear node types cache.",e
);
111 // File customNodeTypes = new File(home.getPath()
112 // + "/repository/nodetypes/custom_nodetypes.xml");
113 // if (customNodeTypes.exists()) {
114 // customNodeTypes.delete();
115 // if (log.isDebugEnabled())
116 // log.debug("Cleared " + customNodeTypes);
118 // log.warn("File " + customNodeTypes + " not found.");
123 * FOR USE IN (SORTED) SETS
126 public int compareTo(JackrabbitDataModelMigration dataModelMigration
) {
127 // TODO make ordering smarter
128 if (dataModelNodePath
.equals(dataModelMigration
.dataModelNodePath
))
129 return compareVersions(targetVersion
, dataModelMigration
.targetVersion
);
131 return dataModelNodePath
.compareTo(dataModelMigration
.dataModelNodePath
);
135 public boolean equals(Object obj
) {
136 if (!(obj
instanceof JackrabbitDataModelMigration
))
138 JackrabbitDataModelMigration dataModelMigration
= (JackrabbitDataModelMigration
) obj
;
139 return dataModelNodePath
.equals(dataModelMigration
.dataModelNodePath
)
140 && targetVersion
.equals(dataModelMigration
.targetVersion
);
144 public int hashCode() {
145 return targetVersion
.hashCode();
148 public void setDataModelNodePath(String dataModelNodePath
) {
149 this.dataModelNodePath
= dataModelNodePath
;
152 public void setTargetVersion(String targetVersion
) {
153 this.targetVersion
= targetVersion
;
156 public void setMigrationCnd(URL migrationCnd
) {
157 this.migrationCnd
= migrationCnd
;
160 public void setDataModification(JcrCallback dataModification
) {
161 this.dataModification
= dataModification
;
164 public String
getDataModelNodePath() {
165 return dataModelNodePath
;
168 public String
getTargetVersion() {
169 return targetVersion
;