/*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ * Copyright (C) 2007-2012 Mathieu Baudier
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.argeo.jackrabbit;
import java.io.IOException;
import javax.jcr.LoginException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
+import javax.jcr.NodeIterator;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
+import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.commons.cnd.CndImporter;
import org.apache.jackrabbit.core.RepositoryImpl;
import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrConstants;
import org.argeo.jcr.ArgeoNames;
+import org.argeo.jcr.ArgeoTypes;
import org.argeo.jcr.JcrUtils;
import org.argeo.security.SystemAuthentication;
import org.osgi.framework.Bundle;
// data model
/** Node type definitions in CND format */
private List<String> cndFiles = new ArrayList<String>();
+ /**
+ * Always import CNDs. Useful during development of new data models. In
+ * production, explicit migration processes should be used.
+ */
+ private Boolean forceCndImport = false;
/** Migrations to execute (if not already done) */
private Set<JackrabbitDataModelMigration> dataModelMigrations = new HashSet<JackrabbitDataModelMigration>();
// load CND files from classpath or as URL
for (String resUrl : cndFiles) {
boolean classpath;
- // if (resUrl.startsWith("classpath:")) {
- // // resUrl = resUrl.substring("classpath:".length());
- // classpath = true;
- // } else if (resUrl.indexOf(':') < 0) {
- // if (!resUrl.startsWith("/")) {
- // resUrl = "/" + resUrl;
- // log.warn("Classpath should start with '/'");
- // }
- // resUrl = "classpath:" + resUrl;
- // classpath = true;
- // } else {
- // classpath = false;
- // }
-
+ // normalize URL
if (resUrl.startsWith("classpath:")) {
resUrl = resUrl.substring("classpath:".length());
classpath = true;
classpath = false;
}
- // Resource resource =
- // resourceLoader.getResource(resUrl);
-
- // = classpath ? new ClassPathResource(resUrl) : new
- // UrlResource(resUrl);
-
URL url;
Bundle dataModelBundle = null;
if (classpath) {
url = new URL(resUrl);
}
+ // check existing data model nodes
+ new NamespaceHelper(session).registerNamespace(
+ ArgeoNames.ARGEO, ArgeoNames.ARGEO_NAMESPACE);
+ if (!session
+ .itemExists(ArgeoJcrConstants.DATA_MODELS_BASE_PATH))
+ JcrUtils.mkdirs(session,
+ ArgeoJcrConstants.DATA_MODELS_BASE_PATH);
+ Node dataModels = session
+ .getNode(ArgeoJcrConstants.DATA_MODELS_BASE_PATH);
+ NodeIterator it = dataModels.getNodes();
+ Node dataModel = null;
+ while (it.hasNext()) {
+ Node node = it.nextNode();
+ if (node.getProperty(ArgeoNames.ARGEO_URI).getString()
+ .equals(resUrl)) {
+ dataModel = node;
+ break;
+ }
+ }
+
+ // does nothing if data model already registered
+ if (dataModel != null && !forceCndImport) {
+ if (dataModelBundle != null) {
+ String version = dataModel.getProperty(
+ ArgeoNames.ARGEO_DATA_MODEL_VERSION)
+ .getString();
+ String dataModelBundleVersion = dataModelBundle
+ .getVersion().toString();
+ if (!version.equals(dataModelBundleVersion)) {
+ log.warn("Data model with version "
+ + dataModelBundleVersion
+ + " available, current version is "
+ + version);
+ }
+ }
+ // do not implicitly update
+ return;
+ }
+
Reader reader = null;
try {
reader = new InputStreamReader(url.openStream());
+ // actually imports the CND
CndImporter.registerNodeTypes(reader, session, true);
+
+ // FIXME: what if argeo.cnd would not be the first called on
+ // a new repo? argeo:dataModel would not be found
+ String fileName = FilenameUtils.getName(url.getPath());
+ if (dataModel == null) {
+ dataModel = dataModels.addNode(fileName);
+ dataModel.addMixin(ArgeoTypes.ARGEO_DATA_MODEL);
+ dataModel.setProperty(ArgeoNames.ARGEO_URI, resUrl);
+ } else {
+ session.getWorkspace().getVersionManager()
+ .checkout(dataModel.getPath());
+ }
+ if (dataModelBundle != null)
+ dataModel.setProperty(
+ ArgeoNames.ARGEO_DATA_MODEL_VERSION,
+ dataModelBundle.getVersion().toString());
+ else
+ dataModel.setProperty(
+ ArgeoNames.ARGEO_DATA_MODEL_VERSION, "0.0.0");
+ JcrUtils.updateLastModified(dataModel);
+ session.save();
+ session.getWorkspace().getVersionManager()
+ .checkin(dataModel.getPath());
} finally {
IOUtils.closeQuietly(reader);
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
+
+ public void setForceCndImport(Boolean forceCndUpdate) {
+ this.forceCndImport = forceCndUpdate;
+ }
+
}