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.ModelMetadata; import org.codehaus.modello.plugin.model.ModelClassMetadata; 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 Model extends BaseElement { private String id; private List<ModelClass> classes = new ArrayList<ModelClass>(); private List<ModelDefault> defaults = new ArrayList<ModelDefault>(); private List<ModelInterface> interfaces = new ArrayList<ModelInterface>(); private transient Map<String, List<ModelClass>> classMap = new HashMap<String, List<ModelClass>>(); private transient Map<String, ModelDefault> defaultMap = new HashMap<String, ModelDefault>(); private transient Map<String, List<ModelInterface>> interfaceMap = new HashMap<String, List<ModelInterface>>(); private VersionDefinition versionDefinition; public Model() { super( true ); } public String getId() { return id; } public void setId( String id ) { this.id = id; } public VersionDefinition getVersionDefinition() { return versionDefinition; } public void setVersionDefinition( VersionDefinition versionDefinition ) { this.versionDefinition = versionDefinition; } public ModelMetadata getMetadata( String key ) { return getMetadata( ModelMetadata.class, key ); } public String getRoot( Version version ) { List<ModelClass> classes = getClasses( version ); String className = null; for ( ModelClass currentClass : classes ) { ModelClassMetadata metadata = null; try { metadata = (ModelClassMetadata) currentClass.getMetadata( ModelClassMetadata.ID ); } catch ( Exception e ) { } if ( metadata != null && metadata.isRootElement() ) { if ( className == null ) { className = currentClass.getName(); } else { throw new ModelloRuntimeException( "There are more than one class as root element for this version " + version + "." ); } } } if ( className == null ) { throw new ModelloRuntimeException( "There aren't root element for version " + version + "." ); } return className; } /** * @deprecated This shouldn't be used, anything querying the model should read the * package of the class. Use getDefaultPackageName(..). */ public String getPackageName( boolean withVersion, Version version ) { return getDefaultPackageName( withVersion, version ); } public List<ModelClass> getAllClasses() { return classes; } public List<ModelClass> getClasses( Version version ) { List<ModelClass> classList = new ArrayList<ModelClass>(); for ( ModelClass currentClass : classes ) { if ( version.inside( currentClass.getVersionRange() ) ) { classList.add( currentClass ); } } return classList; } public ModelClass getClass( String type, Version version, boolean optionnal ) { return getClass( type, new VersionRange( version ), optionnal ); } public ModelClass getClass( String type, Version version ) { return getClass( type, new VersionRange( version ), false ); } public ModelClass getClass( String type, VersionRange versionRange, boolean optionnal ) { ModelClass value = getModelClass( type, versionRange ); if ( value != null ) { return value; } if ( optionnal ) { return null; } throw new ModelloRuntimeException( "There is no class '" + type + "' in the version range '" + versionRange.toString() + "'." ); } public ModelClass getClass( String type, VersionRange versionRange ) { ModelClass value = getModelClass( type, versionRange ); if ( value != null ) { return value; } throw new ModelloRuntimeException( "There is no class '" + type + "' in the version range '" + versionRange.toString() + "'." ); } public boolean hasClass( String type, Version version ) { ModelClass value = getModelClass( type, new VersionRange( version ) ); return value != null; } private ModelClass getModelClass( String type, VersionRange versionRange ) { List<ModelClass> classList = classMap.get( type ); ModelClass value = null; if ( classList != null ) { for ( ModelClass modelClass : classList ) { if ( versionRange.getFromVersion().inside( modelClass.getVersionRange() ) && versionRange.getToVersion().inside( modelClass.getVersionRange() ) ) { value = modelClass; } } } return value; } public void addClass( ModelClass modelClass ) { if ( classMap.containsKey( modelClass.getName() ) ) { List<ModelClass> classList = classMap.get( modelClass.getName() ); for ( ModelClass currentClass : classList ) { if ( VersionUtil.isInConflict( modelClass.getVersionRange(), currentClass.getVersionRange() ) ) { throw new ModelloRuntimeException( "Duplicate class: " + modelClass.getName() + "." ); } } } else { List<ModelClass> classList = new ArrayList<ModelClass>(); classMap.put( modelClass.getName(), classList ); } getAllClasses().add( modelClass ); classMap.get( modelClass.getName() ).add( modelClass ); } // ---------------------------------------------------------------------- // Defaults // ---------------------------------------------------------------------- public List<ModelDefault> getDefaults() { return defaults; } public ModelDefault getDefault( String key ) { ModelDefault modelDefault = (ModelDefault) defaultMap.get( key ); if ( modelDefault == null ) { try { modelDefault = ModelDefault.getDefault( key ); } catch ( ModelValidationException mve ) { throw new ModelloRuntimeException( mve.getMessage(), mve ); } } return modelDefault; } public void addDefault( ModelDefault modelDefault ) { if ( defaultMap.containsKey( modelDefault.getKey() ) ) { throw new ModelloRuntimeException( "Duplicate default: " + modelDefault.getKey() + "." ); } getDefaults().add( modelDefault ); defaultMap.put( modelDefault.getKey(), modelDefault ); } public String getDefaultPackageName( boolean withVersion, Version version ) { String packageName = getDefault( ModelDefault.PACKAGE ).getValue(); if ( withVersion ) { packageName += "." + version.toString( "v", "_" ); } return packageName; } // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- public List<ModelInterface> getAllInterfaces() { return interfaces; } public List<ModelInterface> getInterfaces( Version version ) { List<ModelInterface> interfaceList = new ArrayList<ModelInterface>(); for ( ModelInterface currentInterface : interfaces ) { if ( version.inside( currentInterface.getVersionRange() ) ) { interfaceList.add( currentInterface ); } } return interfaceList; } public ModelInterface getInterface( String type, Version version ) { return getInterface( type, new VersionRange( version ) ); } public ModelInterface getInterface( String type, VersionRange versionRange ) { ModelInterface value = getModelInterface( type, versionRange ); if ( value != null ) { return value; } throw new ModelloRuntimeException( "There is no interface '" + type + "' in the version range '" + versionRange.toString() + "'." ); } private ModelInterface getModelInterface( String type, VersionRange versionRange ) { List<ModelInterface> interfaceList = interfaceMap.get( type ); if ( interfaceList != null ) { for ( ModelInterface modelInterface : interfaceList ) { if ( versionRange.getFromVersion().inside( modelInterface.getVersionRange() ) && versionRange.getToVersion().inside( modelInterface.getVersionRange() ) ) { return modelInterface; } } } return null; } public void addInterface( ModelInterface modelInterface ) { if ( interfaceMap.containsKey( modelInterface.getName() ) ) { List<ModelInterface> interfaceList = interfaceMap.get( modelInterface.getName() ); for ( ModelInterface currentInterface : interfaceList ) { if ( VersionUtil.isInConflict( modelInterface.getVersionRange(), currentInterface.getVersionRange() ) ) { throw new ModelloRuntimeException( "Duplicate interface: " + modelInterface.getName() + "." ); } } } else { List<ModelInterface> interfaceList = new ArrayList<ModelInterface>(); interfaceMap.put( modelInterface.getName(), interfaceList ); } getAllInterfaces().add( modelInterface ); interfaceMap.get( modelInterface.getName() ).add( modelInterface ); } public ModelType getType( String type, Version version ) { return getType( type, new VersionRange( version ) ); } public ModelType getType( String type, VersionRange versionRange ) { ModelType value = getModelClass( type, versionRange ); if ( value != null ) { return value; } value = getModelInterface( type, versionRange ); if ( value != null ) { return value; } throw new ModelloRuntimeException( "There is no class or interface '" + type + "' in the version range '" + versionRange.toString() + "'." ); } public void initialize() { for ( ModelClass modelClass : classes ) { modelClass.initialize( this ); } for ( ModelInterface modelInterface : interfaces ) { modelInterface.initialize( this ); } } public void validateElement() { } public ModelClass getLocationTracker( Version version ) { List<ModelClass> modelClasses = getClasses( version ); ModelClass locationTracker = null; for ( ModelClass modelClass : modelClasses ) { ModelClassMetadata metadata = (ModelClassMetadata) modelClass.getMetadata( ModelClassMetadata.ID ); if ( metadata != null && StringUtils.isNotEmpty( metadata.getLocationTracker() ) ) { if ( locationTracker == null ) { locationTracker = modelClass; } else { throw new ModelloRuntimeException( "There are multiple location tracker classes (" + locationTracker.getName() + " vs. " + modelClass.getName() + ") for this version " + version + "." ); } } } return locationTracker; } public ModelClass getSourceTracker( Version version ) { List<ModelClass> modelClasses = getClasses( version ); ModelClass sourceTracker = null; for ( ModelClass modelClass : modelClasses ) { ModelClassMetadata metadata = (ModelClassMetadata) modelClass.getMetadata( ModelClassMetadata.ID ); if ( metadata != null && StringUtils.isNotEmpty( metadata.getSourceTracker() ) ) { if ( sourceTracker == null ) { sourceTracker = modelClass; } else { throw new ModelloRuntimeException( "There are multiple source tracker classes (" + sourceTracker.getName() + " vs. " + modelClass.getName() + ") for this version " + version + "." ); } } } return sourceTracker; } }