/* * Copyright 2012 The Solmix Project * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.gnu.org/licenses/ * or see the FSF site: http://www.fsf.org. */ package org.solmix.cms.server; import java.util.Dictionary; import java.util.Hashtable; import javax.jcr.Repository; import javax.jcr.RepositoryException; import org.apache.jackrabbit.api.management.DataStoreGarbageCollector; import org.apache.jackrabbit.api.management.RepositoryManager; import org.apache.jackrabbit.core.RepositoryImpl; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.cms.api.SolmixRepository; /** * * @author Administrator * @version 0.1.1 2012-8-17 */ public class SolmixJcrRepository extends AbstractSolmixRepository implements Runnable, Repository, RepositoryManager { private static final Logger LOG = LoggerFactory.getLogger(SolmixJcrRepository.class); private RepositoryBuilder builder; private Thread monitorThread; private boolean running; /** * seconds. */ private long pollTimeInActive = 30; private long pollTimeActive = 60; /** * @return the running */ public boolean isRunning() { return running; } /** * Repository Service start method.Used by blueprint configuration. */ public void start() { try { if (startRepository()) { LOG.info("Repository started successfully"); } else { LOG.warn("Repository started failed ,try again"); } } catch (Throwable t) { LOG.warn("start repository throw unexpected problem", t); } startRepositoryMonitor(); } /** * */ protected void startRepositoryMonitor() { if (monitorThread == null) { running = true; monitorThread = new Thread(this, "Repository Monitor"); monitorThread.start(); } } public void stop() { // First stop repository monitor. stopRepositoryMonitor(); stopRepository(); builder.setContext(null); } /** * */ protected void stopRepositoryMonitor() { running = false; Thread rpThread = monitorThread; if (rpThread == null) { return; } monitorThread = null; synchronized (rpThread) { rpThread.notifyAll(); } try { rpThread.join(10000L); } catch (InterruptedException ie) { } if (rpThread.isAlive()) { LOG.error("imed waiting for thread {0} to terminate", rpThread); } } /** * @return the builder */ public RepositoryBuilder getBuilder() { return builder; } /** * @param builder the builder to set */ public void setBuilder(RepositoryBuilder builder) { this.builder = builder; } /** * {@inheritDoc} * * @see org.solmix.cms.server.AbstractSolmixRepository#acquireRepository() */ @Override protected Repository acquireRepository() { return builder.getRepository(); } /** * {@inheritDoc} * * @see org.solmix.cms.server.AbstractSolmixRepository#getContext() */ @Override protected BundleContext getContext() { return builder.getContext(); } /** * {@inheritDoc} * * @see java.lang.Runnable#run() */ @Override public void run() { long pollTime = 100L; final long MSEC = 1000L; final int pollTimeFactor = 2; Object lock = monitorThread; try { while (running) { synchronized (lock) { try { lock.wait(pollTime); } catch (InterruptedException e) { } } long newPollTime = pollTime; if (running) { Repository repo = this.getRepository(); boolean ok = false; if (repo == null) { if (startRepository()) { ok = true; newPollTime = pollTimeActive * MSEC; } else { newPollTime = Math.min(pollTime * pollTimeFactor, Math.max(pollTimeInActive, pollTimeActive * MSEC)); } } else if (this.checkRepository()) { ok = true; newPollTime = pollTimeActive * MSEC; } else { stopRepository(); newPollTime = pollTimeInActive * MSEC; } if (newPollTime != pollTime) { pollTime = newPollTime; LOG.debug("Repository monitor internal poll time set to " + pollTime + " repository is " + (ok ? "available" : "Not avaliable")); } } }// END while(running) LOG.info("Repository monitor is stopping "); } catch (Exception e) { LOG.error("Repsitory monitor caught unexpected problem", e); } finally { LOG.info("Stoping repository on shutdown"); stopRepository(); } } /** * {@inheritDoc} * * @see org.apache.jackrabbit.api.management.RepositoryManager#createDataStoreGarbageCollector() */ @Override public DataStoreGarbageCollector createDataStoreGarbageCollector() throws RepositoryException { RepositoryImpl repository = (RepositoryImpl) getRepository(); if (repository != null) { return repository.createDataStoreGarbageCollector(); } throw new RepositoryException("Repository couldn't be acquired"); } @SuppressWarnings("rawtypes") protected ServiceRegistration registerService() { BundleContext context = getContext(); Dictionary<String, Object> props = new Hashtable<String, Object>(); props.put("service.vendor", "solmix"); String interfaces[] = new String[] { SolmixRepository.class.getName(), Repository.class.getName(), RepositoryManager.class.getName() }; return context.registerService(interfaces, this, props); } protected void disposeRepository(Repository repository) { super.disposeRepository(repository); if (repository instanceof RepositoryImpl) { try { ((RepositoryImpl) repository).shutdown(); } catch (Throwable t) { // todo } } } // protected Credentials getAdminCredentials(String adminUser) { // return new AdminCredentials(adminUser); // } // // protected Credentials getAnonymousCredentials(String user) { // return new AnonCredentials(user); // } }