/* * #%L * carewebframework * %% * Copyright (C) 2008 - 2016 Regenstrief Institute, Inc. * %% * 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. * * This Source Code Form is also subject to the terms of the Health-Related * Additional Disclaimer of Warranty and Limitation of Liability available at * * http://www.carewebframework.org/licensing/disclaimer. * * #L% */ package org.carewebframework.api.alias; import java.io.IOException; import java.io.InputStream; import java.util.Map.Entry; import java.util.Properties; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.carewebframework.common.AbstractRegistry; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.io.Resource; /** * Global registry for aliases. Supports aliases for different alias types as defined by the * AliasType class. Aliases may be loaded from one or more property files and may be added * programmatically. */ public class AliasTypeRegistry extends AbstractRegistry<String, AliasType> implements ApplicationContextAware { private static final Log log = LogFactory.getLog(AliasTypeRegistry.class); private static final AliasTypeRegistry instance = new AliasTypeRegistry(); private static final char PREFIX_DELIM = '^'; private static final String PREFIX_DELIM_REGEX = "\\" + PREFIX_DELIM; private String propertyFile; private int fileCount; private int entryCount; /** * Returns reference to the alias registry. * * @return Reference to the alias registry. */ public static AliasTypeRegistry getInstance() { return instance; } /** * Convenience method for accessing alias type. * * @param type Key associated with alias type. * @return The alias type (never null). */ public static AliasType getType(String type) { return instance.get(type); } /** * Registers an alias for a key. * * @param type Name of the alias type. * @param local Local name. * @param alias Alias for the local name. A null value removes any existing alias. */ public static void register(String type, String local, String alias) { instance.get(type).register(local, alias); } /** * Enforce singleton instance. */ private AliasTypeRegistry() { super(); } /** * Sets the property file from which aliases are to be loaded. May be null or empty. * * @param propertyFile Path of the property file. */ public void setPropertyFile(String propertyFile) { this.propertyFile = propertyFile; } /** * Returns the AliasType given the key, creating and registering it if it does not already * exist. * * @param key Unique key of alias type. * @return The alias type (never null). */ @Override public AliasType get(String key) { key = key.toUpperCase(); AliasType type = super.get(key); if (type == null) { register(type = new AliasType(key)); } return type; } /** * Loads aliases defined in an external property file, if specified. */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (StringUtils.isEmpty(propertyFile)) { return; } for (String pf : propertyFile.split("\\,")) { loadAliases(applicationContext, pf); } if (fileCount > 0) { log.info("Loaded " + entryCount + " aliases from " + fileCount + " files."); } } /** * Load aliases from a property file. * * @param applicationContext The application context. * @param propertyFile A property file. */ private void loadAliases(ApplicationContext applicationContext, String propertyFile) { if (propertyFile.isEmpty()) { return; } Resource[] resources; try { resources = applicationContext.getResources(propertyFile); } catch (IOException e) { log.error("Failed to locate alias property file: " + propertyFile, e); return; } for (Resource resource : resources) { if (!resource.exists()) { log.info("Did not find alias property file: " + resource.getFilename()); continue; } InputStream is = null; try { is = resource.getInputStream(); Properties props = new Properties(); props.load(is); for (Entry<Object, Object> entry : props.entrySet()) { try { register((String) entry.getKey(), (String) entry.getValue()); entryCount++; } catch (Exception e) { log.error("Error registering alias for '" + entry.getKey() + "'.", e); } } fileCount++; } catch (IOException e) { log.error("Failed to load alias property file: " + resource.getFilename(), e); } finally { IOUtils.closeQuietly(is); } } } /** * Registers an alias for a key prefixed with an alias type. * * @param key Local name with alias type prefix. * @param alias Alias for the key. A null value removes any existing alias. */ private void register(String key, String alias) { String[] pcs = key.split(PREFIX_DELIM_REGEX, 2); if (pcs.length != 2) { throw new IllegalArgumentException("Illegal key value: " + key); } register(pcs[0], pcs[1], alias); } @Override protected String getKey(AliasType item) { return item.getName(); } }