argeo.osgi.start.2.node=\
org.eclipse.equinox.http.servlet,\
org.eclipse.equinox.http.jetty,\
+org.eclipse.equinox.cm,\
org.eclipse.rap.rwt.osgi
argeo.osgi.start.3.node=\
--- /dev/null
+package org.argeo.cms;
+
+import java.util.List;
+
+import javax.jcr.Session;
+
+public interface CmsExtension {
+ public List<String> getDataModels();
+
+ public List<String> getRoles();
+
+ public void onInit(Session adminSession);
+
+ public void onStart(Session adminSession);
+
+ public void onShutdown(Session adminSession);
+
+ public void onDestroy(Session adminSession);
+}
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.security.PrivilegedAction;
+import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import org.argeo.ArgeoLogger;
import org.argeo.cms.CmsException;
import org.argeo.cms.maintenance.MaintenanceUi;
+import org.argeo.jackrabbit.JackrabbitDataModel;
+import org.argeo.jackrabbit.ManagedJackrabbitRepository;
import org.argeo.jackrabbit.OsgiJackrabbitRepositoryFactory;
import org.argeo.jcr.ArgeoJcrConstants;
import org.argeo.jcr.ArgeoJcrUtils;
+import org.argeo.jcr.RepoConf;
import org.eclipse.equinox.http.jetty.JettyConfigurator;
import org.eclipse.equinox.http.jetty.JettyConstants;
import org.eclipse.equinox.http.servlet.ExtendedHttpService;
import org.eclipse.rap.rwt.application.ApplicationConfiguration;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ManagedService;
import org.osgi.service.log.LogReaderService;
import org.osgi.service.useradmin.UserAdmin;
import org.osgi.util.tracker.ServiceTracker;
private BitronixTransactionManager transactionManager;
private BitronixTransactionSynchronizationRegistry transactionSynchronizationRegistry;
private OsgiJackrabbitRepositoryFactory repositoryFactory;
- NodeRepository repository;
+ JackrabbitRepository repository;
private NodeUserAdmin userAdmin;
// Members
}
final void init() {
- Subject.doAs(nodeSecurity.getKernelSubject(),
- new PrivilegedAction<Void>() {
- @Override
- public Void run() {
- doInit();
- return null;
- }
- });
+ Subject.doAs(nodeSecurity.getKernelSubject(), new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ doInit();
+ return null;
+ }
+ });
}
private void doInit() {
long begin = System.currentTimeMillis();
// Use CMS bundle classloader
- ClassLoader currentContextCl = Thread.currentThread()
- .getContextClassLoader();
- Thread.currentThread().setContextClassLoader(
- Kernel.class.getClassLoader());
+ ClassLoader currentContextCl = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(Kernel.class.getClassLoader());
try {
if (nodeSecurity.isFirstInit())
firstInit();
- defaultLocale = new Locale(getFrameworkProp(I18N_DEFAULT_LOCALE,
- ENGLISH.getLanguage()));
+ defaultLocale = new Locale(getFrameworkProp(I18N_DEFAULT_LOCALE, ENGLISH.getLanguage()));
locales = asLocaleList(getFrameworkProp(I18N_LOCALES));
ServiceTracker<LogReaderService, LogReaderService> logReaderService = new ServiceTracker<LogReaderService, LogReaderService>(
Thread.currentThread().setContextClassLoader(currentContextCl);
// FIXME better manage lifecycle.
try {
- new LoginContext(LOGIN_CONTEXT_KERNEL,
- nodeSecurity.getKernelSubject()).logout();
+ new LoginContext(LOGIN_CONTEXT_KERNEL, nodeSecurity.getKernelSubject()).logout();
} catch (LoginException e) {
e.printStackTrace();
}
}
long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
- log.info("## ARGEO CMS UP in " + (jvmUptime / 1000) + "."
- + (jvmUptime % 1000) + "s ##");
+ log.info("## ARGEO CMS UP in " + (jvmUptime / 1000) + "." + (jvmUptime % 1000) + "s ##");
long initDuration = System.currentTimeMillis() - begin;
if (log.isTraceEnabled())
log.trace("Kernel initialization took " + initDuration + "ms");
private void normalInit() {
ConfigurationAdmin conf = findConfigurationAdmin();
+
+ // HTTP
+ initWebServer(conf);
+ ServiceReference<ExtendedHttpService> sr = bc.getServiceReference(ExtendedHttpService.class);
+ if (sr != null)
+ addHttpService(sr);
+
// Initialise services
initTransactionManager();
+
+ try {
+ Configuration nodeConf = conf.getConfiguration(ArgeoJcrConstants.REPO_PID_NODE);
+ if (nodeConf.getProperties() == null) {
+ Dictionary<String, ?> props = getNodeConfigFromFrameworkProperties();
+ if(props==null)// TODO interactive configuration
+ return;
+ nodeConf.update(props);
+ }
+ } catch (IOException e) {
+ throw new CmsException("Cannot get configuration", e);
+ }
+
+ ManagedJackrabbitRepository nodeRepo = new ManagedJackrabbitRepository();
+ String[] clazzes = { ManagedService.class.getName(), Repository.class.getName(),
+ JackrabbitRepository.class.getName() };
+ Hashtable<String, String> serviceProps = new Hashtable<String, String>();
+ serviceProps.put(Constants.SERVICE_PID, ArgeoJcrConstants.REPO_PID_NODE);
+ serviceProps.put(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS, ArgeoJcrConstants.ALIAS_NODE);
+ ServiceRegistration<?> nodeSr = bc.registerService(clazzes, nodeRepo, serviceProps);
+ nodeRepo.waitForInit();
+ new JackrabbitDataModel(bc).prepareDataModel(nodeRepo);
+
+ repository = (JackrabbitRepository) bc.getService(nodeSr.getReference());
+
if (repository == null)
repository = new NodeRepository();
if (repositoryFactory == null)
repositoryFactory = new OsgiJackrabbitRepositoryFactory();
userAdmin = new NodeUserAdmin(transactionManager, repository);
- // HTTP
- initWebServer(conf);
- ServiceReference<ExtendedHttpService> sr = bc
- .getServiceReference(ExtendedHttpService.class);
- if (sr != null)
- addHttpService(sr);
-
// ADMIN UIs
UserUi userUi = new UserUi();
Hashtable<String, String> props = new Hashtable<String, String>();
publish();
}
+ private Dictionary<String, ?> getNodeConfigFromFrameworkProperties() {
+ String repoType = KernelUtils
+ .getFrameworkProp(KernelConstants.NODE_REPO_PROP_PREFIX + RepoConf.type.name());
+ if (repoType == null)
+ return null;
+
+ Hashtable<String, Object> props = new Hashtable<String, Object>();
+ for (RepoConf repoConf : RepoConf.values()) {
+ String value = KernelUtils.getFrameworkProp(KernelConstants.NODE_REPO_PROP_PREFIX + repoConf.name());
+ if (value != null)
+ props.put(repoConf.name(), value);
+ }
+ return props;
+ }
+
private boolean isMaintenance() {
String startLevel = KernelUtils.getFrameworkProp("osgi.startLevel");
if (startLevel == null)
return false;
- int bundleStartLevel = bc.getBundle().adapt(BundleStartLevel.class)
- .getStartLevel();
+ int bundleStartLevel = bc.getBundle().adapt(BundleStartLevel.class).getStartLevel();
// int frameworkStartLevel =
// bc.getBundle(0).adapt(BundleStartLevel.class)
// .getStartLevel();
// TODO also uncompress archives
if (initDir.exists())
try {
- FileUtils.copyDirectory(initDir, getOsgiInstanceDir(),
- new FileFilter() {
-
- @Override
- public boolean accept(File pathname) {
- if (pathname.getName().equals(".svn")
- || pathname.getName().equals(".git"))
- return false;
- return true;
- }
- });
+ FileUtils.copyDirectory(initDir, getOsgiInstanceDir(), new FileFilter() {
+
+ @Override
+ public boolean accept(File pathname) {
+ if (pathname.getName().equals(".svn") || pathname.getName().equals(".git"))
+ return false;
+ return true;
+ }
+ });
log.info("CMS initialized from " + initDir.getCanonicalPath());
} catch (IOException e) {
throw new CmsException("Cannot initialize from " + initDir, e);
try {
repository = new NodeRepository();
repositoryFactory = new OsgiJackrabbitRepositoryFactory();
- Repository remoteRepository = ArgeoJcrUtils.getRepositoryByUri(
- repositoryFactory, uri);
- Session remoteSession = remoteRepository
- .login(new SimpleCredentials("root", "demo".toCharArray()),
- "main");
+ Repository remoteRepository = ArgeoJcrUtils.getRepositoryByUri(repositoryFactory, uri);
+ Session remoteSession = remoteRepository.login(new SimpleCredentials("root", "demo".toCharArray()), "main");
Session localSession = this.repository.login();
// FIXME register node type
// if (false)
// CndImporter.registerNodeTypes(null, localSession);
ByteArrayOutputStream out = new ByteArrayOutputStream();
remoteSession.exportSystemView("/", out, true, false);
- ByteArrayInputStream in = new ByteArrayInputStream(
- out.toByteArray());
- localSession.importXML("/", in,
- ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ localSession.importXML("/", in, ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
// JcrUtils.copy(remoteSession.getRootNode(),
// localSession.getRootNode());
} catch (Exception e) {
}
private void initTransactionManager() {
- bitronix.tm.Configuration tmConf = TransactionManagerServices
- .getConfiguration();
+ bitronix.tm.Configuration tmConf = TransactionManagerServices.getConfiguration();
tmConf.setServerId(getFrameworkProp(FRAMEWORK_UUID));
// File tmBaseDir = new File(getFrameworkProp(TRANSACTIONS_HOME,
File tmBaseDir = bc.getDataFile(DIR_TRANSACTIONS);
File tmDir1 = new File(tmBaseDir, "btm1");
tmDir1.mkdirs();
- tmConf.setLogPart1Filename(new File(tmDir1, tmDir1.getName() + ".tlog")
- .getAbsolutePath());
+ tmConf.setLogPart1Filename(new File(tmDir1, tmDir1.getName() + ".tlog").getAbsolutePath());
File tmDir2 = new File(tmBaseDir, "btm2");
tmDir2.mkdirs();
- tmConf.setLogPart2Filename(new File(tmDir2, tmDir2.getName() + ".tlog")
- .getAbsolutePath());
+ tmConf.setLogPart2Filename(new File(tmDir2, tmDir2.getName() + ".tlog").getAbsolutePath());
transactionManager = getTransactionManager();
transactionSynchronizationRegistry = getTransactionSynchronizationRegistry();
}
jettyProps.put(JettyConstants.HTTPS_PORT, httpsPort);
jettyProps.put(JettyConstants.HTTPS_ENABLED, true);
jettyProps.put(JettyConstants.SSL_KEYSTORETYPE, "PKCS12");
- jettyProps.put(JettyConstants.SSL_KEYSTORE, nodeSecurity
- .getHttpServerKeyStore().getCanonicalPath());
+ jettyProps.put(JettyConstants.SSL_KEYSTORE,
+ nodeSecurity.getHttpServerKeyStore().getCanonicalPath());
jettyProps.put(JettyConstants.SSL_PASSWORD, "changeit");
jettyProps.put(JettyConstants.SSL_WANTCLIENTAUTH, true);
}
if (conf != null) {
// TODO make filter more generic
- String filter = "(" + JettyConstants.HTTP_PORT + "="
- + httpPort + ")";
+ String filter = "(" + JettyConstants.HTTP_PORT + "=" + httpPort + ")";
if (conf.listConfigurations(filter) != null)
return;
- Configuration jettyConf = conf.createFactoryConfiguration(
- JETTY_FACTORY_PID, null);
+ Configuration jettyConf = conf.createFactoryConfiguration(JETTY_FACTORY_PID, null);
jettyConf.update(jettyProps);
} else {
JettyConfigurator.startServer("default", jettyProps);
}
}
} catch (Exception e) {
- throw new CmsException("Cannot initialize web server on "
- + httpPortsMsg(httpPort, httpsPort), e);
+ throw new CmsException("Cannot initialize web server on " + httpPortsMsg(httpPort, httpsPort), e);
}
}
// Logging
loggerReg = bc.registerService(ArgeoLogger.class, logger, null);
// Transaction
- tmReg = bc.registerService(TransactionManager.class,
- transactionManager, null);
- utReg = bc.registerService(UserTransaction.class, transactionManager,
- null);
- tsrReg = bc.registerService(TransactionSynchronizationRegistry.class,
- transactionSynchronizationRegistry, null);
+ tmReg = bc.registerService(TransactionManager.class, transactionManager, null);
+ utReg = bc.registerService(UserTransaction.class, transactionManager, null);
+ tsrReg = bc.registerService(TransactionSynchronizationRegistry.class, transactionSynchronizationRegistry, null);
// User admin
- userAdminReg = bc.registerService(UserAdmin.class, userAdmin,
- userAdmin.currentState());
+ userAdminReg = bc.registerService(UserAdmin.class, userAdmin, userAdmin.currentState());
// JCR
Hashtable<String, String> regProps = new Hashtable<String, String>();
regProps.put(JCR_REPOSITORY_ALIAS, ALIAS_NODE);
- repositoryReg = (ServiceRegistration<? extends Repository>) bc
- .registerService(new String[] { Repository.class.getName(),
- JackrabbitRepository.class.getName() }, repository,
- regProps);
- repositoryFactoryReg = bc.registerService(RepositoryFactory.class,
- repositoryFactory, null);
+ repositoryReg = (ServiceRegistration<? extends Repository>) bc.registerService(
+ new String[] { Repository.class.getName(), JackrabbitRepository.class.getName() }, repository,
+ regProps);
+ repositoryFactoryReg = bc.registerService(RepositoryFactory.class, repositoryFactory, null);
}
void destroy() {
if (userAdmin != null)
userAdmin.destroy();
if (repository != null)
- repository.destroy();
+ repository.shutdown();
if (transactionManager != null)
transactionManager.shutdown();
nodeSecurity.destroy();
long duration = System.currentTimeMillis() - begin;
- log.info("## ARGEO CMS DOWN in " + (duration / 1000) + "."
- + (duration % 1000) + "s ##");
+ log.info("## ARGEO CMS DOWN in " + (duration / 1000) + "." + (duration % 1000) + "s ##");
}
private void unpublish() {
ServiceReference<?> sr = event.getServiceReference();
Object service = bc.getService(sr);
if (service instanceof Repository) {
- Object jcrRepoAlias = sr
- .getProperty(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS);
+ Object jcrRepoAlias = sr.getProperty(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS);
if (jcrRepoAlias != null) {// JCR repository
String alias = jcrRepoAlias.toString();
Repository repository = (Repository) bc.getService(sr);
repositoryFactory.register(repository, props);
dataHttp.registerRepositoryServlets(alias, repository);
} catch (Exception e) {
- throw new CmsException(
- "Could not publish JCR repository " + alias, e);
+ throw new CmsException("Could not publish JCR repository " + alias, e);
}
} else if (ServiceEvent.UNREGISTERING == event.getType()) {
repositoryFactory.unregister(repository, props);
private void addHttpService(ServiceReference<?> sr) {
// for (String key : sr.getPropertyKeys())
// log.debug(key + "=" + sr.getProperty(key));
- ExtendedHttpService httpService = (ExtendedHttpService) bc
- .getService(sr);
+ ExtendedHttpService httpService = (ExtendedHttpService) bc.getService(sr);
// TODO find constants
Object httpPort = sr.getProperty("http.port");
Object httpsPort = sr.getProperty("https.port");
}
private String httpPortsMsg(Object httpPort, Object httpsPort) {
- return "HTTP " + httpPort
- + (httpsPort != null ? " - HTTPS " + httpsPort : "");
+ return "HTTP " + httpPort + (httpsPort != null ? " - HTTPS " + httpsPort : "");
}
@Override
final private static void directorsCut(long initDuration) {
// final long ms = 128l + (long) (Math.random() * 128d);
long ms = initDuration / 100;
- log.info("Spend " + ms + "ms"
- + " reflecting on the progress brought to mankind"
- + " by Free Software...");
+ log.info("Spend " + ms + "ms" + " reflecting on the progress brought to mankind" + " by Free Software...");
long beginNano = System.nanoTime();
try {
Thread.sleep(ms, 0);
final double M = 1000d * 1000d;
double sleepAccuracy = ((double) durationNano) / (ms * M);
if (log.isDebugEnabled())
- log.debug("Sleep accuracy: "
- + String.format("%.2f", 100 - (sleepAccuracy * 100 - 100))
- + " %");
+ log.debug("Sleep accuracy: " + String.format("%.2f", 100 - (sleepAccuracy * 100 - 100)) + " %");
}
/** Workaround for blocking Gogo shell by system shutdown. */
final static String NODE_INIT = "argeo.node.init";
// Node
- final static String REPO_HOME = "argeo.node.repo.home";
- final static String REPO_TYPE = "argeo.node.repo.type";
+ /** Properties configuring the node repository */
+ final static String NODE_REPO_PROP_PREFIX = "argeo.node.repo.";
+ // final static String REPO_HOME = "argeo.node.repo.home";
+ // final static String REPO_TYPE = "argeo.node.repo.type";
// final static String REPO_CONFIGURATION = "argeo.node.repo.configuration";
- final static String REPO_DEFAULT_WORKSPACE = "argeo.node.repo.defaultWorkspace";
- final static String REPO_DBURL = "argeo.node.repo.dburl";
- final static String REPO_DBUSER = "argeo.node.repo.dbuser";
- final static String REPO_DBPASSWORD = "argeo.node.repo.dbpassword";
- final static String REPO_MAX_POOL_SIZE = "argeo.node.repo.maxPoolSize";
- final static String REPO_MAX_CACHE_MB = "argeo.node.repo.maxCacheMB";
- final static String REPO_BUNDLE_CACHE_MB = "argeo.node.repo.bundleCacheMB";
- final static String REPO_EXTRACTOR_POOL_SIZE = "argeo.node.repo.extractorPoolSize";
- final static String REPO_SEARCH_CACHE_SIZE = "argeo.node.repo.searchCacheSize";
- final static String REPO_MAX_VOLATILE_INDEX_SIZE = "argeo.node.repo.maxVolatileIndexSize";
+ // final static String REPO_DEFAULT_WORKSPACE =
+ // "argeo.node.repo.defaultWorkspace";
+ // final static String REPO_DBURL = "argeo.node.repo.dburl";
+ // final static String REPO_DBUSER = "argeo.node.repo.dbuser";
+ // final static String REPO_DBPASSWORD = "argeo.node.repo.dbpassword";
+ // final static String REPO_MAX_POOL_SIZE = "argeo.node.repo.maxPoolSize";
+ // final static String REPO_MAX_CACHE_MB = "argeo.node.repo.maxCacheMB";
+ // final static String REPO_BUNDLE_CACHE_MB =
+ // "argeo.node.repo.bundleCacheMB";
+ // final static String REPO_EXTRACTOR_POOL_SIZE =
+ // "argeo.node.repo.extractorPoolSize";
+ // final static String REPO_SEARCH_CACHE_SIZE =
+ // "argeo.node.repo.searchCacheSize";
+ // final static String REPO_MAX_VOLATILE_INDEX_SIZE =
+ // "argeo.node.repo.maxVolatileIndexSize";
final static String TRANSACTIONS_HOME = "argeo.node.transactions.home";
final static String ROLES_URI = "argeo.node.roles.uri";
/** URI to an LDIF file or LDAP server used as initialization or backend */
final static String USERADMIN_URIS = "argeo.node.useradmin.uris";
- final static String[] DEFAULT_CNDS = { "/org/argeo/jcr/argeo.cnd",
- "/org/argeo/cms/cms.cnd" };
+ final static String[] DEFAULT_CNDS = { "/org/argeo/jcr/argeo.cnd", "/org/argeo/cms/cms.cnd" };
// Directories
final static String DIR_NODE = "node";
class KernelThread extends Thread {
@SuppressWarnings("unused")
private final Kernel kernel;
- private final RepositoryStatisticsImpl repoStats;
+ private RepositoryStatisticsImpl repoStats;
/** The smallest period of operation, in ms */
private final long PERIOD = 60 * 1000l;
public KernelThread(Kernel kernel) {
super(kernel.threadGroup, kernel.getClass().getSimpleName());
this.kernel = kernel;
- this.repoStats = kernel.repository.getRepositoryStatistics();
+ // this.repoStats = kernel.repository.getRepositoryStatistics();
}
private void doSmallestPeriod() {
long freeMem = Runtime.getRuntime().freeMemory() / M;
long totalMem = Runtime.getRuntime().totalMemory() / M;
long maxMem = Runtime.getRuntime().maxMemory() / M;
- double loadAvg = ManagementFactory.getOperatingSystemMXBean()
- .getSystemLoadAverage();
+ double loadAvg = ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage();
// in min
boolean min = true;
- long uptime = ManagementFactory.getRuntimeMXBean().getUptime()
- / (1000 * 60);
+ long uptime = ManagementFactory.getRuntimeMXBean().getUptime() / (1000 * 60);
if (uptime > 24 * 60) {
min = false;
uptime = uptime / 60;
}
line.append(uptime).append(min ? " min" : " h").append('\t');
- line.append(loadAvg).append('\t').append(maxMem).append('\t')
- .append(totalMem).append('\t').append(freeMem).append('\t');
+ line.append(loadAvg).append('\t').append(maxMem).append('\t').append(totalMem).append('\t').append(freeMem)
+ .append('\t');
kernelStatsLog.debug(line);
}
// }
// long totalSpace = currentRoot.getTotalSpace();
StringBuilder line = new StringBuilder(128);
- line.append("§\t").append(freeSpace)
- .append(" MB left in " + dataDir);
+ line.append("§\t").append(freeSpace).append(" MB left in " + dataDir);
line.append('\n');
- for (RepositoryStatistics.Type type : RepositoryStatistics.Type
- .values()) {
- long[] vals = repoStats.getTimeSeries(type).getValuePerMinute();
- long val = vals[vals.length - 1];
- line.append(type.name()).append('\t').append(val).append('\n');
- }
+ if (repoStats != null)
+ for (RepositoryStatistics.Type type : RepositoryStatistics.Type.values()) {
+ long[] vals = repoStats.getTimeSeries(type).getValuePerMinute();
+ long val = vals[vals.length - 1];
+ line.append(type.name()).append('\t').append(val).append('\n');
+ }
nodeStatsLog.debug(line);
}
}
private Repository repository;
- NodeHttp(ExtendedHttpService httpService, NodeRepository node) {
+ NodeHttp(ExtendedHttpService httpService, Repository node) {
this.repository = node;
// rootFilter = new RootFilter();
// dosFilter = new CustomDosFilter();
/** Jacrabbit based data layer */
class NodeRepository extends JackrabbitWrapper implements KernelConstants,
ArgeoJcrConstants {
- private static Log log = LogFactory.getLog(NodeRepository.class);
-
- private RepositoryContext repositoryContext;
-
- public NodeRepository() {
- setBundleContext(Activator.getBundleContext());
- JackrabbitNodeType type = JackrabbitNodeType.valueOf(prop(REPO_TYPE,
- h2.name()));
- try {
- repositoryContext = createNode(type);
- setCndFiles(Arrays.asList(DEFAULT_CNDS));
- prepareDataModel();
- } catch (Exception e) {
- throw new ArgeoException(
- "Cannot create Jackrabbit repository of type " + type, e);
- }
- }
-
- public void destroy() {
- ((RepositoryImpl) getRepository()).shutdown();
- }
-
- RepositoryStatisticsImpl getRepositoryStatistics() {
- return repositoryContext.getRepositoryStatistics();
- }
-
- private RepositoryConfig getConfiguration(JackrabbitNodeType type,
- Hashtable<String, Object> vars) throws RepositoryException {
- ClassLoader cl = getClass().getClassLoader();
- InputStream in = null;
- try {
- final String base = "/org/argeo/cms/internal/kernel";
- switch (type) {
- case h2:
- in = cl.getResourceAsStream(base + "/repository-h2.xml");
- break;
- case postgresql:
- in = cl.getResourceAsStream(base + "/repository-postgresql.xml");
- break;
- case memory:
- in = cl.getResourceAsStream(base + "/repository-memory.xml");
- break;
- case localfs:
- in = cl.getResourceAsStream(base + "/repository-localfs.xml");
- break;
- default:
- throw new CmsException("Unsupported node type " + type);
- }
-
- if (in == null)
- throw new CmsException("Repository configuration not found");
- InputSource config = new InputSource(in);
- Properties jackrabbitProps = new Properties();
- jackrabbitProps.putAll(vars);
- RepositoryConfig repositoryConfig = RepositoryConfig.create(config,
- jackrabbitProps);
- return repositoryConfig;
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- private Hashtable<String, Object> getConfigurationProperties(
- JackrabbitNodeType type) {
- // use Hashtable to ease integration with Properties
- Hashtable<String, Object> defaults = new Hashtable<String, Object>();
-
- // home
- File osgiInstanceDir = KernelUtils.getOsgiInstanceDir();
- File homeDir = new File(osgiInstanceDir, DIR_NODE);
- // home cannot be overridden
- defaults.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
- homeDir.getAbsolutePath());
-
- // common
- setProp(defaults, REPO_DEFAULT_WORKSPACE, "main");
- setProp(defaults, REPO_MAX_POOL_SIZE, "10");
- // Jackrabbit defaults
- setProp(defaults, REPO_BUNDLE_CACHE_MB, "8");
- // See http://wiki.apache.org/jackrabbit/Search
- setProp(defaults, REPO_EXTRACTOR_POOL_SIZE, "0");
- setProp(defaults, REPO_SEARCH_CACHE_SIZE, "1000");
- setProp(defaults, REPO_MAX_VOLATILE_INDEX_SIZE, "1048576");
-
- // specific
- String dburl;
- switch (type) {
- case h2:
- dburl = "jdbc:h2:" + homeDir.getPath() + "/h2/repository";
- setProp(defaults, REPO_DBURL, dburl);
- setProp(defaults, REPO_DBUSER, "sa");
- setProp(defaults, REPO_DBPASSWORD, "");
- break;
- case postgresql:
- dburl = "jdbc:postgresql://localhost/demo";
- setProp(defaults, REPO_DBURL, dburl);
- setProp(defaults, REPO_DBUSER, "argeo");
- setProp(defaults, REPO_DBPASSWORD, "argeo");
- break;
- case memory:
- break;
- case localfs:
- break;
- default:
- throw new CmsException("Unsupported node type " + type);
- }
- return defaults;
- }
-
- private void setProp(Dictionary<String, Object> props, String key,
- String defaultValue) {
- String value = prop(key, defaultValue);
- props.put(key, value);
- }
-
- private String prop(String key, String defaultValue) {
- // TODO use OSGi CM instead of Framework/System properties
- return KernelUtils.getFrameworkProp(key, defaultValue);
- }
-
- private RepositoryContext createNode(JackrabbitNodeType type)
- throws RepositoryException {
- Hashtable<String, Object> vars = getConfigurationProperties(type);
- RepositoryConfig repositoryConfig = getConfiguration(type, vars);
- RepositoryContext repositoryContext = createJackrabbitRepository(repositoryConfig);
- RepositoryImpl repository = repositoryContext.getRepository();
-
- // cache
- String maxCacheMbStr = prop(REPO_MAX_CACHE_MB, null);
- if (maxCacheMbStr != null) {
- Integer maxCacheMB = Integer.parseInt(maxCacheMbStr);
- CacheManager cacheManager = repository.getCacheManager();
- cacheManager.setMaxMemory(maxCacheMB * 1024l * 1024l);
- cacheManager.setMaxMemoryPerCache((maxCacheMB / 4) * 1024l * 1024l);
- }
-
- // wrap the repository
- setRepository(repository);
- return repositoryContext;
- }
-
- private RepositoryContext createJackrabbitRepository(
- RepositoryConfig repositoryConfig) throws RepositoryException {
- long begin = System.currentTimeMillis();
- //
- // Actual repository creation
- //
- RepositoryContext repositoryContext = RepositoryContext
- .create(repositoryConfig);
-
- double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
- if (log.isTraceEnabled())
- log.trace("Created Jackrabbit repository in " + duration
- + " s, home: " + repositoryConfig.getHomeDir());
-
- return repositoryContext;
- }
+// private static Log log = LogFactory.getLog(NodeRepository.class);
+//
+// private RepositoryContext repositoryContext;
+//
+// public NodeRepository() {
+// setBundleContext(Activator.getBundleContext());
+// JackrabbitNodeType type = JackrabbitNodeType.valueOf(prop(REPO_TYPE,
+// h2.name()));
+// try {
+// repositoryContext = createNode(type);
+// setCndFiles(Arrays.asList(DEFAULT_CNDS));
+// prepareDataModel();
+// } catch (Exception e) {
+// throw new ArgeoException(
+// "Cannot create Jackrabbit repository of type " + type, e);
+// }
+// }
+//
+// public void destroy() {
+// ((RepositoryImpl) getRepository()).shutdown();
+// }
+//
+// RepositoryStatisticsImpl getRepositoryStatistics() {
+// return repositoryContext.getRepositoryStatistics();
+// }
+//
+// private RepositoryConfig getConfiguration(JackrabbitNodeType type,
+// Hashtable<String, Object> vars) throws RepositoryException {
+// ClassLoader cl = getClass().getClassLoader();
+// InputStream in = null;
+// try {
+// final String base = "/org/argeo/cms/internal/kernel";
+// switch (type) {
+// case h2:
+// in = cl.getResourceAsStream(base + "/repository-h2.xml");
+// break;
+// case postgresql:
+// in = cl.getResourceAsStream(base + "/repository-postgresql.xml");
+// break;
+// case memory:
+// in = cl.getResourceAsStream(base + "/repository-memory.xml");
+// break;
+// case localfs:
+// in = cl.getResourceAsStream(base + "/repository-localfs.xml");
+// break;
+// default:
+// throw new CmsException("Unsupported node type " + type);
+// }
+//
+// if (in == null)
+// throw new CmsException("Repository configuration not found");
+// InputSource config = new InputSource(in);
+// Properties jackrabbitProps = new Properties();
+// jackrabbitProps.putAll(vars);
+// RepositoryConfig repositoryConfig = RepositoryConfig.create(config,
+// jackrabbitProps);
+// return repositoryConfig;
+// } finally {
+// IOUtils.closeQuietly(in);
+// }
+// }
+//
+// private Hashtable<String, Object> getConfigurationProperties(
+// JackrabbitNodeType type) {
+// // use Hashtable to ease integration with Properties
+// Hashtable<String, Object> defaults = new Hashtable<String, Object>();
+//
+// // home
+// File osgiInstanceDir = KernelUtils.getOsgiInstanceDir();
+// File homeDir = new File(osgiInstanceDir, DIR_NODE);
+// // home cannot be overridden
+// defaults.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
+// homeDir.getAbsolutePath());
+//
+// // common
+// setProp(defaults, REPO_DEFAULT_WORKSPACE, "main");
+// setProp(defaults, REPO_MAX_POOL_SIZE, "10");
+// // Jackrabbit defaults
+// setProp(defaults, REPO_BUNDLE_CACHE_MB, "8");
+// // See http://wiki.apache.org/jackrabbit/Search
+// setProp(defaults, REPO_EXTRACTOR_POOL_SIZE, "0");
+// setProp(defaults, REPO_SEARCH_CACHE_SIZE, "1000");
+// setProp(defaults, REPO_MAX_VOLATILE_INDEX_SIZE, "1048576");
+//
+// // specific
+// String dburl;
+// switch (type) {
+// case h2:
+// dburl = "jdbc:h2:" + homeDir.getPath() + "/h2/repository";
+// setProp(defaults, REPO_DBURL, dburl);
+// setProp(defaults, REPO_DBUSER, "sa");
+// setProp(defaults, REPO_DBPASSWORD, "");
+// break;
+// case postgresql:
+// dburl = "jdbc:postgresql://localhost/demo";
+// setProp(defaults, REPO_DBURL, dburl);
+// setProp(defaults, REPO_DBUSER, "argeo");
+// setProp(defaults, REPO_DBPASSWORD, "argeo");
+// break;
+// case memory:
+// break;
+// case localfs:
+// break;
+// default:
+// throw new CmsException("Unsupported node type " + type);
+// }
+// return defaults;
+// }
+//
+// private void setProp(Dictionary<String, Object> props, String key,
+// String defaultValue) {
+// String value = prop(key, defaultValue);
+// props.put(key, value);
+// }
+//
+// private String prop(String key, String defaultValue) {
+// // TODO use OSGi CM instead of Framework/System properties
+// return KernelUtils.getFrameworkProp(key, defaultValue);
+// }
+//
+// private RepositoryContext createNode(JackrabbitNodeType type)
+// throws RepositoryException {
+// Hashtable<String, Object> vars = getConfigurationProperties(type);
+// RepositoryConfig repositoryConfig = getConfiguration(type, vars);
+// RepositoryContext repositoryContext = createJackrabbitRepository(repositoryConfig);
+// RepositoryImpl repository = repositoryContext.getRepository();
+//
+// // cache
+// String maxCacheMbStr = prop(REPO_MAX_CACHE_MB, null);
+// if (maxCacheMbStr != null) {
+// Integer maxCacheMB = Integer.parseInt(maxCacheMbStr);
+// CacheManager cacheManager = repository.getCacheManager();
+// cacheManager.setMaxMemory(maxCacheMB * 1024l * 1024l);
+// cacheManager.setMaxMemoryPerCache((maxCacheMB / 4) * 1024l * 1024l);
+// }
+//
+// // wrap the repository
+// setRepository(repository);
+// return repositoryContext;
+// }
+//
+// private RepositoryContext createJackrabbitRepository(
+// RepositoryConfig repositoryConfig) throws RepositoryException {
+// long begin = System.currentTimeMillis();
+// //
+// // Actual repository creation
+// //
+// RepositoryContext repositoryContext = RepositoryContext
+// .create(repositoryConfig);
+//
+// double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
+// if (log.isTraceEnabled())
+// log.trace("Created Jackrabbit repository in " + duration
+// + " s, home: " + repositoryConfig.getHomeDir());
+//
+// return repositoryContext;
+// }
}
--- /dev/null
+package org.argeo.jackrabbit;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+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.NamespaceHelper;
+import org.apache.jackrabbit.commons.cnd.CndImporter;
+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.util.security.DigestUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+public class JackrabbitDataModel {
+ private final static Log log = LogFactory.getLog(JackrabbitDataModel.class);
+ private final static String DIGEST_ALGORITHM = "MD5";
+ final static String[] DEFAULT_CNDS = { "/org/argeo/jcr/argeo.cnd", "/org/argeo/cms/cms.cnd" };
+
+ // 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 = true;
+
+ /** Namespaces to register: key is prefix, value namespace */
+ private Map<String, String> namespaces = new HashMap<String, String>();
+
+ private final BundleContext bc;
+
+ public JackrabbitDataModel(BundleContext bc) {
+ this.bc = bc;
+ }
+
+ /**
+ * Import declared node type definitions and register namespaces. Tries to
+ * update the node definitions if they have changed. In case of failures an
+ * error will be logged but no exception will be thrown.
+ */
+ public void prepareDataModel(Repository repository) {
+ cndFiles = Arrays.asList(DEFAULT_CNDS);
+ if ((cndFiles == null || cndFiles.size() == 0) && (namespaces == null || namespaces.size() == 0))
+ return;
+
+ Session session = null;
+ try {
+ session = repository.login();
+ // register namespaces
+ if (namespaces.size() > 0) {
+ NamespaceHelper namespaceHelper = new NamespaceHelper(session);
+ namespaceHelper.registerNamespaces(namespaces);
+ }
+
+ // load CND files from classpath or as URL
+ for (String resUrl : cndFiles) {
+ processCndFile(session, resUrl);
+ }
+ } catch (Exception e) {
+ JcrUtils.discardQuietly(session);
+ throw new ArgeoException("Cannot import node type definitions " + cndFiles, e);
+ } finally {
+ JcrUtils.logoutQuietly(session);
+ }
+
+ }
+
+ protected void processCndFile(Session session, String resUrl) {
+ Reader reader = null;
+ try {
+ // 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;
+ }
+ }
+
+ Bundle bundle = findDataModelBundle(resUrl);
+
+ byte[] cndContent = readCndContent(resUrl);
+ String newDigest = DigestUtils.digest(DIGEST_ALGORITHM, cndContent);
+
+ String currentVersion = null;
+ if (dataModel != null) {
+ currentVersion = dataModel.getProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION).getString();
+ if (dataModel.hasNode(Node.JCR_CONTENT)) {
+ String oldDigest = JcrUtils.checksumFile(dataModel, DIGEST_ALGORITHM);
+ if (oldDigest.equals(newDigest)) {
+ if (log.isTraceEnabled())
+ log.trace("Data model " + resUrl + " hasn't changed, keeping version " + currentVersion);
+ return;
+ }
+ }
+ }
+
+ if (dataModel != null && !forceCndImport) {
+ log.info(
+ "Data model " + resUrl + " has changed since version " + currentVersion
+ + (bundle != null
+ ? ": version " + bundle.getVersion() + ", bundle " + bundle.getSymbolicName()
+ : ""));
+ return;
+ }
+
+ reader = new InputStreamReader(new ByteArrayInputStream(cndContent));
+ // actually imports the CND
+ try {
+ CndImporter.registerNodeTypes(reader, session, true);
+ } catch (Exception e) {
+ log.error("Cannot import data model " + resUrl, e);
+ return;
+ }
+
+ if (dataModel != null && !dataModel.isNodeType(NodeType.NT_FILE)) {
+ dataModel.remove();
+ dataModel = null;
+ }
+
+ // 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(resUrl);
+ if (dataModel == null) {
+ dataModel = dataModels.addNode(fileName, NodeType.NT_FILE);
+ dataModel.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
+ dataModel.addMixin(ArgeoTypes.ARGEO_DATA_MODEL);
+ dataModel.setProperty(ArgeoNames.ARGEO_URI, resUrl);
+ } else {
+ session.getWorkspace().getVersionManager().checkout(dataModel.getPath());
+ }
+ if (bundle != null)
+ dataModel.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION, bundle.getVersion().toString());
+ else
+ dataModel.setProperty(ArgeoNames.ARGEO_DATA_MODEL_VERSION, "0.0.0");
+ JcrUtils.copyBytesAsFile(dataModel.getParent(), fileName, cndContent);
+ JcrUtils.updateLastModified(dataModel);
+ session.save();
+ session.getWorkspace().getVersionManager().checkin(dataModel.getPath());
+
+ if (currentVersion == null)
+ log.info(
+ "Data model " + resUrl
+ + (bundle != null
+ ? ", version " + bundle.getVersion() + ", bundle " + bundle.getSymbolicName()
+ : ""));
+ else
+ log.info(
+ "Data model " + resUrl + " updated from version " + currentVersion
+ + (bundle != null
+ ? ", version " + bundle.getVersion() + ", bundle " + bundle.getSymbolicName()
+ : ""));
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot process data model " + resUrl, e);
+ } finally {
+ IOUtils.closeQuietly(reader);
+ }
+ }
+
+ protected byte[] readCndContent(String resUrl) {
+ BundleContext bundleContext = bc;
+ InputStream in = null;
+ try {
+ boolean classpath;
+ // normalize URL
+ if (bundleContext != null && 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 '/'");
+ }
+ classpath = true;
+ } else {
+ classpath = false;
+ }
+
+ URL url = null;
+ if (classpath) {
+ // if (bundleContext != null) {
+ Bundle currentBundle = bundleContext.getBundle();
+ url = currentBundle.getResource(resUrl);
+ // } else {
+ // resUrl = "classpath:" + resUrl;
+ // url = null;
+ // }
+ } else if (!resUrl.startsWith("classpath:")) {
+ url = new URL(resUrl);
+ }
+
+ if (url != null) {
+ in = url.openStream();
+ // } else if (resourceLoader != null) {
+ // Resource res = resourceLoader.getResource(resUrl);
+ // in = res.getInputStream();
+ // url = res.getURL();
+ } else {
+ throw new ArgeoException(
+ "No " + resUrl + " in the classpath," + " make sure the containing" + " package is visible.");
+ }
+
+ return IOUtils.toByteArray(in);
+ } catch (Exception e) {
+ throw new ArgeoException("Cannot read CND from " + resUrl, e);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ /*
+ * UTILITIES
+ */
+ /** Find which OSGi bundle provided the data model resource */
+ protected Bundle findDataModelBundle(String resUrl) {
+ BundleContext bundleContext = bc;
+ if (bundleContext == null)
+ return null;
+
+ if (resUrl.startsWith("/"))
+ resUrl = resUrl.substring(1);
+ String pkg = resUrl.substring(0, resUrl.lastIndexOf('/')).replace('/', '.');
+ ServiceReference<PackageAdmin> paSr = bundleContext.getServiceReference(PackageAdmin.class);
+ PackageAdmin packageAdmin = (PackageAdmin) bundleContext.getService(paSr);
+
+ // find exported package
+ ExportedPackage exportedPackage = null;
+ ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(pkg);
+ if (exportedPackages == null)
+ throw new ArgeoException("No exported package found for " + pkg);
+ for (ExportedPackage ep : exportedPackages) {
+ for (Bundle b : ep.getImportingBundles()) {
+ if (b.getBundleId() == bundleContext.getBundle().getBundleId()) {
+ exportedPackage = ep;
+ break;
+ }
+ }
+ }
+
+ Bundle exportingBundle = null;
+ if (exportedPackage != null) {
+ exportingBundle = exportedPackage.getExportingBundle();
+ } else {
+ // assume this is in the same bundle
+ exportingBundle = bundleContext.getBundle();
+ // throw new ArgeoException("No OSGi exporting package found for "
+ // + resUrl);
+ }
+ return exportingBundle;
+ }
+
+}
--- /dev/null
+package org.argeo.jackrabbit;
+
+/** The available Jackrabbit node types */
+public enum JackrabbitNodeType {
+ NOT_CONFIGURED, h2, postgresql, memory, localfs;
+}
--- /dev/null
+package org.argeo.jackrabbit;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.jcr.Credentials;
+import javax.jcr.LoginException;
+import javax.jcr.NoSuchWorkspaceException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.core.RepositoryContext;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.cache.CacheManager;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
+import org.apache.jackrabbit.stats.RepositoryStatisticsImpl;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrException;
+import org.argeo.jcr.JcrRepositoryWrapper;
+import org.argeo.jcr.RepoConf;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.xml.sax.InputSource;
+
+public class ManagedJackrabbitRepository extends JcrRepositoryWrapper implements ManagedService, JackrabbitRepository {
+ private final static Log log = LogFactory.getLog(ManagedJackrabbitRepository.class);
+
+ // Node
+ final static String REPO_TYPE = "repoType";
+ // final static String REPO_CONFIGURATION = "argeo.node.repo.configuration";
+ // final static String REPO_DEFAULT_WORKSPACE = "defaultWorkspace";
+ // final static String REPO_DBURL = "dburl";
+ // final static String REPO_DBUSER = "dbuser";
+ // final static String REPO_DBPASSWORD = "dbpassword";
+ // final static String REPO_MAX_POOL_SIZE = "maxPoolSize";
+ // final static String REPO_MAX_CACHE_MB = "maxCacheMB";
+ // final static String REPO_BUNDLE_CACHE_MB = "bundleCacheMB";
+ // final static String REPO_EXTRACTOR_POOL_SIZE = "extractorPoolSize";
+ // final static String REPO_SEARCH_CACHE_SIZE = "searchCacheSize";
+ // final static String REPO_MAX_VOLATILE_INDEX_SIZE =
+ // "maxVolatileIndexSize";
+
+ private Dictionary<String, ?> properties;
+
+ @Override
+ public void updated(Dictionary<String, ?> properties) throws ConfigurationException {
+ this.properties = properties;
+ if (properties == null)
+ return;
+
+ JackrabbitNodeType type = JackrabbitNodeType.valueOf(prop(RepoConf.type).toString());
+ try {
+ repositoryContext = createNode(type);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new ArgeoException("Cannot create Jackrabbit repository of type " + type, e);
+ }
+ }
+
+ private RepositoryContext repositoryContext;
+
+ public ManagedJackrabbitRepository() {
+ // setBundleContext(Activator.getBundleContext());
+ // JackrabbitNodeType type = JackrabbitNodeType.valueOf(prop(REPO_TYPE,
+ // JackrabbitNodeType.h2.name()));
+ // try {
+ // repositoryContext = createNode(type);
+ // cndFiles = Arrays.asList(DEFAULT_CNDS);
+ // prepareDataModel();
+ // } catch (Exception e) {
+ // throw new ArgeoException("Cannot create Jackrabbit repository of type
+ // " + type, e);
+ // }
+ }
+
+ public void destroy() {
+ ((RepositoryImpl) getRepository()).shutdown();
+ }
+
+ RepositoryStatisticsImpl getRepositoryStatistics() {
+ return repositoryContext.getRepositoryStatistics();
+ }
+
+ private RepositoryConfig getConfiguration(JackrabbitNodeType type, Hashtable<String, Object> props)
+ throws RepositoryException {
+ ClassLoader cl = getClass().getClassLoader();
+ InputStream in = null;
+ try {
+ final String base = "/org/argeo/jackrabbit";
+ switch (type) {
+ case h2:
+ in = cl.getResourceAsStream(base + "/repository-h2.xml");
+ break;
+ case postgresql:
+ in = cl.getResourceAsStream(base + "/repository-postgresql.xml");
+ break;
+ case memory:
+ in = cl.getResourceAsStream(base + "/repository-memory.xml");
+ break;
+ case localfs:
+ in = cl.getResourceAsStream(base + "/repository-localfs.xml");
+ break;
+ default:
+ throw new ArgeoJcrException("Unsupported node type " + type);
+ }
+
+ if (in == null)
+ throw new ArgeoJcrException("Repository configuration not found");
+ InputSource config = new InputSource(in);
+ Properties jackrabbitVars = new Properties();
+ // convert values to Strings, otherwise they are skipped
+ for (String key : props.keySet())
+ jackrabbitVars.setProperty(key, props.get(key).toString());
+ RepositoryConfig repositoryConfig = RepositoryConfig.create(config, jackrabbitVars);
+ return repositoryConfig;
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ private Hashtable<String, Object> getConfigurationProperties(JackrabbitNodeType type) {
+ Hashtable<String, Object> props = new Hashtable<String, Object>();
+
+ // home
+ File osgiInstanceDir = getOsgiInstanceDir();
+ File homeDir = new File(osgiInstanceDir, "repos/node");
+ homeDir.mkdirs();
+ // home cannot be overridden
+ props.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, homeDir.getAbsolutePath());
+
+ // common
+ setProp(props, RepoConf.defaultWorkspace);
+ setProp(props, RepoConf.maxPoolSize);
+ // Jackrabbit defaults
+ setProp(props, RepoConf.bundleCacheMB);
+ // See http://wiki.apache.org/jackrabbit/Search
+ setProp(props, RepoConf.extractorPoolSize);
+ setProp(props, RepoConf.searchCacheSize);
+ setProp(props, RepoConf.maxVolatileIndexSize);
+
+ // specific
+ String dburl;
+ switch (type) {
+ case h2:
+ dburl = "jdbc:h2:" + homeDir.getPath() + "/h2/repository";
+ setProp(props, RepoConf.dburl, dburl);
+ setProp(props, RepoConf.dbuser, "sa");
+ setProp(props, RepoConf.dbpassword, "");
+ break;
+ case postgresql:
+ dburl = "jdbc:postgresql://localhost/demo";
+ setProp(props, RepoConf.dburl, dburl);
+ setProp(props, RepoConf.dbuser, "argeo");
+ setProp(props, RepoConf.dbpassword, "argeo");
+ break;
+ case memory:
+ break;
+ case localfs:
+ break;
+ default:
+ throw new ArgeoJcrException("Unsupported node type " + type);
+ }
+ return props;
+ }
+
+ private void setProp(Dictionary<String, Object> props, RepoConf key, String def) {
+ Object value = prop(key);
+ if (value == null)
+ value = def;
+ props.put(key.name(), value);
+ }
+
+ private void setProp(Dictionary<String, Object> props, RepoConf key) {
+ setProp(props, key, null);
+ }
+
+ private Object prop(RepoConf key) {
+ if (properties == null)
+ throw new ArgeoJcrException("Properties are not set");
+ Object value = properties.get(key.name());
+ if (value == null)
+ return key.getDefault();
+ else
+ return value;
+ }
+
+ private RepositoryContext createNode(JackrabbitNodeType type) throws RepositoryException {
+ Hashtable<String, Object> props = getConfigurationProperties(type);
+ RepositoryConfig repositoryConfig = getConfiguration(type, props);
+ RepositoryContext repositoryContext = createJackrabbitRepository(repositoryConfig);
+ RepositoryImpl repository = repositoryContext.getRepository();
+
+ // cache
+ Object maxCacheMbStr = prop(RepoConf.maxCacheMB);
+ if (maxCacheMbStr != null) {
+ Integer maxCacheMB = Integer.parseInt(maxCacheMbStr.toString());
+ CacheManager cacheManager = repository.getCacheManager();
+ cacheManager.setMaxMemory(maxCacheMB * 1024l * 1024l);
+ cacheManager.setMaxMemoryPerCache((maxCacheMB / 4) * 1024l * 1024l);
+ }
+
+ // wrap the repository
+ setRepository(repository);
+ return repositoryContext;
+ }
+
+ private RepositoryContext createJackrabbitRepository(RepositoryConfig repositoryConfig) throws RepositoryException {
+ long begin = System.currentTimeMillis();
+ //
+ // Actual repository creation
+ //
+ RepositoryContext repositoryContext = RepositoryContext.create(repositoryConfig);
+
+ double duration = ((double) (System.currentTimeMillis() - begin)) / 1000;
+ if (log.isTraceEnabled())
+ log.trace("Created Jackrabbit repository in " + duration + " s, home: " + repositoryConfig.getHomeDir());
+
+ return repositoryContext;
+ }
+
+ /*
+ * DATA MODEL
+ */
+
+ public synchronized void waitForInit() {
+ while (repositoryContext == null)
+ try {
+ wait(100);
+ } catch (InterruptedException e) {
+ return;
+ }
+ }
+
+ private final static String OSGI_INSTANCE_AREA = "osgi.instance.area";
+
+ private File getOsgiInstanceDir() {
+ String instanceArea = System.getProperty(OSGI_INSTANCE_AREA);
+ return new File(instanceArea.substring("file:".length())).getAbsoluteFile();
+ }
+
+ @Override
+ public Session login(Credentials credentials, String workspaceName, Map<String, Object> attributes)
+ throws LoginException, NoSuchWorkspaceException, RepositoryException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void shutdown() {
+ destroy();
+
+ }
+
+}
+++ /dev/null
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
- "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
-<Repository>
- <!-- File system and datastore -->
- <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
- <param name="path" value="${rep.home}/fs" />
- </FileSystem>
- <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
- <param name="path" value="${rep.home}/datastore" />
- </DataStore>
-
- <!-- Workspace templates -->
- <Workspaces rootPath="${rep.home}/workspaces"
- defaultWorkspace="${argeo.node.repo.defaultWorkspace}" />
- <Workspace name="${wsp.name}">
- <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
- <param name="path" value="${wsp.home}" />
- </FileSystem>
- <PersistenceManager
- class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager" />
- <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${wsp.home}/index" />
- </SearchIndex>
- </Workspace>
-
- <!-- Versioning -->
- <Versioning rootPath="${rep.home}/version">
- <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
- <param name="path" value="${rep.home}/version" />
- </FileSystem>
- <PersistenceManager
- class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager" />
- </Versioning>
-
- <!-- Indexing -->
- <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${rep.home}/index" />
- <param name="extractorPoolSize" value="2" />
- <param name="supportHighlighting" value="true" />
- </SearchIndex>
-
- <!-- Security -->
- <Security appName="Jackrabbit">
- <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
- workspaceName="security">
- </SecurityManager>
- <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
- </AccessManager>
- <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
- </LoginModule>
- </Security>
-</Repository>
\ No newline at end of file
-<?xml version="1.0"?>
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
- "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
<Repository>
<!-- Shared datasource -->
<DataSources>
<DataSource name="dataSource">
<param name="driver" value="org.h2.Driver" />
- <param name="url" value="jdbc:h2:${rep.home}/h2/repository" />
- <param name="user" value="sa" />
- <param name="password" value="" />
+ <param name="url" value="${dburl}" />
+ <param name="user" value="${dbuser}" />
+ <param name="password" value="${dbpassword}" />
<param name="databaseType" value="h2" />
- <param name="maxPoolSize" value="10" />
+ <param name="maxPoolSize" value="${maxPoolSize}" />
</DataSource>
</DataSources>
<!-- Workspace templates -->
<Workspaces rootPath="${rep.home}/workspaces"
- defaultWorkspace="main" />
+ defaultWorkspace="${defaultWorkspace}" />
<Workspace name="${wsp.name}">
<FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
<param name="dataSourceName" value="dataSource" />
class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
<param name="dataSourceName" value="dataSource" />
<param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
+ <param name="bundleCacheSize" value="${bundleCacheMB}" />
</PersistenceManager>
<SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
<param name="path" value="${wsp.home}/index" />
+ <param name="extractorPoolSize" value="${extractorPoolSize}" />
+ <param name="cacheSize" value="${searchCacheSize}" />
+ <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
</SearchIndex>
+ <WorkspaceSecurity>
+ <AccessControlProvider
+ class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
+ </WorkspaceSecurity>
</Workspace>
<!-- Versioning -->
class="org.apache.jackrabbit.core.persistence.pool.H2PersistenceManager">
<param name="dataSourceName" value="dataSource" />
<param name="schemaObjectPrefix" value="pm_ver_" />
+ <param name="bundleCacheSize" value="${bundleCacheMB}" />
</PersistenceManager>
</Versioning>
<!-- Indexing -->
<SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
<param name="path" value="${rep.home}/index" />
- <param name="extractorPoolSize" value="2" />
- <param name="supportHighlighting" value="true" />
+ <param name="extractorPoolSize" value="${extractorPoolSize}" />
+ <param name="cacheSize" value="${searchCacheSize}" />
+ <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
</SearchIndex>
<!-- Security -->
<Security appName="Jackrabbit">
<SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
- workspaceName="security">
- </SecurityManager>
- <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
- </AccessManager>
- <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
- </LoginModule>
+ workspaceName="security" />
+ <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
</Security>
</Repository>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
+<Repository>
+ <!-- File system and datastore -->
+ <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${rep.home}/repository" />
+ </FileSystem>
+ <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
+ <param name="path" value="${rep.home}/datastore" />
+ </DataStore>
+
+ <!-- Workspace templates -->
+ <Workspaces rootPath="${rep.home}/workspaces"
+ defaultWorkspace="${defaultWorkspace}" />
+ <Workspace name="${wsp.name}">
+ <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${wsp.home}" />
+ </FileSystem>
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
+ <param name="bundleCacheSize" value="${bundleCacheMB}" />
+ </PersistenceManager>
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${wsp.home}/index" />
+ <param name="extractorPoolSize" value="${extractorPoolSize}" />
+ <param name="cacheSize" value="${searchCacheSize}" />
+ <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
+ </SearchIndex>
+ <WorkspaceSecurity>
+ <AccessControlProvider
+ class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
+ </WorkspaceSecurity>
+ </Workspace>
+
+ <!-- Versioning -->
+ <Versioning rootPath="${rep.home}/version">
+ <FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${rep.home}/version" />
+ </FileSystem>
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
+ <param name="bundleCacheSize" value="${bundleCacheMB}" />
+ </PersistenceManager>
+ </Versioning>
+
+ <!-- Indexing -->
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${rep.home}/index" />
+ <param name="extractorPoolSize" value="${extractorPoolSize}" />
+ <param name="cacheSize" value="${searchCacheSize}" />
+ <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
+ </SearchIndex>
+
+ <!-- Security -->
+ <Security appName="Jackrabbit">
+ <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
+ workspaceName="security" />
+ <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
+ </Security>
+</Repository>
\ No newline at end of file
<?xml version="1.0"?>
-<!--
-
- Copyright (C) 2007-2012 Argeo GmbH
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
--->
-<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
- "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
<Repository>
<!-- File system and datastore -->
<FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
<!-- Workspace templates -->
<Workspaces rootPath="${rep.home}/workspaces"
- defaultWorkspace="main" configRootPath="/workspaces" />
+ defaultWorkspace="${defaultWorkspace}" configRootPath="/workspaces" />
<Workspace name="${wsp.name}">
<FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
<PersistenceManager
class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
<param name="blobFSBlockSize" value="1" />
+ <param name="bundleCacheSize" value="${bundleCacheMB}" />
</PersistenceManager>
<SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${rep.home}/repository/index" />
+ <param name="path" value="${wsp.home}/index" />
<param name="directoryManagerClass"
value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
+ <param name="extractorPoolSize" value="${extractorPoolSize}" />
+ <param name="cacheSize" value="${searchCacheSize}" />
+ <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
<FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
</SearchIndex>
</Workspace>
<PersistenceManager
class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
<param name="blobFSBlockSize" value="1" />
+ <param name="bundleCacheSize" value="${bundleCacheMB}" />
</PersistenceManager>
</Versioning>
<!-- Indexing -->
<SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
- <param name="path" value="${rep.home}/repository/index" />
+ <param name="path" value="${rep.home}/index" />
<param name="directoryManagerClass"
value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
+ <param name="extractorPoolSize" value="${extractorPoolSize}" />
+ <param name="cacheSize" value="${searchCacheSize}" />
+ <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
<FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
</SearchIndex>
<!-- Security -->
<Security appName="Jackrabbit">
<SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
- workspaceName="security">
- </SecurityManager>
- <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager">
- </AccessManager>
- <LoginModule class="org.argeo.security.jackrabbit.ArgeoLoginModule">
- </LoginModule>
+ workspaceName="security" />
+ <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
</Security>
</Repository>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
+<Repository>
+ <!-- Shared datasource -->
+ <DataSources>
+ <DataSource name="dataSource">
+ <param name="driver" value="org.postgresql.Driver" />
+ <param name="url" value="${dburl}" />
+ <param name="user" value="${dbuser}" />
+ <param name="password" value="${dbpassword}" />
+ <param name="databaseType" value="postgresql" />
+ <param name="maxPoolSize" value="${maxPoolSize}" />
+ </DataSource>
+ </DataSources>
+
+ <!-- File system and datastore -->
+ <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schema" value="postgresql" />
+ <param name="schemaObjectPrefix" value="fs_" />
+ </FileSystem>
+ <DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
+ <param name="path" value="${rep.home}/datastore" />
+ </DataStore>
+
+ <!-- Workspace templates -->
+ <Workspaces rootPath="${rep.home}/workspaces"
+ defaultWorkspace="${defaultWorkspace}" />
+ <Workspace name="${wsp.name}">
+ <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schema" value="postgresql" />
+ <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
+ </FileSystem>
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
+ <param name="bundleCacheSize" value="${bundleCacheMB}" />
+ </PersistenceManager>
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${wsp.home}/index" />
+ <param name="extractorPoolSize" value="${extractorPoolSize}" />
+ <param name="cacheSize" value="${searchCacheSize}" />
+ <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
+ </SearchIndex>
+ <WorkspaceSecurity>
+ <AccessControlProvider
+ class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
+ </WorkspaceSecurity>
+ </Workspace>
+
+ <!-- Versioning -->
+ <Versioning rootPath="${rep.home}/version">
+ <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schema" value="postgresql" />
+ <param name="schemaObjectPrefix" value="fs_ver_" />
+ </FileSystem>
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schemaObjectPrefix" value="pm_ver_" />
+ <param name="bundleCacheSize" value="${bundleCacheMB}" />
+ </PersistenceManager>
+ </Versioning>
+
+ <!-- Indexing -->
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${rep.home}/index" />
+ <param name="extractorPoolSize" value="${extractorPoolSize}" />
+ <param name="cacheSize" value="${searchCacheSize}" />
+ <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
+ </SearchIndex>
+
+ <!-- Security -->
+ <Security appName="Jackrabbit">
+ <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
+ workspaceName="security" />
+ <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
+ </Security>
+</Repository>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE Repository PUBLIC "Jackrabbit 2.6" "http://jackrabbit.apache.org/dtd/repository-2.6.dtd">
+<Repository>
+ <!-- Shared datasource -->
+ <DataSources>
+ <DataSource name="dataSource">
+ <param name="driver" value="org.postgresql.Driver" />
+ <param name="url" value="${dburl}" />
+ <param name="user" value="${dbuser}" />
+ <param name="password" value="${dbpassword}" />
+ <param name="databaseType" value="postgresql" />
+ <param name="maxPoolSize" value="${maxPoolSize}" />
+ </DataSource>
+ </DataSources>
+
+ <!-- File system and datastore -->
+ <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schema" value="postgresql" />
+ <param name="schemaObjectPrefix" value="fs_" />
+ </FileSystem>
+
+ <!-- Workspace templates -->
+ <Workspaces rootPath="${rep.home}/workspaces"
+ defaultWorkspace="${defaultWorkspace}" />
+ <Workspace name="${wsp.name}">
+ <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schema" value="postgresql" />
+ <param name="schemaObjectPrefix" value="${wsp.name}_fs_" />
+ </FileSystem>
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schemaObjectPrefix" value="${wsp.name}_pm_" />
+ <param name="bundleCacheSize" value="${bundleCacheMB}" />
+ </PersistenceManager>
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${wsp.home}/index" />
+ <param name="extractorPoolSize" value="${extractorPoolSize}" />
+ <param name="cacheSize" value="${searchCacheSize}" />
+ <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
+ </SearchIndex>
+ <WorkspaceSecurity>
+ <AccessControlProvider
+ class="org.argeo.security.jackrabbit.ArgeoAccessControlProvider" />
+ </WorkspaceSecurity>
+ </Workspace>
+
+ <!-- Versioning -->
+ <Versioning rootPath="${rep.home}/version">
+ <FileSystem class="org.apache.jackrabbit.core.fs.db.DbFileSystem">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schema" value="postgresql" />
+ <param name="schemaObjectPrefix" value="fs_ver_" />
+ </FileSystem>
+ <PersistenceManager
+ class="org.apache.jackrabbit.core.persistence.pool.PostgreSQLPersistenceManager">
+ <param name="dataSourceName" value="dataSource" />
+ <param name="schemaObjectPrefix" value="pm_ver_" />
+ <param name="bundleCacheSize" value="${bundleCacheMB}" />
+ </PersistenceManager>
+ </Versioning>
+
+ <!-- Indexing -->
+ <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${rep.home}/index" />
+ <param name="extractorPoolSize" value="${extractorPoolSize}" />
+ <param name="cacheSize" value="${searchCacheSize}" />
+ <param name="maxVolatileIndexSize" value="${maxVolatileIndexSize}" />
+ </SearchIndex>
+
+ <!-- Security -->
+ <Security appName="Jackrabbit">
+ <SecurityManager class="org.argeo.security.jackrabbit.ArgeoSecurityManager"
+ workspaceName="security" />
+ <AccessManager class="org.argeo.security.jackrabbit.ArgeoAccessManager" />
+ </Security>
+</Repository>
\ No newline at end of file
/** Argeo model specific constants */
public interface ArgeoJcrConstants {
public final static String ARGEO_BASE_PATH = "/argeo:system";
- public final static String DATA_MODELS_BASE_PATH = ARGEO_BASE_PATH
- + "/argeo:dataModels";
- public final static String PEOPLE_BASE_PATH = ARGEO_BASE_PATH
- + "/argeo:people";
+ public final static String DATA_MODELS_BASE_PATH = ARGEO_BASE_PATH + "/argeo:dataModels";
+ public final static String PEOPLE_BASE_PATH = ARGEO_BASE_PATH + "/argeo:people";
// parameters (typically for call to a RepositoryFactory)
/** Key for a JCR repository alias */
* JCR repository.
*/
public final static String ALIAS_NODE = "node";
+ public final static String BASE_REPO_PID = "argeo.repo.";
+ public final static String REPO_PID_NODE = BASE_REPO_PID + ALIAS_NODE;
}
--- /dev/null
+package org.argeo.jcr;
+
+/** Argeo JCR specific exceptions. */
+public class ArgeoJcrException extends RuntimeException {
+ private static final long serialVersionUID = -1941940005390084331L;
+
+ public ArgeoJcrException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ArgeoJcrException(String message) {
+ super(message);
+ }
+
+}
--- /dev/null
+package org.argeo.jcr;
+
+/** JCR repository configuration */
+public enum RepoConf {
+ /** Repository type */
+ type("localfs"),
+ /** Default workspace */
+ defaultWorkspace("main"),
+ /** Database URL */
+ dburl(null),
+ /** Database user */
+ dbuser(null),
+ /** Database password */
+ dbpassword(null),
+
+ //
+ // JACKRABBIT SPECIFIC
+ //
+ /** Maximum database pool size */
+ maxPoolSize(10),
+ /** Maximum cache size in MB */
+ maxCacheMB(null),
+ /** Bundle cache size in MB */
+ bundleCacheMB(8),
+ /** Extractor pool size */
+ extractorPoolSize(0),
+ /** Search cache size */
+ searchCacheSize(1000),
+ /** Max volatile index size */
+ maxVolatileIndexSize(1048576);
+
+ /** The default value. */
+ private Object def;
+
+ RepoConf(Object def) {
+ this.def = def;
+ }
+
+ public Object getDefault() {
+ return def;
+ }
+}