package org.codehaus.modello.model;
/*
* Copyright (c) 2004, Codehaus.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import org.codehaus.modello.ModelloRuntimeException;
import org.codehaus.modello.metadata.ClassMetadata;
import org.codehaus.plexus.util.StringUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author <a href="mailto:jason@modello.org">Jason van Zyl</a>
* @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
*/
public class ModelClass
extends ModelType
{
private String superClass;
private boolean isInternalSuperClass;
private List<String> interfaces;
private List<ModelField> fields;
private transient Map<String, List<ModelField>> fieldMap = new HashMap<String, List<ModelField>>();
public ModelClass()
{
super();
}
public ModelClass( Model model, String name )
{
super( model, name );
}
public String getSuperClass()
{
return superClass;
}
public void setSuperClass( String superClass )
{
this.superClass = superClass;
}
// ----------------------------------------------------------------------
// Interfaces
// ----------------------------------------------------------------------
/**
* Returns the list of all interfaces of this class.
*
* @return Returns the list of all interfaces of this class.
*/
public List<String> getInterfaces()
{
if ( interfaces == null )
{
interfaces = new ArrayList<String>();
}
return interfaces;
}
public void addInterface( String modelInterface )
{
if ( getInterfaces().contains( modelInterface ) )
{
throw new ModelloRuntimeException( "Duplicate interface in " + getName() + ": " + modelInterface + "." );
}
getInterfaces().add( modelInterface );
}
// ----------------------------------------------------------------------
// Field
// ----------------------------------------------------------------------
/**
* {@inheritDoc}
*/
public List<ModelField> getAllFields()
{
if ( fields == null )
{
fields = new ArrayList<ModelField>();
}
return fields;
}
/**
* Returns all the fields in this class and all super classes if withInheritedField equals to true.
*
* @return Returns all the fields in this class and all super classes.
*/
public List<ModelField> getAllFields( boolean withInheritedField )
{
if ( ! withInheritedField )
{
return getAllFields();
}
List<ModelField> fields = new ArrayList<ModelField>( getAllFields() );
ModelClass c = this;
while ( c.hasSuperClass() && c.isInternalSuperClass() )
{
ModelClass parent = getModel().getClass( c.getSuperClass(), getVersionRange() );
fields.addAll( parent.getAllFields() );
c = parent;
}
return fields;
}
public ModelField getField( String type, VersionRange versionRange )
{
List<ModelField> fieldList = fieldMap.get( type );
if ( fieldList != null )
{
for ( ModelField modelField : fieldList )
{
if ( versionRange.getFromVersion().inside( modelField.getVersionRange() )
&& versionRange.getToVersion().inside( modelField.getVersionRange() ) )
{
return modelField;
}
}
}
throw new ModelloRuntimeException( "There are no field '" + type + "' in version range '" + versionRange.toString() + "'." );
}
public void addField( ModelField modelField )
{
if ( fieldMap.containsKey( modelField.getName() ) )
{
List<ModelField> fieldList = fieldMap.get( modelField.getName() );
for ( ModelField currentField : fieldList )
{
if ( VersionUtil.isInConflict( modelField.getVersionRange(), currentField.getVersionRange() ) )
{
throw new ModelloRuntimeException( "Duplicate field in " + getName() + ": " + modelField.getName() + "." );
}
}
}
else
{
List<ModelField> fieldList = new ArrayList<ModelField>();
fieldMap.put( modelField.getName(), fieldList );
}
getAllFields().add( modelField );
fieldMap.get( modelField.getName() ).add( modelField );
}
// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
public boolean hasSuperClass()
{
return StringUtils.isNotEmpty( superClass );
}
public boolean isInternalSuperClass()
{
return isInternalSuperClass;
}
public ClassMetadata getMetadata( String key )
{
return getMetadata( ClassMetadata.class, key );
}
public void initialize( Model model )
{
super.initialize( model );
for ( ModelField modelField : getAllFields() )
{
modelField.initialize( this );
}
}
public void validateElement()
throws ModelValidationException
{
// Check if superClass exists
if ( hasSuperClass() )
{
try
{
getModel().getClass( superClass, getVersionRange() );
isInternalSuperClass = true;
}
catch ( ModelloRuntimeException e )
{
isInternalSuperClass = false;
}
}
if ( getModel().getDefault( ModelDefault.CHECK_DEPRECATION ).getBoolean() )
{
if ( ! Version.INFINITE.equals( getVersionRange().getToVersion() )
&& getDeprecatedVersion() == null )
{
throw new ModelValidationException( "You must define the deprecated version of '" + getName() + "' class." );
}
}
}
// ----------------------------------------------------------------------
// Object Overrides
// ----------------------------------------------------------------------
public boolean equals( Object o )
{
if ( ! super.equals( o ) )
{
return false;
}
if ( !( o instanceof ModelClass ) )
{
return false;
}
ModelClass other = (ModelClass) o;
return getPackageName().equals( other.getPackageName() );
}
public int hashCode()
{
int hashCode = getName().hashCode();
if ( !StringUtils.isEmpty( getPackageName() ) )
{
hashCode += 37 * getPackageName().hashCode();
}
return hashCode;
}
}