001    /*
002     * The contents of this file are subject to the Mozilla Public
003     * License Version 1.1 (the "License"); you may not use this file
004     * except in compliance with the License. You may obtain a copy of
005     * the License at http://www.mozilla.org/MPL/
006     *
007     * Software distributed under the License is distributed on an "AS
008     * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
009     * implied. See the License for the specific language governing
010     * rights and limitations under the License.
011     *
012     * The Original Code is Knowtator.
013     *
014     * The Initial Developer of the Original Code is University of Colorado.  
015     * Copyright (C) 2005 - 2008.  All Rights Reserved.
016     *
017     * Knowtator was developed by the Center for Computational Pharmacology
018     * (http://compbio.uchcs.edu) at the University of Colorado Health 
019     *  Sciences Center School of Medicine with support from the National 
020     *  Library of Medicine.  
021     *
022     * Current information about Knowtator can be obtained at 
023     * http://knowtator.sourceforge.net/
024     *
025     * Contributor(s):
026     *   Philip V. Ogren <philip@ogren.info> (Original Author)
027     */
028    
029    package edu.uchsc.ccp.knowtator.textsource.filelines;
030    
031    import java.awt.Component;
032    import java.io.File;
033    import java.io.FileInputStream;
034    import java.io.IOException;
035    import java.util.ArrayList;
036    import java.util.HashMap;
037    import java.util.List;
038    import java.util.Map;
039    import java.util.regex.Matcher;
040    import java.util.regex.Pattern;
041    
042    import javax.swing.JFileChooser;
043    import javax.swing.JOptionPane;
044    
045    import edu.stanford.smi.protege.model.Cls;
046    import edu.stanford.smi.protege.model.KnowledgeBase;
047    import edu.stanford.smi.protege.model.Project;
048    import edu.uchsc.ccp.knowtator.KnowtatorProjectUtil;
049    import edu.uchsc.ccp.knowtator.textsource.TextSource;
050    import edu.uchsc.ccp.knowtator.textsource.TextSourceAccessException;
051    import edu.uchsc.ccp.knowtator.textsource.TextSourceCollection;
052    import edu.uchsc.ccp.knowtator.textsource.TextSourceIterator;
053    import edu.uchsc.ccp.util.io.FileReadingUtil;
054    
055    public class FileLinesTextSourceCollection extends TextSourceCollection {
056    
057            public static final String DISPLAY_NAME = "Lines from file";
058    
059            public static final String CLS_NAME = "file line text source";
060    
061            public static final String PROJECT_SETTING_RECENT_FILE = new String("FileLinesTextSourceCollection_RECENT_FILE");
062    
063            File file;
064    
065            char nameChar;
066    
067            String name;
068    
069            protected Map<String, TextSource> namesToTextSource;
070    
071            protected Map<TextSource, Integer> textSourceToIndex;
072    
073            List<TextSource> textSources;
074    
075            List<String> textSourceNames;
076    
077            public FileLinesTextSourceCollection(String fileName) throws IOException {
078                    this(new File(fileName));
079            }
080    
081            public FileLinesTextSourceCollection(File file) throws IOException {
082                    this.file = file;
083                    name = file.getName();
084                    namesToTextSource = new HashMap<String, TextSource>();
085                    textSourceToIndex = new HashMap<TextSource, Integer>();
086    
087                    String[] fileLines = FileReadingUtil.readFileLines(new FileInputStream(file));
088    
089                    textSources = new ArrayList<TextSource>(fileLines.length);
090                    textSourceNames = new ArrayList<String>(fileLines.length);
091    
092                    for (int i = 0; i < fileLines.length; i++) {
093                            TextSource textSource = createTextSource(fileLines[i]);
094                            String name = textSource.getName();
095                            namesToTextSource.put(name, textSource);
096                            textSourceToIndex.put(textSource, i);
097    
098                            textSources.add(textSource);
099                            textSourceNames.add(name);
100                    }
101                    // Collections.sort(textSourceNames);
102            }
103    
104            protected TextSource createTextSource(String fileLine) {
105                    String name = fileLine.substring(0, fileLine.indexOf("|"));
106                    String text = fileLine.substring(name.length() + 1) + " ";
107                    return new FileLineTextSource(name, text);
108            }
109    
110            public File getFile() {
111                    return this.file;
112            }
113    
114            public TextSource get(int index) throws TextSourceAccessException {
115                    TextSource textSource = textSources.get(index);
116                    if (textSource != null)
117                            return textSources.get(index);
118                    throw new TextSourceAccessException("There is no text source at index=" + index
119                                    + " for text source collection = " + getName());
120            }
121    
122            public int size() {
123                    return textSources.size();
124            }
125    
126            public String getName() {
127                    return name;
128            }
129    
130            public int getIndex(TextSource textSource) {
131                    return textSourceToIndex.get(textSource);
132            }
133    
134            public TextSource get(String name) throws TextSourceAccessException {
135                    TextSource textSource = (TextSource) namesToTextSource.get(name);
136                    if (textSource != null)
137                            return textSource;
138                    throw new TextSourceAccessException("There is no text source for name='" + name
139                                    + "' for text source collection = " + getName());
140            }
141    
142            public TextSource select(Component parent) {
143                    Object selection = JOptionPane.showInputDialog(parent, "Select text source", "Select text source",
144                                    JOptionPane.INFORMATION_MESSAGE, null, textSourceNames.toArray(), textSourceNames.toArray()[0]);
145                    try {
146                            if (selection != null)
147                                    return get((String) selection);
148                    } catch (TextSourceAccessException tsae) {
149                            return null;
150                    }
151                    return null;
152            }
153    
154            
155            public TextSource find(Component parent) {
156                    String searchString = JOptionPane.showInputDialog(parent, "Enter a regular expression for the name of a text source", "Find a text source",
157                                    JOptionPane.PLAIN_MESSAGE);
158                    Pattern pattern = Pattern.compile(searchString);
159                    Matcher matcher;
160                    try {
161    
162                            for (String textSourceName : textSourceNames) {
163                                    matcher = pattern.matcher(textSourceName);
164                                    if (matcher.find())
165                                            return get(textSourceName);
166    
167                            }
168                    } catch (TextSourceAccessException tsae) {
169                            tsae.printStackTrace();
170                    }
171                    
172                    JOptionPane.showMessageDialog(parent, "No text source found with a name matching the search string you provided.");
173                    return null;
174            }
175    
176            public void save(Project project) {
177                    String filePath = getFile().getPath();
178                    String projectPath = new File(project.getProjectDirectoryURI().getPath()).getPath();
179    
180                    if (filePath.startsWith(projectPath)) {
181                            filePath = filePath.substring(projectPath.length() + 1);
182                    }
183                    project.setClientInformation(PROJECT_SETTING_RECENT_FILE, filePath);
184            }
185    
186            public static TextSourceCollection open(Project project) {
187                    File recentFile = getRecentFile(project);
188                    if (recentFile != null) {
189                            try {
190                                    TextSourceCollection tsc = new FileLinesTextSourceCollection(recentFile);
191                                    return tsc;
192                            } catch (IOException ioe) {
193                                    ioe.printStackTrace();
194                            }
195                    }
196                    return null;
197            }
198    
199            private static File getRecentFile(Project project) {
200                    String path = (String) project.getClientInformation(PROJECT_SETTING_RECENT_FILE);
201                    if (path == null)
202                            return null;
203    
204                    File recentFile = new File(path);
205                    if (!recentFile.isAbsolute()) {
206                            // the path of the annotation project files
207                            String annotationProjectPath = new File(project.getProjectDirectoryURI()).getPath();
208                            String recentPath = annotationProjectPath + File.separator + path;
209                            recentFile = new File(recentPath);
210                            if (recentFile != null && recentFile.exists() && recentFile.isFile()) {
211                                    return recentFile;
212                            } else
213                                    recentFile = new File(path); // set it back to what it was
214                                                                                             // before trying to resolve to
215                                                                                             // annotation project path.
216                    }
217                    if (recentFile != null && recentFile.exists() && recentFile.isFile()) {
218                            return recentFile;
219                    }
220                    return null;
221            }
222    
223            public static TextSourceCollection open(Project project, Component parent) {
224                    JFileChooser chooser = new JFileChooser();
225                    File recentFile = getRecentFile(project);
226                    if (recentFile != null) {
227                            chooser.setSelectedFile(recentFile);
228                    }
229                    chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
230                    int returnVal = chooser.showOpenDialog(parent);
231                    if (returnVal == JFileChooser.APPROVE_OPTION) {
232                            File file = chooser.getSelectedFile();
233                            if (file.exists()) {
234                                    try {
235                                            return new FileLinesTextSourceCollection(file);
236                                    } catch (IOException ioe) {
237                                            ioe.printStackTrace();
238                                            JOptionPane.showMessageDialog(parent, "Unable to open file as a text source collection: "
239                                                            + ioe.getMessage(), "", JOptionPane.ERROR_MESSAGE);
240                                    }
241                            } else {
242                                    JOptionPane.showMessageDialog(parent, "The file: '" + file.getPath() + "' was not found.");
243                            }
244                    }
245                    return null;
246            }
247    
248            public TextSourceIterator iterator() {
249                    return new FileLinesTextSourceIterator();
250            }
251    
252            class FileLinesTextSourceIterator implements TextSourceIterator {
253                    int tsIndex = -1;
254    
255                    public TextSource next() throws TextSourceAccessException {
256                            try {
257                                    return textSources.get(++tsIndex);
258                            } catch (IndexOutOfBoundsException ioobe) {
259                                    throw new TextSourceAccessException(ioobe);
260                            }
261                    }
262    
263                    public boolean hasNext() {
264                            return (tsIndex + 1) < textSources.size();
265                    }
266    
267            }
268    
269            public static void createCls(KnowledgeBase kb) {
270    
271                    if (kb.getCls(CLS_NAME) == null) {
272                            Cls textSourceParent = kb.getCls(KnowtatorProjectUtil.TEXT_SOURCE_CLS_NAME);
273                            ArrayList parents = new ArrayList();
274                            parents.add(textSourceParent);
275                            kb.createCls(CLS_NAME, parents);
276                    }
277                    return;
278            }
279    
280    }