001package org.andromda.metafacades.uml14; 002 003import java.util.ArrayList; 004import java.util.Collection; 005import java.util.Collections; 006import java.util.Iterator; 007import org.andromda.core.common.ExceptionUtils; 008import org.andromda.core.configuration.Filters; 009import org.andromda.core.metafacade.MetafacadeBase; 010import org.andromda.core.metafacade.MetafacadeConstants; 011import org.andromda.core.metafacade.MetafacadeFactory; 012import org.andromda.core.metafacade.ModelAccessFacade; 013import org.andromda.metafacades.uml.EntityMetafacadeUtils; 014import org.andromda.metafacades.uml.ModelElementFacade; 015import org.andromda.metafacades.uml.PackageFacade; 016import org.apache.commons.collections.CollectionUtils; 017import org.apache.commons.collections.Predicate; 018import org.apache.commons.lang.StringUtils; 019import org.apache.log4j.Logger; 020import org.omg.uml.UmlPackage; 021import org.omg.uml.foundation.core.ModelElement; 022 023/** 024 * Contains a UML model, follows the {@link ModelAccessFacade} interface and can therefore be processed by AndroMDA. 025 * 026 * @author <a href="http://www.mbohlen.de">Matthias Bohlen </a> 027 * @author Chad Brandon 028 * @author Bob Fields 029 */ 030public class UMLModelAccessFacade 031 implements ModelAccessFacade 032{ 033 private static final Logger logger = Logger.getLogger(UMLModelAccessFacade.class); 034 private UmlPackage model; 035 036 /** 037 * @see org.andromda.core.metafacade.ModelAccessFacade#setModel(Object) 038 */ 039 public void setModel(final Object model) 040 { 041 ExceptionUtils.checkNull("model", model); 042 ExceptionUtils.checkAssignable( 043 UmlPackage.class, 044 "modelElement", 045 model.getClass()); 046 this.model = (UmlPackage)model; 047 // TODO: - clears out the foreign key cache (probably not 048 // the cleanest way, but the easiest at this point). 049 EntityMetafacadeUtils.clearForeignKeyConstraintNameCache(); 050 } 051 052 /** 053 * @see org.andromda.core.metafacade.ModelAccessFacade#getModel() 054 */ 055 public UmlPackage getModel() 056 { 057 return model; 058 } 059 060 /** 061 * @see org.andromda.core.metafacade.ModelAccessFacade#getName(Object) 062 */ 063 public String getName(final Object modelElement) 064 { 065 ExceptionUtils.checkNull("modelElement", modelElement); 066 ExceptionUtils.checkAssignable( 067 ModelElementFacade.class, 068 "modelElement", 069 modelElement.getClass()); 070 return ((ModelElementFacade)modelElement).getName(); 071 } 072 073 /** 074 * @see org.andromda.core.metafacade.ModelAccessFacade#getPackageName(Object) 075 */ 076 public String getPackageName(final Object modelElement) 077 { 078 ExceptionUtils.checkNull("modelElement", modelElement); 079 ExceptionUtils.checkAssignable( 080 ModelElementFacade.class, 081 "modelElement", 082 modelElement.getClass()); 083 final ModelElementFacade modelElementFacade = (ModelElementFacade)modelElement; 084 final StringBuilder packageName = new StringBuilder(modelElementFacade.getPackageName(true)); 085 086 // - if the model element is a package then the package name will be the name 087 // of the package with its package name 088 if (modelElement instanceof PackageFacade) 089 { 090 final String name = modelElementFacade.getName(); 091 if (StringUtils.isNotBlank(name)) 092 { 093 packageName.append(MetafacadeConstants.NAMESPACE_SCOPE_OPERATOR); 094 packageName.append(name); 095 } 096 } 097 return packageName.toString(); 098 } 099 100 /** 101 * @see org.andromda.core.metafacade.ModelAccessFacade#getStereotypeNames(Object) 102 */ 103 public Collection<String> getStereotypeNames(final Object modelElement) 104 { 105 Collection<String> stereotypeNames = new ArrayList(); 106 if (modelElement instanceof ModelElement) 107 { 108 ModelElement element = (ModelElement)modelElement; 109 Collection<ModelElement> stereotypes = element.getStereotype(); 110 for (final Iterator<ModelElement> iterator = stereotypes.iterator(); iterator.hasNext();) 111 { 112 ModelElement stereotype = iterator.next(); 113 stereotypeNames.add(stereotype.getName()); 114 } 115 } 116 else if (modelElement instanceof ModelElementFacade) 117 { 118 stereotypeNames = ((ModelElementFacade)modelElement).getStereotypeNames(); 119 } 120 return stereotypeNames; 121 } 122 123 /** 124 * @see org.andromda.core.metafacade.ModelAccessFacade#findByStereotype(String) 125 */ 126 public Collection<MetafacadeBase> findByStereotype(String stereotype) 127 { 128 final String methodName = "UMLModelAccessFacade.findByStereotype"; 129 final Collection<MetafacadeBase> metafacades = new ArrayList<MetafacadeBase>(); 130 stereotype = StringUtils.trimToEmpty(stereotype); 131 if (StringUtils.isNotBlank(stereotype)) 132 { 133 if (this.model != null) 134 { 135 final Collection<ModelElement> underlyingElements = model.getCore().getModelElement().refAllOfType(); 136 if (underlyingElements != null && !underlyingElements.isEmpty()) 137 { 138 for (final ModelElement element : underlyingElements) 139 { 140 Collection<String> stereotypeNames = this.getStereotypeNames(element); 141 if (stereotypeNames != null && stereotypeNames.contains(stereotype)) 142 { 143 metafacades.add(MetafacadeFactory.getInstance().createMetafacade(element)); 144 } 145 } 146 } 147 if (logger.isDebugEnabled()) 148 { 149 logger.debug("completed " + methodName + " with " + metafacades.size() + " modelElements"); 150 } 151 } 152 this.filterMetafacades(metafacades); 153 } 154 return metafacades; 155 } 156 157 /** 158 * @see org.andromda.core.metafacade.ModelAccessFacade#getModelElements() 159 */ 160 public Collection<MetafacadeBase> getModelElements() 161 { 162 Collection<MetafacadeBase> metafacades = Collections.emptyList(); 163 if (this.model != null) 164 { 165 metafacades = 166 MetafacadeFactory.getInstance().createMetafacades( 167 this.model.getCore().getModelElement().refAllOfType()); 168 this.filterMetafacades(metafacades); 169 } 170 return metafacades; 171 } 172 173 /** 174 * Stores the package filter information. Protected 175 * visibility for better inner class access performance. 176 */ 177 protected Filters modelPackages; 178 179 /** 180 * @see org.andromda.core.metafacade.ModelAccessFacade#setPackageFilter(org.andromda.core.configuration.Filters) 181 */ 182 public void setPackageFilter(final Filters modelPackages) 183 { 184 this.modelPackages = modelPackages; 185 } 186 187 /** 188 * Filters out those metafacades which <strong>should </strong> be processed. 189 * 190 * @param metafacades the Collection of modelElements. 191 */ 192 private void filterMetafacades(final Collection metafacades) 193 { 194 if (this.modelPackages != null && !this.modelPackages.isEmpty()) 195 { 196 CollectionUtils.filter( 197 metafacades, 198 new Predicate() 199 { 200 public boolean evaluate(final Object metafacade) 201 { 202 boolean valid = false; 203 if (metafacade instanceof MetafacadeBase) 204 { 205 final ModelElementFacade modelElementFacade = (ModelElementFacade)metafacade; 206 final StringBuilder packageName = new StringBuilder(modelElementFacade.getPackageName(true)); 207 208 // - if the model element is a package then the package name will be the name 209 // of the package with its package name 210 if (metafacade instanceof PackageFacade) 211 { 212 final String name = modelElementFacade.getName(); 213 if (StringUtils.isNotBlank(name)) 214 { 215 packageName.append(MetafacadeConstants.NAMESPACE_SCOPE_OPERATOR); 216 packageName.append(name); 217 } 218 } 219 valid = modelPackages.isApply(packageName.toString()); 220 } 221 return valid; 222 } 223 }); 224 } 225 } 226}