Author: niclas
Date: Sun Aug 15 13:30:48 2004
New Revision: 36418

Added:
   avalon/trunk/planet/facilities/reflector/
   avalon/trunk/planet/facilities/reflector/README.TXT
   avalon/trunk/planet/facilities/reflector/api/
   avalon/trunk/planet/facilities/reflector/api/build.properties   (contents, 
props changed)
   avalon/trunk/planet/facilities/reflector/api/build.xml   (contents, props 
changed)
   avalon/trunk/planet/facilities/reflector/api/src/
   avalon/trunk/planet/facilities/reflector/api/src/main/
   avalon/trunk/planet/facilities/reflector/api/src/main/org/
   avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/
   avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/
   
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/
   
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/
   
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectionEvent.java
   (contents, props changed)
   
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectionException.java
   (contents, props changed)
   
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectionListener.java
   (contents, props changed)
   
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectorService.java
   (contents, props changed)
   avalon/trunk/planet/facilities/reflector/build.properties   (contents, props 
changed)
   avalon/trunk/planet/facilities/reflector/build.xml   (contents, props 
changed)
   avalon/trunk/planet/facilities/reflector/impl/
   avalon/trunk/planet/facilities/reflector/impl/build.properties   (contents, 
props changed)
   avalon/trunk/planet/facilities/reflector/impl/build.xml   (contents, props 
changed)
   avalon/trunk/planet/facilities/reflector/impl/src/
   avalon/trunk/planet/facilities/reflector/impl/src/main/
   avalon/trunk/planet/facilities/reflector/impl/src/main/org/
   avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/
   avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/
   
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/
   
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/
   
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/
   
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/ModelRegistrator.java
   (contents, props changed)
   
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/ReflectionHandler.java
   (contents, props changed)
   
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/ReflectorImpl.java
   (contents, props changed)
   
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/RequestContext.java
   (contents, props changed)
   
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/package.html
   (contents, props changed)
   avalon/trunk/planet/facilities/reflector/static_request.log
   avalon/trunk/planet/facilities/reflector/test/
   avalon/trunk/planet/facilities/reflector/test/etc/
   avalon/trunk/planet/facilities/reflector/test/etc/config.xml   (contents, 
props changed)
Modified:
   avalon/trunk/planet/facilities/index.xml
Log:
A brand new facility. Allows you to 'browse' the java instances, change the 
values and even instantiate (if classloaders allow) new objects and assign them.

Modified: avalon/trunk/planet/facilities/index.xml
==============================================================================
--- avalon/trunk/planet/facilities/index.xml    (original)
+++ avalon/trunk/planet/facilities/index.xml    Sun Aug 15 13:30:48 2004
@@ -627,5 +627,34 @@
     </dependencies>
   </project>
 
+  <project basedir="reflector/api">
+    <info>
+      <group>metro/facilities/reflector</group>
+      <name>metro-reflector-api</name>
+      <version>1.0.0</version>
+      <status>SNAPSHOT</status> 
+      <type>jar</type>
+    </info>
+  </project>
 
+  <project basedir="reflector/impl">
+    <info>
+      <group>metro/facilities/reflector</group>
+      <name>metro-reflector-impl</name>
+      <version>1.0.0</version>
+      <status>SNAPSHOT</status> 
+      <type>jar</type>
+    </info>
+    <dependencies>
+      <include key="avalon-framework-api"/>
+      <include key="metro-reflector-api"/>
+      <include key="avalon-composition-api"/>
+      <include key="org.mortbay.jetty"/>
+      <include key="avalon-http-spi"/>
+      <include key="avalon-http-impl"/>
+    </dependencies>
+    <plugins>
+      <include key="avalon-meta-tools"/>
+    </plugins>
+  </project>
 </index>

Added: avalon/trunk/planet/facilities/reflector/README.TXT
==============================================================================
--- (empty file)
+++ avalon/trunk/planet/facilities/reflector/README.TXT Sun Aug 15 13:30:48 2004
@@ -0,0 +1,15 @@
+
+To build:
+
+  $ cd planet/facilities/http
+  $ ant
+
+To start the http server:
+
+  $ cd test
+  $ merlin target/deliverables/blocks/avalon-http-test.block
+
+To see the result:
+
+  http://localhost:8080/test/primary
+

Added: avalon/trunk/planet/facilities/reflector/api/build.properties
==============================================================================
--- (empty file)
+++ avalon/trunk/planet/facilities/reflector/api/build.properties       Sun Aug 
15 13:30:48 2004
@@ -0,0 +1,2 @@
+project.system = ../../../../central/system
+project.home = ../..

Added: avalon/trunk/planet/facilities/reflector/api/build.xml
==============================================================================
--- (empty file)
+++ avalon/trunk/planet/facilities/reflector/api/build.xml      Sun Aug 15 
13:30:48 2004
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="metro-reflector-api" default="install" basedir="." 
+    xmlns:x="antlib:org.apache.avalon.tools">
+
+  <property file="build.properties"/>
+  <import file="${project.system}/build/standard.xml"/>
+
+</project>
+

Added: 
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectionEvent.java
==============================================================================
--- (empty file)
+++ 
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectionEvent.java
    Sun Aug 15 13:30:48 2004
@@ -0,0 +1,59 @@
+/*
+ * 1.0    1999/07/30 Niclas Hedhman     First Public Release
+ *
+ * Copyright (c) 1996-1999 Bali Automation. All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies. Please refer to the file "copyright.html"
+ * for further important copyright and licensing information.
+ *
+ * BALI AUTOMATION MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE 
+ * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING 
+ * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. BALI AUTOMATION
+ * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A 
+ * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 
+ * DERIVATIVES.
+ */
+package org.apache.metro.facilities.reflector;
+
+import java.util.EventObject;
+import java.io.Serializable;
+
+public final class ReflectionEvent extends EventObject
+    implements Serializable
+{
+    static final long serialVersionUID = 1L;
+    
+    private final Object m_Object;
+    private final Object m_Value;
+    private final String m_Method;
+    
+    public ReflectionEvent( Object source, 
+                            Object object, 
+                            Object value, 
+                            String method )
+    {
+        super(source);
+        m_Object = object;
+        m_Value = value;
+        m_Method = method;
+    }
+    
+    public Object getObject()
+    {
+        return m_Object;
+    }
+    
+    public Object getValue()
+    {
+        return m_Value;
+    }
+    
+    public String getMethod()
+    {
+        return m_Method;
+    }
+}

Added: 
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectionException.java
==============================================================================
--- (empty file)
+++ 
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectionException.java
        Sun Aug 15 13:30:48 2004
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 1996-2003 Bali Automation. All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies. Please refer to the file "copyright.html"
+ * for further important copyright and licensing information.
+ *
+ * BALI AUTOMATION MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE 
+ * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING 
+ * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. BALI AUTOMATION
+ * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A 
+ * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 
+ * DERIVATIVES.
+ */
+package org.apache.metro.facilities.reflector;
+
+public class ReflectionException extends Exception
+{
+    static final long serialVersionUID = 1L;
+
+    public ReflectionException()
+    {
+        super();
+    }
+
+    public ReflectionException( String message )
+    {
+        super(message);
+    }
+
+    public ReflectionException( String message, Exception exception )
+    {
+        super(message, exception);
+    }
+}

Added: 
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectionListener.java
==============================================================================
--- (empty file)
+++ 
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectionListener.java
 Sun Aug 15 13:30:48 2004
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 1996-2003 Bali Automation. All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies. Please refer to the file "copyright.html"
+ * for further important copyright and licensing information.
+ *
+ * BALI AUTOMATION MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE 
+ * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING 
+ * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. BALI AUTOMATION
+ * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A 
+ * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 
+ * DERIVATIVES.
+ */
+package org.apache.metro.facilities.reflector;
+
+import java.util.EventListener;
+
+public interface ReflectionListener extends EventListener
+{
+    void reflected( ReflectionEvent event );
+}

Added: 
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectorService.java
==============================================================================
--- (empty file)
+++ 
avalon/trunk/planet/facilities/reflector/api/src/main/org/apache/metro/facilities/reflector/ReflectorService.java
   Sun Aug 15 13:30:48 2004
