/* * CATMA Computer Aided Text Markup and Analysis * * Copyright (C) 2009-2013 University Of Hamburg * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.catma.document.repository; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import de.catma.backgroundservice.BackgroundServiceProvider; import de.catma.tag.TagManager; /** * This class handles open/close requests of {@link Repository repositories). * * @author marco.petris@web.de * */ public class RepositoryManager { /** * Events emitted by the RepositoryManager. * * @see RepositoryManager#addPropertyChangeListener(RepositoryManagerEvent, PropertyChangeListener) */ public static enum RepositoryManagerEvent { /** * <p>{@link Repository} opened: * <li>{@link PropertyChangeEvent#getNewValue()} = {@link Repository}</li> * <li>{@link PropertyChangeEvent#getOldValue()} = <code>null</code></li> * </p><br /> * <p>{@link Repository} closed: * <li>{@link PropertyChangeEvent#getNewValue()} = <code>null</code></li> * <li>{@link PropertyChangeEvent#getOldValue()} = {@link Repository}</li> * </p><br /> */ repositoryStateChange, ; } private BackgroundServiceProvider backgroundServiceProvider; private TagManager tagManager; private Set<RepositoryReference> repositoryReferences; private Set<Repository> openRepositories; private PropertyChangeSupport propertyChangeSupport; /** * Creates a repository factory for each repository specified in the properties. * @param backgroundServiceProvider used for creating a {@link RepositoryFactory#createRepository(BackgroundServiceProvider, TagManager, Properties, int) Repository}. * @param tagManager used for creating a {@link RepositoryFactory#createRepository(BackgroundServiceProvider, TagManager, Properties, int) Repository}. * @param properties used for creating a {@link RepositoryFactory#createRepository(BackgroundServiceProvider, TagManager, Properties, int) Repository}. * @throws Exception error creating repositories */ public RepositoryManager( BackgroundServiceProvider backgroundServiceProvider, TagManager tagManager, Properties properties) throws Exception { propertyChangeSupport = new PropertyChangeSupport(this); this.backgroundServiceProvider = backgroundServiceProvider; this.tagManager = tagManager; repositoryReferences = new TreeSet<RepositoryReference>( new Comparator<RepositoryReference>() { @Override public int compare(RepositoryReference o1, RepositoryReference o2) { return o1.getName().compareTo(o2.getName()); } }); openRepositories = new HashSet<Repository>(); int index=1; while(RepositoryPropertyKey.Repository.exists(properties, index)) { RepositoryFactory repositoryFactory = (RepositoryFactory)Class.forName( RepositoryPropertyKey.RepositoryFactory.getProperty(properties, index), true, Thread.currentThread().getContextClassLoader()).newInstance(); repositoryReferences.add( new RepositoryReference( repositoryFactory, properties, index)); index++; } } /** * @see RepositoryManagerEvent * @see PropertyChangeSupport#addPropertyChangeListener(String, PropertyChangeListener) */ public void addPropertyChangeListener(RepositoryManagerEvent propertyName, PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(propertyName.name(), listener); } /** * @see RepositoryManagerEvent * @see PropertyChangeSupport#removePropertyChangeListener(String, PropertyChangeListener) */ public void removePropertyChangeListener(RepositoryManagerEvent propertyName, PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(propertyName.name(), listener); } /** * @return all possible, i. e. configured, repositories */ public Set<RepositoryReference> getRepositoryReferences() { return Collections.unmodifiableSet(repositoryReferences); } /** * @param repositoryReference the repository configuration to open * @param userIdentification a key/value store with items for user identification * @return the opened repository * @throws Exception */ public Repository openRepository( RepositoryReference repositoryReference, Map<String, String> userIdentification) throws Exception { Repository repository = repositoryReference.getRepositoryFactory().createRepository( backgroundServiceProvider, tagManager, repositoryReference.getProperties(), repositoryReference.getIndex()); repository.open(userIdentification); openRepositories.add(repository); propertyChangeSupport.firePropertyChange( RepositoryManagerEvent.repositoryStateChange.name(), null, repository); return repository; } /** * @param repository the repo to be closed */ public void close(Repository repository) { openRepositories.remove(repository); repository.close(); propertyChangeSupport.firePropertyChange( RepositoryManagerEvent.repositoryStateChange.name(), repository, null); } /** * Close all open repositories. */ public void close() { for (Repository r : openRepositories) { try { r.close(); } catch (Throwable t) { Logger.getLogger(getClass().getName()).log( Level.SEVERE, "error closing repository " + r, t); } } openRepositories.clear(); repositoryReferences.clear(); } /** * @param repositoryReference * @return true if there is an open repository for the given configuration */ public boolean isOpen(RepositoryReference repositoryReference) { for (Repository r : openRepositories) { if (r.getName().equals(repositoryReference.getName())) { return true; } } return false; } /** * @return true if ther is any open repository. */ public boolean hasOpenRepository() { return !openRepositories.isEmpty(); } public Repository getFirstOpenRepository() { if (hasOpenRepository()) { return openRepositories.iterator().next(); } else { return null; } } }