001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021package org.biojava.nbio.structure.align;
022
023import org.biojava.nbio.structure.StructureException;
024import org.biojava.nbio.structure.align.ce.CeCPMain;
025import org.biojava.nbio.structure.align.ce.CeMain;
026import org.biojava.nbio.structure.align.fatcat.FatCatFlexible;
027import org.biojava.nbio.structure.align.fatcat.FatCatRigid;
028import org.biojava.nbio.structure.align.seq.SmithWaterman3Daligner;
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031
032import java.util.ArrayList;
033import java.util.List;
034import java.util.ListIterator;
035
036
037public class StructureAlignmentFactory {
038
039        private final static Logger logger = LoggerFactory.getLogger(StructureAlignmentFactory.class);
040
041        private static List<StructureAlignment> algorithms = new ArrayList<>();
042
043        static {
044                algorithms.add( new CeMain() );
045                algorithms.add( new CeCPMain() );
046                //algorithms.add( new OptimalCECPMain() );
047                //algorithms.add(new CeSideChainMain());
048
049                StructureAlignment fatcatRigid    = new FatCatRigid();
050                StructureAlignment fatcatFlexible = new FatCatFlexible();
051
052                algorithms.add( fatcatRigid) ;
053
054                algorithms.add( fatcatFlexible );
055
056                algorithms.add( new SmithWaterman3Daligner()) ;
057                //algorithms.add( new BioJavaStructureAlignment());
058        }
059
060        /**
061         * Adds a new StructureAlignment algorithm to the list.
062         *
063         * Only one instance is stored for each algorithmName, so it is possible
064         * that a different instance may be returned by getAlgorithm(alg.getAlgorithmName())
065         *
066         * @param alg the alignment algorithm
067         */
068        public static void addAlgorithm(StructureAlignment alg) {
069                //ensure uniqueness
070                try {
071                        getAlgorithm(alg.getAlgorithmName());
072                        // algorithm was found. Do nothing.
073                } catch(StructureException e) {
074                        // no algorithm found, so it's new
075                        algorithms.add(alg);
076                }
077        }
078
079        /**
080         * Removes the specified algorithm from the list of options
081         * @param name the name of the algorithm to remove
082         * @return true if the specified algorithm was found and removed
083         */
084        public static boolean removeAlgorithm(String name) {
085                ListIterator<StructureAlignment> algIt = algorithms.listIterator();
086                while(algIt.hasNext()) {
087                        StructureAlignment alg = algIt.next();
088                        if(alg.getAlgorithmName().equalsIgnoreCase(name)) {
089                                algIt.remove();
090                                return true;
091                        }
092                }
093                return false;
094        }
095
096        /**
097         * Removes all algorithms from the list
098         */
099        public static void clearAlgorithms() {
100                algorithms.clear();
101        }
102
103        public static StructureAlignment getAlgorithm(String name) throws StructureException{
104                for ( StructureAlignment algo : algorithms){
105                        if (algo.getAlgorithmName().equalsIgnoreCase(name)) {
106                                //return algo;
107                                // CeCalculator is not thread safe,
108                                // avoid issues with this in multi-threaded environments bu
109                                // creating a new StructureAlignment every time this is called
110                                try {
111                                        @SuppressWarnings("unchecked")
112                                        Class<StructureAlignment> c = (Class<StructureAlignment>) Class.forName(algo.getClass().getName());
113                                        return c.newInstance();
114                                } catch (ClassNotFoundException e){
115                                        logger.error("Exception: ", e);
116                                        return null;
117                                } catch (IllegalAccessException e){
118                                        logger.error("Exception: ", e);
119                                        return null;
120                                } catch (InstantiationException e){
121                                        logger.error("Exception: ", e);
122                                        return null;
123                                }
124
125
126                        }
127                }
128
129                throw new StructureException("Unknown alignment algorithm: " + name);
130        }
131
132        public static StructureAlignment[] getAllAlgorithms(){
133                return algorithms.toArray(new StructureAlignment[algorithms.size()]);
134        }
135
136        public static String[] getAllAlgorithmNames(){
137                StructureAlignment[] algos = getAllAlgorithms();
138                List<String> names = new ArrayList<String>();
139
140                for (StructureAlignment alg : algos){
141                        names.add(alg.getAlgorithmName());
142                }
143
144                return names.toArray(new String[names.size()]);
145        }
146
147}