Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 191077 Details for
Bug 339827
Eliminate duplicate object instantiation code and its exception handling
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
ClassUtil
clipboard.txt (text/plain), 46.68 KB, created by
Rüdiger Herrmann
on 2011-03-13 11:11:10 EDT
(
hide
)
Description:
ClassUtil
Filename:
MIME Type:
Creator:
Rüdiger Herrmann
Created:
2011-03-13 11:11:10 EDT
Size:
46.68 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.rap.rwt >Index: src/org/eclipse/rwt/RWT.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/RWT.java,v >retrieving revision 1.22 >diff -u -r1.22 RWT.java >--- src/org/eclipse/rwt/RWT.java 6 Mar 2011 17:38:00 -0000 1.22 >+++ src/org/eclipse/rwt/RWT.java 13 Mar 2011 15:10:49 -0000 >@@ -24,6 +24,7 @@ > import org.eclipse.rwt.internal.lifecycle.RWTLifeCycle; > import org.eclipse.rwt.internal.resources.ResourceManager; > import org.eclipse.rwt.internal.service.*; >+import org.eclipse.rwt.internal.util.ClassUtil; > import org.eclipse.rwt.internal.widgets.BrowserHistory; > import org.eclipse.rwt.lifecycle.ILifeCycle; > import org.eclipse.rwt.resources.IResourceManager; >@@ -133,13 +134,7 @@ > synchronized( map ) { > result = map.get( bundle ); > if( result == null ) { >- try { >- Constructor constructor = clazz.getDeclaredConstructor( null ); >- constructor.setAccessible( true ); >- result = constructor.newInstance( null ); >- } catch( final Exception ex ) { >- throw new IllegalStateException( ex.getMessage() ); >- } >+ result = ClassUtil.newInstance( clazz ); > Field[] fields = clazz.getDeclaredFields(); > for( int i = 0; i < fields.length; i++ ) { > String fieldName = fields[ i ].getName(); >@@ -161,12 +156,8 @@ > } > } > } catch( final Exception ex ) { >- String msg >- = "Failed to load localized message for: " >- + clazz.getName() >- + "#" >- + fieldName; >- ServletLog.log( msg, ex ); >+ String qualifiedName = clazz.getName() + "#" + fieldName; >+ ServletLog.log( "Failed to load localized message for: " + qualifiedName, ex ); > } > } > map.put( bundle, result ); >Index: src/org/eclipse/rwt/SessionSingletonBase.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/SessionSingletonBase.java,v >retrieving revision 1.8 >diff -u -r1.8 SessionSingletonBase.java >--- src/org/eclipse/rwt/SessionSingletonBase.java 12 Jun 2008 13:12:18 -0000 1.8 >+++ src/org/eclipse/rwt/SessionSingletonBase.java 13 Mar 2011 15:10:49 -0000 >@@ -10,13 +10,12 @@ > ******************************************************************************/ > package org.eclipse.rwt; > >-import java.lang.reflect.Constructor; >-import java.lang.reflect.InvocationTargetException; > import java.util.Hashtable; > import java.util.Map; > > import org.eclipse.rwt.internal.service.ContextProvider; > import org.eclipse.rwt.internal.service.IServiceStateInfo; >+import org.eclipse.rwt.internal.util.ClassUtil; > import org.eclipse.rwt.service.ISessionStore; > > >@@ -62,8 +61,6 @@ > private final static String PREFIX = "com_w4t_session_singleton_"; > private static final String LOCK_POSTFIX = "#typeLock"; > >- private final static Class[] EMPTY_PARAMS = new Class[ 0 ]; >- > private final static Map instanceKeyMap = new Hashtable(); > private final static Map lockKeyMap = new Hashtable(); > >@@ -145,49 +142,7 @@ > private static Object getInstanceInternal( final Class type ) { > Object result = getAttribute( getInstanceKey( type ) ); > if( result == null ) { >- try { >- Constructor constructor = type.getDeclaredConstructor( EMPTY_PARAMS ); >- if( constructor.isAccessible() ) { >- result = type.newInstance(); >- } else { >- constructor.setAccessible( true ); >- result = constructor.newInstance( null ); >- } >- } catch( final SecurityException ex ) { >- String msg = "Could not created the session singleton instance of '" >- + type.getName() >- + "' due to security restrictions that probably do " >- + "not allow reflection."; >- throw new RuntimeException( msg, ex ); >- } catch( final IllegalArgumentException iae ) { >- String msg = "Could not create the session singleton instance of '" >- + type.getName() >- + "'. Probably there is no parameterless constructor."; >- throw new RuntimeException( msg, iae ); >- } catch( final NoSuchMethodException nsme ) { >- String msg = "Could not create the session singleton instance of '" >- + type.getName() >- + "'. Probably there is no parameterless constructor."; >- throw new RuntimeException( msg, nsme ); >- } catch( final InstantiationException ise ) { >- String msg = "Could not create the session singleton instance of '" >- + type.getName() >- + "'. Unable to create an instance."; >- throw new RuntimeException( msg, ise ); >- } catch( final IllegalAccessException iae ) { >- String msg = "Could not create the session singleton instance of '" >- + type.getName() >- + "'. Not allowed to access the constructor " >- + "for unknown reasons."; >- throw new RuntimeException( msg, iae ); >- } catch( final InvocationTargetException ite ) { >- String msg = "Could not create the session singleton instance of '" >- + type.getName() >- + "' because an Exception was thrown by the constructor:\n" >- + ite.getCause().getMessage() >- + "."; >- throw new RuntimeException( msg, ite ); >- } >+ result = ClassUtil.newInstance( type ); > setAttribute( getInstanceKey( type ), result ); > } > return result; >Index: src/org/eclipse/rwt/internal/AdapterFactoryRegistryInstance.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/AdapterFactoryRegistryInstance.java,v >retrieving revision 1.1 >diff -u -r1.1 AdapterFactoryRegistryInstance.java >--- src/org/eclipse/rwt/internal/AdapterFactoryRegistryInstance.java 6 Mar 2011 17:38:01 -0000 1.1 >+++ src/org/eclipse/rwt/internal/AdapterFactoryRegistryInstance.java 13 Mar 2011 15:10:49 -0000 >@@ -19,7 +19,7 @@ > import org.eclipse.rwt.Adaptable; > import org.eclipse.rwt.AdapterFactory; > import org.eclipse.rwt.internal.service.ServletLog; >-import org.eclipse.rwt.internal.util.ParamCheck; >+import org.eclipse.rwt.internal.util.*; > > > public class AdapterFactoryRegistryInstance { >@@ -64,13 +64,11 @@ > factoryClass.getName(), > adaptableClass.getName() > }; >- String text >- = "The factory ''{0}'' was already added for the adaptable ''{1}''."; >+ String text = "The factory ''{0}'' was already added for the adaptable ''{1}''."; > String msg = MessageFormat.format( text, params ); > throw new IllegalArgumentException( msg ); > } > } >- > FactoryEntry factoryEntry = new FactoryEntry(); > factoryEntry.factoryClass = factoryClass; > factoryEntry.adaptableClass = adaptableClass; >@@ -82,13 +80,12 @@ > for( int i = 0; i < entries.length; i++ ) { > Class clazz = entries[ i ].factoryClass; > try { >- AdapterFactory factory = ( AdapterFactory )clazz.newInstance(); >- AdapterManager manager = AdapterManagerImpl.getInstance(); >- manager.registerAdapters( factory, entries[ i ].adaptableClass ); >- } catch( Throwable thr ) { >+ AdapterFactory factory = ( AdapterFactory )ClassUtil.newInstance( clazz ); >+ AdapterManagerImpl.getInstance().registerAdapters( factory, entries[ i ].adaptableClass ); >+ } catch( ClassInstantiationException cie ) { > String text = "Could not create an instance of ''{0}''."; > String msg = MessageFormat.format( text, new Object[] { clazz } ); >- ServletLog.log( msg, thr ); >+ ServletLog.log( msg, cie ); > } > } > } >Index: src/org/eclipse/rwt/internal/FacadesInitializer.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/FacadesInitializer.java,v >retrieving revision 1.3 >diff -u -r1.3 FacadesInitializer.java >--- src/org/eclipse/rwt/internal/FacadesInitializer.java 6 Oct 2009 11:17:24 -0000 1.3 >+++ src/org/eclipse/rwt/internal/FacadesInitializer.java 13 Mar 2011 15:10:49 -0000 >@@ -10,21 +10,12 @@ > ******************************************************************************/ > package org.eclipse.rwt.internal; > >-import java.text.MessageFormat; >+import org.eclipse.rwt.internal.util.ClassUtil; > > public final class FacadesInitializer { > > public static Object load( final Class facade ) { > String name = facade.getName(); >- Object result = null; >- try { >- ClassLoader loader = facade.getClassLoader(); >- result = loader.loadClass( name + "Impl" ).newInstance(); >- } catch( Throwable throwable ) { >- String txt = "Could not load facade for {0}"; >- String msg = MessageFormat.format( txt, new Object[] { name } ); >- throw new RuntimeException( msg, throwable ); >- } >- return result; >+ return ClassUtil.newInstance( facade.getClassLoader(), name + "Impl" ); > } > } >Index: src/org/eclipse/rwt/internal/engine/RWTContext.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/engine/RWTContext.java,v >retrieving revision 1.2 >diff -u -r1.2 RWTContext.java >--- src/org/eclipse/rwt/internal/engine/RWTContext.java 7 Mar 2011 17:06:36 -0000 1.2 >+++ src/org/eclipse/rwt/internal/engine/RWTContext.java 13 Mar 2011 15:10:49 -0000 >@@ -11,11 +11,11 @@ > ******************************************************************************/ > package org.eclipse.rwt.internal.engine; > >-import java.lang.reflect.Constructor; > import java.text.MessageFormat; > import java.util.HashMap; > import java.util.Map; > >+import org.eclipse.rwt.internal.util.ClassUtil; > import org.eclipse.rwt.internal.util.ParamCheck; > > >@@ -51,7 +51,7 @@ > > private void createInstances( Class[] instanceTypes ) { > for( int i = 0; i < instanceTypes.length; i++ ) { >- Object instance = createInstance( instanceTypes[ i ] ); >+ Object instance = ClassUtil.newInstance( instanceTypes[ i ] ); > bufferInstance( instanceTypes[ i ], instance ); > } > } >@@ -77,18 +77,6 @@ > } > } > >- private static Object createInstance( Class instanceType ) { >- Object result = null; >- try { >- Constructor constructor = instanceType.getDeclaredConstructor( null ); >- constructor.setAccessible( true ); >- result = constructor.newInstance( null ); >- } catch( Exception shouldNotHappen ) { >- handleCreationProblem( instanceType, shouldNotHappen ); >- } >- return result; >- } >- > private static Object createInstanceFromFactory( Object instance ) { > Object result = instance; > if( instance instanceof InstanceTypeFactory ) { >@@ -107,18 +95,6 @@ > return result; > } > >- private static void handleCreationProblem( Class instanceType, final Exception cause ) { >- String pattern = "Could not create instance of type ''{0}''."; >- Object[] arguments = new Object[] { instanceType.getName() }; >- String msg = MessageFormat.format( pattern, arguments ); >- throw new IllegalArgumentException( msg ) { >- private static final long serialVersionUID = 1L; >- public Throwable getCause() { >- return cause; >- } >- }; >- } >- > private static void checkRegistered( Class instanceType, Object instance ) { > if( instance == null ) { > String pattern = "Unregistered instance type ''{0}''"; >Index: src/org/eclipse/rwt/internal/engine/RWTServletContextListener.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/engine/RWTServletContextListener.java,v >retrieving revision 1.22 >diff -u -r1.22 RWTServletContextListener.java >--- src/org/eclipse/rwt/internal/engine/RWTServletContextListener.java 6 Mar 2011 17:38:00 -0000 1.22 >+++ src/org/eclipse/rwt/internal/engine/RWTServletContextListener.java 13 Mar 2011 15:10:49 -0000 >@@ -28,6 +28,8 @@ > import org.eclipse.rwt.internal.theme.*; > import org.eclipse.rwt.internal.theme.css.CssFileReader; > import org.eclipse.rwt.internal.theme.css.StyleSheet; >+import org.eclipse.rwt.internal.util.ClassInstantiationException; >+import org.eclipse.rwt.internal.util.ClassUtil; > import org.eclipse.rwt.lifecycle.PhaseListener; > import org.eclipse.rwt.resources.IResource; > import org.eclipse.rwt.resources.IResourceManagerFactory; >@@ -40,22 +42,14 @@ > public final class RWTServletContextListener implements ServletContextListener { > > private static final String PREFIX = "org.eclipse.rwt."; >- public static final String ENTRY_POINTS_PARAM >- = PREFIX + "entryPoints"; >- public static final String THEMES_PARAM >- = PREFIX + "themes"; >- public static final String RESOURCE_MANAGER_FACTORY_PARAM >- = PREFIX + "resourceManagerFactory"; >- public static final String SETTING_STORE_FACTORY_PARAM >- = PREFIX + "settingStoreFactory"; >- public static final String ADAPTER_FACTORIES_PARAM >- = PREFIX + "adapterFactories"; >- public static final String PHASE_LISTENERS_PARAM >- = PREFIX + "phaseListeners"; >- public static final String RESOURCES_PARAM >- = PREFIX + "resources"; >- public static final String BRANDINGS_PARAM >- = PREFIX + "brandings"; >+ public static final String ENTRY_POINTS_PARAM = PREFIX + "entryPoints"; >+ public static final String THEMES_PARAM = PREFIX + "themes"; >+ public static final String RESOURCE_MANAGER_FACTORY_PARAM = PREFIX + "resourceManagerFactory"; >+ public static final String SETTING_STORE_FACTORY_PARAM = PREFIX + "settingStoreFactory"; >+ public static final String ADAPTER_FACTORIES_PARAM = PREFIX + "adapterFactories"; >+ public static final String PHASE_LISTENERS_PARAM = PREFIX + "phaseListeners"; >+ public static final String RESOURCES_PARAM = PREFIX + "resources"; >+ public static final String BRANDINGS_PARAM = PREFIX + "brandings"; > > private static final String SEPARATOR = ","; > >@@ -68,6 +62,7 @@ > private static final String REGISTERED_BRANDINGS > = RWTServletContextListener.class.getName() + "registeredBrandings"; > >+ private static final ClassLoader CLASS_LOADER = RWTServletContextListener.class.getClassLoader(); > > public static class ContextDestroyer implements Runnable { > protected final ServletContext servletContext; >@@ -206,15 +201,13 @@ > public static void registerResourceManagerFactory( > final ServletContext context ) > { >- String factoryName >- = context.getInitParameter( RESOURCE_MANAGER_FACTORY_PARAM ); >+ String factoryName = context.getInitParameter( RESOURCE_MANAGER_FACTORY_PARAM ); > if( factoryName != null ) { > try { >- Class clazz = Class.forName( factoryName ); >- IResourceManagerFactory factory; >- factory = ( IResourceManagerFactory )clazz.newInstance(); >+ IResourceManagerFactory factory >+ = ( IResourceManagerFactory )ClassUtil.newInstance( CLASS_LOADER, factoryName ); > ResourceManager.register( factory ); >- } catch( final Exception ex ) { >+ } catch( ClassInstantiationException ex ) { > String text = "Failed to register resource manager factory ''{0}''."; > String msg = MessageFormat.format( text, new Object[] { factoryName } ); > context.log( msg, ex ); >@@ -235,14 +228,13 @@ > = context.getInitParameter( SETTING_STORE_FACTORY_PARAM ); > if( factoryName != null ) { > try { >- Class clazz = Class.forName( factoryName ); >- ISettingStoreFactory factory; >- factory = ( ISettingStoreFactory )clazz.newInstance(); >+ ISettingStoreFactory factory >+ = ( ISettingStoreFactory )ClassUtil.newInstance( CLASS_LOADER, factoryName ); > SettingStoreManager.register( factory ); >- } catch( final Exception ex ) { >+ } catch( ClassInstantiationException cie ) { > String text = "Failed to register setting store factory ''{0}''."; > String msg = MessageFormat.format( text, new Object[] { factoryName } ); >- context.log( msg, ex ); >+ context.log( msg, cie ); > } > } else { > SettingStoreManager.register( new RWTFileSettingStoreFactory() ); >@@ -297,13 +289,12 @@ > for( int i = 0; i < listenerNames.length; i++ ) { > String className = listenerNames[ i ].trim(); > try { >- Class clazz = Class.forName( className ); >- PhaseListener listener = ( PhaseListener )clazz.newInstance(); >+ PhaseListener listener = ( PhaseListener )ClassUtil.newInstance( CLASS_LOADER, className ); > phaseListeners.add( listener ); >- } catch( final Throwable thr ) { >+ } catch( ClassInstantiationException cie ) { > String text = "Failed to register phase listener ''{0}''."; > String msg = MessageFormat.format( text, new Object[] { className } ); >- context.log( msg, thr ); >+ context.log( msg, cie ); > } > } > } else { >@@ -345,13 +336,12 @@ > for( int i = 0; i < resourceClassNames.length; i++ ) { > String className = resourceClassNames[ i ].trim(); > try { >- Class clazz = Class.forName( className ); >- IResource resource = ( IResource )clazz.newInstance(); >+ IResource resource = ( IResource )ClassUtil.newInstance( CLASS_LOADER, className ); > resources.add( resource ); >- } catch( final Throwable thr ) { >+ } catch( ClassInstantiationException cie ) { > String text = "Failed to register resource ''{0}''."; > String msg = MessageFormat.format( text, new Object[] { className } ); >- context.log( msg, thr ); >+ context.log( msg, cie ); > } > } > } >@@ -393,13 +383,11 @@ > String fileName = parts[ 1 ]; > try { > String themeName = "Unnamed Theme: " + themeId; >- StyleSheet styleSheet >- = CssFileReader.readStyleSheet( fileName, loader ); >+ StyleSheet styleSheet = CssFileReader.readStyleSheet( fileName, loader ); > Theme theme = new Theme( themeId, themeName, styleSheet ); > manager.registerTheme( theme ); > } catch( Exception e ) { >- String text = "Failed to register custom theme ''{0}'' " >- + "from resource ''{1}''"; >+ String text = "Failed to register custom theme ''{0}'' from resource ''{1}''"; > Object[] args = new Object[] { themeId, fileName }; > String msg = MessageFormat.format( text, args ); > context.log( msg, e ); >@@ -438,14 +426,14 @@ > for( int i = 0; i < brandings.length; i++ ) { > String className = brandings[ i ].trim(); > try { >- Object newInstance = Class.forName( className ).newInstance(); >- AbstractBranding branding = ( AbstractBranding )newInstance; >+ AbstractBranding branding >+ = ( AbstractBranding )ClassUtil.newInstance( CLASS_LOADER, className ); > BrandingManager.register( branding ); > registeredBrandings.add( branding ); >- } catch( Exception e ) { >+ } catch( ClassInstantiationException cie ) { > String text = "Failed to register branding ''{0}''."; > String msg = MessageFormat.format( text, new Object[] { className } ); >- servletContext.log( msg, e ); >+ servletContext.log( msg, cie ); > } > } > setRegisteredBrandings( servletContext, registeredBrandings ); >Index: src/org/eclipse/rwt/internal/lifecycle/EntryPointInstantiationException.java >=================================================================== >RCS file: src/org/eclipse/rwt/internal/lifecycle/EntryPointInstantiationException.java >diff -N src/org/eclipse/rwt/internal/lifecycle/EntryPointInstantiationException.java >--- src/org/eclipse/rwt/internal/lifecycle/EntryPointInstantiationException.java 12 Jun 2008 13:12:18 -0000 1.2 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,25 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2002, 2007 Innoopract Informationssysteme GmbH. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * Innoopract Informationssysteme GmbH - initial API and implementation >- ******************************************************************************/ >- >-package org.eclipse.rwt.internal.lifecycle; >- >- >-/** >- * TODO [rh] JavaDoc >- */ >-public final class EntryPointInstantiationException extends RuntimeException { >- >- private static final long serialVersionUID = 1L; >- >- EntryPointInstantiationException( final String msg, final Throwable cause ) { >- super( msg, cause ); >- } >-} >Index: src/org/eclipse/rwt/internal/lifecycle/EntryPointManagerInstance.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/lifecycle/EntryPointManagerInstance.java,v >retrieving revision 1.1 >diff -u -r1.1 EntryPointManagerInstance.java >--- src/org/eclipse/rwt/internal/lifecycle/EntryPointManagerInstance.java 6 Mar 2011 17:38:00 -0000 1.1 >+++ src/org/eclipse/rwt/internal/lifecycle/EntryPointManagerInstance.java 13 Mar 2011 15:10:49 -0000 >@@ -16,7 +16,7 @@ > import java.util.Map; > > import org.eclipse.rwt.internal.service.ContextProvider; >-import org.eclipse.rwt.internal.util.ParamCheck; >+import org.eclipse.rwt.internal.util.*; > import org.eclipse.rwt.lifecycle.IEntryPoint; > import org.eclipse.rwt.service.ISessionStore; > >@@ -60,9 +60,9 @@ > } > > int createUI( final String name ) { >+ ParamCheck.notNull( name, "name" ); > IEntryPoint entryPoint; > Class clazz; >- ParamCheck.notNull( name, "name" ); > synchronized( registry ) { > if( !registry.containsKey( name ) ) { > String text = "An entry point named ''{0}'' does not exist."; >@@ -73,14 +73,7 @@ > } > // no synchronization during instance creation to avoid lock in case > // of expensive constructor operations >- try { >- entryPoint = ( IEntryPoint )clazz.newInstance(); >- } catch( Exception e ) { >- String text = "Failed to instantiate ''{0}''."; >- Object[] args = new Object[] { clazz.getName() }; >- String msg = MessageFormat.format( text, args ); >- throw new EntryPointInstantiationException( msg, e ) ; >- } >+ entryPoint = ( IEntryPoint )ClassUtil.newInstance( clazz ); > ISessionStore session = ContextProvider.getSession(); > session.setAttribute( EntryPointManager.CURRENT_ENTRY_POINT, name ); > return entryPoint.createUI(); >Index: src/org/eclipse/rwt/internal/lifecycle/LifeCycleAdapterFactory.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/lifecycle/LifeCycleAdapterFactory.java,v >retrieving revision 1.8 >diff -u -r1.8 LifeCycleAdapterFactory.java >--- src/org/eclipse/rwt/internal/lifecycle/LifeCycleAdapterFactory.java 8 Oct 2010 15:50:42 -0000 1.8 >+++ src/org/eclipse/rwt/internal/lifecycle/LifeCycleAdapterFactory.java 13 Mar 2011 15:10:49 -0000 >@@ -15,6 +15,8 @@ > import java.util.HashMap; > import java.util.Map; > import org.eclipse.rwt.AdapterFactory; >+import org.eclipse.rwt.internal.util.ClassInstantiationException; >+import org.eclipse.rwt.internal.util.ClassUtil; > import org.eclipse.rwt.lifecycle.ILifeCycleAdapter; > import org.eclipse.rwt.lifecycle.IWidgetLifeCycleAdapter; > import org.eclipse.swt.internal.widgets.displaykit.DisplayLCAFacade; >@@ -110,9 +112,8 @@ > String classToLoad = buffer.toString(); > ClassLoader loader = clazz.getClassLoader(); > try { >- Class adapterClass = loader.loadClass( classToLoad ); >- result = ( IWidgetLifeCycleAdapter )adapterClass.newInstance(); >- } catch( final Throwable thr ) { >+ result = ( IWidgetLifeCycleAdapter )ClassUtil.newInstance( loader, classToLoad ); >+ } catch( ClassInstantiationException thr ) { > // ignore and try to load next package name variant > } > } >Index: src/org/eclipse/rwt/internal/lifecycle/LifeCycleFactoryInstance.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/lifecycle/LifeCycleFactoryInstance.java,v >retrieving revision 1.1 >diff -u -r1.1 LifeCycleFactoryInstance.java >--- src/org/eclipse/rwt/internal/lifecycle/LifeCycleFactoryInstance.java 6 Mar 2011 17:38:00 -0000 1.1 >+++ src/org/eclipse/rwt/internal/lifecycle/LifeCycleFactoryInstance.java 13 Mar 2011 15:10:49 -0000 >@@ -12,10 +12,10 @@ > ******************************************************************************/ > package org.eclipse.rwt.internal.lifecycle; > >-import java.text.MessageFormat; >- >-import org.eclipse.rwt.internal.*; >+import org.eclipse.rwt.internal.ConfigurationReader; >+import org.eclipse.rwt.internal.IConfiguration; > import org.eclipse.rwt.internal.service.ContextProvider; >+import org.eclipse.rwt.internal.util.ClassUtil; > import org.eclipse.rwt.lifecycle.ILifeCycle; > import org.eclipse.rwt.service.ISessionStore; > >@@ -41,20 +41,12 @@ > public ILifeCycle loadLifeCycle() { > LifeCycle result = globalLifeCycle; > if( result == null ) { >- String lifeCycleClassName = null; >- try { >- IConfiguration configuration = ConfigurationReader.getConfiguration(); >- lifeCycleClassName = configuration.getLifeCycle(); >- Class lifeCycleClass = Class.forName( lifeCycleClassName ); >- result = ( LifeCycle )lifeCycleClass.newInstance(); >- if( result.getScope().equals( Scope.APPLICATION ) ) { >- globalLifeCycle = result; >- } >- } catch( Exception ex ) { >- String text = "Could not load life cycle implementation {0}: {1}"; >- Object[] args = new Object[] { lifeCycleClassName, ex.toString() }; >- String msg = MessageFormat.format( text, args ); >- throw new IllegalStateException( msg ); >+ IConfiguration configuration = ConfigurationReader.getConfiguration(); >+ String lifeCycleClassName = configuration.getLifeCycle(); >+ ClassLoader classLoader = LifeCycleFactoryInstance.class.getClassLoader(); >+ result = ( LifeCycle )ClassUtil.newInstance( classLoader, lifeCycleClassName ); >+ if( result.getScope().equals( Scope.APPLICATION ) ) { >+ globalLifeCycle = result; > } > } > return result; >Index: src/org/eclipse/rwt/internal/service/ServiceManagerInstance.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/service/ServiceManagerInstance.java,v >retrieving revision 1.1 >diff -u -r1.1 ServiceManagerInstance.java >--- src/org/eclipse/rwt/internal/service/ServiceManagerInstance.java 6 Mar 2011 17:38:01 -0000 1.1 >+++ src/org/eclipse/rwt/internal/service/ServiceManagerInstance.java 13 Mar 2011 15:10:49 -0000 >@@ -24,6 +24,7 @@ > import javax.xml.parsers.DocumentBuilderFactory; > > import org.eclipse.rwt.internal.resources.ResourceManager; >+import org.eclipse.rwt.internal.util.ClassUtil; > import org.eclipse.rwt.resources.IResourceManager; > import org.eclipse.rwt.service.IServiceHandler; > import org.w3c.dom.*; >@@ -72,8 +73,7 @@ > Enumeration resources = manager.getResources( SERVICEHANDLER_XML ); > while( resources != null && resources.hasMoreElements() ) { > URL url = ( URL )resources.nextElement(); >- DocumentBuilderFactory factory >- = DocumentBuilderFactory.newInstance(); >+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); > DocumentBuilder builder = factory.newDocumentBuilder(); > URLConnection con = url.openConnection(); > con.setUseCaches( false ); >@@ -92,8 +92,7 @@ > String name = attributes.getNamedItem( "class" ).getNodeValue(); > String param = "requestparameter"; > String id = attributes.getNamedItem( param ).getNodeValue(); >- Class clazz = getClass().getClassLoader().loadClass( name ); >- Object handlerInstance = clazz.newInstance(); >+ Object handlerInstance = ClassUtil.newInstance( getClass().getClassLoader(), name ); > customHandlers.put( id, handlerInstance ); > } > } >Index: src/org/eclipse/rwt/internal/theme/ThemeAdapterUtil.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/rwt/internal/theme/ThemeAdapterUtil.java,v >retrieving revision 1.12 >diff -u -r1.12 ThemeAdapterUtil.java >--- src/org/eclipse/rwt/internal/theme/ThemeAdapterUtil.java 7 Mar 2011 16:29:04 -0000 1.12 >+++ src/org/eclipse/rwt/internal/theme/ThemeAdapterUtil.java 13 Mar 2011 15:10:49 -0000 >@@ -17,6 +17,8 @@ > > import org.eclipse.rwt.internal.engine.RWTContext; > import org.eclipse.rwt.internal.lifecycle.LifeCycleAdapterUtil; >+import org.eclipse.rwt.internal.util.ClassInstantiationException; >+import org.eclipse.rwt.internal.util.ClassUtil; > import org.eclipse.swt.widgets.Widget; > > >@@ -77,18 +79,9 @@ > { > IThemeAdapter result = null; > try { >- Class adapterClass = classLoader.loadClass( className ); >- result = ( IThemeAdapter )adapterClass.newInstance(); >- } catch( final ClassNotFoundException e ) { >+ result = ( IThemeAdapter )ClassUtil.newInstance( classLoader, className ); >+ } catch( ClassInstantiationException cie ) { > // ignore, try to load from next package name variant >- } catch( final InstantiationException e ) { >- String message = "Failed to instantiate theme adapter class " >- + className; >- throw new ThemeManagerException( message, e ); >- } catch( final IllegalAccessException e ) { >- String message = "Failed to instantiate theme adapter class " >- + className; >- throw new ThemeManagerException( message, e ); > } > return result; > } >Index: src/org/eclipse/rwt/internal/util/ClassInstantiationException.java >=================================================================== >RCS file: src/org/eclipse/rwt/internal/util/ClassInstantiationException.java >diff -N src/org/eclipse/rwt/internal/util/ClassInstantiationException.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/rwt/internal/util/ClassInstantiationException.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,21 @@ >+/******************************************************************************* >+ * Copyright (c) 2002, 2011 Innoopract Informationssysteme GmbH. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Innoopract Informationssysteme GmbH - initial API and implementation >+ ******************************************************************************/ >+package org.eclipse.rwt.internal.util; >+ >+ >+public final class ClassInstantiationException extends RuntimeException { >+ >+ private static final long serialVersionUID = 1L; >+ >+ public ClassInstantiationException( String msg, Throwable cause ) { >+ super( msg, cause ); >+ } >+} >Index: src/org/eclipse/rwt/internal/util/ClassUtil.java >=================================================================== >RCS file: src/org/eclipse/rwt/internal/util/ClassUtil.java >diff -N src/org/eclipse/rwt/internal/util/ClassUtil.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/rwt/internal/util/ClassUtil.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,57 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Rüdiger Herrmann and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Rüdiger Herrmann - initial API and implementation >+ ******************************************************************************/ >+package org.eclipse.rwt.internal.util; >+ >+import java.lang.reflect.Constructor; >+ >+ >+public final class ClassUtil { >+ >+ public static Object newInstance( ClassLoader classLoader, String className ) { >+ ParamCheck.notNull( className, "className" ); >+ ParamCheck.notNull( classLoader, "classLoader" ); >+ Class type; >+ try { >+ type = classLoader.loadClass( className ); >+ } catch( ClassNotFoundException cnfe ) { >+ throw new ClassInstantiationException( "Failed to load type: " + className, cnfe ); >+ } >+ return newInstance( type ); >+ } >+ >+ public static Object newInstance( Class type ) { >+ return newInstance( type, null, null ); >+ } >+ >+ public static Object newInstance( Class type, Class[] paramTypes, Object[] paramValues ) { >+ ParamCheck.notNull( type, "type" ); >+ try { >+ return createInstance( type, paramTypes, paramValues ); >+ } catch( Exception e ) { >+ String msg = "Failed to create instance of type: " + type.getName(); >+ throw new ClassInstantiationException( msg, e ); >+ } >+ } >+ >+ private static Object createInstance( Class type, Class[] paramTypes, Object[] paramValues ) >+ throws Exception >+ { >+ Constructor constructor = type.getDeclaredConstructor( paramTypes ); >+ if( !constructor.isAccessible() ) { >+ constructor.setAccessible( true ); >+ } >+ return constructor.newInstance( paramValues ); >+ } >+ >+ private ClassUtil() { >+ // prevent instantiation >+ } >+} >Index: src/org/eclipse/swt/internal/graphics/ImageFactoryInstance.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/swt/internal/graphics/ImageFactoryInstance.java,v >retrieving revision 1.2 >diff -u -r1.2 ImageFactoryInstance.java >--- src/org/eclipse/swt/internal/graphics/ImageFactoryInstance.java 7 Mar 2011 17:34:46 -0000 1.2 >+++ src/org/eclipse/swt/internal/graphics/ImageFactoryInstance.java 13 Mar 2011 15:10:52 -0000 >@@ -17,6 +17,7 @@ > import java.util.Map; > > import org.eclipse.rwt.internal.resources.ResourceManager; >+import org.eclipse.rwt.internal.util.ClassUtil; > import org.eclipse.rwt.resources.IResourceManager; > import org.eclipse.swt.graphics.Device; > import org.eclipse.swt.graphics.Image; >@@ -80,18 +81,9 @@ > } > > private static Image createImageInstance( Device device, InternalImage internalImage ) { >- Image result; >- try { >- Class imageClass = Image.class; >- Class[] paramList = new Class[] { Device.class, InternalImage.class }; >- Constructor constructor = imageClass.getDeclaredConstructor( paramList ); >- constructor.setAccessible( true ); >- Object[] args = new Object[] { device, internalImage }; >- result = ( Image )constructor.newInstance( args ); >- } catch( final Exception e ) { >- throw new RuntimeException( "Failed to instantiate Image", e ); >- } >- return result; >+ Class[] paramTypes = new Class[] { Device.class, InternalImage.class }; >+ Object[] paramValues = new Object[] { device, internalImage }; >+ return ( Image )ClassUtil.newInstance( Image.class, paramTypes, paramValues ); > } > > private static InputStream getInputStream( String path, ClassLoader imageLoader ) { >Index: src/org/eclipse/swt/internal/graphics/ResourceFactoryInstance.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt/org.eclipse.rap.rwt/src/org/eclipse/swt/internal/graphics/ResourceFactoryInstance.java,v >retrieving revision 1.1 >diff -u -r1.1 ResourceFactoryInstance.java >--- src/org/eclipse/swt/internal/graphics/ResourceFactoryInstance.java 6 Mar 2011 17:38:01 -0000 1.1 >+++ src/org/eclipse/swt/internal/graphics/ResourceFactoryInstance.java 13 Mar 2011 15:10:52 -0000 >@@ -16,6 +16,7 @@ > import java.util.HashMap; > import java.util.Map; > >+import org.eclipse.rwt.internal.util.ClassUtil; > import org.eclipse.swt.graphics.*; > > >@@ -90,45 +91,20 @@ > } > > private static Color createColorInstance( final int colorNr ) { >- Color result = null; >- try { >- Class[] paramList = new Class[] { int.class }; >- Constructor constr = Color.class.getDeclaredConstructor( paramList ); >- constr.setAccessible( true ); >- Object[] args = new Object[] { new Integer( colorNr ) }; >- result = ( Color )constr.newInstance( args ); >- } catch( final Exception e ) { >- throw new RuntimeException( "Failed to instantiate Color", e ); >- } >- return result; >+ Class[] paramTypes = new Class[] { int.class }; >+ Object[] paramValues = new Object[] { new Integer( colorNr ) }; >+ return ( Color )ClassUtil.newInstance( Color.class, paramTypes, paramValues ); > } > > private static Font createFontInstance( final FontData fontData ) { >- Font result = null; >- try { >- Class[] paramList = new Class[] { FontData.class }; >- Constructor constr = Font.class.getDeclaredConstructor( paramList ); >- constr.setAccessible( true ); >- result = ( Font )constr.newInstance( new Object[] { fontData } ); >- } catch( final Exception e ) { >- throw new RuntimeException( "Failed to instantiate Font", e ); >- } >- return result; >+ Class[] paramTypes = new Class[] { FontData.class }; >+ Object[] paramValues = new Object[] { fontData }; >+ return ( Font )ClassUtil.newInstance( Font.class, paramTypes, paramValues ); > } > > private static Cursor createCursorInstance( final int style ) { >- Cursor result = null; >- try { >- Class cursorClass = Cursor.class; >- Class[] paramList = new Class[] { int.class }; >- Constructor constr = cursorClass.getDeclaredConstructor( paramList ); >- constr.setAccessible( true ); >- result = ( Cursor )constr.newInstance( new Object[] { >- new Integer( style ) >- } ); >- } catch( final Exception e ) { >- throw new RuntimeException( "Failed to instantiate Cursor", e ); >- } >- return result; >+ Class[] paramTypes = new Class[] { int.class }; >+ Object[] paramValues = new Object[] { new Integer( style ) }; >+ return ( Cursor )ClassUtil.newInstance( Cursor.class, paramTypes, paramValues ); > } > } >#P org.eclipse.rap.rwt.test >Index: src/org/eclipse/RWTHostTestSuite.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt.test/org.eclipse.rap.rwt.test/src/org/eclipse/RWTHostTestSuite.java,v >retrieving revision 1.71 >diff -u -r1.71 RWTHostTestSuite.java >--- src/org/eclipse/RWTHostTestSuite.java 12 Mar 2011 19:53:10 -0000 1.71 >+++ src/org/eclipse/RWTHostTestSuite.java 13 Mar 2011 15:10:53 -0000 >@@ -26,6 +26,7 @@ > import org.eclipse.rwt.internal.service.*; > import org.eclipse.rwt.internal.theme.*; > import org.eclipse.rwt.internal.theme.css.*; >+import org.eclipse.rwt.internal.util.ClassUtil_Test; > import org.eclipse.rwt.internal.widgets.JSExecutor_Test; > import org.eclipse.rwt.lifecycle.*; > import org.eclipse.rwt.service.*; >@@ -115,6 +116,7 @@ > suite.addTestSuite( LifeCycleServiceHandler_Test.class ); > suite.addTestSuite( StartupPageTemplateHolder_Test.class ); > suite.addTestSuite( EncodingUtil_Test.class ); >+ suite.addTestSuite( ClassUtil_Test.class ); > > suite.addTestSuite( Display_Test.class ); > suite.addTestSuite( Monitor_Test.class ); >Index: src/org/eclipse/rwt/internal/engine/RWTContext_Test.java >=================================================================== >RCS file: /cvsroot/rt/org.eclipse.rap/runtime.rwt.test/org.eclipse.rap.rwt.test/src/org/eclipse/rwt/internal/engine/RWTContext_Test.java,v >retrieving revision 1.2 >diff -u -r1.2 RWTContext_Test.java >--- src/org/eclipse/rwt/internal/engine/RWTContext_Test.java 7 Mar 2011 17:06:35 -0000 1.2 >+++ src/org/eclipse/rwt/internal/engine/RWTContext_Test.java 13 Mar 2011 15:10:53 -0000 >@@ -14,6 +14,7 @@ > import junit.framework.TestCase; > > import org.eclipse.rwt.internal.engine.RWTContext.InstanceTypeFactory; >+import org.eclipse.rwt.internal.util.ClassInstantiationException; > > > public class RWTContext_Test extends TestCase { >@@ -81,7 +82,7 @@ > try { > new RWTContext( new Class[] { AbstractClass.class } ); > fail(); >- } catch( IllegalArgumentException expected ) { >+ } catch( ClassInstantiationException expected ) { > } > } > >Index: src/org/eclipse/rwt/internal/util/ClassUtil_Test.java >=================================================================== >RCS file: src/org/eclipse/rwt/internal/util/ClassUtil_Test.java >diff -N src/org/eclipse/rwt/internal/util/ClassUtil_Test.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/rwt/internal/util/ClassUtil_Test.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,153 @@ >+/******************************************************************************* >+ * Copyright (c) 2011 Rüdiger Herrmann and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Rüdiger Herrmann - initial API and implementation >+ ******************************************************************************/ >+package org.eclipse.rwt.internal.util; >+ >+import java.lang.reflect.InvocationTargetException; >+ >+import junit.framework.TestCase; >+ >+ >+public class ClassUtil_Test extends TestCase { >+ >+ private ClassLoader classLoader; >+ >+ static class ConstructorException extends RuntimeException { >+ private static final long serialVersionUID = 1L; >+ } >+ >+ public static abstract class AbstractClass { >+ } >+ >+ public static class PublicClass { >+ Object objectParam; >+ String stringParam; >+ Long longParam; >+ public PublicClass() { >+ } >+ private PublicClass( Object objectParam ) { >+ this.objectParam = objectParam; >+ } >+ public PublicClass( String stringParam, Long longParam ) { >+ this.stringParam = stringParam; >+ this.longParam = longParam; >+ } >+ } >+ >+ static class ClassWithPrivateConstructor { >+ private ClassWithPrivateConstructor() { >+ } >+ } >+ >+ static class ClassWithExceptionInConstructor { >+ ClassWithExceptionInConstructor() { >+ throw new ConstructorException(); >+ } >+ } >+ >+ public void testNewInstanceWithNullClass() { >+ try { >+ ClassUtil.newInstance( ( Class )null ); >+ fail(); >+ } catch( NullPointerException expected ) { >+ } >+ } >+ >+ public void testNewInstanceWithAbstractClass() { >+ try { >+ ClassUtil.newInstance( AbstractClass.class ); >+ fail(); >+ } catch( ClassInstantiationException expected ) { >+ } >+ } >+ >+ public void testNewInstanceWithInterface() { >+ try { >+ ClassUtil.newInstance( Runnable.class ); >+ fail(); >+ } catch( ClassInstantiationException expected ) { >+ } >+ } >+ >+ public void testNewInstanceWithPublicClass() { >+ Object instance = ClassUtil.newInstance( ClassWithPrivateConstructor.class ); >+ assertEquals( instance.getClass(), ClassWithPrivateConstructor.class ); >+ } >+ >+ public void testNewInstanceWithPrivateDefaultConstructor() { >+ Object instance = ClassUtil.newInstance( PublicClass.class ); >+ assertEquals( instance.getClass(), PublicClass.class ); >+ } >+ >+ public void testNewInstanceWithEceptionInConstructor() { >+ try { >+ ClassUtil.newInstance( ClassWithExceptionInConstructor.class ); >+ fail(); >+ } catch( ClassInstantiationException e ) { >+ assertEquals( e.getCause().getClass(), InvocationTargetException.class ); >+ } >+ } >+ >+ public void testNewInstanceWithNullClassNameAndClassLoader() { >+ try { >+ ClassUtil.newInstance( classLoader, null ); >+ fail(); >+ } catch( NullPointerException expected ) { >+ } >+ } >+ >+ public void testNewInstanceWithNullClassLoader() { >+ try { >+ ClassUtil.newInstance( null, "" ); >+ fail(); >+ } catch( NullPointerException expected ) { >+ } >+ } >+ >+ public void testNewInstanceWithNonExistingClassName() { >+ try { >+ ClassUtil.newInstance( classLoader, "does.not.exist" ); >+ fail(); >+ } catch( ClassInstantiationException expected ) { >+ } >+ } >+ >+ public void testNewInstanceWithExistingClassName() { >+ Object instance = ClassUtil.newInstance( classLoader, PublicClass.class.getName() ); >+ assertEquals( instance.getClass(), PublicClass.class ); >+ } >+ >+ >+ public void testNewInstanceWithPublicParameterizedConstructor() { >+ String stringValue = "string"; >+ Long longValue = new Long( 0 ); >+ Class[] paramTypes = new Class[] { String.class, Long.class }; >+ Object[] paramValues = new Object[] { stringValue, longValue }; >+ Object instance = ClassUtil.newInstance( PublicClass.class, paramTypes, paramValues ); >+ assertEquals( instance.getClass(), PublicClass.class ); >+ PublicClass publicClass = ( PublicClass )instance; >+ assertEquals( stringValue, publicClass.stringParam ); >+ assertEquals( longValue, publicClass.longParam ); >+ } >+ >+ public void testNewInstanceWithPrivateParameterizedConstructor() { >+ Object objectValue = new Object(); >+ Class[] paramTypes = new Class[] { Object.class }; >+ Object[] paramValues = new Object[] { objectValue }; >+ Object instance = ClassUtil.newInstance( PublicClass.class, paramTypes, paramValues ); >+ assertEquals( instance.getClass(), PublicClass.class ); >+ PublicClass publicClass = ( PublicClass )instance; >+ assertEquals( objectValue, publicClass.objectParam ); >+ } >+ >+ protected void setUp() throws Exception { >+ classLoader = ClassUtil_Test.class.getClassLoader(); >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 339827
: 191077