@@ -0,0 +1,53 @@
+/* 
+ * Copyright 2004 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.metro.facilities.reflector;
+
+/**
+ * @avalon.service name="ReflectorService"
+ */
+public interface ReflectorService
+{
+    String get( String object ) throws ReflectionException;
+    Object getObject( String object ) throws ReflectionException;
+    Object getObject( Object container, String memberName ) throws 
ReflectionException;
+
+    void set( String object, String value ) throws ReflectionException;
+    void setObject( String objectname, Object object ) throws 
ReflectionException;
+    void setObject( Object container, String memberName, Object object ) 
throws ReflectionException;
+
+    String[] getNames( String object ) throws ReflectionException;
+    String[] getNames( Object object ) throws ReflectionException;
+    
+    Class getClass( String objectname ) throws ReflectionException;
+    Class getClass( Object container, String memberName ) throws 
ReflectionException;
+    
+    String getClassName( String objectname ) throws ReflectionException;
+    String getClassName( Object container, String memberName ) throws 
ReflectionException;
+    
+    boolean isSettable( String objectname ) throws ReflectionException;
+    boolean isSettable( Object container, String member) throws 
ReflectionException;
+    
+    String getContainer( String objectname ) throws ReflectionException;
+    String getMember( String objectname ) throws ReflectionException;
+
+    void addRootObject( String name, Object object ) throws 
ReflectionException;
+    void removeRootObject( String name ) throws ReflectionException;
+
+    void addReflectionListener( ReflectionListener listener );
+    void removeReflectionListener( ReflectionListener listener );
+}

Added: avalon/trunk/planet/facilities/reflector/build.properties
==============================================================================
--- (empty file)
+++ avalon/trunk/planet/facilities/reflector/build.properties   Sun Aug 15 
13:30:48 2004
@@ -0,0 +1,2 @@
+project.system = ../../../central/system
+project.home = ..

Added: avalon/trunk/planet/facilities/reflector/build.xml
==============================================================================
--- (empty file)
+++ avalon/trunk/planet/facilities/reflector/build.xml  Sun Aug 15 13:30:48 2004
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="reflector" default="default" basedir=".">
+
+  <property file="build.properties"/>
+  <import file="${project.system}/build/reactor.xml"/>
+
+</project>

Added: avalon/trunk/planet/facilities/reflector/impl/build.properties
==============================================================================
--- (empty file)
+++ avalon/trunk/planet/facilities/reflector/impl/build.properties      Sun Aug 
15 13:30:48 2004
@@ -0,0 +1,2 @@
+project.system = ../../../../central/system
+project.home = ../..

Added: avalon/trunk/planet/facilities/reflector/impl/build.xml
==============================================================================
--- (empty file)
+++ avalon/trunk/planet/facilities/reflector/impl/build.xml     Sun Aug 15 
13:30:48 2004
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="metro-reflector-impl" default="install" basedir="." 
+    xmlns:x="antlib:org.apache.avalon.tools">
+
+  <property file="build.properties"/>
+  <import file="${project.system}/build/standard.xml"/>
+
+  <target name="build" depends="standard.build">
+  
+    <x:block name="reflector">
+      <x:component name="impl" 
class="org.apache.metro.facilities.reflector.impl.ReflectorImpl" />
+      <x:component name="model-registrar" 
class="org.apache.metro.facilities.reflector.impl.ModelRegistrator" />
+      <x:component name="reflector-http-handler" 
class="org.apache.metro.facilities.reflector.impl.ReflectionHandler" >
+        <x:parameters>
+          <x:parameter name="handler-index" value="0" />
+          <x:parameter name="context-path" value="/inspect" />
+        </x:parameters>
+      </x:component>
+      <x:include name="http" 
artifact="block:avalon/http/avalon-http-static#SNAPSHOT" />
+      <x:include name="http-server" 
artifact="block:avalon/http/avalon-http-server#SNAPSHOT" />
+    </x:block>
+  </target>
+
+</project>

Added: 
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/ModelRegistrator.java
==============================================================================
--- (empty file)
+++ 
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/ModelRegistrator.java
     Sun Aug 15 13:30:48 2004
@@ -0,0 +1,80 @@
+/* 
+ * Copyright 2004 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.metro.facilities.reflector.impl;
+
+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.service.Serviceable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+
+import org.apache.avalon.composition.model.ContainmentModel;
+
+import org.apache.metro.facilities.reflector.ReflectorService;
+
+/** This component will lookup the composition model and register
+ *
+ * @avalon.component name="model-registrator" lifestyle="singleton"
+ *                   collection="weak"
+ */
+public class ModelRegistrator
+    implements Contextualizable, Serviceable, Initializable
+{
+    private ContainmentModel m_Model;
+    private ReflectorService m_Reflector;
+    
+    /**
+     * Contextulaization of the listener by the container during 
+     * which we are supplied with the root composition model for 
+     * the application.
+     *
+     * @param ctx the supplied listener context
+     *
+     * @exception ContextException if a contextualization error occurs
+     *
+     * @avalon.entry key="urn:composition:containment.model" 
+     *               
type="org.apache.avalon.composition.model.ContainmentModel" 
+     */
+    public void contextualize( Context ctx ) 
+        throws ContextException
+    {
+        m_Model = (ContainmentModel) ctx.get( 
"urn:composition:containment.model" );
+    }
+
+    /** The service method is called by the Avalon framework container.
+     * <p>It is imoprtant that this method is not called directly.</p>
+     *
+     * @avalon.dependency 
type="org.apache.metro.facilities.reflector.ReflectorService"
+     *                   key="reflector"
+     */
+    public void service( ServiceManager man )
+        throws ServiceException
+    {
+        m_Reflector = (ReflectorService) man.lookup( "reflector" );
+    }    
+    
+    public void initialize()
+        throws Exception
+    {
+        m_Reflector.addRootObject( "model", m_Model );
+    }
+}

Added: 
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/ReflectionHandler.java
==============================================================================
--- (empty file)
+++ 
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/ReflectionHandler.java
    Sun Aug 15 13:30:48 2004
