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     *   Health Language, Inc.
028     *   
029     *   The original contents of this file were developed under contract with Health Language, Inc. and were subsequently generously donated to this project.
030     *   The original methods were:
031     *    - openProject
032     *    - saveProject
033     *    - examineErrors
034     *    - saveProjectAs
035     *    - fixKnowtatorProjectPath
036     */
037    
038    package edu.uchsc.ccp.knowtator.util;
039    
040    import java.io.File;
041    import java.io.IOException;
042    import java.net.URI;
043    import java.util.ArrayList;
044    import java.util.Collection;
045    import java.util.List;
046    
047    import edu.stanford.smi.protege.model.KnowledgeBase;
048    import edu.stanford.smi.protege.model.Project;
049    import edu.stanford.smi.protege.plugin.PluginUtilities;
050    import edu.stanford.smi.protege.storage.clips.ClipsKnowledgeBaseFactory;
051    import edu.stanford.smi.protege.util.MessageError;
052    import edu.stanford.smi.protege.util.PropertyList;
053    import edu.uchsc.ccp.util.io.FileCopy;
054    
055    public class ProjectUtil {
056    
057            public static Project openProject(String projectFileName) {
058                    List<?> errors = new ArrayList<Object>();
059                    Project project = new Project(projectFileName, errors);
060                    examineErrors(errors);
061                    return project;
062            }
063    
064            public static void saveProject(Project project) {
065                    List<?> errors = new ArrayList<Object>();
066                    project.save(errors);
067                    examineErrors(errors);
068            }
069    
070            private static void examineErrors(List<?> errors) {
071                    if (errors.size() > 0) {
072                            Object error = errors.get(0);
073                            if (error instanceof MessageError) {
074                                    MessageError msgError = (MessageError) error;
075                                    throw new IllegalArgumentException(msgError.getMessage(), msgError.getException());
076                            } else
077                                    throw new IllegalArgumentException(error.toString());
078                    }
079            }
080    
081            /**
082             * This method returns the default location of the knowtator project files:
083             * knowtator.pprj, knowtator.pins, knowtator.pont, new-project.pprj, etc.
084             * This method will only work from the context of a running Protege
085             * application - i.e. it will work if called from Knowtator.java but will
086             * not run if you are writing a script that runs from the command line. In
087             * such cases you will need to know the location of the knowtator project
088             * files to call methods such as {@link #saveProjectAs(Project, File, File)}
089             * , {@link #fixKnowtatorProjectPath(Project, File)}, or
090             * {@link #createNewProject(File, File)}. If you need to call one of these
091             * methods from a script, then you must find the project files on your file
092             * system. If you have knowtator installed, then you can pass in the
093             * knowtator plugin directory. If you have a local copy of the source code,
094             * then you can find them locally at "resources/knowtator.pprj".
095             * 
096             * @return the default location of the knowtator project files.
097             */
098            public static File getKnowtatorProjectDirectory() {
099                    return new File(PluginUtilities.getPluginsDirectory().getPath() + File.separator + "edu.uchsc.ccp.knowtator");
100            }
101    
102            /**
103             * @see #getKnowtatorProjectDirectory()
104             */
105            public static void saveProjectAs(Project project, File projectFile) throws IOException {
106                    saveProjectAs(project, projectFile, getKnowtatorProjectDirectory());
107            }
108    
109            /**
110             * This method provides a programmatic way to safely save a Knowtator
111             * project with a different name. Simply changing the name of the files on
112             * your file system is problematic for a number of reasons. Using Protege's
113             * "Save as" is also problematic for reasons described in
114             * {@link #fixKnowtatorProjectPath(Project, String)}.
115             * <p>
116             * NOTE: This method does not update the reference to your text source
117             * collection. If your text source collection is referenced by a relative
118             * path (by default) then you will need to update the reference.
119             * 
120             * 
121             * @param project
122             *            the project to save with a different name
123             * @param projectFile
124             *            the new file name of the project
125             * @param knowtatorProjectDirectory
126             *            see note for {@link #getKnowtatorProjectDirectory()}
127             * 
128             * @see #saveProjectAs(Project, File)
129             */
130            public static void saveProjectAs(Project project, File projectFile, File knowtatorProjectDirectory)
131                            throws IOException {
132                    String projectName = projectFile.getName();
133                    File projectDirectory = projectFile.getParentFile();
134    
135                    if (projectName.endsWith(".pprj")) {
136                            projectName = projectName.substring(0, projectName.length() - 5);
137                    }
138    
139                    PropertyList sources = project.getSources();
140                    ClipsKnowledgeBaseFactory.setSourceFiles(sources, projectName + ".pont", projectName + ".pins");
141                    projectFile = new File(projectDirectory, projectName + ".pprj");
142                    project.setProjectURI(projectFile.toURI());
143                    saveProject(project);
144                    fixKnowtatorProjectPath(project, knowtatorProjectDirectory);
145            }
146    
147        /**
148         * @see #getKnowtatorProjectDirectory()
149         */
150            public static void fixKnowtatorProjectPath(Project project) throws IOException {
151                    fixKnowtatorProjectPath(project, getKnowtatorProjectDirectory());
152            }
153    
154            /**
155             * Knowtator annotation projects require that the project knowtator.pprj is
156             * a directly included project - i.e. the annotation project
157             * <your-project>.pprj will include another project called knowtator.pprj.
158             * This project is found in the knowtator plugin directory and is copied to
159             * your projects directory when you initially set up knowtator and is
160             * referenced with a relative path. There are times when Protege will insert
161             * an absolute path into this reference to knowtator.pprj (usually when
162             * using Protege's "Save As..." menu option.) This often goes undetected
163             * until you try to open the project on a different computer in which case
164             * the absolute path is often no longer valid. It is possible (and easy -
165             * though annoying) to manually fix this problem by editing
166             * <your-project>.pprj. However, this method provides a way to do this
167             * programmatically.
168             * 
169             * @param project
170             * @param knowtatorProjectDirectory
171             *            - the name of the directory containing current knowtator
172             *            project files: knowtator.pprj, knowtator.pont, and
173             *            knowtator.pins - e.g. "C:\Program
174             *            Files\Protege_3.3.1\plugins\edu.uchsc.ccp.knowtator"
175             * @throws IOException
176             * @see #saveProject(Project)
177             */
178            public static void fixKnowtatorProjectPath(Project project, File knowtatorProjectDirectory) throws IOException {
179                    KnowledgeBase kb = project.getKnowledgeBase();
180    
181                    File annotationProjectDirectory = new File(project.getProjectDirectoryURI());
182                    copyKnowtatorFilesToProjectDirectory(annotationProjectDirectory, knowtatorProjectDirectory);
183    
184                    Collection<URI> directIncludedProjects = kb.getProject().getDirectIncludedProjectURIs();
185                    Collection<URI> updatedIncludedProjects = new ArrayList<URI>();
186                    for (URI projectURI : directIncludedProjects) {
187                            if (!projectURI.getPath().endsWith("knowtator.pprj")) {
188                                    updatedIncludedProjects.add(projectURI);
189                            }
190                    }
191    
192                    File localKnowtatorPPRJ = new File(annotationProjectDirectory, "knowtator.pprj");
193    
194                    updatedIncludedProjects.add(localKnowtatorPPRJ.toURI());
195    
196                    project.setDirectIncludedProjectURIs(updatedIncludedProjects);
197                    saveProject(project);
198            }
199    
200            
201            /**
202             * @see #getKnowtatorProjectDirectory()
203             */
204            public static void copyKnowtatorFilesToProjectDirectory(Project project) throws IOException {
205                    copyKnowtatorFilesToProjectDirectory(project, getKnowtatorProjectDirectory());
206            }
207    
208            public static void copyKnowtatorFilesToProjectDirectory(Project project, File knowtatorProjectDirectory)
209                            throws IOException {
210                    copyKnowtatorFilesToProjectDirectory(new File(project.getProjectDirectoryURI()), knowtatorProjectDirectory);
211            }
212    
213            public static void copyKnowtatorFilesToProjectDirectory(File projectDirectory, File knowtatorProjectDirectory)
214                            throws IOException {
215    
216                    File knowtatorPPRJ = new File(knowtatorProjectDirectory, "knowtator.pprj");
217                    File knowtatorPONT = new File(knowtatorProjectDirectory, "knowtator.pont");
218                    File knowtatorPINS = new File(knowtatorProjectDirectory, "knowtator.pins");
219    
220                    File localKnowtatorPPRJ = new File(projectDirectory, "knowtator.pprj");
221                    File localKnowtatorPONT = new File(projectDirectory, "knowtator.pont");
222                    File localKnowtatorPINS = new File(projectDirectory, "knowtator.pins");
223    
224                    FileCopy.copyFile(knowtatorPPRJ, localKnowtatorPPRJ);
225                    FileCopy.copyFile(knowtatorPONT, localKnowtatorPONT);
226                    FileCopy.copyFile(knowtatorPINS, localKnowtatorPINS);
227    
228            }
229    
230            /**
231             * @see #getKnowtatorProjectDirectory()
232             */
233            public static Project createNewProject(File newProjectFile) throws IOException {
234                    return createNewProject(getKnowtatorProjectDirectory(), newProjectFile);
235            }
236            
237            public static Project createNewProject(File knowtatorProjectDirectory, File newProjectFile) throws IOException {
238    
239                    File newProjectDirectory = newProjectFile.getParentFile();
240    
241                    copyKnowtatorFilesToProjectDirectory(newProjectDirectory, knowtatorProjectDirectory);
242                    
243                    File newPPRJ = new File(knowtatorProjectDirectory, "new-project.pprj");
244                    File newPONT = new File(knowtatorProjectDirectory, "new-project.pont");
245                    File newPINS = new File(knowtatorProjectDirectory, "new-project.pins");
246    
247                    File localNewPPRJ = new File(newProjectDirectory, "new-project.pprj");
248                    File localNewPONT = new File(newProjectDirectory, "new-project.pont");
249                    File localNewPINS = new File(newProjectDirectory, "new-project.pins");
250    
251                    FileCopy.copyFile(newPPRJ, localNewPPRJ);
252                    FileCopy.copyFile(newPONT, localNewPONT);
253                    FileCopy.copyFile(newPINS, localNewPINS);
254    
255                    Project newProject = openProject(localNewPPRJ.getPath());
256                    saveProjectAs(newProject, newProjectFile, knowtatorProjectDirectory);
257    
258                    return newProject;
259            }
260    }