svn commit: rev 36418 - in avalon/trunk/planet/facilities: . reflector reflector/api reflector/api/src reflector/api/src/main reflector/api/src/main/org reflector/api/src/main/org/apache reflector/api/src/main/org/apache/metro reflector/api/src/main/org/apache/metro/facilities reflector/api/src/main/org/apache/metro/facilities/reflector reflector/impl reflector/impl/src reflector/impl/src/main reflector/impl/src/main/org reflector/impl/src/main/org/apache reflector/impl/src/main/org/apache/metro reflector/impl/src/main/org/apache/metro/facilities reflector/impl/src/main/org/apache/metro/facilities/reflector reflector/impl/src/main/org/apache/metro/facilities/reflector/impl reflector/test reflector/test/etc
[email protected] 15 Aug 2004 20:30:49 -0000
| Newsgroups | gmane.comp.jakarta.avalon.cvs |
|---|---|
| Message-ID | <[email protected]> |
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 = "<null>";
+ 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( "<unknown>" );
+ 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>