001    package calhoun.analysis.crf.io;
002    
003    import java.io.File;
004    import java.io.IOException;
005    import java.io.Serializable;
006    import java.util.ArrayList;
007    import java.util.HashMap;
008    import java.util.Iterator;
009    import java.util.List;
010    import java.util.Map;
011    
012    import calhoun.analysis.crf.Conrad;
013    
014    /** a legacy input used in the original XML configuration.  No longer used. <p>
015     * Represents a composite input made of several different sequences.  This is useful when putting together different
016     * features that may take different inputs. 
017     * If the input components are created without file entries, then the input is read from a single file and all of the components are included in the single file.
018     * If the input components are created with file names, then each input component is read from its own file. 
019     */
020    @Deprecated
021    public class CompositeInput implements Serializable {
022            private static final long serialVersionUID = -5179361895471860850L;
023    
024            List<InputComponent> components;
025            String hiddenSequenceFile = "hidden.dat";
026            TrainingSequenceIO hiddenSequenceReader = new IntInput();
027            
028            public static class InputComponent implements Serializable {
029                    private static final long serialVersionUID = -652343588509377034L;
030                    String name;
031                    InterleavedInputComponentBase inputSequence;
032                    String filename;
033                    
034                    public String getFilename() {
035                            return filename;
036                    }
037                    public void setFilename(String filename) {
038                            this.filename = filename;
039                    }
040                    public InterleavedInputComponentBase getInputSequence() {
041                            return inputSequence;
042                    }
043                    public void setInputSequence(InterleavedInputComponentBase inputSequence) {
044                            this.inputSequence = inputSequence;
045                    }
046                    public String getName() {
047                            return name;
048                    }
049                    public void setName(String name) {
050                            this.name = name;
051                    }
052            }
053            
054            public void setComponents(List<InputComponent> components) {
055                    this.components = components;
056            }
057    
058            public String getHiddenSequenceFile() {
059                    return hiddenSequenceFile;
060            }
061    
062            public void setHiddenSequenceFile(String hiddenSequenceFile) {
063                    this.hiddenSequenceFile = hiddenSequenceFile;
064            }
065    
066            public TrainingSequenceIO getHiddenSequenceReader() {
067                    return hiddenSequenceReader;
068            }
069            
070            public void setHiddenSequenceReader(TrainingSequenceIO hiddenSequenceReader) {
071                    this.hiddenSequenceReader = hiddenSequenceReader;
072            }
073            
074            /** legacy {@link InputHandler} that mirrors the original XML config file behavior.  
075             * There is a small amount of support in {@link Conrad} to set this up to be truly backwards compatible.
076            */
077            public static class LegacyInputHandler implements InputHandler {
078                    private static final long serialVersionUID = -5031580949745955877L;
079    
080                    Object inputComponent;
081                    InputHandler handler;
082                    
083                    /** special constructor used by {@link Conrad} to pass the old style input config to the legacy input handler.
084                     * @param inputComponent the originally configured inputFormat bean.
085                     */
086                    public LegacyInputHandler(Object inputComponent) {
087                            this.inputComponent = inputComponent;
088                    }
089                    
090                    public Iterator<? extends InputSequence<?>> readInputData(String inputLocation) throws IOException {
091                            initInputHandler(inputLocation);
092                            return handler.readInputData(inputLocation);
093                    }
094                    
095                    public List<? extends TrainingSequence<?>> readTrainingData(String location) throws IOException {
096                            return readTrainingData(location, false);
097                    }
098                    
099                    public List<? extends TrainingSequence<?>> readTrainingData(String inputLocation, boolean predict) throws IOException {
100                            initInputHandler(inputLocation);
101                            return handler.readTrainingData(inputLocation, predict);
102                    }
103                    
104                    public void writeTrainingData(String location, List data) throws IOException {
105                            initInputHandler(location);
106                            handler.writeTrainingData(location, data);
107                    }
108    
109                    public void writeInputData(String location, Iterator data) throws IOException {
110                            initInputHandler(location);
111                            handler.writeInputData(location, data);
112                    }
113    
114                    /** default behavor.  If a single input component is listed, always assume it is a file.  If a composite is specified,
115                     * choose interleaved or directory based on the value of the inputLocation parameter.
116                     */
117                    void initInputHandler(final String inputLocation) {
118                            if(handler != null)
119                                    return;
120                            if(!(inputComponent instanceof CompositeInput)) {
121                                    handler = new InputHandlerInterleaved((InterleavedInputComponent) inputComponent);
122                                    return;
123                            }
124                            final CompositeInput compositeInput = (CompositeInput) inputComponent;
125                            File file = new File(inputLocation);
126                            if(file.isDirectory()) {
127                                    InputHandlerDirectory d = new InputHandlerDirectory();
128                                    d.setHiddenSequenceFile(compositeInput.getHiddenSequenceFile());
129                                    d.setHiddenStateReader(compositeInput.getHiddenSequenceReader());
130    
131                                    Map<String, InputComponentIO> components = new HashMap();
132                                    for(InputComponent comp : compositeInput.components) {
133                                            comp.getInputSequence().setName(comp.getName());
134                                            components.put(comp.getFilename(), comp.getInputSequence());
135                                    }
136                                    d.setInputReaders(components);
137                                    handler = d;
138                            }
139                            else {
140                                    InputHandlerInterleaved interleaved = new InputHandlerInterleaved();
141                                    interleaved.setHiddenStateReader((IntInput)compositeInput.getHiddenSequenceReader());
142                                    List<InterleavedInputComponent> components = new ArrayList();
143                                    for(InputComponent comp : compositeInput.components) {
144                                            comp.getInputSequence().setName(comp.getName());
145                                            components.add(comp.getInputSequence());
146                                    }
147                                    interleaved.setComponents(components);
148                                    handler = interleaved;
149                            }
150                    }
151            }
152    }