001package org.biopax.paxtools.util;
002
003
004import org.apache.commons.logging.Log;
005import org.apache.commons.logging.LogFactory;
006import org.biopax.paxtools.model.BioPAXElement;
007
008import java.util.HashMap;
009import java.util.HashSet;
010import java.util.Map;
011import java.util.Set;
012
013
014public enum BPCollections
015{
016        I;
017
018        private CollectionProvider cProvider;
019
020        private final Log log = LogFactory.getLog(BPCollections.class);
021
022        private BPCollections()
023        {
024                String prop = System.getProperty("paxtools.CollectionProvider");
025                log.info("System property: paxtools.CollectionProvider=" + prop);               
026                if (prop != null)
027                {
028                        try
029                        {
030                                Class<? extends CollectionProvider> cProviderClass =
031                                                (Class<? extends CollectionProvider>) Class.forName(prop);
032                                cProvider = cProviderClass.newInstance();
033                                log.info("CollectionProvider " + prop + " was successfully activated.");
034                        }
035                        catch (Exception e) // catch (IllegalAccessException | ClassNotFoundException | InstantiationException e)
036                        {
037                                log.warn("Could not initialize the specified collector provider:" + prop +
038                                         " . Falling back to default " +
039                                         "Hash based implementation. Underlying exception is " + e);
040
041                        }
042                }
043
044                if (cProvider == null) {
045                        cProvider = new CollectionProvider() {
046                                @Override
047                                public <R> Set<R> createSet() {
048                                        return new HashSet<R>();
049                                }
050
051                                @Override
052                                public <D, R> Map<D, R> createMap() {
053                                        return new HashMap<D, R>();
054                                }
055                        };
056                        log.info("Using the default CollectionProvider (creates HashMap, HashSet).");
057                }
058                
059        }
060
061        /**
062         * This interface is responsible for setting the class 
063         * and initialize and load factor for all sets and maps 
064         * used in all model objects for performance purposes.
065         */
066        public interface CollectionProvider
067        {
068                public <R> Set<R> createSet();
069
070                public <D, R> Map<D, R> createMap();
071        }
072
073        /**
074         * Sets a specific {@link CollectionProvider} (for 
075         * multiple-cardinality BioPAX properties)
076         * 
077         * @param newProvider not null
078         */
079        public void setProvider(CollectionProvider newProvider)
080        {
081                if(newProvider == null)
082                        throw new IllegalArgumentException();
083                
084                cProvider = newProvider;
085                
086                log.info("Using CollectionProvider: " 
087                                + newProvider.getClass().getSimpleName());
088        }
089
090        public <R> Set<R> createSet()
091        {
092                return cProvider.createSet();
093        }
094
095        public <R extends BioPAXElement> Set<R> createSafeSet()
096        {
097                return new BiopaxSafeSet<R>();
098        }
099
100        public <D, R> Map<D, R> createMap()
101        {
102                return cProvider.createMap();
103        }
104}