Browse Source

Add in the ability for types to automagicall instantiated based on registration into TypeManager as previously discussed.

Also added unit tests to verify everything works as expected


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@270976 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Donald 23 years ago
parent
commit
ed7685cd6f
15 changed files with 574 additions and 76 deletions
  1. +102
    -74
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultConfigurer.java
  2. +8
    -1
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultObjectConfigurer.java
  3. +2
    -1
      proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/Resources.properties
  4. +34
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/ConfigTest6.java
  5. +34
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/ConfigTest7.java
  6. +34
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/ConfigTest8.java
  7. +83
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
  8. +23
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/MyType1.java
  9. +23
    -0
      proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/MyType2.java
  10. +34
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/ConfigTest6.java
  11. +34
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/ConfigTest7.java
  12. +34
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/ConfigTest8.java
  13. +83
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java
  14. +23
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/MyType1.java
  15. +23
    -0
      proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/MyType2.java

+ 102
- 74
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultConfigurer.java View File

@@ -26,6 +26,10 @@ import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.myrmidon.interfaces.configurer.Configurer;
import org.apache.myrmidon.interfaces.converter.MasterConverter;
import org.apache.myrmidon.interfaces.type.TypeFactory;
import org.apache.myrmidon.interfaces.type.TypeManager;
import org.apache.myrmidon.interfaces.type.TypeException;
import org.apache.myrmidon.api.TaskException;

/**
* Class used to configure tasks.
@@ -42,6 +46,9 @@ public class DefaultConfigurer
///Converter to use for converting between values
private MasterConverter m_converter;

//TypeManager to use to create types in typed adders
private TypeManager m_typeManager;

///Cached object configurers. This is a map from Class to the
///ObjectConfigurer for that class.
private Map m_configurerCache = new HashMap();
@@ -50,6 +57,7 @@ public class DefaultConfigurer
throws ComponentException
{
m_converter = (MasterConverter)componentManager.lookup( MasterConverter.ROLE );
m_typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE );
}

/**
@@ -262,7 +270,8 @@ public class DefaultConfigurer
final String name = element.getName();

// Locate the configurer for the child element
final PropertyConfigurer childConfigurer = state.getConfigurer().getProperty( name );
final PropertyConfigurer childConfigurer =
state.getConfigurer().getProperty( name );

// Create & configure the child element
final Object child =
@@ -272,79 +281,6 @@ public class DefaultConfigurer
childConfigurer.addValue( state, child );
}

private Object setupChild( final ConfigurationState state,
final Configuration element,
final Context context,
final PropertyConfigurer childConfigurer )
throws ConfigurationException
{
final String name = element.getName();
final Class type = childConfigurer.getType();
Object child = childConfigurer.createValue( state );

if( null == child && Configuration.class == type )
{
//special case where you have add(Configuration)
return element;
}
else if( null == child )
{
// Create an instance using the default constructor
if( type.isInterface() )
{
child = createdTypedObject( name, type );
configureObject( child, element, context );
}
else
{
child = createObject( type );
configureObject( child, element, context );
}
}
configureObject( child, element, context );
return child;
}

/**
* Utility method to create an instance of the
* specified type that satisfied supplied interface.
*/
private Object createdTypedObject( final String name,
final Class type )
throws ConfigurationException
{
try
{
return type.newInstance();
}
catch( final Exception e )
{
final String message =
REZ.getString( "create-object.error",
type.getName() );
throw new ConfigurationException( message, e );
}
}

/**
* Utility method to instantiate an instance of the specified class.
*/
private Object createObject( final Class type )
throws ConfigurationException
{
try
{
return type.newInstance();
}
catch( final Exception e )
{
final String message =
REZ.getString( "create-object.error",
type.getName() );
throw new ConfigurationException( message, e );
}
}

/**
* Configures a property from a reference.
*/
@@ -468,4 +404,96 @@ public class DefaultConfigurer
}
return configurer;
}

private Object setupChild( final ConfigurationState state,
final Configuration element,
final Context context,
final PropertyConfigurer childConfigurer )
throws ConfigurationException
{
final String name = element.getName();
final Class type = childConfigurer.getType();
Object child = childConfigurer.createValue( state );

if( null == child && Configuration.class == type )
{
//special case where you have add...(Configuration)
return element;
}
else if( null == child )
{
// Create an instance using the default constructor
if( type.isInterface() )
{
child = createdTypedObject( name, type );
configureObject( child, element, context );
}
else
{
child = createObject( type );
configureObject( child, element, context );
}
}
configureObject( child, element, context );
return child;
}

