/** * Mule Development Kit * Copyright 2010-2011 (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.mule.devkit.model.meta; import org.mule.api.MuleContext; import org.mule.api.lifecycle.Disposable; import org.mule.api.lifecycle.Initialisable; import org.mule.api.lifecycle.InitialisationException; import org.mule.api.registry.Registry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PropertiesLoaderUtils; import org.springframework.util.CollectionUtils; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; /** * The meta model is used to describe a Mule module internals. It is leveraged by the dynamic module for the * reflection capabilities. */ public class MetaModel implements Initialisable, Disposable { private static Logger logger = LoggerFactory.getLogger(MetaModel.class); private static final String SPRING_SCHEMAS_LOCATION = "META-INF/spring.schemas"; private Map<String, MetaModule> modules; private MuleContext muleContext; private Registry metaRegistry; public MetaModel(MuleContext muleContext) { this.modules = new HashMap<String, MetaModule>(); this.muleContext = muleContext; } @Override protected void finalize() { if (this.muleContext != null) { this.muleContext.removeRegistry(this.metaRegistry); } } /** * Add a module for this model * * @param module Module to be added */ public void addModule(MetaModule module) { this.modules.put(module.getNamespace(), module); } /** * Retrieve all modules available on the classpath * * @return An iterator of {@link MetaModule} */ public Iterator<MetaModule> getAll() { return modules.values().iterator(); } /** * Remove a module for this model * * @param name The name of the module to be removed */ public void removeModule(String name) { this.modules.remove(name); } /** * Retrieve a module by its namespace * * @param namespace The namespace of the module * @return A {@link MetaModule} */ public MetaModule getModule(String namespace) { if (!this.modules.containsKey(namespace)) { throw new IllegalArgumentException("Unable to find a module for namespace " + namespace); } return this.modules.get(namespace); } public Registry getMetaRegistry() { return metaRegistry; } /** * Load the specified class mappings lazily. */ private static synchronized Map<String, String> getSchemas(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Loading schema mappings from [" + SPRING_SCHEMAS_LOCATION + "]"); } try { Properties mappings = PropertiesLoaderUtils.loadAllProperties(SPRING_SCHEMAS_LOCATION, classLoader); if (logger.isDebugEnabled()) { logger.debug("Loaded schema mappings: " + mappings); } Map<String, String> schemaMappings = new ConcurrentHashMap<String, String>(); CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings); return schemaMappings; } catch (IOException ex) { throw new IllegalStateException( "Unable to load schema mappings from location [" + SPRING_SCHEMAS_LOCATION + "]", ex); } } public synchronized void dispose() { if( this.metaRegistry != null ) { this.metaRegistry.dispose(); this.muleContext.removeRegistry(this.metaRegistry); } this.metaRegistry = null; } public synchronized void initialise() throws InitialisationException { Map<String, String> schemas = getSchemas(muleContext.getExecutionClassLoader()); for (String name : schemas.keySet()) { Resource resource = new ClassPathResource(schemas.get(name), muleContext.getExecutionClassLoader()); MetaModule metaModule = null; try { metaModule = MetaModule.parseSchema(this, resource.getInputStream()); } catch (IOException e) { logger.error(e.getMessage(), e); } if (metaModule != null) { addModule(metaModule); } } this.metaRegistry = new MetaRegistry(muleContext); this.muleContext.addRegistry(this.metaRegistry); this.metaRegistry.initialise(); } }