001package org.biopax.paxtools.pattern.miner;
002
003import org.biopax.paxtools.controller.PathAccessor;
004
005import java.util.*;
006
007/**
008 * This class is used for defining a custom column in the te
009 * @author Ozgun Babur
010 */
011public class OutputColumn
012{
013        /**
014         * Type of the output column.
015         */
016        private Type type;
017        private PathAccessor[] accessors;
018
019        /**
020         * Constructor with output type. The <code>field</code> parameter can either be a value among
021         * OutputValue.Type enum (excluding the value <code>CUSTOM</code>), or a PathAccessor string to
022         * apply to mediator objects.
023         * @param field type of the custom field
024         */
025        public OutputColumn(String field)
026        {
027                if (field == null)
028                {
029                        throw new IllegalArgumentException("The field parameter has to be specified");
030                }
031
032                try
033                {
034                        type = Type.valueOf(field.toUpperCase());
035                        return;
036                }
037                catch (IllegalArgumentException e){}
038
039                if (type == Type.CUSTOM)
040                {
041                        throw new IllegalArgumentException("The \"custom\" type should be stated " +
042                                "implicitly by passing path accessor strings as parameter.");
043                }
044
045                if (type == null)
046                {
047                        type = Type.CUSTOM;
048                        String[] param = field.split(";");
049                        accessors = new PathAccessor[param.length];
050                        for (int i = 0; i < accessors.length; i++)
051                        {
052                                if (!param[i].contains("/"))
053                                {
054                                        throw new IllegalArgumentException("The parameter column field is not " +
055                                                "recognized as a pre-defined type. It also does not qualify as a path" +
056                                                " accessor argument string.");
057                                }
058
059                                accessors[i] = new PathAccessor(param[i]);
060                        }
061                }
062        }
063
064        /**
065         * Get the string to write in the output file.
066         * @param inter the binary interaction
067         * @return column value
068         */
069        public String getColumnValue(SIFInteraction inter)
070        {
071                switch (type)
072                {
073                        case MEDIATOR: return concat(inter.getMediatorIDs());
074                        case PATHWAY: return concat(inter.getPathwayNames());
075                        case PUBMED: return concat(inter.getPubmedIDs());
076                        case RESOURCE: return concat(inter.getDataSources());
077                        case SOURCE_LOC: return concat(inter.getCellularLocationsOfSource());
078                        case TARGET_LOC: return concat(inter.getCellularLocationsOfTarget());
079                        case CUSTOM:
080                        {
081                                Set<String> set = new HashSet<String>();
082                                for (PathAccessor acc : accessors)
083                                {
084                                        for (Object o : acc.getValueFromBeans(inter.mediators))
085                                        {
086                                                set.add(o.toString());
087                                        }
088                                }
089                                List<String> list = new ArrayList<String>(set);
090                                Collections.sort(list);
091                                return concat(list);
092                        }
093                        default: throw new RuntimeException("Unhandled type: " + type +
094                                ". This shouldn't be happening.");
095                }
096        }
097
098        /**
099         * Concatenates the given collection of strings into a single string where values are separated
100         * with a semicolon.
101         * @param col string collection
102         * @return concatenated string
103         */
104        private String concat(Collection<String> col)
105        {
106                StringBuilder b = new StringBuilder();
107                boolean first = true;
108                for (String s : col)
109                {
110                        if (first) first = false;
111                        else b.append(";");
112
113                        b.append(s);
114                }
115                return b.toString();
116        }
117
118        /**
119         * Type of the output column.
120         */
121        public enum Type
122        {
123                MEDIATOR,
124                PUBMED,
125                PATHWAY,
126                RESOURCE,
127                SOURCE_LOC,
128                TARGET_LOC,
129                CUSTOM;
130
131                public static Type getType(String name)
132                {
133                        for (Type type : values())
134                        {
135                                if (type.name().toLowerCase().equals(name.toLowerCase())) return type;
136                        }
137                        return null;
138                }
139        }
140}