/**
* Utility method to create an instance of the
* specified type that satisfied supplied interface.
*/
private Object createdTypedObject( final String name,
final Class type )
throws ConfigurationException
{
final TypeFactory factory = getTypeFactory( type.getName() );
try
{
return factory.create( name );
}
catch( final Exception e )
{
final String message =
REZ.getString( "create-typed-object.error",
name,
type.getName() );
throw new ConfigurationException( message, e );
}
}

/**
* Utility method to instantiate an instance of the specified class.
*/
private Object createObject( final Class type )
throws ConfigurationException
{
try
{
return type.newInstance();
}
catch( final Exception e )
{
final String message =
REZ.getString( "create-object.error",
type.getName() );
throw new ConfigurationException( message, e );
}
}

/**
* Locates a type factory.
*/
protected final TypeFactory getTypeFactory( final String role )
throws ConfigurationException
{
try
{
return m_typeManager.getFactory( role );
}
catch( final TypeException te )
{
final String message = REZ.getString( "no-factory-for-role.error", role );
throw new ConfigurationException( message, te );
}
}
}

+ 8
- 1
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/DefaultObjectConfigurer.java View File

@@ -351,7 +351,14 @@ class DefaultObjectConfigurer
public PropertyConfigurer getProperty( final String name )
throws NoSuchPropertyException
{
final PropertyConfigurer configurer = (PropertyConfigurer)m_props.get( name );
PropertyConfigurer configurer = (PropertyConfigurer)m_props.get( name );
if( null != configurer )
{
return configurer;
}

//Maybe there is a typed adder??
configurer = (PropertyConfigurer)m_props.get( "" );
if( null != configurer )
{
return configurer;


+ 2
- 1
proposal/myrmidon/src/java/org/apache/myrmidon/components/configurer/Resources.properties View File

@@ -20,4 +20,5 @@ no-such-element.error=Nested <{1}> elements are not allowed for element <{0}>.
bad-set-element.error=Could not handle element <{1}>, nested in element <{0}>.
no-content.error=Text content is not allowed for element <{0}>.
bad-set-content.error=Could not set text content for element <{0}>.
typed-adder-non-interface.error=The typed adder for class "{0}" must have a single parameter that is an interface rather than {1} which defines a class.
typed-adder-non-interface.error=The typed adder for class "{0}" must have a single parameter that is an interface rather than {1} which defines a class.
no-factory-for-role.error=Unable to locate type factory for role "{0}"

+ 34
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/ConfigTest6.java View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

import java.util.ArrayList;
import junit.framework.AssertionFailedError;
import org.apache.avalon.framework.configuration.Configuration;

/**
* Simple class to test typed adder.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class ConfigTest6
{
private ArrayList m_roles = new ArrayList();

public void add( final MyRole1 role1 )
{
m_roles.add( role1 );
}

public boolean equals( final Object object )
{
final ConfigTest6 other = (ConfigTest6)object;
return m_roles.equals( other.m_roles );
}
}

+ 34
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/ConfigTest7.java View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

import java.util.ArrayList;
import junit.framework.AssertionFailedError;
import org.apache.avalon.framework.configuration.Configuration;

/**
* Simple class to test adder for Configurations.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class ConfigTest7
{
private ArrayList m_configurations = new ArrayList();

public void add( final Configuration configuration )
{
m_configurations.add( configuration );
}

public boolean equals( final Object object )
{
final ConfigTest7 other = (ConfigTest7)object;
return m_configurations.equals( other.m_configurations );
}
}

+ 34
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/ConfigTest8.java View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

import java.util.ArrayList;
import junit.framework.AssertionFailedError;
import org.apache.avalon.framework.configuration.Configuration;

/**
* Simple class to test adder for Configurations.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class ConfigTest8
{
private ArrayList m_configurations = new ArrayList();

public void addConfig( final Configuration configuration )
{
m_configurations.add( configuration );
}

public boolean equals( final Object object )
{
final ConfigTest8 other = (ConfigTest8)object;
return m_configurations.equals( other.m_configurations );
}
}

+ 83
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java View File

@@ -36,6 +36,7 @@ import org.apache.myrmidon.components.workspace.DefaultTaskContext;
import org.apache.myrmidon.interfaces.configurer.Configurer;
import org.apache.myrmidon.interfaces.converter.ConverterRegistry;
import org.apache.myrmidon.interfaces.converter.MasterConverter;
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
import org.apache.myrmidon.interfaces.type.TypeManager;

/**
@@ -51,6 +52,7 @@ public class DefaultConfigurerTest

private DefaultComponentManager m_componentManager;
private Configurer m_configurer;
private TypeManager m_typeManager;
private Logger m_logger;
private DefaultTaskContext m_context;

@@ -134,6 +136,8 @@ public class DefaultConfigurerTest
// Find the configurer
m_configurer = (Configurer)m_componentManager.lookup( Configurer.ROLE );

// Find the typeManager
m_typeManager = (TypeManager)m_componentManager.lookup( TypeManager.ROLE );
}

/**
@@ -412,6 +416,85 @@ public class DefaultConfigurerTest
}
}

/**
* Tests to see if typed adder works.
*/
public void testTypedAdder()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
final DefaultConfiguration child1 = new DefaultConfiguration( "my-type1", "test" );
final DefaultConfiguration child2 = new DefaultConfiguration( "my-type2", "test" );
config.addChild( child1 );
config.addChild( child2 );

final ClassLoader loader = getClass().getClassLoader();
final DefaultTypeFactory factory = new DefaultTypeFactory( loader );
factory.addNameClassMapping( "my-type1", MyType1.class.getName() );
factory.addNameClassMapping( "my-type2", MyType2.class.getName() );
m_typeManager.registerType( MyRole1.class.getName(), "my-type1", factory );
m_typeManager.registerType( MyRole1.class.getName(), "my-type2", factory );

final ConfigTest6 test = new ConfigTest6();

// Configure the object
m_configurer.configure( test, config, m_context );

final ConfigTest6 expected = new ConfigTest6();
expected.add( new MyType1() );
expected.add( new MyType2() );
assertEquals( expected, test );
}

/**
* Tests to see if typed adder works.
*/
public void testTypedConfigAdder()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
final DefaultConfiguration child1 = new DefaultConfiguration( "my-type1", "test" );
final DefaultConfiguration child2 = new DefaultConfiguration( "my-type2", "test" );
config.addChild( child1 );
config.addChild( child2 );

final ConfigTest7 test = new ConfigTest7();

// Configure the object
m_configurer.configure( test, config, m_context );

final ConfigTest7 expected = new ConfigTest7();
expected.add( child1 );
expected.add( child2 );
assertEquals( expected, test );
}

