package org.korsakow.domain.command;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathExpressionException;
import org.dsrg.soenea.domain.MapperException;
import org.dsrg.soenea.domain.command.CommandException;
import org.dsrg.soenea.environment.CreationException;
import org.dsrg.soenea.environment.KeyNotFoundException;
import org.dsrg.soenea.uow.UoW;
import org.korsakow.domain.Interface;
import org.korsakow.domain.interf.IInterface;
import org.korsakow.domain.interf.IWidget;
import org.korsakow.domain.mapper.input.InterfaceInputMapper;
import org.korsakow.ide.DataRegistry;
import org.korsakow.ide.DomHelper;
import org.korsakow.ide.util.DomUtil;
import org.korsakow.ide.util.Template;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
public class LoadInterfaceCommand extends AbstractCommand
{
public LoadInterfaceCommand(Helper request, Helper response) {
super(request, response);
}
public void execute() throws CommandException
{
String file = request.getString("filename");
try {
Document doc = DomUtil.parseXML(new File(file));
Collection<IInterface> interfaces = getInterfaces(doc);
UoW.getCurrent().commit();
response.set("interfaces", interfaces);
} catch (SAXException e) {
throw new CommandException(e);
} catch (ParserConfigurationException e) {
throw new CommandException(e);
} catch (IOException e) {
throw new CommandException(e);
} catch (MapperException e) {
throw new CommandException(e);
} catch (SQLException e) {
throw new CommandException(e);
} catch (KeyNotFoundException e) {
throw new CommandException(e);
} catch (CreationException e) {
throw new CommandException(e);
} catch (XPathExpressionException e) {
throw new CommandException(e);
} catch (TransformerException e) {
throw new CommandException(e);
}
}
public static Collection<IInterface> getInterfaces(Document doc) throws MapperException, XPathExpressionException, CommandException, TransformerException, IOException, SAXException, ParserConfigurationException
{
// ====
// we swap documents so that we can load the defaults
// and then restore the document
// its all thread-local so it should be safe
// ====
// find the templated ids
List<Node> idElements = DomHelper.xpathAsList(doc, "/korsakow/descendant::*/id");
// reserve as many ids as we need
long idcounter = DataRegistry.advanceMaxId(idElements.size());
long idcountermax = idcounter + idElements.size();
Map<String, String> idMap = new HashMap<String, String>();
// map out template-id to concrete ids
for (Node node : idElements)
{
Element element = (Element)node;
String text = element.getTextContent();
if (text.startsWith("${") && text.endsWith("}"))
text = text.substring(2, text.length()-1);
if (!idMap.containsKey(text)) {
if (idcounter > idcountermax)
throw new CommandException("out of ids: " + idcounter);
long id = ++idcounter;
idMap.put(text, ""+id);
}
}
// well its kind of shoddy, but we convert to text, replace, and back to dom
String docStr = DomUtil.toXMLString(doc);
Template template = new Template(docStr);
template.setValues(idMap);
docStr = template.format();
doc = DomUtil.parseXMLString(docStr);
Document oldDoc = DataRegistry.getDocument();
Collection<IInterface> interfaces = null;
try {
Document tempDoc = doc;
DataRegistry.setDocument(tempDoc);
interfaces = InterfaceInputMapper.findAll();
// we need concrete instances since we put back the doc
for (IInterface interf : interfaces) {
interf.getVersion();
for (IWidget widget : interf.getWidgets()) {
widget.getVersion();
}
}
} finally {
// otherwise an exception would corrupt things
DataRegistry.setDocument(oldDoc);
}
// ====
// this is necessary to do since we swaped back the document
// in short, we re-register the DO's in the current UoW.
// ====
for (IInterface iinterf : interfaces) {
// this is the only way we can register new
Interface interf = InterfaceInputMapper.map(iinterf.getId());
UoW.getCurrent().registerNew(interf);
}
return interfaces;
}
}