@@ -0,0 +1,626 @@
+/* 
+ * Copyright 2004 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.metro.facilities.reflector.impl;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.OutputStreamWriter;
+
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.avalon.framework.activity.Startable;
+
+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.LogEnabled;
+import org.apache.avalon.framework.logger.Logger;
+
+import org.apache.avalon.framework.parameters.ParameterException;
+import org.apache.avalon.framework.parameters.Parameterizable;
+import org.apache.avalon.framework.parameters.Parameters;
+
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+
+import org.apache.avalon.http.HttpContextService;
+
+import org.apache.metro.facilities.reflector.ReflectionException;
+import org.apache.metro.facilities.reflector.ReflectorService;
+
+import org.mortbay.http.HttpContext;
+import org.mortbay.http.HttpHandler;
+import org.mortbay.http.HttpRequest;
+import org.mortbay.http.HttpResponse;
+
+/**
+ * @avalon.component name="reflector-http-handler" lifestyle="singleton"
+ * @avalon.service   type="org.mortbay.http.HttpHandler"
+ */
+public class ReflectionHandler 
+    implements Startable, Parameterizable, LogEnabled, 
+               Serviceable, Contextualizable, HttpHandler
+{
+    private String              m_Name;
+    private Logger              m_Logger;
+    private HttpContextService  m_ContextService;
+    private HttpContext         m_Context;
+    private int                 m_Index;
+    private boolean             m_Started;
+    
+    private ReflectorService    m_Reflector;
+    private String              m_ContextPath;
+    private String              m_Encoding;
+    
+    private Vector    m_Reserved;
+        
+    public ReflectionHandler()
+    {
+        m_Started = false;
+        m_Reserved = new Vector();
+        m_Reserved.addElement("debug");
+        m_Reserved.addElement("app");
+        m_Reserved.addElement("");
+    }
+    
+    /**
+     * Enable the logging system.
+     *
+     * @avalon.logger name="http"
+     */
+    public void enableLogging( Logger logger )
+    {
+        m_Logger = logger;
+    }
+    
+    public Logger getLogger() 
+    {
+        return m_Logger;
+    }
+    
+    /**
+     * Contextulaization of the Handler.
+     *
+     * @param ctx the supplied listener context
+     *
+     * @exception ContextException if a contextualization error occurs
+     *
+     * @avalon.entry key="urn:avalon:name" 
+     *               type="java.lang.String" 
+     */
+    public void contextualize( Context ctx ) 
+        throws ContextException
+    {
+        m_Name = (String) ctx.get( "urn:avalon:name" );
+    }
+
+    public void parameterize( Parameters params )
+        throws ParameterException
+    {
+        m_Index = params.getParameterAsInteger( "handler-index", -1 );
+        m_ContextPath = params.getParameter( "context-path" );
+        m_Encoding = params.getParameter( "encoding", "ISO-8859-1" );
+    }
+
+    /**  
+     * @avalon.dependency type="org.apache.avalon.http.HttpContextService"
+     *                    key="http-context" 
+     * @avalon.dependency 
type="org.apache.metro.facilities.reflector.ReflectorService"
+     *                    key="reflector" 
+     */
+    public void service( ServiceManager man )
+        throws ServiceException
+    {
+        m_ContextService = (HttpContextService) man.lookup( "http-context" );
+        m_Reflector = (ReflectorService) man.lookup( "reflector" );
+    }
+ 
+    public void initialize( HttpContext context )
+    {
+        if( m_Logger.isDebugEnabled() )
+            m_Logger.debug( "Initializing ReflectorHandler: " + context );
+        m_Context = context;
+    }
+    
+    public String getName()
+    {
+        return m_Name;
+    }
+    
+    public void setName( String name )
+    {
+        m_Name = name;
+    }
+    
+    public HttpContext getHttpContext()
+    {
+        return m_Context;
+    }
+    
+    public void start()
+        throws Exception
+    {
+        m_Started = true;
+        if( m_Index >= 0 )
+            m_ContextService.addHandler( m_Index, this );
+        else
+            m_ContextService.addHandler( this );
+        if( m_Logger.isDebugEnabled() )
+            m_Logger.debug( "Starting ReflectorHandler: " + this );
+    }
+    
+    public boolean isStarted()
+    {
+        return m_Started;
+    }
+    
+    public void stop()
+        throws InterruptedException
+    {
+        m_Started = false;
+        if( m_Logger.isDebugEnabled() )
+            m_Logger.debug( "Stopping ReflectorHandler: " + this );
+        m_ContextService.removeHandler( this );
+    }
+    
+    public void handle( String pathInContext, String pathParams, 
+                        HttpRequest request, HttpResponse response ) 
+        throws IOException
+    {
+        m_Logger.info( "Request: " + pathInContext );
+        if( ! pathInContext.startsWith( m_ContextPath ) )
+            return;
+        pathInContext = pathInContext.substring( m_ContextPath.length() );
+        
+        response.setContentType("text/html");
+        RequestContext ctx = new RequestContext( pathInContext, request, 
response, m_Encoding );
+        try
+        {        
+            String method = request.getMethod();
+            if( method.equals( "GET" ) )
+                doGet( ctx );
+            if( method.equals( "POST" ) )
+                doPost( ctx );
+        } catch( Exception e )
+        {
+            ctx.out.println( "<html><body><h1>Exception occurred in 
service.</h1><hr><pre>" );
+            e.printStackTrace( ctx.out );
+            ctx.out.println( "</pre></body></html>" );
+        } finally
+        {
+            ctx.dispose();
+        }
+    }
+
+    private void doGet( RequestContext ctx )
+        throws IOException, ReflectionException
+    {
+        if( m_Logger.isDebugEnabled() )
+        {
+            String s1 = "Reflector get:[" + ctx.req.getRemoteAddr() + ":" + 
ctx.req.getUserPrincipal() + "] --> " + ctx.req.getRequestURL() + "?" + 
ctx.req.getQuery();
+            m_Logger.debug(s1);
+        }
+
+        ctx.out.println( "<html>" );
+        formatGet( ctx );
+        formatDebug(ctx);
+        ctx.out.println( "</body></html>" );
+    }
+
+    private void doPost( RequestContext ctx )
+        throws IOException
+    {
+        if( m_Logger.isDebugEnabled() )
+        {
+            String s1 = "Reflector set:[" + ctx.req.getRemoteAddr() + ":" + 
ctx.req.getUserPrincipal() + "] --> " + ctx.req.getRequestURL() + "?" + 
ctx.req.getQuery();
+            m_Logger.debug( s1 );
+        }
+            
+        ctx.out.println( "<html><head>" );
+        ctx.out.println( "</head><body>" );
+        ctx.out.println( "<h3>Changes made:</h3><hr>" );
+        ctx.out.println( "<table border=1 cellspacing=0 cellpadding=2 
width=\"100%\">" );
+        ctx.out.println( "<tr><td><b><u>Member</b></u></td><td><b><u>Changed 
to</b></u></td></tr>" );
+
+        Iterator names = ctx.req.getParameterNames().iterator();
+        while( names.hasNext() )
+        {
+            String name = (String) names.next();
+            if( ! isReserved(name) ) 
+            {
+                List values = ctx.req.getParameterValues( name );
+                for( int i=0 ; i < values.size() ; i++ )
+                {
+                    String value = (String) values.get(i);
+                    if( value != null )
+                    {
+                        if( ! value.equals("") )try
+                        {
+                            ctx.out.print( "<tr><td>" );
+                            ctx.out.print( name );
+                            ctx.out.print( "</td><td>" );
+                            m_Reflector.set( name, value );
+                            ctx.out.print( value );
+                        } catch( Exception e )
+                        {
+                            e.printStackTrace( ctx.out );
+                        }
+                        ctx.out.print( "</td></tr>" );
+                    }
+                }
+            }
+        }
+        ctx.out.println( "</table>" );
+        if( ctx.debug )
+            ctx.out.println("<hr>Execution Time:" + 
(System.currentTimeMillis()-ctx.start) + " ms" );
+        ctx.out.println( "</body></html>" );
+    }
+    
+    private void formatGet( RequestContext ctx )
+        throws IOException, ReflectionException
+    {
+        // then get the writer and write the response data
+        String title = null;
+        if( ctx.objectname == null || ctx.objectname.equals("") )
+            title = "Application Root Names";
+        else
+            title = ctx.objectname;
+        PrintWriter out = ctx.out;
+
+        out.println( "<head><title>" );
+        out.println( title );
+        out.println( "</title></head><body>" );
+        out.println( "<h1>" );
+        out.println( title );
+        out.println( "</h1>" );
+        if( ctx.objectname == null || ctx.objectname.equals("") )
+            out.println( "<hr>" );
+        else
+        {
+            String container = m_Reflector.getContainer( ctx.objectname );
+            String member = m_Reflector.getMember( ctx.objectname );
+            if( container == null || "".equals(container) )
+            {
+                out.print( "<A href=" );
+                out.print( "\"/bali/debug/" );
+                out.print( "\">Application Root</A><hr>" );
+            }
+            else
+            {
+                out.print( "<A href=" );
+                formatURL( ctx, container );
+                out.println( "\">" );
+                out.println( container );
+                out.println( "</A><hr>" );
+            }
+        }
+        out.print( "<FORM Method=\"POST\" Action=\"modify" );
+        if( ctx.debug )
+            out.print( "?debug=true" );
+        out.print( "\">" );
+        boolean error = false;
+        if( ctx.objectname != null )
+        {
+            if( ! ctx.objectname.equals("") )
+            {
+                Class cls = m_Reflector.getClass(ctx.objectname);
+                if( cls == null )
+                {
+                    formatNotFound(ctx);
+                    error = true;
+                }
+                else if( cls.isArray() ||
+                    Collection.class.isAssignableFrom(cls) ||
+                    Map.class.isAssignableFrom(cls) ||
+                    Dictionary.class.isAssignableFrom(cls)
+                  )
+                    formatArray( ctx );
+                else
+                    formatObject(ctx);
+            }
+            else
+                formatObject(ctx);
+        }
+        else
+            formatObject(ctx);
+        if( ! error )
+            formatButton( ctx );
+        out.println( "</FORM>" );
+    }
+
+    private void formatNotFound( RequestContext ctx )
+    {
+        ctx.out.println( "<h2>Object not found.</h2>" );
+    }
+    
+    private void formatObject( RequestContext ctx)
+        throws ReflectionException
+    {
+        String[] names = m_Reflector.getNames( ctx.objectname );
+        formatTableHeader(ctx);
+        for( int i=0; i<names.length ; i++ )
+        {
+            ctx.out.print( "<tr>" );
+              formatMember( ctx, names[i] );
+            ctx.out.println( "</tr>" );
+        }
+        ctx.out.println( "</table>" ) ;
+    }
+
+    private void formatMember( RequestContext ctx, String member)
+    {
+        int columncount = 0;
+        long then = System.currentTimeMillis();
+        ctx.out.print( "<td><A href=" );
+        columncount++;
+        String str = "";
+        if( ctx.objectname != null && ! "".equals(ctx.objectname) )
+            str = ctx.objectname + ".";
+        str = str + member;
+        formatURL(ctx, str );
+        ctx.out.print ( ">" );
+        ctx.out.print( member );
+        ctx.out.print( "</A></td><td>" );
+        columncount++;
+        try
+        {
+            String value;
+            String membername;
+            if( ctx.objectname == null || "".equals(ctx.objectname) )
+                membername = member;
+            else
+                membername = ctx.objectname + "." + member;
+
+            String obj = m_Reflector.get( membername );
+            if( obj == null )
+                value = "&lt;null&gt;";
+            else
+                value = obj;
+            ctx.out.print( value );
+            
+            if( m_Reflector.isSettable(membername) )
+            {
+                ctx.out.print( "</td><td><INPUT Name=\"" );
+                ctx.out.print( str );
+                ctx.out.print( "\" TYPE=\"TEXT\" SIZE=\"15\" MAXLENGTH=\"300\" 
>" );
+            }
+            else
+            {
+                ctx.out.print( "</td><td><br>" );
+            }
+            columncount++;
+            ctx.out.print( "</td><td>" );
+            columncount++;
+            String name = m_Reflector.getClassName( membername );
+            if( name == null )
+                ctx.out.print( "" );
+            else
+                ctx.out.print( name );
+        }
+        catch( Exception e )
+        {
+            m_Logger.error( e.toString() );
+            ctx.out.print( "<pre>" );
+            ctx.out.print( e.toString() );
+            e.printStackTrace( ctx.out );
+            ctx.out.print( "</pre>" );
+            for( ; columncount < 4 ; columncount++ )
+                ctx.out.print( "</td><td><br>" );
+        }
+        ctx.out.print( "</td>" );
+        long now = System.currentTimeMillis();
+        if( ctx.debug )
+            ctx.out.print( "<td>" + (now-then) + " ms</td>" );
+    }
+    
+    private void formatArrayMember( RequestContext ctx, String membername)
+    {
+        long then = System.currentTimeMillis();
+        int columncount = 0;        
+        
+        ctx.out.print( "<td><A href=" );
+        columncount++;
+        formatURL( ctx, ctx.objectname + membername );
+        ctx.out.print ( ">" );
+        ctx.out.print( membername );
+        ctx.out.print( "</A></td><td>" );
+        columncount++;
+        try
+        {
+            String value = m_Reflector.get(ctx.objectname + membername);
+            Class cls = m_Reflector.getClass(ctx.objectname + membername);
+            ctx.out.print( value );
+            
+            if( m_Reflector.isSettable(ctx.objectname + membername) )
+            {
+                ctx.out.print( "</td><td><INPUT Name=\"" );
+                ctx.out.print( ctx.objectname + membername );
+                ctx.out.print( "\" TYPE=\"TEXT\" SIZE=\"10\" MAXLENGTH=\"30\" 
>" );
+            }
+            else
+            {
+                ctx.out.print( "</td><td><br>" );
+            }
+            columncount++;
+            ctx.out.print( "</td><td>" );
+            columncount++;
+            if( cls == null )
+                ctx.out.print( "&lt;unknown&gt;" );
+            else
+                ctx.out.print( cls.getName() );
+        }
+        catch( Exception e )
+        {
+            m_Logger.error( e.getMessage(), e );
+            ctx.out.print( "<pre>" );
+            ctx.out.print( e.toString() );
+            e.printStackTrace( ctx.out );
+            ctx.out.print( "</pre>" );
+            for( ; columncount < 4 ; columncount++ )
+                ctx.out.print( "</td><td>" );
+        }
+        ctx.out.println( "</td>" );
+        
+        long now = System.currentTimeMillis();
+        if( ctx.debug )
+            ctx.out.print( "<td>" + (now-then) + " ms</td>" );
+    }
+
+    private void formatMapMember( RequestContext ctx, Object key, Object value)
+    {
+        long then = System.currentTimeMillis();
+        int columncount = 0;
+        
+        ctx.out.print( "<td><A href=" );
+        columncount++;
+        formatURL( ctx, ctx.objectname + "['" + key + "']" );
+        ctx.out.print ( ">" );
+        ctx.out.print( "[\"" + key + "\"]" );
+        ctx.out.print( "</A></td><td>" );
+        columncount++;
+        try
+        {
+            ctx.out.print( value );
+            Class cls = key.getClass();
+            ctx.out.print( "</td><td>" );
+            if( isPrimitive( cls ) )
+            {
+                ctx.out.print( "<INPUT Name=\"" );
+                ctx.out.print( ctx.objectname + "[\"" + key + "\"]" );
+                ctx.out.print( "\" TYPE=\"TEXT\" SIZE=\"10\" MAXLENGTH=\"30\" 
>" );
+            }
+            columncount++;
+            ctx.out.print( "</td><td>" );
+            columncount++;
+            ctx.out.print( cls.getName() );
+        }
+        catch( Exception e )
+        {
+            m_Logger.error( e.getMessage(), e );
+            ctx.out.print( "<pre>" );
+            ctx.out.print( e.toString() );
+            e.printStackTrace( ctx.out );
+            ctx.out.print( "</pre>" );
+            for( ; columncount < 4 ; columncount++ )
+                ctx.out.print( "</td><td>" );
+        }
+        ctx.out.println( "</td>" );
+        
+        long now = System.currentTimeMillis();
+        if( ctx.debug )
+            ctx.out.print( "<td>" + (now-then) + " ms</td>" );
+    }
+
+    private void formatArray( RequestContext ctx )
+        throws ReflectionException
+    {
+        formatTableHeader(ctx);
+        String[] names = m_Reflector.getNames(ctx.objectname);
+        for( int i=0; i < names.length ; i++ )
+        {
+            ctx.out.print( "<tr>" );   
+            formatArrayMember( ctx, "[\'" + names[i] + "\']" );
+            ctx.out.println( "</tr>" );
+        }
+        ctx.out.println( "</table>" ) ;
+    }
+    
+    private void formatButton( RequestContext ctx )
+    {
+        ctx.out.print( "<p><center><INPUT TYPE=\"SUBMIT\" 
VALUE=\"Change\"></center></p>" );
+    }
+    
+    private void formatDebug( RequestContext ctx )
+    {
+        if( ctx.debug )
+        {
+            long i = System.currentTimeMillis() - ctx.start;
+            ctx.out.println( "<hr>Execution time:" + i + " ms" );
+        }
+    }
+    
+    private boolean isPrimitive( Class cls )
+    {
+        if( cls.isPrimitive() )
+            return true;
+        
+        if( cls.equals( Boolean.class ) )
+            return true;
+        if( cls.equals( Number.class ) )
+            return true;
+        else if( cls.equals(Character.class) )
+            return true;
+        else if( cls.equals(Void.class) )
+            return true;
+        else if( cls.equals(String.class) )
+            return true;
+        else
+            return false;
+    }
+
+    private void formatURL( RequestContext ctx, String objectname )
+    {
+        ctx.out.print( "\"" );
+        ctx.out.print( encode( objectname ) );
+        if( ctx.debug )
+            ctx.out.print( "?debug=true" );
+        ctx.out.print( "\"" );
+    }
+
+    private String encode( String text )
+    {
+        StringBuffer buf = new StringBuffer();
+        
+        for( int i=0 ; i < text.length() ; i++ )
+        {
+            
+            char ch = text.charAt(i);
+            if( (ch >= 'A' && ch <= 'z') || (ch >= '(' && ch <= '9') &&
+                ( ch != '/' )
+              )
+            {
+                buf.append( ch );
+            }
+            else
+            {
+                buf.append( '{' );
+                buf.append( "" + ((int) ch) );
+                buf.append( '}' );
+            }
+        }
+        return buf.toString();
+    }
+    
+    private void formatTableHeader( RequestContext ctx )
+    {
+        ctx.out.println( "<table border=1 cellspacing=0 cellpadding=2 
width=\"100%\">" );
+        ctx.out.println( 
"<tr><td><b><u>Member</b></u></td><td><b><u>Value</b></u></td><td><b><u>Change</b></u></td><td><b><u>Class/Type</b></u></td></tr>"
 );
+    }
+    
+    private boolean isReserved( String text )
+    {
+        return m_Reserved.contains(text);
+    }
+} 

Added: 
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/ReflectorImpl.java
==============================================================================
--- (empty file)
+++ 
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/ReflectorImpl.java
        Sun Aug 15 13:30:48 2004
@@ -0,0 +1,1159 @@
+/*
+ * 1.0    1999/07/30 Niclas Hedhman     First Public Release
+ *
+ * Copyright (c) 1996-1999 Bali Automation. All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies. Please refer to the file "copyright.html"
+ * for further important copyright and licensing information.
+ *
+ * BALI AUTOMATION MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE 
+ * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING 
+ * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. BALI AUTOMATION
+ * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A 
+ * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 
+ * DERIVATIVES.
+ */
+package org.apache.metro.facilities.reflector.impl;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import java.util.Map;
+import java.util.List;
+import java.util.Vector;
+import java.util.Iterator;
+import java.util.Hashtable;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Properties;
+import java.util.Enumeration;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.apache.avalon.framework.activity.Disposable;
+
+import org.apache.metro.facilities.reflector.ReflectorService;
+import org.apache.metro.facilities.reflector.ReflectionListener;
+import org.apache.metro.facilities.reflector.ReflectionEvent;
+import org.apache.metro.facilities.reflector.ReflectionException;
+
+/** The Reflector Implementation is capable of digging through any
+*   Java application that is added as a root object.
+*
+* @avalon.component name="reflector" lifestyle="singleton"
+* @avalon.service type="org.apache.metro.facilities.reflector.ReflectorService"
+*/
+public final class ReflectorImpl
+    implements ReflectorService, Disposable
+{
+    private Map        m_Properties;
+    private Vector     m_Listeners;
+    private Hashtable  m_RootObjects;
+    
+    public ReflectorImpl()
+    {
+        super();
+        m_RootObjects = new Hashtable();
+    }
+
+    public void addRootObject( String name, Object obj )
+    {
+        m_RootObjects.put( name, obj );
+        ReflectionEvent event = 
+            new ReflectionEvent(this, name, obj, "addRootObject" );
+        fireEvent(event);
+    }
+
+    public void removeRootObject( String name )
+    {
+        m_RootObjects.remove(name);
+        ReflectionEvent event = 
+            new ReflectionEvent(this, name, null, "removeRootObject" );
+        fireEvent(event);
+    }
+
+    public Object getRootObject( String name )
+    {
+        Object result = m_RootObjects.get(name);
+        ReflectionEvent event = 
+            new ReflectionEvent(this, name, result, "getRootObject" );
+        fireEvent(event);
+        return result;
+    }
+
+    public Map getRootObjects()
+    {
+        return m_RootObjects;
+    }
+    
+    public String[] getAllRootNames() 
+    {
+        synchronized( m_RootObjects )
+        {
+            Enumeration list = m_RootObjects.keys();
+            String[] names = new String[m_RootObjects.size()];
+            
+            for( int i=0; list.hasMoreElements() ; i++ )
+                names[i] = (String) list.nextElement();
+            
+            ReflectionEvent event = 
+                new ReflectionEvent(this, null, names, "getAllRootNames" );
+            fireEvent(event);
+            return names;
+        }
+    }
+
+    public String[] getNames( String object) 
+        throws ReflectionException
+    {
+        Object container;
+        
+        try
+        {
+            if( object == null )
+                return getAllRootNames();
+            if( object.equals("") )
+                return getAllRootNames();
+            container = resolveObject(object);
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Exception in Server.", e );
+        }
+        String[] result = getNames( container );
+        ReflectionEvent event = 
+            new ReflectionEvent(this, object, result, "getNames" );
+        fireEvent(event);
+        return result;
+    }
+    
+    public String[] getNames( Object container) 
+        throws ReflectionException
+    {
+        Vector names = new Vector();
+        
+        try
+        {
+            if( container == null )
+                return getAllRootNames();
+            
+            if( container instanceof Collection )
+                return getCollectionNames((Collection) container);
+            else if( container instanceof Map )
+                return getMapNames( (Map) container);
+            else if( container instanceof Dictionary )
+                return getDictionaryNames( (Dictionary) container);
+            else if( container.getClass().isArray() )
+                return getArrayNames( (Object[]) container);
+            else
+            {
+                /////  NORMAL OBJECT
+                // Retrieve all PUBLIC, non-STATIC fields.
+                Field[] flds = container.getClass().getDeclaredFields();
+                for( int i=0 ; i < flds.length ; i++ )
+                {
+                    int mod = flds[i].getModifiers();
+                    if( Modifier.isPublic( mod ) && !Modifier.isStatic( mod ) )
+                    {
+                        String str = flds[i].getName();
+                        int j = str.indexOf( '_' );
+                        if( j == 1 )
+                            str = str.substring( 2 );
+                        names.addElement( str);
+                    }
+                }
+                // Retrieve PUBLIC non-STATIC GET methods
+                Method[] methods = container.getClass().getMethods();
+                for( int i=0 ; i < methods.length ; i++ )
+                {
+                    int mod = methods[i].getModifiers();
+                    if( Modifier.isPublic( mod ) && ! Modifier.isStatic( mod ))
+                    {
+                        String str = methods[i].getName();
+                        if( str.startsWith("get") )
+                        {
+                            if( methods[i].getParameterTypes().length == 0 )
+                            {
+                                str = str.substring( 3 );
+                                if( ! names.contains(str) )
+                                    names.addElement( str );
+                            }
+                        }
+                        else if( str.startsWith("is") )
+                        {
+                            if( methods[i].getParameterTypes().length == 0 )
+                            {
+                                str = str.substring( 2 );
+                                if( ! names.contains(str) )
+                                    names.addElement( str );
+                            }
+                        }
+                    }
+                }
+            }
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Exception in Server.", e );
+        }
+        String[] ret = new String[names.size()];
+        for( int i= 0; i < names.size() ; i++ )
+            ret[i] = (String) names.elementAt(i);
+        return ret;
+    }
+
+    public String get( String object )
+        throws ReflectionException
+    {
+        String str = null;
+        try
+        {
+            Object obj = resolveObject( object );
+            str = "" + obj;
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Exception in 
ReflectorServer.", e );
+        }
+        ReflectionEvent event = 
+            new ReflectionEvent(this, object, str, "get" );
+        fireEvent(event);
+        return str;
+    }
+
+    public void set( String object, String value )
+        throws ReflectionException
+    {
+        String str = null;
+
+        try
+        {
+            String container = dropLast( object );
+            String member = getLast(object);
+            Object obj = resolveObject( container );
+            setObject( obj, member, value ); //calls private setObject( 
Object, String, String)
+            ReflectionEvent event = 
+                new ReflectionEvent(this, object, value, "set" );
+            fireEvent(event);
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Exception in 
ReflectorServer.", e );
+        }
+    }
+    
+    public Object getObject( String object )
+        throws ReflectionException
+    {
+        Object obj = null;
+        try
+        {
+            obj = resolveObject( object );
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Exception in Server.", e );
+        }
+        ReflectionEvent event = 
+            new ReflectionEvent(this, object, obj, "getObject" );
+        fireEvent(event);
+        return obj;
+    }
+    
+    public Object getObject( Object container, String memberName )
+        throws ReflectionException
+    {
+        try
+        {
+            if( container == null || container.equals("") )
+            {
+                Object root = m_RootObjects.get(memberName);
+                return root;
+            }
+            if( container.getClass().isPrimitive() )
+                return null;
+            if( memberName.startsWith("[") )
+            {
+                return getCollection(container, memberName);
+            }
+            else
+            {
+                Method method = findMethod( container, "get" + memberName );
+                if( method == null )
+                    method = findMethod( container, "is" + memberName );
+                
+                Object obj = null;
+                
+                if( method != null )
+                {
+                    try
+                    {
+                        obj = method.invoke(container, new Object[0] );
+                    } catch( IllegalAccessException e )
+                    {
+                        throw new ReflectionException( 
container.getClass().toString() + ".get" + memberName + "() is not declared 
public.", e );
+                    } catch( IllegalArgumentException e )
+                    {
+                        throw new 
ReflectionException(container.getClass().toString() + ".get" + memberName + "() 
received illegal arguments. Internal Error?", e);
+                    } catch( InvocationTargetException e )
+                    {
+                        Exception exc;
+                        Throwable t = e.getTargetException();
+                        if( t instanceof Exception )
+                            exc = (Exception) t;
+                        else
+                            exc = null;
+                        throw new ReflectionException( 
container.getClass().toString() + ".get" + memberName + "() resulted in an 
exception.\n" + e , exc );
+                    }
+                    ReflectionEvent event = 
+                        new ReflectionEvent(this, container, obj, "getObject[" 
+ memberName + "]" );
+                    fireEvent(event);
+                    return obj;
+                }
+                if( method == null )
+                {
+                    Field fld=findField( container, memberName );
+                    obj = fld.get( container );
+                    ReflectionEvent event = 
+                        new ReflectionEvent(this, container, obj, "getObject[" 
+ memberName + "]" );
+                    fireEvent(event);
+                    return obj;
+                }
+            }
+            return null;
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Container="+container + ", 
member=" + memberName, e );
+        }
+    }
+
+    public void setObject( String objectname, Object object )
+        throws ReflectionException
+    {
+        String str = null;
+
+        try
+        {
+            String containerName = dropLast( objectname );
+            String member = getLast(objectname);
+            Object container = resolveObject( containerName );
+            setObject( container, member, object );
+            
+            ReflectionEvent event = 
+                new ReflectionEvent(this, objectname, object, "setObject" );
+            fireEvent(event);
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Exception in Server.", e );
+        }
+    }
+
+    public void setObject( Object container, String member, Object value )
+        throws ReflectionException
+    {
+        try
+        {
+            Object obj = null;
+            Class cls = container.getClass();
+            Field[] flds = cls.getDeclaredFields();
+            
+            if( member.startsWith("[") )
+            {
+                setCollection(container, member, value);
+            }
+            else
+            {
+                Method method = findMethod( container, "set" + member );
+                if( method != null )
+                {
+                    try
+                    {
+                        Class[] argTypes = method.getParameterTypes();
+                        Object[] args = new Object[1];
+                        args[0] = value;
+                        obj = method.invoke(container, args );
+                        ReflectionEvent event = 
+                            new ReflectionEvent(this, container, obj, 
"setObject[" + member + "]" );
+                        fireEvent(event);
+                    } catch( IllegalAccessException e )
+                    {
+                        throw new ReflectionException( 
container.getClass().toString() + ".set" + member + "() is not declared 
public.", e);
+                    } catch( IllegalArgumentException e )
+                    {
+                        throw new ReflectionException( 
container.getClass().toString() + ".set" + member + "() .", e);
+                    }
+                }
+                if( method == null )
+                {
+                    for( int i=0; i < flds.length ; i++ )
+                    {
+                        if( matchField( flds[i].getName(), member ) )
+                        {
+                            setObject( flds[i], container, value );
+                            ReflectionEvent event = 
+                                new ReflectionEvent(this, container, obj, 
"setObject[" + member + "]" );
+                            fireEvent(event);
+                        }
+                    }
+                }
+            }
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Container=:" + container + ", 
Member=" + member + ", Object=" + value, e );
+        }
+    }
+
+    public String getContainer( String objectname )
+    {
+        String result = dropLast(objectname);
+        ReflectionEvent event = 
+            new ReflectionEvent(this, objectname, result, "getContainer" );
+        fireEvent(event);
+        return result;
+    }
+    
+    public String getMember( String objectname )
+    {
+        String result = getLast(objectname);
+        ReflectionEvent event = 
+            new ReflectionEvent(this, objectname, result, "getMember" );
+        fireEvent(event);
+        return result;
+    }
+    
+    private Object resolveObject( String name )
+        throws ReflectionException
+    {
+        Object obj = null;
+
+        if( "".equals(name) || name == null)
+            return null;
+        String container = dropLast(name);
+        String member = getLast(name);
+        obj = resolveObject( container );
+        obj = getObject( obj, member );
+        return obj;
+    }
+
+    private String dropLast( String name )
+    {
+        int pos1 = name.lastIndexOf( '[' );
+        int pos2 = name.lastIndexOf( '.' );
+        int pos3 = name.lastIndexOf( ']' );
+        if( pos1 == -1 && pos2 == -1 )
+            return "";
+        String result = name.substring( 0, pos3 > pos2 ? pos1 : pos2 );
+        return result;
+    }
+
+    private String getLast( String name )
+    {
+        int pos1 = name.lastIndexOf( '[' );
+        int pos2 = name.lastIndexOf( '.' );
+        int pos3 = name.lastIndexOf( ']' );
+        if( pos1 == -1 && pos2 == -1 )
+            return name;
+        String result = name.substring( pos3 > pos2 ? pos1 : pos2+1 );
+        return result;
+    }
+
+    public String getClassName( String name )
+        throws ReflectionException
+    {
+        return getClass(name).getName();
+    }
+    
+    public String getClassName( Object container, String memberName )
+        throws ReflectionException
+    {
+        return getClass(container, memberName).getName();
+    }
+    
+    public Class getClass( String name )
+        throws ReflectionException
+    {
+        if( "".equals(name) || name == null)
+            return null;
+        String container = dropLast(name);
+        String member = getLast(name);
+        Object obj = resolveObject( container );
+        return getClass( obj, member );
+    }
+    
+    public Class getClass( Object container, String memberName )
+        throws ReflectionException
+    {
+        try
+        {
+            if( container == null || container.equals("") )
+            {
+                Object root = m_RootObjects.get(memberName);
+                return root.getClass();
+            }
+            if( isPrimitive(container) )
+                return null;
+            
+            if( memberName.startsWith("[") )
+            {
+                return getClassInCollection(container, memberName);
+            }
+            else
+            {
+                Method method = findMethod( container, "get" + memberName );
+                if( method == null )
+                    method = findMethod( container, "is" + memberName );
+
+                if( method != null )
+                {
+                    Class retClass = method.getReturnType();
+                    if( Modifier.isNative(retClass.getModifiers()) )
+                        return retClass;
+
+                    // Native classes are not properly serialized/deserialized 
over RMI.
+
+                    return expandNativeClass( retClass );
+                }
+                
+                Field fld=findField( container, memberName );
+                return fld.getType();
+            }
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Container="+container + ", 
member=" + memberName, e );
+        }
+    }
+
+    public boolean isSettable( String name )
+        throws ReflectionException
+    {
+        if( "".equals(name) || name == null)
+            return false;
+        String container = dropLast(name);
+        String member = getLast(name);
+        Object obj = resolveObject( container );
+        return isSettable( obj, member );
+    }
+
+    public boolean isSettable( Object container, String memberName)
+        throws ReflectionException
+    {
+        try
+        {
+            if( container == null || "".equals(container) )
+                return false;
+            if( isPrimitive(container) )
+                return false;
+            
+            Method method = findMethod( container, "set" + memberName );
+            
+            if( method != null )
+                return true;
+            else
+                return false;
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Container="+container + ", 
member=" + memberName, e );
+        }
+    }
+
+    private void setPrimitive( Field fld, Object obj, String value )
+        throws IllegalAccessException, ClassNotFoundException
+    {
+        Class fldClass = fld.getType();
+        if( fldClass == Boolean.TYPE )
+        {
+            fld.setBoolean(obj, (new Boolean(value)).booleanValue());
+        }
+        else if( fldClass == Double.TYPE )
+        {
+            fld.setDouble(obj, (new Double(value)).doubleValue());
+        }
+        else if( fldClass == Integer.TYPE )
+        {
+            fld.setInt(obj, (new Integer(value)).intValue());
+        }
+        else if( fldClass == Short.TYPE )
+        {
+            fld.setShort(obj, (new Short(value)).shortValue());
+        }
+        else if( fldClass == Byte.TYPE )
+        {
+            fld.setByte(obj, (new Byte(value)).byteValue());
+        }
+        else if( fldClass == Float.TYPE )
+        {
+            fld.setFloat(obj, (new Float(value)).floatValue());
+        }
+        else if( fldClass == Long.TYPE )
+        {
+            fld.setLong(obj, (new Long(value)).longValue());
+        }
+        else if( fldClass == Character.TYPE )
+        {
+            fld.setChar(obj, value.charAt(0) );
+        }
+        else if( fldClass == Void.TYPE )
+        {
+            throw new IllegalAccessException( " Can not set void primitives." 
);
+        }
+        else 
+            throw new ClassNotFoundException( "Invalid primitive 
Class.Type()." );
+    }
+
+    private Object convPrimitive( Class type, String value )
+        throws IllegalAccessException, ClassNotFoundException, 
+               InstantiationException, NoSuchMethodException, 
InvocationTargetException
+    {
+        Object ret ;
+        if( type.isPrimitive() )
+        {
+            if( type.equals(Boolean.TYPE) )
+                ret = new Boolean( value );
+            else if( type.equals(Double.TYPE) )
+                ret = new Double( value );
+            else if( type.equals(Integer.TYPE) )
+                ret = new Integer( value );
+            else if( type.equals(Short.TYPE) )
+                ret = new Short( value );
+            else if( type.equals(Byte.TYPE) )
+                ret = new Byte( value );
+            else if( type.equals(Float.TYPE) )
+                ret = new Float( value );
+            else if( type.equals(Long.TYPE ) )
+                ret = new Long( value );
+            else if( type.equals(Character.TYPE) )
+                ret = new Character( value.charAt(0) );
+            else if( type.equals( String.class ) )
+                ret = value;
+            else if( type == Void.TYPE )
+                throw new IllegalAccessException( " Can not set void 
primitives." );
+            else
+                throw new IllegalAccessException( " Unknown primitive type." );
+        }
+        else
+        {
+            if( Boolean.class.isAssignableFrom(type) )
+                ret = new Boolean( value );
+            else if( Double.class.isAssignableFrom(type))
+                ret = new Double( value );
+            else if( Integer.class.isAssignableFrom(type))
+                ret = new Integer( value );
+            else if( Short.class.isAssignableFrom(type))
+                ret = new Short( value );
+            else if( Byte.class.isAssignableFrom(type))
+                ret = new Byte( value );
+            else if( Float.class.isAssignableFrom(type))
+                ret = new Float( value );
+            else if( Long.class.isAssignableFrom(type))
+                ret = new Long( value );
+            else if( Character.class.isAssignableFrom(type))
+                ret = new Character( value.charAt(0) );
+            else if( type.equals( String.class ) )
+                ret = value;
+            else if( Void.class.isAssignableFrom(type) )
+                throw new IllegalAccessException( " Can not set void 
primitives." );
+            else if( Number.class.isAssignableFrom(type))
+            {
+                ret = new Double( value );
+            }
+            else
+            {
+                // Class name is assumed in value...
+                // create a new instance of this class and return as the 
+                // value to assign
+                ret = Class.forName(value).newInstance();
+            }
+        }
+        return ret;
+    }
+    
+    private Class expandNativeClass( Class nativeClass )
+    {
+        Class ret = nativeClass;
+        
+        if( nativeClass.equals(Boolean.TYPE) )
+        {
+            ret = Boolean.class;
+        }
+        else if( nativeClass.equals(Double.TYPE) )
+        {
+            ret = Double.class;
+        }
+        else if( nativeClass.equals(Integer.TYPE) )
+        {
+            ret = Integer.class;
+        }
+        else if( nativeClass.equals(Short.TYPE) )
+        {
+            ret = Short.class;
+        }
+        else if( nativeClass.equals(Byte.TYPE) )
+        {
+            ret = Byte.class;
+        }
+        else if( nativeClass.equals(Float.TYPE) )
+        {
+            ret = Float.class;
+        }
+        else if( nativeClass.equals(Long.TYPE ) )
+        {
+            ret = Long.class;
+        }
+        else if( nativeClass.equals(Character.TYPE) )
+        {
+            ret = Character.class;
+        }
+        return ret;
+    }
+    
+    private Object getCollection( Object container, String memberName )
+    {
+        Object obj = null;
+     
+        String index = memberName.substring( 1, memberName.length()-1);
+        int numindex = 0;
+        try
+        {   
+            if( index.startsWith( "\'" ) )
+                index = index.substring( 1, index.length() - 1);
+            numindex = Integer.parseInt( index );
+        } catch( NumberFormatException e ) {}  // Ignore
+        
+        if( container.getClass().isArray() )
+        {
+            obj = Array.get(container, numindex);
+        }
+        else if( container instanceof List )
+        {
+            obj = ((List) container).get(numindex);
+        }
+        else if( container instanceof Collection )
+        {
+            synchronized( container )
+            {
+                Object arr[] = ((Collection) container).toArray();
+                if( numindex < arr.length )
+                    obj = arr[numindex];
+            }
+        }
+        else if( container instanceof Map )
+        {
+            synchronized( container )
+            {
+                obj = ((Map) container).get(index);
+            }
+        }
+        else if( container instanceof Dictionary )
+        {
+            synchronized( container )
+            {
+                obj = ((Dictionary) container).get(index);
+            }
+        }
+        return obj;
+    }
+    
+    private void setCollection( Object container, String memberName, Object 
value )
+        throws ReflectionException
+    {
+        try
+        {
+            Object obj = null;
+            
+            String index = memberName.substring( 1, memberName.length()-1);
+            int numindex = 0;
+            try
+            {
+                numindex = Integer.parseInt( index );            
+            } catch( NumberFormatException e ){}  // Ignore
+            synchronized( container )
+            {
+                if( container.getClass().isArray() )
+                {
+                    obj = Array.get(container, numindex );
+                    if( ! obj.getClass().isInstance( value ) )
+                    {
+                        if( value instanceof String )
+                            value = convPrimitive( obj.getClass(), (String) 
value);
+                    }
+                    Array.set(container, numindex, value);
+                }
+                else if( container instanceof List )
+                {
+                    obj = ((List) container).get(numindex);
+                    if( ! obj.getClass().isInstance( value ) )
+                    {
+                        if( value instanceof String )
+                            value = convPrimitive( obj.getClass(), (String) 
value);
+                    }
+                    ((List) container).set(numindex, value);
+                }
+                else if( container instanceof Collection )
+                {
+                    Iterator collection = ((Collection) container).iterator();
+                    for( int i=0; i < numindex && collection.hasNext(); 
collection.next() );
+                    obj = collection.next();
+                    if( ! obj.getClass().isInstance( value ) )
+                    {
+                        if( value instanceof String )
+                            value = convPrimitive( obj.getClass(), (String) 
value);
+                    }
+                    collection.remove();
+                    ((Collection) container).add(value);
+                }
+                else if( container instanceof Map )
+                {
+                    index = index.substring( 1, index.length() - 1 );
+                    obj = ((Map) container).get( index );
+                    if( ! obj.getClass().isInstance( value ) )
+                    {
+                        if( value instanceof String )
+                            value = convPrimitive( obj.getClass(), (String) 
value);
+                    }
+                    ((Map) container).put(index, value);
+                }
+                else if( container instanceof Dictionary )
+                {
+                    index = index.substring( 1, index.length() - 1 );
+                    obj = ((Dictionary) container).get( index );
+                    if( ! obj.getClass().isInstance( value ) )
+                    {
+                        if( value instanceof String )
+                            value = convPrimitive( obj.getClass(), (String) 
value);
+                    }
+                    ((Dictionary) container).put(index, value);
+                }
+            }
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Container=" + container + ", 
Member=" + memberName + ", Value=" + value, e );
+        }
+    }
+    
+    private Class getClassInCollection(Object container, String memberName)
+    {
+        String index = memberName.substring( 1, memberName.length()-1);
+        int numindex = 0;
+        try
+        {   
+            if( index.startsWith( "\'" ) )
+                index = index.substring( 1, index.length() - 1);
+            numindex = Integer.parseInt( index );
+        } catch( NumberFormatException e ) {}  // Ignore
+        
+        Class result = null;
+        Object obj;
+        synchronized( container )
+        {
+            if( container.getClass().isArray() )
+            {
+            // If primitive types, Serialization does not work anyway,
+            // so the expansion to wrapper classes is OK, for now.
+                result = Array.get(container, numindex).getClass();
+            }
+            else if( container instanceof List )
+            {
+                obj = ((List) container).get(numindex);
+                if( obj == null )
+                    return null;
+                result = obj.getClass();
+            }
+            else if( container instanceof Collection )
+            {
+                Object arr[] = ((Collection) container).toArray();
+                if( numindex < arr.length )
+                    result = arr[numindex].getClass();
+                else
+                result = null;
+            }
+            else if( container instanceof Map )
+            {
+                obj = ((Map) container).get(index);
+                if( obj == null )
+                    return null;
+                result = obj.getClass();
+            }
+            else if( container instanceof Dictionary)
+            {
+                obj = ((Dictionary) container).get(index);
+                if( obj == null )
+                    return null;
+                result = obj.getClass();
+            }
+    }
+        return result;
+    }
+
+    private void setObject( Object container, String member, String value )
+        throws ReflectionException
+    {
+        try
+        {
+            Object obj = null;
+            Class cls = container.getClass();
+            Field[] flds = cls.getDeclaredFields();
+            
+            if( member.startsWith("[") )
+            {
+                setCollection(container, member, value);
+            }
+            else
+            {
+                Method method = findMethod( container, "set" + member );
+                if( method != null )
+                {
+                    try
+                    {
+                        Class[] argTypes = method.getParameterTypes(); 
+                        Object arg = convPrimitive( argTypes[0], value);
+                        Object[] args = { arg };
+                        obj = method.invoke(container, args );
+                    } catch( IllegalAccessException e )
+                    {
+                        throw new ReflectionException( 
container.getClass().toString() + ".set" + member + "() is not declared 
public.", e);
+                    } catch( IllegalArgumentException e )
+                    {
+                        throw new ReflectionException( 
container.getClass().toString() + ".set" + member + "() .", e);
+                    }
+                }
+                if( method == null )
+                {
+                    for( int i=0; i < flds.length ; i++ )
+                    {
+                        if( matchField( flds[i].getName(), member ) )
+                        {
+                            if( flds[i].getType().isPrimitive() )
+                                setPrimitive( flds[i], container, value );
+                            else
+                                setObject( flds[i], container, value );
+                        }
+                    }
+                }
+            }
+        } catch( Exception e )
+        {
+            if( e instanceof ReflectionException )
+                throw (ReflectionException) e.fillInStackTrace();
+            else
+                throw new ReflectionException( "Container=" + container + ", 
Member=" + member + ", Value=" + value, e );
+        }
+    }
+    
+    private void setObject( Field fld, Object obj, Object value )
+        throws IllegalAccessException, InvocationTargetException, 
+        InstantiationException
+    {
+        // Create a new instance of the object
+        // Assign instance to reference.
+        Class fldClass = fld.getType();
+        
+        Constructor[] constructors = fldClass.getConstructors();
+        Constructor constr = null;
+        for( int j=0; j < constructors.length ; j++ )
+        {
+            Class[] params = constructors[j].getParameterTypes();
+            if( params.length == 1 && params[0].getName().equals("String"))
+            {
+                constr = constructors[j];
+                break;
+            }
+        }
+        
+        if( constr != null )
+        {
+            Object[] args = {value};
+            Object newObj = constr.newInstance( args );
+            fld.set(obj, newObj );
+        }
+        else
+            throw new IllegalAccessException( "No valid Constructors available 
for object:" + fldClass );
+    }   
+         
+    private Field findField( Object container, String memberName )
+        throws NoSuchFieldException
+    {
+        Class cls = container.getClass();
+        try
+        {
+            Field fld = cls.getDeclaredField( memberName );
+            return fld;
+        } catch( NoSuchFieldException e )
+        {
+            Field fld = cls.getDeclaredField( "m_" + memberName );
+            return fld;
+        }            
+    }
+
+    private Method findMethod( Object container, String methodName )
+    {
+        Method[] methods = container.getClass().getMethods();
+        for( int i = 0; i < methods.length ; i++ )
+        {
+            if( methods[i].getName().equals( methodName ) )
+                return methods[i];
+        }
+        return null;
+    }
+
+    private boolean matchField( String programmatic, String global )
+    {
+        int i = programmatic.indexOf( '_' );
+        if( i >= 0 )
+            programmatic = programmatic.substring( i + 1 );
+        return global.equalsIgnoreCase( programmatic );
+    }
+
+    private boolean isPrimitive( Object obj )
+    {
+        // This doesn't seem to work!!!
+        // Class cls = obj.getClass();
+        // return cls.isPrimitive();
+        
+        // So need to do this????
+        if( obj instanceof Boolean )
+            return true;
+        else if( obj instanceof Double )
+            return true;
+        else if( obj instanceof Integer )
+            return true;
+        else if( obj instanceof Long )
+            return true;
+        else if( obj instanceof Byte )
+            return true;
+        else if( obj instanceof Float )
+            return true;
+        else if( obj instanceof Character )
+            return true;
+        else if( obj instanceof Short )
+            return true;
+        else if( obj instanceof Void )
+            return true;
+        else
+            return false;
+    }
+
+    private String[] getCollectionNames(Collection container)
+    {
+        String[] sa = new String[container.size()];
+        for( int i=0; i < container.size() ; i++ )
+            sa[i] = "" + i;
+        return sa;
+    }
+    
+    private String[] getMapNames( Map container)
+    {
+        String[] sa = new String[container.size()];
+        int i=0;
+        
+        Iterator list = container.keySet().iterator();
+        while( list.hasNext() )
+        {
+            sa[i++] = list.next().toString();
+        }
+        return sa;
+    }
+    
+    private String[] getDictionaryNames( Dictionary container)
+    {
+        String[] sa = new String[container.size()];
+        int i=0;
+        
+        Enumeration list = container.keys();
+        while( list.hasMoreElements() )
+        {
+            sa[i++] = list.nextElement().toString();
+        }
+        return sa;
+    }
+    
+    private String[] getArrayNames( Object[] container)
+    {
+        String[] sa = new String[container.length];
+        for( int i=0 ; i < sa.length ; i++ )
+            sa[i] = "" + i;
+        return sa;
+    }
+    
+    public synchronized void addReflectionListener( ReflectionListener 
listener )
+    {
+        Vector v;
+        if( m_Listeners == null )
+            v = new Vector();
+        else
+            v = (Vector) m_Listeners.clone();
+        v.add( listener );
+        m_Listeners = v;
+    }
+    
+    public synchronized void removeReflectionListener( ReflectionListener 
listener )
+    {
+        if( m_Listeners == null )
+            return;
+        Vector v = (Vector) m_Listeners.clone();
+        v.remove( listener );
+        m_Listeners = v;
+    }
+    
+    private void fireEvent( ReflectionEvent event )
+    {
+        // Use intermediary Vector reference for atomicity without synchronized
+        Vector v = m_Listeners;
+        
+        if( v == null )
+            return;
+        for( int i=0; i < v.size() ; i++ )
+        {
+            ReflectionListener listener = (ReflectionListener) v.elementAt(i);
+            listener.reflected( event );
+        }
+    }
+
+    public void dispose()
+    {
+        if( m_Listeners != null )
+            m_Listeners.removeAllElements();
+        m_Listeners = null;
+        
+        m_RootObjects.clear();
+        m_RootObjects = null;
+    }
+}

Added: 
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/RequestContext.java
==============================================================================
--- (empty file)
+++ 
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/RequestContext.java
       Sun Aug 15 13:30:48 2004
@@ -0,0 +1,147 @@
+/*
+ * 1.0    1999/07/30 Niclas Hedhman     First Public Release
+ *
+ * Copyright (c) 1996-1999 Bali Automation. All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies. Please refer to the file "copyright.html"
+ * for further important copyright and licensing information.
+ *
+ * BALI AUTOMATION MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE 
+ * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING 
+ * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. BALI AUTOMATION
+ * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A 
+ * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 
+ * DERIVATIVES.
+ */
+
+package org.apache.metro.facilities.reflector.impl;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+
+import java.util.List;
+
+import org.apache.metro.facilities.reflector.ReflectorService;
+import org.apache.metro.facilities.reflector.ReflectionException;
+
+import org.mortbay.http.HttpRequest;
+import org.mortbay.http.HttpResponse;
+
+final class RequestContext
+{
+    HttpRequest req;
+    HttpResponse res;
+    PrintWriter out;
+    
+    String      objectname;
+    
+    long        start;
+    boolean     debug;
+
+
+    RequestContext( String path,
+                           HttpRequest request,
+                           HttpResponse response,
+                           String encoding
+    )
+        throws IOException
+    {
+        start = System.currentTimeMillis();
+
+        req = request;
+        res = response;
+        OutputStreamWriter osw = new OutputStreamWriter( 
response.getOutputStream(), encoding );
+        
+        out = new PrintWriter( osw, true );
+        
+        List dblist = req.getParameterValues( "debug" );
+        debug = (dblist != null) && ( dblist.size() > 0 );
+        
+        String str = path;
+        if( str.startsWith("//") )
+            str = str.substring(2);
+        if( str.startsWith("/") )
+            str = str.substring(1);
+
+        objectname = decode( str );
+        objectname = replace( objectname, '/', '.' );
+        
+        if( objectname.endsWith( "/" ) )
+            objectname = objectname.substring( 0, objectname.length()-1 );
+        
+        if( debug )
+            out.print( "object=" + objectname + "<hr>" );
+    }
+
+    void dispose()
+        throws IOException
+    {
+        if( out != null )
+        {
+            out.flush();
+            out.close();
+        }
+    }
+        
+    
+    private String replace( String text, char original, char replacement )
+    {
+        StringBuffer buf = new StringBuffer();
+        int mode = 0;
+
+        for( int i=0 ; i < text.length() ; i++ )
+        {
+            char ch = text.charAt(i);
+            switch( mode )
+            {
+            case 0:
+                if( ch == '"' )
+                    mode = 1;
+                else if( ch == '\'' )
+                    mode = 2;
+                else if( ch == original )
+                    ch = replacement;
+                buf.append(ch);
+                break;
+            case 1:
+                if( ch == '"' )
+                    mode = 0;
+                buf.append(ch);
+                break;
+            case 2:
+                if( ch == '\'' )
+                    mode = 0;
+                buf.append(ch);
+                break;
+            }
+        }
+        return buf.toString();
+    }
+
+    private String decode( String text )
+    {
+        StringBuffer buf = new StringBuffer();
+        for( int i=0 ; i < text.length() ; i++ )
+        {
+            char ch = text.charAt(i);
+            if( ch == '{' )
+            {
+                int pos = text.indexOf( '}', i );
+                String numtxt = text.substring( i+1, pos );
+                int num = Integer.parseInt( numtxt );
+                buf.append( (char) num );
+                i = pos;
+            }
+            else
+                buf.append( ch );
+        }
+        return buf.toString();
+    }
+    
+    
+}

Added: 
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/package.html
==============================================================================
--- (empty file)
+++ 
avalon/trunk/planet/facilities/reflector/impl/src/main/org/apache/metro/facilities/reflector/impl/package.html
      Sun Aug 15 13:30:48 2004
@@ -0,0 +1,5 @@
+<body>
+<p>
+   Implementation of the Reflector facility.
+</p>
+</body>

Added: avalon/trunk/planet/facilities/reflector/static_request.log
==============================================================================
--- (empty file)
+++ avalon/trunk/planet/facilities/reflector/static_request.log Sun Aug 15 
13:30:48 2004
@@ -0,0 +1,5 @@
+127.0.0.1 - - [16/Aug/2004:03:36:02 +0800] "GET /demo/ HTTP/1.1" 200 1027 
"http://localhost:8080/"; "Mozilla/5.0 (compatible; Konqueror/3.1; Linux)"
+127.0.0.1 - - [16/Aug/2004:03:37:02 +0800] "GET /demo/inspect HTTP/1.1" 404 
1253 "-" "Mozilla/5.0 (compatible; Konqueror/3.1; Linux)"
+127.0.0.1 - - [16/Aug/2004:03:37:05 +0800] "GET /demo/inspect/ HTTP/1.1" 404 
1256 "-" "Mozilla/5.0 (compatible; Konqueror/3.1; Linux)"
+127.0.0.1 - - [16/Aug/2004:03:38:27 +0800] "GET /demo/inspect/ HTTP/1.1" 404 
1256 "-" "Mozilla/5.0 (compatible; Konqueror/3.1; Linux)"
+127.0.0.1 - - [16/Aug/2004:03:38:32 +0800] "GET /demo/ HTTP/1.1" 200 1029 "-" 
"Mozilla/5.0 (compatible; Konqueror/3.1; Linux)"

Added: avalon/trunk/planet/facilities/reflector/test/etc/config.xml
==============================================================================
--- (empty file)
+++ avalon/trunk/planet/facilities/reflector/test/etc/config.xml        Sun Aug 
15 13:30:48 2004
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<targets>
+
+  <target path="/reflector/http/context">
+    <configuration>
+      <context-path>/demo</context-path>
+      <resource-base>.</resource-base>
+    </configuration>
+  </target>
+
+</targets>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to