001package org.andromda.core.configuration; 002 003import java.io.InputStream; 004import java.io.InputStreamReader; 005import java.io.Serializable; 006import java.net.URL; 007import java.util.ArrayList; 008import java.util.Arrays; 009import java.util.Collection; 010import org.andromda.core.common.ResourceUtils; 011import org.andromda.core.common.XmlObjectFactory; 012import org.andromda.core.mapping.Mappings; 013import org.apache.commons.lang.StringUtils; 014 015/** 016 * This object is configured from the AndroMDA configuration 017 * XML file. Its used to configure AndroMDA before modeling 018 * processing occurs. 019 * 020 * @author Chad Brandon 021 */ 022public class Configuration 023 implements Serializable 024{ 025 private static final long serialVersionUID = 34L; 026 027 /** 028 * Gets a Configuration instance from the given <code>uri</code>. 029 * 030 * @param uri the URI to the configuration file. 031 * @return the configured instance. 032 */ 033 public static Configuration getInstance(final URL uri) 034 { 035 final Configuration configuration = 036 (Configuration)XmlObjectFactory.getInstance(Configuration.class).getObject(uri); 037 configuration.setContents(ResourceUtils.getContents(uri)); 038 return configuration; 039 } 040 041 /** 042 * Gets a Configuration instance from the given <code>stream</code>. 043 * 044 * @param stream the InputStream containing the configuration file. 045 * @return the configured instance. 046 */ 047 public static Configuration getInstance(final InputStream stream) 048 { 049 final Configuration configuration = 050 (Configuration)XmlObjectFactory.getInstance(Configuration.class).getObject(new InputStreamReader(stream)); 051 configuration.setContents(ResourceUtils.getContents(new InputStreamReader(stream))); 052 return configuration; 053 } 054 055 /** 056 * Gets a Configuration instance from the given <code>string</code>. 057 * 058 * @param string the String containing the configuration. 059 * @return the configured instance. 060 */ 061 public static Configuration getInstance(final String string) 062 { 063 final Configuration configuration = 064 (Configuration)XmlObjectFactory.getInstance(Configuration.class).getObject(string); 065 configuration.setContents(string); 066 return configuration; 067 } 068 069 /** 070 * Initializes this configuration instance. 071 */ 072 public void initialize() 073 { 074 this.initializeNamespaces(); 075 this.initializeMappings(); 076 } 077 078 /** 079 * Stores the repositories for this Configuration instance. 080 */ 081 private final Collection<Repository> repositories = new ArrayList<Repository>(); 082 083 /** 084 * Adds the repository to this configuration. 085 * 086 * @param repository the repository instance. 087 */ 088 public void addRepository(final Repository repository) 089 { 090 this.repositories.add(repository); 091 } 092 093 /** 094 * Gets the repository instances belonging to this configuration. 095 * 096 * @return the collection of repository instances. 097 */ 098 public Repository[] getRepositories() 099 { 100 return this.repositories.toArray(new Repository[this.repositories.size()]); 101 } 102 103 /** 104 * Stores the configuration namespaces. 105 */ 106 private final Collection<Namespace> namespaces = new ArrayList<Namespace>(); 107 108 /** 109 * Adds a namespace to this configuration. 110 * 111 * @param namespace the configured namespace to add. 112 */ 113 public void addNamespace(final Namespace namespace) 114 { 115 this.namespaces.add(namespace); 116 } 117 118 /** 119 * Gets the configuration namespaces. 120 * 121 * @return the array of {@link Namespace} instances. 122 */ 123 public Namespace[] getNamespaces() 124 { 125 return this.namespaces.toArray(new Namespace[this.namespaces.size()]); 126 } 127 128 /** 129 * Stores the properties for this configuration (these 130 * gobally configure AndroMDA). 131 */ 132 private final Collection<Property> properties = new ArrayList<Property>(); 133 134 /** 135 * Adds a property to this configuration instance. 136 * 137 * @param property the property to add. 138 */ 139 public void addProperty(final Property property) 140 { 141 this.properties.add(property); 142 } 143 144 /** 145 * Gets the properties belonging to this configuration. 146 * 147 * @return the collection of {@link Property} instances. 148 */ 149 public Property[] getProperties() 150 { 151 return this.properties.toArray(new Property[this.properties.size()]); 152 } 153 154 /** 155 * Stores the AndroMDA server configuration information. 156 */ 157 private Server server; 158 159 /** 160 * Sets the server instance for this configuration. 161 * 162 * @param server the information which configures the AndroMDA server. 163 */ 164 public void setServer(final Server server) 165 { 166 this.server = server; 167 } 168 169 /** 170 * Gets the server instance for this configuration. 171 * The {@link Server} holds the information to configure 172 * the AndroMDA server. 173 * 174 * @return the andromda server. 175 */ 176 public Server getServer() 177 { 178 return this.server; 179 } 180 181 /** 182 * The locations in which to search for mappings. 183 */ 184 private final Collection<Location> mappingsSearchLocations = new ArrayList<Location>(); 185 186 /** 187 * Adds a mappings search location (these are the locations 188 * in which a search for mappings is performed). 189 * 190 * @param location a location path. 191 * @see #addMappingsSearchLocation(String) 192 */ 193 public void addMappingsSearchLocation(final Location location) 194 { 195 if (location != null) 196 { 197 this.mappingsSearchLocations.add(location); 198 } 199 } 200 201 /** 202 * Adds a mappings search location path (a location 203 * without a pattern defined). 204 * 205 * @param path a location path. 206 * @see #addMappingsSearchLocation(Location) 207 */ 208 public void addMappingsSearchLocation(final String path) 209 { 210 if (path != null) 211 { 212 final Location location = new Location(); 213 location.setPath(path); 214 this.mappingsSearchLocations.add(location); 215 } 216 } 217 218 /** 219 * Gets the mappings search locations for this configuration instance. 220 * 221 * @return the mappings search locations. 222 */ 223 public Location[] getMappingsSearchLocations() 224 { 225 return this.mappingsSearchLocations.toArray(new Location[this.mappingsSearchLocations.size()]); 226 } 227 228 /** 229 * Stores the contents of the configuration as a string. 230 */ 231 private String contents = null; 232 233 /** 234 * Gets the URI from which this instance was 235 * configured or null (it it was not set). 236 * @return the URI as a String instance 237 */ 238 public String getContents() 239 { 240 return this.contents; 241 } 242 243 /** 244 * Clears out any caches used by this configuration. 245 */ 246 public static void clearCaches() 247 { 248 Model.clearLastModifiedTimes(); 249 } 250 251 /** 252 * Sets the contents of this configuration as a 253 * string. 254 * @param contents the contents of this configuration as a string. 255 */ 256 private void setContents(final String contents) 257 { 258 this.contents = StringUtils.trimToEmpty(contents); 259 } 260 261 /** 262 * Initializes the namespaces with the namespaces from 263 * this configuration. 264 */ 265 private void initializeNamespaces() 266 { 267 final Namespaces namespaces = Namespaces.instance(); 268 namespaces.clear(); 269 namespaces.addNamespaces(this.getNamespaces()); 270 } 271 272 /** 273 * Loads all mappings from the specified mapping search locations. 274 * If the location points to a directory the directory 275 * contents will be loaded, otherwise just the mapping itself will be loaded. 276 */ 277 private void initializeMappings() 278 { 279 if (this.mappingsSearchLocations != null) 280 { 281 final Collection<URL> mappingsLocations = new ArrayList<URL>(); 282 final Location[] locations = this.getMappingsSearchLocations(); 283 for (final Location location : locations) 284 { 285 mappingsLocations.addAll(Arrays.asList(location.getResources())); 286 } 287 288 // clear out any old cached mappings 289 Mappings.clearLogicalMappings(); 290 291 for (final URL mappingsUri : mappingsLocations) 292 { 293 try 294 { 295 Mappings.addLogicalMappings(mappingsUri); 296 } 297 catch (final Throwable throwable) 298 { 299 // - ignore the exception (probably means its a file 300 // other than a mapping and in that case we don't care) 301 } 302 } 303 // - now initialize the logical mappings since we've found them all 304 Mappings.initializeLogicalMappings(); 305 } 306 } 307}