001    /*
002     @license.text@ 
003     */
004    package biz.hammurapi.sql.xml;
005    
006    import java.util.ArrayList;
007    import java.util.Collection;
008    import java.util.Iterator;
009    
010    import org.w3c.dom.Document;
011    import org.w3c.dom.Element;
012    import org.w3c.dom.Node;
013    import org.w3c.dom.NodeList;
014    
015    import biz.hammurapi.config.ConfigurationException;
016    import biz.hammurapi.config.Context;
017    import biz.hammurapi.config.DomConfigFactory;
018    import biz.hammurapi.sql.SQLProcessor;
019    import biz.hammurapi.xml.dom.DOMUtils;
020    import biz.hammurapi.xml.dom.AbstractDomObject;
021    
022    
023    /**
024     * @author Pavel Vlasov
025     * @version $Revision: 1.2 $
026     */
027    public class CompositeCommand extends AbstractDomObject implements Command {
028            private Collection commands=new ArrayList();
029    
030            public void addCommand(Command command) {
031                    commands.add(command);  
032            }
033            
034            private SQLProcessor processor;
035            
036            public Document execute(Document document, SQLProcessor processor, Context context) {
037                    Element element=document.createElement("sql2xml");
038                    document.appendChild(element);
039                    try {
040                            execute(element, processor, context);
041                    } catch (SQL2XMLException e) {
042                            log(e);
043                            Element errorElement=element.getOwnerDocument().createElement("error");
044                            toDom(e, errorElement);
045                            element.setAttribute("result", "error");
046                            element.appendChild(errorElement);
047                    }
048                    return document;
049            }
050            
051            /**
052             * Override for proper logging
053             * @param e
054             */
055            public void log(SQL2XMLException e) {
056                    e.printStackTrace();
057            }
058            
059            public void execute(Element holder, SQLProcessor processor, Context context) throws SQL2XMLException {
060                    Iterator it=commands.iterator();
061                    while (it.hasNext()) {
062                            ((Command) it.next()).execute(holder, this.processor==null ? processor : this.processor, context);
063                    }
064            }
065            
066            
067            public void configure(Node configNode, Context context) throws ConfigurationException {
068                    try {
069                            // TODO Handle <transaction> and <update> here as well
070                            NodeList nl = DOMUtils.selectNodeList(configNode, "query|update|transaction|message|java");
071                            for (int i=0, l=nl.getLength(); i<l; ++i) {
072                                    Node n = (Element) nl.item(i);
073                                    if ("query".equals(n.getNodeName())) {
074                                            Select select=new Select();
075                                            select.configure(n, context);
076                                            addCommand(select);
077                                    } else if ("update".equals(n.getNodeName())) {
078                                            Update update=new Update();
079                                            update.configure(n, context);
080                                            addCommand(update);                                     
081                                    } else if ("transaction".equals(n.getNodeName())) {
082                                            Transaction transaction=new Transaction();
083                                            transaction.configure(n, context);
084                                            addCommand(transaction);
085                                    } else if ("message".equals(n.getNodeName())) {
086                                            Message message=new Message();
087                                            message.configure(n, context);
088                                            addCommand(message);
089                                    } else if ("java".equals(n.getNodeName())) {
090                                            DomConfigFactory factory=new DomConfigFactory(this.getClass().getClassLoader(), context);
091                                            factory.create(n);
092                                    }
093                                    
094                                    processor=SQLCommand.initProcessor(configNode);
095                            }
096                    } catch (Exception e) {
097                            throw new ConfigurationException(e);
098                    }
099            }
100            
101            public void toDom(Throwable throwable, Element holder) {
102                    holder.setAttribute("type", throwable.getClass().getName());
103                    if (throwable.getMessage()!=null) {
104                            holder.setAttribute("message", throwable.getMessage());
105                    }
106                    
107                    Document ownerDocument = holder.getOwnerDocument();
108                    StackTraceElement[] frames=throwable.getStackTrace();
109                    for (int i=0; i<frames.length; i++) {
110                            Element frameElement=ownerDocument.createElement("frame");
111                            holder.appendChild(frameElement);
112                            frameElement.appendChild(ownerDocument.createTextNode(frames[i].toString()));
113                    }
114                    
115                    if (throwable.getCause()!=null) {
116                            Element causeElement=ownerDocument.createElement("cause");
117                            holder.appendChild(causeElement);
118                            toDom(throwable.getCause(), causeElement);
119                    }
120            }
121    }