/*
* Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* bstefanescu
*
* $Id$
*/
package org.eclipse.ecr.runtime.deploy;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.nuxeo.common.collections.ListenerList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.ecr.runtime.model.RuntimeContext;
/**
* @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
*/
public class ConfigurationDeployer implements FileChangeListener {
private static final Log log = LogFactory.getLog(ConfigurationDeployer.class);
protected final Map<String, Entry> urls;
protected final FileChangeNotifier notifier;
protected final ListenerList listeners = new ListenerList();
public ConfigurationDeployer() {
this(null);
}
public ConfigurationDeployer(FileChangeNotifier notifier) {
this.notifier = notifier;
urls = new HashMap<String, Entry>();
if (notifier != null) {
notifier.addListener(this);
}
}
public void deploy(RuntimeContext ctx, URL url, boolean trackChanges) throws Exception {
File watchFile = null;
if (trackChanges) {
try {
String str = url.toExternalForm();
if (str.startsWith("file:")) {
watchFile = new File(url.toURI());
} else if (str.startsWith("jar:file:")) {
int p = str.lastIndexOf('!');
if (p > -1) {
str = str.substring(4, p);
} else {
str = str.substring(4);
}
watchFile = new File(new URI(str));
}
} catch (Exception e) {
log.error(e);
watchFile = null;
}
}
_deploy(ctx, url, watchFile, trackChanges);
}
public void undeploy(URL url) throws Exception {
Entry entry = urls.remove(url.toExternalForm());
if (entry != null) {
_undeploy(entry);
}
}
public synchronized void _undeploy(Entry entry) throws Exception {
try {
entry.ctx.undeploy(entry.url);
} finally {
if (notifier != null && entry.watchFile != null) {
notifier.unwatch(entry.url.toExternalForm(), entry.watchFile);
}
}
}
public void deploy(RuntimeContext ctx, File file, boolean trackChanges) throws Exception {
_deploy(ctx, file.getCanonicalFile().toURI().toURL(), file, trackChanges);
}
public void undeploy(File file) throws Exception {
undeploy(file.getCanonicalFile().toURI().toURL());
}
protected synchronized void _deploy(RuntimeContext ctx, URL url, File watchFile, boolean trackChanges) throws Exception {
String id = url.toExternalForm();
Entry entry = new Entry(ctx, url, watchFile);
ctx.deploy(url);
urls.put(id, entry);
if (trackChanges && notifier != null && watchFile != null) {
notifier.watch(id, watchFile);
}
}
@Override
public void fileChanged(FileChangeNotifier.FileEntry entry, long now) throws Exception {
Entry e = urls.get(entry.id);
if (e != null) {
try {
e.ctx.undeploy(e.url);
e.ctx.deploy(e.url);
} finally {
fireConfigurationChanged(e);
}
}
}
public void addConfigurationChangedListener(
ConfigurationChangedListener listener) {
listeners.add(listener);
}
public void removeConfigurationChangedListener(
ConfigurationChangedListener listener) {
listeners.remove(listener);
}
public void fireConfigurationChanged(Entry entry) throws Exception {
for (Object obj : listeners.getListenersCopy()) {
((ConfigurationChangedListener)obj).configurationChanged(entry);
}
}
public static class Entry {
final RuntimeContext ctx;
final URL url;
File watchFile;
Entry(RuntimeContext ctx, URL config, File watchFile) throws IOException {
url = config;
this.ctx = ctx;
if (watchFile != null) {
this.watchFile = watchFile.getCanonicalFile();
}
}
public RuntimeContext getContext() {
return ctx;
}
public File getWatchFile() {
return watchFile;
}
public URL getUrl() {
return url;
}
@Override
public String toString() {
return url.toExternalForm();
}
}
}