cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r232596 - in /cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging: Client.java Debugger.java RemoteDebuggingSitemapExecutor.java
Date Sun, 14 Aug 2005 11:13:48 GMT
Author: cziegeler
Date: Sun Aug 14 04:13:12 2005
New Revision: 232596

URL: http://svn.apache.org/viewcvs?rev=232596&view=rev
Log:
Add an experimental remote debugger

Added:
    cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Client.java   (with
props)
    cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Debugger.java 
 (with props)
    cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/RemoteDebuggingSitemapExecutor.java
  (with props)

Added: cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Client.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Client.java?rev=232596&view=auto
==============================================================================
--- cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Client.java (added)
+++ cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Client.java Sun
Aug 14 04:13:12 2005
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.profiler.debugging;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URL;
+
+/**
+ * This is a simple cli client for the {@link Debugger}.
+ * @since 2.2
+ * @version $Id:$
+ */
+public class Client implements Runnable {
+
+    protected static final String HOST = "localhost";
+    protected static final int PORT = 4444;
+
+    protected PrintWriter  writer;
+    protected Reader       reader;
+    protected ServerSocket server;
+    protected Socket       socket;
+
+    /**
+     * @see java.lang.Runnable#run()
+     */
+    public void run() {
+        try {
+            this.server = new ServerSocket(PORT);
+            
+            this.socket = this.server.accept();
+            if ( this.socket != null ) {
+                this.writer = new PrintWriter(this.socket.getOutputStream());
+                this.reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
+                while ( this.isSocketReaderReady() ) {
+                    int read;
+                    final StringBuffer response = new StringBuffer();
+                    do {
+                        try {
+                            read = this.reader.read();
+                            if (read > 0) {
+                                response.append((char)read);
+                            }
+                        } catch (IOException ioe) {
+                            // ignore
+                            read = 0;
+                        }
+                    } while (read > 0);
+                    System.out.println("Response");
+                    System.out.println(response.toString());
+                    System.out.println();
+                    this.writer.write("<message><status>0</status></message>");
+                    this.writer.write(0);
+                    this.writer.flush();
+                }
+                this.writer.close();
+                this.reader.close();
+            }
+            
+        } catch (Exception ignore) {
+            ignore.printStackTrace();
+        } finally {
+            this.close();
+        }
+    }
+
+    /**
+     * Close the connection
+     */
+    protected void close() {
+        if (this.socket != null) {
+            try {
+                this.writer.close();
+            } catch (Exception ignore) {}
+            try {
+                this.reader.close();
+            } catch (Exception ignore) {}
+            try {
+                this.socket.close();
+            } catch (Exception ignore) {}
+            this.socket = null;
+            this.reader = null;
+            this.writer = null;
+        }
+        if ( this.server != null ) {
+            try {
+                this.server.close();
+            } catch (Exception ignore) {}            
+        }
+    }
+
+    protected boolean isSocketReaderReady() {
+        try {
+            while (!this.reader.ready() /*&& !this.socket.isInputShutdown()*/) {
+                try {
+                    java.lang.Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                }
+            }
+            return this.reader.ready();
+        } catch (IOException e) {
+            return false;
+        }
+    }
+
+    /**
+     * The <code>main</code> method.
+     *
+     * @param args a <code>String[]</code> of arguments
+     * @exception Exception if an error occurs
+     */
+    public static void main(String[] args) throws Exception {
+        // the first argument is the full uri
+        if ( args.length == 0 ) {
+            printUsage();
+        }
+        // start thread
+        Thread t = new Thread(new Client());
+        t.start();
+        Thread.yield();
+        System.out.println("Invoking.");
+        StringBuffer buffer = new StringBuffer(args[0]);
+        if ( buffer.indexOf("?") != -1 ) {
+            buffer.append('&');
+        } else {
+            buffer.append('?');
+        }
+        buffer.append(Debugger.REQUEST_PARAMETER);
+        buffer.append('=');
+        buffer.append(HOST);
+        buffer.append(':');
+        buffer.append(PORT);
+
+        URL url = new URL(buffer.toString());
+        InputStream is = url.openConnection().getInputStream();
+        byte[] b = new byte[4096];
+        int length;
+        while ((length = is.read(b)) > -1) {
+            // ignore content
+        }
+        is.close();
+    }
+
+    protected static void printUsage() {
+        System.out.println("Usage: client [uri]");
+    }
+}