/**
* Tests to see if typed adder works.
*/
public void testConfigAdder()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
final DefaultConfiguration child1 = new DefaultConfiguration( "config", "test" );
final DefaultConfiguration child2 = new DefaultConfiguration( "config", "test" );
config.addChild( child1 );
config.addChild( child2 );

final ConfigTest8 test = new ConfigTest8();

// Configure the object
m_configurer.configure( test, config, m_context );

final ConfigTest8 expected = new ConfigTest8();
expected.addConfig( child1 );
expected.addConfig( child2 );
assertEquals( expected, test );
}

/**
* Test resolving properties in an id.
*/


+ 23
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/MyType1.java View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

/**
* A basic implementation of MyRole1 to test configurer.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class MyType1
implements MyRole1
{
public boolean equals( final Object object )
{
return object.getClass() == getClass();
}
}

+ 23
- 0
proposal/myrmidon/src/test/org/apache/myrmidon/components/configurer/MyType2.java View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

/**
* A basic implementation of MyRole1 to test configurer.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class MyType2
implements MyRole1
{
public boolean equals( final Object object )
{
return object.getClass() == getClass();
}
}

+ 34
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/ConfigTest6.java View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

import java.util.ArrayList;
import junit.framework.AssertionFailedError;
import org.apache.avalon.framework.configuration.Configuration;

/**
* Simple class to test typed adder.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class ConfigTest6
{
private ArrayList m_roles = new ArrayList();

public void add( final MyRole1 role1 )
{
m_roles.add( role1 );
}

public boolean equals( final Object object )
{
final ConfigTest6 other = (ConfigTest6)object;
return m_roles.equals( other.m_roles );
}
}

+ 34
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/ConfigTest7.java View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

import java.util.ArrayList;
import junit.framework.AssertionFailedError;
import org.apache.avalon.framework.configuration.Configuration;

/**
* Simple class to test adder for Configurations.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class ConfigTest7
{
private ArrayList m_configurations = new ArrayList();

public void add( final Configuration configuration )
{
m_configurations.add( configuration );
}

public boolean equals( final Object object )
{
final ConfigTest7 other = (ConfigTest7)object;
return m_configurations.equals( other.m_configurations );
}
}

+ 34
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/ConfigTest8.java View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

import java.util.ArrayList;
import junit.framework.AssertionFailedError;
import org.apache.avalon.framework.configuration.Configuration;

/**
* Simple class to test adder for Configurations.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class ConfigTest8
{
private ArrayList m_configurations = new ArrayList();

public void addConfig( final Configuration configuration )
{
m_configurations.add( configuration );
}

public boolean equals( final Object object )
{
final ConfigTest8 other = (ConfigTest8)object;
return m_configurations.equals( other.m_configurations );
}
}

+ 83
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/DefaultConfigurerTest.java View File

@@ -36,6 +36,7 @@ import org.apache.myrmidon.components.workspace.DefaultTaskContext;
import org.apache.myrmidon.interfaces.configurer.Configurer;
import org.apache.myrmidon.interfaces.converter.ConverterRegistry;
import org.apache.myrmidon.interfaces.converter.MasterConverter;
import org.apache.myrmidon.interfaces.type.DefaultTypeFactory;
import org.apache.myrmidon.interfaces.type.TypeManager;

/**
@@ -51,6 +52,7 @@ public class DefaultConfigurerTest

private DefaultComponentManager m_componentManager;
private Configurer m_configurer;
private TypeManager m_typeManager;
private Logger m_logger;
private DefaultTaskContext m_context;

@@ -134,6 +136,8 @@ public class DefaultConfigurerTest
// Find the configurer
m_configurer = (Configurer)m_componentManager.lookup( Configurer.ROLE );

// Find the typeManager
m_typeManager = (TypeManager)m_componentManager.lookup( TypeManager.ROLE );
}

/**
@@ -412,6 +416,85 @@ public class DefaultConfigurerTest
}
}

/**
* Tests to see if typed adder works.
*/
public void testTypedAdder()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
final DefaultConfiguration child1 = new DefaultConfiguration( "my-type1", "test" );
final DefaultConfiguration child2 = new DefaultConfiguration( "my-type2", "test" );
config.addChild( child1 );
config.addChild( child2 );

