001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.contrib.ajax;
016    
017    import java.io.IOException;
018    import java.io.OutputStream;
019    import java.io.StringWriter;
020    
021    import javax.xml.parsers.DocumentBuilder;
022    import javax.xml.parsers.DocumentBuilderFactory;
023    import javax.xml.transform.OutputKeys;
024    import javax.xml.transform.Transformer;
025    import javax.xml.transform.TransformerFactory;
026    import javax.xml.transform.dom.DOMSource;
027    import javax.xml.transform.stream.StreamResult;
028    
029    import org.apache.hivemind.ApplicationRuntimeException;
030    import org.apache.tapestry.IComponent;
031    import org.apache.tapestry.IPage;
032    import org.apache.tapestry.IRequestCycle;
033    import org.apache.tapestry.engine.IEngineService;
034    import org.apache.tapestry.engine.ILink;
035    import org.apache.tapestry.error.RequestExceptionReporter;
036    import org.apache.tapestry.request.RequestContext;
037    import org.apache.tapestry.services.ServiceConstants;
038    import org.apache.tapestry.util.ContentType;
039    import org.apache.tapestry.web.WebResponse;
040    import org.w3c.dom.Document;
041    import org.w3c.dom.Node;
042    
043    /**
044     * @author mindbridge
045     * @author Paul Green
046     * @since 4.0
047     */
048    public class XTileService implements IEngineService 
049    {
050        public static final String SERVICE_NAME = "xtile";
051    
052        private RequestExceptionReporter _exceptionReporter;
053        private WebResponse _response;
054        
055            public String getName() 
056            {
057                    return SERVICE_NAME;
058            }
059            
060            public ILink getLink(IRequestCycle cycle, boolean post, Object parameter) {
061                    throw new UnsupportedOperationException();
062            }
063            
064            public void service(IRequestCycle cycle) throws IOException {
065            String pageName = cycle.getParameter(ServiceConstants.PAGE);
066            String componentId = cycle.getParameter(ServiceConstants.COMPONENT);
067            
068            IPage componentPage = cycle.getPage(pageName);
069            IComponent component = componentPage.getNestedComponent(componentId);
070            
071            if (!(component instanceof IXTile))
072                    throw new ApplicationRuntimeException("Incorrect component type: was " + component.getClass() + " but must be " + IXTile.class, 
073                                    component, null, null);
074            
075            IXTile xtile = (IXTile) component;
076            
077            // do not squeeze on input
078                    RequestContext context = cycle.getRequestContext();
079            String[] params = context.getParameters(ServiceConstants.PARAMETER);
080            cycle.setServiceParameters(params);
081            xtile.trigger(cycle);
082            
083            // do not squeeze on output either
084            Object[] args = cycle.getServiceParameters();
085            String strArgs = generateOutputString(args);
086            if (strArgs != null) {
087                    OutputStream output = _response.getOutputStream(new ContentType("text/xml"));
088                    output.write(strArgs.getBytes("utf-8"));
089            }
090            }
091            
092            protected String generateOutputString(Object[] args)
093            {
094                    try {
095                            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
096                            dbf.setValidating(false);
097                            DocumentBuilder db = dbf.newDocumentBuilder();
098                            Document doc = db.newDocument();
099    
100                            Node rootNode = doc.createElement("data");
101                            doc.appendChild(rootNode);
102                            
103                            if (args != null) {
104                                    for (int i = 0; i < args.length; i++) {
105                                            Object value = args[i];
106                                            
107                                            Node spNode = doc.createElement("sp");
108                                            rootNode.appendChild(spNode);
109                                            
110                                            Node valueNode = doc.createTextNode(value.toString());
111                                            spNode.appendChild(valueNode);
112                                    }
113                            }
114                            
115                            TransformerFactory trf = TransformerFactory.newInstance();
116                            Transformer tr = trf.newTransformer();
117                            tr.setOutputProperty(OutputKeys.INDENT, "yes");
118    
119                            DOMSource domSrc = new DOMSource(doc);
120                            StringWriter writer = new StringWriter();
121                            StreamResult res = new StreamResult(writer);
122                            tr.transform(domSrc, res);
123                            writer.close();
124                            
125                            return writer.toString();
126                    } 
127                    catch (Exception e) {
128                            _exceptionReporter.reportRequestException("Cannot generate XML", e);
129                            return null;
130                    }
131            }
132    
133        public void setExceptionReporter(RequestExceptionReporter exceptionReporter)
134        {
135            _exceptionReporter = exceptionReporter;
136        }
137    
138        public void setResponse(WebResponse response)
139        {
140            _response = response;
141        }
142        
143            public static void main(String[] args) {
144                    XTileService objService = new XTileService();
145                    System.out.println(objService.generateOutputString(new Object[] { "test > work", new Integer(20) }));
146            }
147    
148    
149    }