001    package ca.uhn.hl7v2.conf.store;
002    
003    import java.util.*;
004    import java.util.regex.*;
005    import ca.uhn.hl7v2.util.Home;
006    
007    /**
008     * Provides access to a (configurable) ProfileStore.  
009     * @author Bryan Tripp
010     */
011    public class ProfileStoreFactory {
012        
013        private static ProfileStore instance;
014        private static ArrayList codeStores = new ArrayList();
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 = (CodeStoreRegistration) 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    }