package org.safehaus.penrose.source; import org.safehaus.penrose.connection.Connection; import org.safehaus.penrose.connection.ConnectionManager; import org.safehaus.penrose.directory.DirectoryConfig; import org.safehaus.penrose.directory.EntryConfig; import org.safehaus.penrose.directory.EntrySourceConfig; import org.safehaus.penrose.partition.Partition; import org.safehaus.penrose.partition.PartitionConfig; import org.safehaus.penrose.partition.PartitionContext; import org.safehaus.penrose.adapter.Adapter; import org.safehaus.penrose.Penrose; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; /** * @author Endi Sukma Dewata */ public class SourceManager { public Logger log = LoggerFactory.getLogger(getClass()); public Partition partition; protected SourceConfigManager sourceConfigManager; protected Map<String,Source> sources = new LinkedHashMap<String,Source>(); protected Map<String,Collection<Source>> sourcesByConnectionName = new LinkedHashMap<String,Collection<Source>>(); public SourceManager(Partition partition) { this.partition = partition; PartitionConfig partitionConfig = partition.getPartitionConfig(); sourceConfigManager = partitionConfig.getSourceConfigManager(); } public void init() throws Exception { Collection<String> names = new ArrayList<String>(); names.addAll(getSourceNames()); for (String sourceName : names) { SourceConfig sourceConfig = getSourceConfig(sourceName); if (!sourceConfig.isEnabled()) continue; try { startSource(sourceName); } catch (Exception e) { Penrose.errorLog.error("Failed creating source "+sourceName+" in partition "+partition.getName()+".", e); } } } public void destroy() throws Exception { Collection<String> names = new ArrayList<String>(); names.addAll(sources.keySet()); for (String sourceName : names) { try { stopSource(sourceName); } catch (Exception e) { Penrose.errorLog.error("Failed removing source "+sourceName+" in partition "+partition.getName()+".", e); } } } public Collection<String> getSourceNames() { return sourceConfigManager.getSourceNames(); } public SourceConfig getSourceConfig(String name) { return sourceConfigManager.getSourceConfig(name); } public void startSource(String sourceName) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Starting source "+sourceName+"."); SourceConfig sourceConfig = getSourceConfig(sourceName); Source source = createSource(sourceConfig); sources.put(sourceName, source); String connectionName = source.getConnectionName(); Collection<Source> list = sourcesByConnectionName.get(connectionName); if (list == null) { list = new ArrayList<Source>(); sourcesByConnectionName.put(connectionName, list); } list.add(source); } public void stopSource(String sourceName) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Stopping source "+sourceName+"."); Source source = sources.get(sourceName); source.destroy(); sources.remove(sourceName); String connectionName = source.getConnectionName(); Collection<Source> list = sourcesByConnectionName.get(connectionName); if (list != null) { list.remove(source); if (list.isEmpty()) sourcesByConnectionName.remove(connectionName); } } public boolean isRunning(String name) { return sources.containsKey(name); } public Source createSource(SourceConfig sourceConfig) throws Exception { boolean debug = log.isDebugEnabled(); String sourceName = sourceConfig.getName(); if (debug) log.debug("Creating source "+sourceName+"."); String partitionName = sourceConfig.getPartitionName(); String connectionName = sourceConfig.getConnectionName(); Partition sourcePartition; if (partitionName == null) { sourcePartition = partition; } else { sourcePartition = partition.getPartitionContext().getPartition(partitionName); if (sourcePartition == null) throw new Exception("Unknown partition "+partitionName+"."); } String className = sourceConfig.getSourceClass(); SourceContext sourceContext = new SourceContext(); sourceContext.setPartition(partition); Source source; if (connectionName != null) { ConnectionManager connectionManager = sourcePartition.getConnectionManager(); Connection connection = connectionManager.getConnection(connectionName); if (connection == null) throw new Exception("Unknown connection "+connectionName+"."); Adapter adapter = connection.getAdapter(); sourceContext.setAdapter(adapter); sourceContext.setConnection(connection); if (className == null) className = adapter.getSourceClassName(); } PartitionContext partitionContext = partition.getPartitionContext(); ClassLoader cl = partitionContext.getClassLoader(); if (debug) log.debug("Creating "+className+"."); Class clazz = cl.loadClass(className); source = (Source)clazz.newInstance(); source.init(sourceConfig, sourceContext); return source; } public void updateSource(SourceConfig sourceConfig) throws Exception { sourceConfigManager.updateSourceConfig(sourceConfig); String sourceName = sourceConfig.getName(); if (isRunning(sourceName)) { stopSource(sourceName); startSource(sourceName); } PartitionConfig partitionConfig = partition.getPartitionConfig(); DirectoryConfig directoryConfig = partitionConfig.getDirectoryConfig(); for (EntryConfig entryConfig : directoryConfig.getEntryConfigs()) { for (EntrySourceConfig sourceMapping : entryConfig.getSourceConfigs()) { if (!sourceMapping.getSourceName().equals(sourceName)) continue; sourceMapping.setSourceName(sourceConfig.getName()); } } } public Collection<Source> getSources() { return sources.values(); } public Source getSource(String name) { Source source = sources.get(name); if (source != null) return source; if (partition.getName().equals(PartitionConfig.ROOT)) return null; Partition rootPartition = partition.getPartitionContext().getPartition(PartitionConfig.ROOT); SourceManager sourceManager = rootPartition.getSourceManager(); return sourceManager.getSource(name); } public Collection<Source> getSourcesByConnectionName(String connectionName) { return sourcesByConnectionName.get(connectionName); } public SourceConfigManager getSourceConfigManager() { return sourceConfigManager; } }