Propchange: cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Client.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Client.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Debugger.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Debugger.java?rev=232596&view=auto
==============================================================================
--- cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Debugger.java (added)
+++ cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Debugger.java Sun
Aug 14 04:13:12 2005
@@ -0,0 +1,494 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.profiler.debugging;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.net.Socket;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+import java.util.Map.Entry;
+
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.ProcessingException;
+import org.apache.cocoon.components.ContextHelper;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.wrapper.AbstractRequestWrapper;
+import org.apache.cocoon.xml.dom.DOMUtil;
+import org.apache.excalibur.xml.dom.DOMParser;
+import org.apache.excalibur.xml.xpath.XPathProcessor;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+/**
+ * This is an experimental debugger.
+ * @since 2.2
+ * @version $Id$
+ */
+public class Debugger
+    extends AbstractLogEnabled
+    implements Serviceable, Disposable, Initializable, Contextualizable {
+
+    protected static final String DEBUGGER_KEY = Debugger.class.getName();
+    protected static final String SITEMAP_COUNTER_KEY = DEBUGGER_KEY + "/sitemap-counter";
+    public static final String REQUEST_PARAMETER = "remote-debug";
+
+    protected PrintWriter     writer;
+    protected BufferedReader  reader;
+    protected String          information;
+    protected Socket          socket;
+    protected ServiceManager  manager;
+    protected DOMParser       parser;
+    protected XPathProcessor  processor;
+    protected String          debugInfo;
+    protected boolean         finished;
+    protected Context         context;
+    private Stack infoStack = new Stack();
+    
+    /**
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+        this.parser = (DOMParser)this.manager.lookup(DOMParser.ROLE);
+        this.processor = (XPathProcessor)this.manager.lookup(XPathProcessor.ROLE);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Initializable#initialize()
+     */
+    public void initialize() throws Exception {
+        int pos = this.debugInfo.indexOf(':');
+        
+        String host = this.debugInfo.substring(0, pos);
+        int   port = new Integer(this.debugInfo.substring(pos+1)).intValue();
+        this.getLogger().info("Trying to open connection to: " + host + " using port " +
port);
+        this.socket = new Socket(host, port);
+        this.socket.setKeepAlive(true);
+        this.socket.setSoTimeout(60);
+        this.writer = new PrintWriter(socket.getOutputStream());
+        this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+        this.finished = false;
+        Map objectModel = ContextHelper.getObjectModel(this.context);
+        objectModel.put(DEBUGGER_KEY, this);
+        Request oldRequest = ObjectModelHelper.getRequest(objectModel);
+        Request newRequest = new RequestWrapper(oldRequest);
+        objectModel.put(ObjectModelHelper.REQUEST_OBJECT, newRequest);
+    }
+
+    /**
+     * @see org.apache.avalon.framework.activity.Disposable#dispose()
+     */
+    public void dispose() {
+        if ( this.context != null ) {
+            Map objectModel = ContextHelper.getObjectModel(this.context);
+            objectModel.remove(DEBUGGER_KEY);
+            this.context = null;
+        }
+        if ( this.manager != null ) {
+            this.manager.release(this.parser);
+            this.manager.release(this.processor);
+            this.parser = null;
+            this.processor = null;
+            this.manager = null;
+        }
+    }
+
+    public Debugger(){
+        this.finished = true;
+    }
+
+    public void setDebugInfo(String value) {
+        this.debugInfo = value;
+    }
+
+    public void sendFinal(String value) {
+        if (this.finished) {
+            return;
+        }
+        this.writer.write("<message>\n");
+        this.writer.write(value);
+        this.writer.write("</message>\n");
+        this.writer.write(0);
+        this.writer.flush();
+    }
+    
+    public void send(String value) {
+        if (this.finished) {
+            return;
+        }
+        
+        this.sendFinal(value);
+                
+        if (!isSocketReaderReady()) {
+            this.getLogger().warn("Socket disconnected.");
+            this.close();
+        }
+
+        int read;
+        final StringBuffer response = new StringBuffer();
+        do {
+            try {
+                read = this.reader.read();
+                if (read > 0) {
+                    response.append((char)read);
+                }
+            } catch (IOException ioe) {
+                this.getLogger().warn("IOException during reading - stop debugging.");
+                this.close();
+                return;
+            }
+        } while (read > 0);
+        
+        Document doc = null;
+        try {
+            InputSource is = new InputSource();
+            is.setCharacterStream(new StringReader(response.toString()));
+            doc = this.parser.parseDocument(is);
+        } catch (Exception any) {
+            this.getLogger().warn("Exception during parsing - stop debugging.");
+            // if an exception during parsing occurs, we simply stop debugging
+            this.close();
+            return;
+        }
+       
+        try {
+            String status = DOMUtil.getValueOf(doc, "message/status", this.processor);
+        
+            if ( status != null && !status.equals("0")) {
+                this.finished = true;
+            }
+        } catch (ProcessingException any) {
+            this.getLogger().warn("Exception during parsing of status - stop debugging.");
+            // if an exception during parsing occurs, we simply stop debugging
+            this.close();
+            return;
+        }
+        /*
+         * Not used
+        NodeList list = DOMUtil.getNodeListFromPath(doc, new String[] {"message","status","get"});
+        if (list != null && list.getLength() > 0) {
+            StringBuffer message = new StringBuffer();
+            for(int i = 0; i < list.getLength(); i++) {
+                final Node current = list.item(i);
+                final String getKey = DOMUtil.getValueOfNode(current, "key");
+                message.append("<get>\n");
+                message.append("<key>").append(getKey).append("</key>\n");
+                VariableResolver vr = VariableResolverFactory.getResolver(getKey, this.manager);
+                final String getValue = vr.resolve(this.context, this.objectModel);
+                message.append("<value>").append(getValue).append("</value>\n");
+                message.append("</get>\n");
+            }
+            
+            // FIXME: Avoid recursion!
+            this.send(message.toString());
+        }
+         */
+    }
+    
+    /**
+     * Close the connection
+     */
+    public void close() {
+        if (this.socket != null) {
+            this.getLogger().info("Closing connection.");
+            this.finished = true;
+            try {
+                this.writer.close();
+            } catch (Exception ignore) {}
+            try {
+                this.reader.close();
+            } catch (Exception ignore) {}
+            try {
+                this.socket.close();
+            } catch (Exception ignore) {}
+            this.socket = null;
+            this.reader = null;
+            this.writer = null;
+        }
+    }
+    
+    public void sendSitemapElement(String type, String configuration) {
+        if (this.finished) {
+            return;
+        }
+        this.sendSitemapElement(type, configuration, null);
+    }
+    
+    public void sendSitemapElement(String type, String configuration, Parameters p) {
+        if (this.finished) {
+            return;
+        }
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("<sitemap-element>\n");
+        if (this.information != null) {
+            buffer.append("<information>\n");
+            buffer.append(this.information).append('\n');
+            buffer.append("</information>\n");
+        }
+        buffer.append("<statement type=\"").append(type).append("\">\n");
+        if (configuration != null) {
+            buffer.append(configuration).append('\n');
+        }
+        if (p != null) {
+            String[] names = p.getNames();
+            if (names != null && names.length > 0) {
+                buffer.append("<parameters>\n");
+                for(int i=0; i < names.length; i++) {
+                    buffer.append("<parameter name=\"").append(names[i]).append("\">");
+                    buffer.append(xmlText(p.getParameter(names[i], ""))).append("</parameter>\n");
+                }
+                buffer.append("</parameters>\n");
+            }
+        }
+        buffer.append("</statement>\n");
+        buffer.append("</sitemap-element>\n");
+        
+        this.send(buffer.toString());
+    }
+
+    public void pushInformation(Map infoMap) {
+        if ( !this.infoStack.empty() ) {
+            final Map oldMap = (Map)this.infoStack.peek();
+            infoMap = new HashMap(infoMap);
+            final Iterator i = oldMap.entrySet().iterator();
+            while ( i.hasNext() ) {
+                final Map.Entry entry = (Map.Entry)i.next();
+                final String key = entry.getKey().toString();
+                if ( key.indexOf(':') == -1) {
+                    infoMap.put("../"+key, entry.getValue());
+                } else {
+                    infoMap.put(key, entry.getValue());
+                }
+            }
+        }
+        
+        this.infoStack.push(infoMap);
+        this.calcInfo();
+    }
+    
+    public void popInformation() {
+        if ( !this.infoStack.empty() ) {
+            this.infoStack.pop();
+        }
+        this.calcInfo();
+    }
+    
+    public void clearInformation() {
+        this.infoStack.clear();
+        this.calcInfo();
+    }
+    
+    /**
+     * Calculate the current information string
+     */
+    protected void calcInfo() {
+        if ( this.infoStack.empty() ) {
+            this.information = null;
+        } else {
+            Map value = (Map)this.infoStack.peek();
+            Iterator e = value.keySet().iterator();
+            StringBuffer buffer = new StringBuffer("<values>\n");
+            while (e.hasNext()) {
+                Object key = e.next();
+                Object singleValue = value.get(key);
+                buffer.append("<value name=\"").append(key).append("\">");
+                buffer.append(xmlText(singleValue.toString())).append("</value>\n");
+            }
+            buffer.append("</values>\n");
+            this.information = buffer.toString();
+        }
+    }
+    
+    /**
+     * Get the debugger
+     */
+    static public Debugger getDebugger(Map objectModel) {
+        return (Debugger)objectModel.get(DEBUGGER_KEY);
+    }
+
+    public static Integer getSitemapCounter(Map objectModel) {
+        Integer i = (Integer)objectModel.get(SITEMAP_COUNTER_KEY);
+        if ( i == null ) {
+            i = new Integer(0);
+            objectModel.put(SITEMAP_COUNTER_KEY, i);
+        }
+        return i;
+    }
+    
+    public static Integer incSitemapCounter(Map objectModel) {
+        Integer i = getSitemapCounter(objectModel);
+        i = new Integer(i.intValue() + 1 );
+        objectModel.put(SITEMAP_COUNTER_KEY, i);        
+        return i;
+    }
+    
+    public static Integer decSitemapCounter(Map objectModel) {
+        Integer i = getSitemapCounter(objectModel);
+        i = new Integer(i.intValue() - 1 );
+        objectModel.put(SITEMAP_COUNTER_KEY, i);
+        return i;
+    }
+
+    private boolean isSocketReaderReady() {
+        try {
+            while (!reader.ready() /*&& !this.socket.isInputShutdown()*/) {
+                try {
+                    java.lang.Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                }
+            }
+            return reader.ready();
+        } catch (IOException e) {
+            return false;
+        }
+    }
+
+    /**
+     * @param name
+     * @param info
+     */
+    public void addNamedInformation(String name, Map info) {
+        Map last = (Map)this.infoStack.peek();
+        if ( last != null && name != null && info != null) {
+            Iterator iter = info.entrySet().iterator();
+            while ( iter.hasNext() ) {
+                Map.Entry current = (Entry) iter.next();
+                String key = current.getKey().toString();
+                last.put('#'+name+':'+key, current.getValue());
+            }
+        }        
+        this.calcInfo();
+    }
+    
+    public static String xmlText(String text) {
+        return "<![CDATA[" + text + "]]>";
+    }
+    
+    public static String xmlElement(String name, String text) {
+        return "<"+name+">"+xmlText(text)+"</"+name+">\n";        
+    }
+
+    /**
+     * We wrap the request to remove the request parameter from the list
+     * of parameters. This ensures that internal requests are not debugged.
+     */
+    protected final static class RequestWrapper extends AbstractRequestWrapper {
+
+        public RequestWrapper(Request request) {
+            super(request);
+        }
+
+        /**
+         * @see org.apache.cocoon.environment.Request#getParameter(java.lang.String)
+         */
+        public String getParameter(String name) {
+            if (REQUEST_PARAMETER.equals(name)) {
+                return null;
+            }
+            return super.getParameter(name);
+        }
+
+        /**
+         * @see org.apache.cocoon.environment.Request#getParameterNames()
+         */
+        public Enumeration getParameterNames() {
+            // put all parameter names into a set
+            Set parameterNames = new HashSet();
+            Enumeration names = super.getParameterNames();
+            while (names.hasMoreElements()) {
+                String name = (String)names.nextElement();
+                if (!REQUEST_PARAMETER.equals(name)) {
+                    parameterNames.add(names.nextElement());
+                }
+            }
+            return new EnumerationFromIterator(parameterNames.iterator());
+        }
+
+        final class EnumerationFromIterator implements Enumeration {
+            private Iterator iter;
+            EnumerationFromIterator(Iterator iter) {
+                this.iter = iter;
+            }
+
+            public boolean hasMoreElements() {
+                return iter.hasNext();
+            }
+            public Object nextElement() { return iter.next(); }
+        }
+
+        /**
+         * @see org.apache.cocoon.environment.Request#getParameterValues(java.lang.String)
+         */
+        public String[] getParameterValues(String name) {
+            if (REQUEST_PARAMETER.equals(name)) {
+                return null;
+            }
+            return super.getParameterValues(name);
+        }
+
+        /**
+         * @see org.apache.cocoon.environment.Request#getQueryString()
+         */
+        public String getQueryString() {
+            String qs = super.getQueryString();
+            int pos = qs.indexOf("sunbow_debug=");
+            if (pos != -1) {
+                int end = qs.indexOf("&", pos+1);
+                if (end == -1) {
+                    if (pos == 0) {
+                        qs = null;
+                    } else {
+                        qs = qs.substring(0, pos-2);   
+                    }
+                } else {
+                    if (pos == 0) {
+                        qs = qs.substring(end+1);
+                    } else {
+                        qs = qs.substring(0, pos-2) + qs.substring(end);
+                    }
+                }
+            }
+            return qs;
+        }
+
+    }
+}