final ClassLoader loader = getClass().getClassLoader();
final DefaultTypeFactory factory = new DefaultTypeFactory( loader );
factory.addNameClassMapping( "my-type1", MyType1.class.getName() );
factory.addNameClassMapping( "my-type2", MyType2.class.getName() );
m_typeManager.registerType( MyRole1.class.getName(), "my-type1", factory );
m_typeManager.registerType( MyRole1.class.getName(), "my-type2", factory );

final ConfigTest6 test = new ConfigTest6();

// Configure the object
m_configurer.configure( test, config, m_context );

final ConfigTest6 expected = new ConfigTest6();
expected.add( new MyType1() );
expected.add( new MyType2() );
assertEquals( expected, test );
}

/**
* Tests to see if typed adder works.
*/
public void testTypedConfigAdder()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
final DefaultConfiguration child1 = new DefaultConfiguration( "my-type1", "test" );
final DefaultConfiguration child2 = new DefaultConfiguration( "my-type2", "test" );
config.addChild( child1 );
config.addChild( child2 );

final ConfigTest7 test = new ConfigTest7();

// Configure the object
m_configurer.configure( test, config, m_context );

final ConfigTest7 expected = new ConfigTest7();
expected.add( child1 );
expected.add( child2 );
assertEquals( expected, test );
}

/**
* Tests to see if typed adder works.
*/
public void testConfigAdder()
throws Exception
{
// Setup test data
final DefaultConfiguration config = new DefaultConfiguration( "test", "test" );
final DefaultConfiguration child1 = new DefaultConfiguration( "config", "test" );
final DefaultConfiguration child2 = new DefaultConfiguration( "config", "test" );
config.addChild( child1 );
config.addChild( child2 );

final ConfigTest8 test = new ConfigTest8();

// Configure the object
m_configurer.configure( test, config, m_context );

final ConfigTest8 expected = new ConfigTest8();
expected.addConfig( child1 );
expected.addConfig( child2 );
assertEquals( expected, test );
}

/**
* Test resolving properties in an id.
*/


+ 23
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/MyType1.java View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

/**
* A basic implementation of MyRole1 to test configurer.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class MyType1
implements MyRole1
{
public boolean equals( final Object object )
{
return object.getClass() == getClass();
}
}

+ 23
- 0
proposal/myrmidon/src/testcases/org/apache/myrmidon/components/configurer/MyType2.java View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.myrmidon.components.configurer;

/**
* A basic implementation of MyRole1 to test configurer.
*
* @author <a href="mailto:peter@apache.org">Peter Donald</a>
* @version $Revision$ $Date$
*/
public class MyType2
implements MyRole1
{
public boolean equals( final Object object )
{
return object.getClass() == getClass();
}
}

Loading…
Cancel
Save