001package ca.uhn.hl7v2.conf.store;
002
003import java.util.*;
004import java.util.regex.*;
005import ca.uhn.hl7v2.util.Home;
006
007/**
008 * Provides access to a (configurable) ProfileStore.  
009 * @author Bryan Tripp
010 */
011public class ProfileStoreFactory {
012    
013    private static ProfileStore instance;
014    private static List<CodeStoreRegistration> codeStores = new ArrayList<CodeStoreRegistration>();
015    
016    /** 
017     * Returns a single configurable instance of a ProfileStore.   
018     * Configurable by calling setStore().  Defaults to FileProfileStore
019     * using the current <hapi.home>/profiles as a base directory
020     * Note: not a singleton (by design) in that nothing prevents creation 
021     * of profile stores by other means.  
022     */
023    public synchronized static ProfileStore getProfileStore() {
024        if (instance == null) 
025            instance = new FileProfileStore(Home.getHomeDirectory().getAbsolutePath() + "/profiles");
026        
027        return instance;
028    }
029    
030    /**
031     * Sets the profile store that will be returned in subsequent calls 
032     * to getProfileStore(). 
033     */
034    public synchronized static void setStore(ProfileStore store) {
035        instance = store;
036    }
037    
038    /**
039     * Registers a code store for use with all profiles.  
040     */
041    public static void addCodeStore(CodeStore store) {
042        addCodeStore(store, ".*");
043    }
044    
045    
046    /**
047     * Registers a code store for use with a specific profile.  
048     */
049    public static void addCodeStore(CodeStore store, String profileID) {
050        Pattern p = Pattern.compile(profileID);
051        addCodeStore(store, p);
052    }
053    
054    /**
055     * Registers a code store for use with certain profiles.  The profiles with 
056     * which the code store are used are determined by profileIdPattern, which is 
057     * a regular expression that will be matched against profile IDs.  For example
058     * suppose there are three profiles in the profile store, with the following IDs: 
059     * <ol><li>ADT:confsig-UHN-2.4-profile-AL-NE-Immediate</li>
060     * <li>ADT:confsig-CIHI-2.4-profile-AL-NE-Immediate</li>
061     * <li>ADT:confsig-CIHI-2.3-profile-AL-NE-Immediate</li>
062     * </ol>
063     * Then to use a code store with only the first profile, the profileIdPattern 
064     * would be "ADT:confsig-UHN-2.4-profile-AL-NE-Immediate".  To use a code store 
065     * with both of the 2.4 profiles, the pattern would be ".*2\\.4.*".  To use a 
066     * code store with all profiles, the pattern would be '.*".
067     * Multiple stores can be registered for use with the same profile.  If this 
068     * happens, the first one that returned true for knowsCodes(codeSystem) will 
069     * used.  Stores are searched in the order they are added here.  
070     */
071    public static void addCodeStore(CodeStore store, Pattern profileIdPattern) {
072        codeStores.add(new CodeStoreRegistration(profileIdPattern, store));
073    }
074    
075    /**
076     * Returns the first code store that knows the codes in the given code 
077     * system (as per CodeStore.knowsCodes) and is registered for the given profile.  
078     * Code stores are checked in the order in which they are added (with addCodeStore()).  
079     * @return null if none are found 
080     */
081    public static CodeStore getCodeStore(String profileID, String codeSystem) {
082        CodeStore store = null;
083        for (int i = 0; i < codeStores.size() && store == null; i++) {            
084            CodeStoreRegistration reg = codeStores.get(i);
085            
086            if (reg.pattern.matcher(profileID).matches() 
087                && reg.store.knowsCodes(codeSystem))
088                    store = reg.store;            
089        }
090        return store;
091    }
092    
093    /** A struct to hold registrations of code stores */
094    private static class CodeStoreRegistration {
095        public Pattern pattern;
096        public CodeStore store;
097
098        public CodeStoreRegistration(Pattern p, CodeStore cs) {
099            pattern = p;
100            store = cs;
101        }
102    }
103}