/* RegisterCodecAction.java created 2007-09-19
*
*/
package org.signalml.app.action.document;
import static org.signalml.app.util.i18n.SvarogI18n._;
import static org.signalml.app.util.i18n.SvarogI18n._R;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.apache.log4j.Logger;
import org.signalml.app.SvarogApplication;
import org.signalml.app.config.ApplicationConfiguration;
import org.signalml.app.model.document.RegisterCodecDescriptor;
import org.signalml.app.util.XmlFileFilter;
import org.signalml.app.view.common.dialogs.OptionPane;
import org.signalml.app.view.common.dialogs.PleaseWaitDialog;
import org.signalml.app.view.common.dialogs.errors.Dialogs;
import org.signalml.app.view.signal.signalml.RegisterCodecDialog;
import org.signalml.app.worker.document.CreateCodecReaderWorker;
import org.signalml.codec.SignalMLCodec;
import org.signalml.codec.SignalMLCodecManager;
import org.signalml.codec.SignalMLCodecReader;
import org.signalml.codec.SignalMLCodecSelector;
import org.signalml.codec.XMLSignalMLCodec;
import org.signalml.codec.StaticCodec;
import org.signalml.plugin.export.view.AbstractSignalMLAction;
/** RegisterCodecAction
*
*
* @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o.
*/
public class RegisterCodecAction extends AbstractSignalMLAction {
public static final String CODEC_REGISTERED = "codecRegistered";
private static final long serialVersionUID = 1L;
protected static final Logger logger = Logger.getLogger(RegisterCodecAction.class);
private static boolean initialized = false;
private SignalMLCodecManager codecManager;
private RegisterCodecDialog registerCodecDialog;
private PleaseWaitDialog pleaseWaitDialog;
private SignalMLCodecSelector selector;
public RegisterCodecAction() {
super();
setText(_("Register new codec"));
codecManager = SvarogApplication.getSharedInstance().getSignalMLCodecManager();
}
@Override
public void actionPerformed(ActionEvent ev) {
logger.debug("Register codec");
RegisterCodecDescriptor model = new RegisterCodecDescriptor();
boolean ok = registerCodecDialog.showDialog(model, true);
if (!ok)
return;
createCodec(model);
}
public void initializeAll() {
if (initialized)
return;
initialized = true;
logger.debug("Registering static codecs");
register(org.signalml.codec.precompiled.EASYS.class, "precompiled");
register(org.signalml.codec.precompiled.EDF.class, "precompiled");
register(org.signalml.codec.precompiled.M4D.class, "precompiled");
File specsDir = new File(System.getProperty("user.dir"), "specs");
if (!specsDir.isDirectory()) {
logger.info("Spec directory is not a directory, ignoring: " + specsDir);
return;
}
logger.debug("Registering all available codecs in spec directory");
File[] files = specsDir.listFiles(new XmlFileFilter());
for (File file : files)
register(file);
}
private void register(File file) {
logger.info("Registering codec: " + file);
try {
jsignalml.compiler.CompiledClass<? extends jsignalml.Source> klass
= loadFromFile("compiled", file);
this.register(klass.theClass(), "compiled");
} catch(Exception e) {
logger.error("Failed to compile file " + file + ": " + e);
OptionPane.showError(null, _R("Failed to compile file {0}: {1}", file, e));
}
}
private void register(Class<? extends jsignalml.Source> source, String message) {
logger.info("Registering codec: " + source.getCanonicalName());
SignalMLCodec codec = new StaticCodec(source);
RegisterCodecDescriptor model = new RegisterCodecDescriptor();
model.setCodec(codec);
model.setSourceFile(new File(""));
model.setFormatName(codec.getFormatName() + " [" + message + "]");
createCodec(model);
}
private void createCodec(RegisterCodecDescriptor model) {
// try to create codec to be sure that it works
SignalMLCodec codec = model.getCodec();
CreateCodecReaderWorker worker = new CreateCodecReaderWorker(codec, pleaseWaitDialog);
worker.execute();
pleaseWaitDialog.setActivity(_("creating codec reader"));
pleaseWaitDialog.configureForIndeterminateSimulated();
pleaseWaitDialog.waitAndShowDialogIn(null, 3000, worker);
SignalMLCodecReader reader = null;
try {
reader = worker.get();
} catch (InterruptedException ex) {
// ignore
} catch (ExecutionException ex) {
logger.error("Exception during worker exectution", ex);
Dialogs.showExceptionDialog((Window) null, ex);
return;
}
if (reader == null) {
logger.error("Failed to compile the codec");
OptionPane.showError(null, _("Failed to compile the codec"));
return;
}
String formatName = model.getFormatName();
SignalMLCodec oldCodec = codecManager.getCodecForFormat(formatName);
if (oldCodec != null) {
codecManager.removeSignalMLCodec(oldCodec);
}
codec.setFormatName(formatName);
codecManager.registerSignalMLCodec(codec);
if (selector != null) {
selector.setSelectedCodec(codec);
}
if (getApplicationConfig().isSaveConfigOnEveryChange()) {
try {
codecManager.writeToPersistence(null);
} catch (IOException ex) {
logger.error("Failed to save codec configuration", ex);
}
}
firePropertyChange(CODEC_REGISTERED, null, codec);
}
public RegisterCodecDialog getRegisterCodecDialog() {
return registerCodecDialog;
}
public void setRegisterCodecDialog(RegisterCodecDialog registerCodecDialog) {
this.registerCodecDialog = registerCodecDialog;
}
public SignalMLCodecSelector getSelector() {
return selector;
}
public void setSelector(SignalMLCodecSelector selector) {
this.selector = selector;
}
public PleaseWaitDialog getPleaseWaitDialog() {
return pleaseWaitDialog;
}
public void setPleaseWaitDialog(PleaseWaitDialog pleaseWaitDialog) {
this.pleaseWaitDialog = pleaseWaitDialog;
}
public ApplicationConfiguration getApplicationConfig() {
return SvarogApplication.getApplicationConfiguration();
}
// XXX: find a home for this function. Should it go to jsignalml?
public static
jsignalml.compiler.CompiledClass<? extends jsignalml.Source> loadFromFile(String pkg, File file)
throws java.io.IOException,
java.lang.ClassNotFoundException,
org.xml.sax.SAXException
{
jsignalml.JavaClassGen gen =
jsignalml.CodecParser.generateFromFile(file, "org.signalml.codec." + pkg, false);
String name = gen.getFullClassName();
CharSequence code = gen.getSourceCode();
jsignalml.compiler.CompiledClass<jsignalml.Source> klass =
jsignalml.compiler.CompiledClass.newCompiledClass(name, code);
logger.info("class " + name + " has been sourced");
return klass;
}
}