Propchange: cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Debugger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/Debugger.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/RemoteDebuggingSitemapExecutor.java
URL: http://svn.apache.org/viewcvs/cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/RemoteDebuggingSitemapExecutor.java?rev=232596&view=auto
==============================================================================
--- cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/RemoteDebuggingSitemapExecutor.java
(added)
+++ cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/RemoteDebuggingSitemapExecutor.java
Sun Aug 14 04:13:12 2005
@@ -0,0 +1,436 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.profiler.debugging;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.avalon.framework.container.ContainerUtil;
+import org.apache.avalon.framework.context.Context;
+import org.apache.avalon.framework.context.ContextException;
+import org.apache.avalon.framework.context.Contextualizable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.parameters.Parameters;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.acting.Action;
+import org.apache.cocoon.components.profiler.Profiler;
+import org.apache.cocoon.components.profiler.ProfilerResult;
+import org.apache.cocoon.components.sax.XMLDeserializer;
+import org.apache.cocoon.environment.ObjectModelHelper;
+import org.apache.cocoon.environment.Redirector;
+import org.apache.cocoon.environment.Request;
+import org.apache.cocoon.environment.SourceResolver;
+import org.apache.cocoon.matching.Matcher;
+import org.apache.cocoon.matching.PreparableMatcher;
+import org.apache.cocoon.selection.Selector;
+import org.apache.cocoon.selection.SwitchSelector;
+import org.apache.cocoon.sitemap.ExecutionContext;
+import org.apache.cocoon.sitemap.PatternException;
+import org.apache.cocoon.sitemap.SitemapExecutor;
+import org.apache.cocoon.xml.XMLUtils;
+import org.apache.cocoon.xml.dom.DOMBuilder;
+import org.apache.excalibur.source.Source;
+
+/**
+ * Sample sitemap executor that prints out everything to a logger
+ * 
+ * @since 2.2
+ * @version $Id$
+ */
+public class RemoteDebuggingSitemapExecutor 
+    extends AbstractLogEnabled
+    implements ThreadSafe, SitemapExecutor, Serviceable, Contextualizable {
+
+    protected ServiceManager manager;
+    protected Context        context;
+
+    /**
+     * @see org.apache.avalon.framework.context.Contextualizable#contextualize(org.apache.avalon.framework.context.Context)
+     */
+    public void contextualize(Context context) throws ContextException {
+        this.context = context;
+    }
+
+    /**
+     * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
+     */
+    public void service(ServiceManager manager) throws ServiceException {
+        this.manager = manager;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#invokeAction(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, org.apache.cocoon.acting.Action, org.apache.cocoon.environment.Redirector,
org.apache.cocoon.environment.SourceResolver, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public Map invokeAction(final ExecutionContext context,
+                            final Map              objectModel, 
+                            final Action           action, 
+                            final Redirector       redirector, 
+                            final SourceResolver   resolver, 
+                            final String           resolvedSource, 
+                            final Parameters       resolvedParams )
+    throws Exception {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if (debugger != null) {
+            String configuration = Debugger.xmlElement("src",resolvedSource);
+            debugger.sendSitemapElement("act", configuration, resolvedParams);
+        }
+        final Map result = action.act(redirector, resolver, objectModel, resolvedSource,
resolvedParams);
+        return result;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#invokeMatcher(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, org.apache.cocoon.matching.Matcher, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public Map invokeMatcher(ExecutionContext context, 
+                             Map objectModel,
+                             Matcher matcher, 
+                             String pattern, 
+                             Parameters resolvedParams)
+    throws PatternException {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if (debugger != null) {
+            String p = Debugger.xmlElement("pattern", pattern);
+            debugger.sendSitemapElement("match", p, resolvedParams);
+        }
+        final Map result = matcher.match(pattern, objectModel, resolvedParams);
+        return result;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#invokePreparableMatcher(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, org.apache.cocoon.matching.PreparableMatcher, java.lang.Object, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public Map invokePreparableMatcher(ExecutionContext  context,
+                                       Map               objectModel,
+                                       PreparableMatcher matcher,
+                                       Object            preparedPattern,
+                                       Parameters        resolvedParams )
+    throws PatternException {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if (debugger != null) {
+            String p = Debugger.xmlElement("pattern", preparedPattern.toString());
+            debugger.sendSitemapElement("match", p, resolvedParams);
+        }
+        final Map result = matcher.preparedMatch(preparedPattern, objectModel, resolvedParams);
+        return result;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#invokeSelector(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, org.apache.cocoon.selection.Selector, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
+     */
+    public boolean invokeSelector(ExecutionContext context,
+                                  Map objectModel,
+                                  Selector selector,
+                                  String expression,
+                                  Parameters parameters) {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if ( debugger != null ) {
+            debugger.sendSitemapElement("select", 
+                                        null, 
+                                        parameters);
+            String configuration = Debugger.xmlElement("test", expression);
+            debugger.sendSitemapElement("when", 
+                                        configuration, 
+                                        parameters);
+        }
+        final boolean result = selector.select(expression, objectModel, parameters);
+        return result;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#invokeSwitchSelector(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, org.apache.cocoon.selection.SwitchSelector, java.lang.String, org.apache.avalon.framework.parameters.Parameters,
java.lang.Object)
+     */
+    public boolean invokeSwitchSelector(ExecutionContext context,
+                                        Map objectModel,
+                                        SwitchSelector selector,
+                                        String expression,
+                                        Parameters parameters,
+                                        Object selectorContext) {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if ( debugger != null ) {
+            debugger.sendSitemapElement("select", 
+                                        null, 
+                                        parameters);
+            String configuration = Debugger.xmlElement("test", expression);
+            debugger.sendSitemapElement("when", 
+                                        configuration, 
+                                        parameters);
+        }
+        final boolean result = selector.select(expression, selectorContext);
+        return result;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#popVariables(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map)
+     */
+    public void popVariables(ExecutionContext context,
+                             Map              objectModel) {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if ( debugger != null ) {
+            debugger.popInformation();
+        }
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#pushVariables(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, java.lang.String, java.util.Map)
+     */
+    public Map pushVariables(ExecutionContext context, 
+                             Map              objectModel,
+                             String           key, 
+                             Map              variables) {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if ( debugger != null ) {
+            debugger.pushInformation(variables);
+            if ( key != null ) {
+                debugger.addNamedInformation(key, variables);
+            }
+        }
+        return variables;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#enterSitemap(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, java.lang.String)
+     */
+    public String enterSitemap(ExecutionContext context, 
+                               Map objectModel,
+                               String source) {
+        Integer sitemapCounter = Debugger.getSitemapCounter(objectModel);
+        Debugger debugger = Debugger.getDebugger(objectModel);
+        if ( debugger == null ) {
+            // is this the first sitemap?
+            if ( sitemapCounter.intValue() == 0 ) {
+                final Request request = ObjectModelHelper.getRequest(objectModel);
+                if (request.getParameter(Debugger.REQUEST_PARAMETER) != null) {
+                    String value = request.getParameter(Debugger.REQUEST_PARAMETER);
+                    debugger = new Debugger();
+                    try {
+                        debugger.setDebugInfo(value);
+                        ContainerUtil.enableLogging(debugger, getLogger());
+                        ContainerUtil.contextualize(debugger, this.context);
+                        ContainerUtil.service(debugger, this.manager);
+                        ContainerUtil.initialize(debugger);
+                    } catch (Exception ignore) {
+                        // we simply ignore this and turn off debugging
+                        debugger = null;
+                    }
+                }
+                if (debugger != null) {
+                    
+                }
+            }
+        }
+        if (debugger != null) {
+            // if this is not the first sitemap, then we have a mount
+            if ( sitemapCounter.intValue() > 0 ) {
+                String p = Debugger.xmlElement("src", source);
+                debugger.sendSitemapElement("mount", p, null);
+            }
+
+            // first we send the sitemap
+            org.apache.excalibur.source.SourceResolver resolver = null;
+            Source src = null;
+            try {
+                resolver = (org.apache.excalibur.source.SourceResolver)this.manager.lookup(org.apache.excalibur.source.SourceResolver.ROLE);
+                src = resolver.resolveURI(source);
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                InputStream inputStream = src.getInputStream();
+                byte[] buffer = new byte[4096];
+                int length;
+                while ((length = inputStream.read(buffer)) > -1) {
+                    baos.write(buffer, 0, length);
+                }
+                inputStream.close();
+                baos.close();
+                debugger.send(new String(baos.toString("utf-8")));
+            } catch (Exception ignore ) {
+                // we ignore this for now
+            } finally {
+                if ( source != null ) {
+                    resolver.release(src);
+                }
+                this.manager.release(resolver);
+            }
+            
+            debugger.sendSitemapElement("pipelines", null);
+                                
+        }
+        Debugger.incSitemapCounter(objectModel);
+        return source;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#leaveSitemap(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map)
+     */
+    public void leaveSitemap(ExecutionContext context, Map objectModel) {
+        Integer count = Debugger.decSitemapCounter(objectModel);
+        if ( count.intValue() == 0 ) {
+            final Debugger debugger = Debugger.getDebugger(objectModel);
+            if ( debugger != null ) {
+                debugger.sendFinal("<finished/>");
+                debugger.close();
+                ContainerUtil.dispose(debugger);
+            }
+        }
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#addGenerator(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, org.apache.cocoon.sitemap.SitemapExecutor.PipelineComponentDescription)
+     */
+    public PipelineComponentDescription addGenerator(ExecutionContext context,
+                                                     Map objectModel,
+                                                     PipelineComponentDescription desc) {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if (debugger != null) {
+            String configuration = Debugger.xmlElement("src", desc.source);
+            debugger.sendSitemapElement("generate", 
+                                        configuration, 
+                                        desc.parameters);
+        }
+        return desc;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#addReader(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, org.apache.cocoon.sitemap.SitemapExecutor.PipelineComponentDescription)
+     */
+    public PipelineComponentDescription addReader(ExecutionContext context,
+                                                  Map objectModel,
+                                                  PipelineComponentDescription desc) {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if (debugger != null) {
+            String configuration = Debugger.xmlElement("src", desc.source);
+            debugger.sendSitemapElement("read", 
+                                        configuration, 
+                                        desc.parameters);
+        }
+        return desc;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#addSerializer(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, org.apache.cocoon.sitemap.SitemapExecutor.PipelineComponentDescription)
+     */
+    public PipelineComponentDescription addSerializer(ExecutionContext context,
+                                                      Map objectModel,
+                                                      PipelineComponentDescription desc)
{
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if (debugger != null) {
+            String configuration = Debugger.xmlElement("src", desc.source);
+            debugger.sendSitemapElement("serialize", 
+                                        configuration, 
+                                        desc.parameters);
+        }
+        return desc;
+    }
+    
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#addTransformer(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, org.apache.cocoon.sitemap.SitemapExecutor.PipelineComponentDescription)
+     */
+    public PipelineComponentDescription addTransformer(ExecutionContext context,
+                                                       Map objectModel,
+                                                       PipelineComponentDescription desc)
{
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if (debugger != null) {
+            String configuration = Debugger.xmlElement("src", desc.source);
+            debugger.sendSitemapElement("transform", 
+                                        configuration, 
+                                        desc.parameters);
+        }
+        return desc;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#redirectTo(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, java.lang.String, boolean, boolean, boolean)
+     */
+    public String redirectTo(ExecutionContext context,
+                             Map objectModel,
+                             String uri,
+                             boolean createSession,
+                             boolean global,
+                             boolean permanent) {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if (debugger != null) {
+            String configuration = Debugger.xmlElement("uri", uri);
+            debugger.sendSitemapElement("redirect-to", 
+                                     configuration, 
+                                     null);
+        }
+        return uri;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#enteringPipeline(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map, org.apache.cocoon.sitemap.SitemapExecutor.PipelineComponentDescription)
+     */
+    public PipelineComponentDescription enteringPipeline(ExecutionContext context, Map objectModel,
PipelineComponentDescription desc) {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if ( debugger != null ) {
+            // we always use the profiling noncaching pipeline
+            desc.type = "profile-noncaching";
+        }
+        return desc;
+    }
+
+    /**
+     * @see org.apache.cocoon.sitemap.SitemapExecutor#notifyPipelineProcessed(org.apache.cocoon.sitemap.ExecutionContext,
java.util.Map)
+     */
+    public void notifyPipelineProcessed(ExecutionContext context, Map objectModel) {
+        final Debugger debugger = Debugger.getDebugger(objectModel);
+        if (debugger != null) {
+            Profiler profiler = null;
+            try {
+                profiler = (Profiler) this.manager.lookup(Profiler.ROLE);
+                ProfilerResult data = null; 
+                Collection c = profiler.getResultKeys();
+                Iterator it = c.iterator();
+                while (it.hasNext()) {
+                    Object o = it.next();
+                    data = profiler.getResult(o);
+                }
+                if (data != null) {
+                    // TODO - is this right, it was getLatestSAXFragments()
+                    Object[][] frags = data.getSAXFragments();
+                    Object[] os = frags[0];
+                    for(int i = 0; i<os.length-1; i++) {
+                        Object o = os[i];
+                        XMLDeserializer deserializer = null;
+                        try {
+                            DOMBuilder builder = new DOMBuilder();
+                            deserializer = (XMLDeserializer)this.manager.lookup(XMLDeserializer.ROLE);
+                            deserializer.setConsumer(builder);
+                            deserializer.deserialize(o);
+                            String xml = "<stream>\n"+
+                                         XMLUtils.serializeNode(builder.getDocument()) +
+                                         "\n</stream>\n";
+                            debugger.send(xml);
+                        } catch (Exception ignore) {
+                            // ignore this
+                        } finally { 
+                            this.manager.release(deserializer);
+                        }
+                    }
+                }
+                profiler.clearResults();
+            } catch (Exception ignore) {
+                // ignore this
+            } finally {
+                this.manager.release(profiler);
+            }
+        }
+    }
+}

Propchange: cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/RemoteDebuggingSitemapExecutor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/blocks/profiler/trunk/java/org/apache/cocoon/profiler/debugging/RemoteDebuggingSitemapExecutor.java
------------------------------------------------------------------------------
    svn:keywords = Id



Mime
View raw message