001    package org.meta_environment.eclipse.files;
002    
003    import java.io.File;
004    import java.io.FileInputStream;
005    import java.io.FileNotFoundException;
006    import java.io.IOException;
007    import java.io.InputStream;
008    import java.net.MalformedURLException;
009    import java.net.URL;
010    
011    import nl.cwi.sen1.configapi.types.Property;
012    import nl.cwi.sen1.configapi.types.PropertyList;
013    
014    import org.eclipse.core.runtime.FileLocator;
015    import org.eclipse.core.runtime.IPath;
016    import org.eclipse.core.runtime.Path;
017    import org.eclipse.imp.runtime.RuntimePlugin;
018    import org.eclipse.imp.utils.StreamUtils;
019    
020    import toolbus.adapter.AbstractTool;
021    import toolbus.adapter.eclipse.EclipseTool;
022    import aterm.ATerm;
023    import aterm.ATermList;
024    import errorapi.types.ErrorList;
025    import errorapi.types.SubjectList;
026    import errorapi.types.subject.Subject;
027    import errorapi.types.summary.Summary;
028    
029    public class IOJ extends EclipseTool {
030    
031            private static class InstanceKeeper {
032                    private static IOJ sInstance = new IOJ();
033                    static {
034                            sInstance.connect();
035                    }
036            }
037    
038            private errorapi.Factory errorFactory = errorapi.Factory.getInstance(factory);
039            private nl.cwi.sen1.configapi.Factory configFactory = nl.cwi.sen1.configapi.Factory.getInstance(factory);
040            
041            private IOJ() {
042                    super("ioj");
043            }
044    
045            static public IOJ getInstance() {
046                    return InstanceKeeper.sInstance;
047            }
048    
049            public ATerm readTextFile(String path) {
050                    URL url = null;
051    
052                    try {
053                            url = FileLocator.resolve(new URL(path));
054                    } catch (Exception e) {
055                            RuntimePlugin.getInstance().logException(
056                                            "Could resolve url " + path, e);
057                    }
058    
059                    try {
060                            InputStream fileContents = null;
061    
062                            if (url == null) {
063                                    /* TODO getFileContentsFromOS should be made obsolete */
064                                    fileContents = getFileContentsFromOS(path);
065                            } else {
066                                    fileContents = url.openConnection().getInputStream();
067                            }
068    
069                            String text = StreamUtils.readStreamContents(fileContents);
070                            fileContents.close();
071                            return factory.make("file-contents(<str>)", text);
072    
073                    } catch (Exception e) {
074                            RuntimePlugin.getInstance().logException(
075                                            "Could not read file " + path, e);
076                            return factory.make("failure(<term>)", getErrorSummary(
077                                            "Could not read file", path));
078                    }
079            }
080    
081            public ATerm getFilename(String Directory, String Name, String Extension) {
082                    IPath path = new Path(Directory);
083                    path = path.append(Name + Extension);
084                    String fileName = path.toString();
085                    return factory.make("filename(<str>)", fileName);
086            }
087    
088            public ATerm getPathFilename(String Path) {
089                    IPath path = new Path(Path);
090                    String fileName = path.removeFileExtension().lastSegment();
091                    if (fileName == null) {
092                            fileName = "";
093                    }
094                    //System.err.println("\ngetPathFilename for " + Path + " returned: " + fileName);
095                    return factory.make("filename(<str>)", fileName);
096            }
097    
098            public ATerm getPathDirectory(String Path) {
099                    IPath path = new Path(Path);
100                    int numberOfSegments = path.segmentCount();
101    
102                    String directory = "";
103                    if (numberOfSegments > 1) {
104                            directory = path.removeLastSegments(1).toString();
105                    }
106                    //System.err.println("\ngetPathDirectory for " + Path + " returned: " + directory);
107                    return factory.make("directory(<str>)", directory);
108            }
109    
110            public ATerm getPathExtension(String Path) {
111                    IPath path = new Path(Path);
112                    String extension = path.getFileExtension();
113    
114                    if (extension == null) {
115                            extension = "";
116                    } else {
117                            extension = "." + extension;
118                    }
119    
120                    //System.err.println("\ngetPathExtension for " + Path + " returned: " + extension);
121                    return factory.make("extension(<str>)", extension);
122            }
123    
124            public ATerm compareFiles(String fileName1, String fileName2) {
125                    File file1 = new Path(fileName1).toFile();
126                    File file2 = new Path(fileName2).toFile();
127    
128                    if (!file1.exists()) {
129                            return factory.make("failure(<trm>)", getErrorSummary(
130                                            "File does not exist", file1.getPath()));
131                    }
132                    if (!file2.exists()) {
133                            return factory.make("failure(<trm>)", getErrorSummary(
134                                            "File does not exist", file2.getPath()));
135                    }
136    
137                    ATerm result = factory.make("different");
138                    /*
139                     * TODO I'm not 100% sure that 'equals' is the appropriate way to
140                     * compare file handles.
141                     */
142                    if (file1.equals(file2)) {
143                            result = factory.make("equal");
144                    }
145    
146                    return result;
147            }
148    
149            public ATerm packTerm(ATerm term) {
150                    return factory.make("term(<trm>)", AbstractTool.pack(term));
151            }
152    
153            public ATerm unpackTerm(ATerm term) {
154                    return factory.make("term(<trm>)", AbstractTool.unpack(term));
155            }
156    
157            public ATerm findFile(ATermList directories, String fileName,
158                            String extension) {
159                    ATermList containingDirectories = factory.makeList();
160                    PropertyList pl = configFactory.PropertyListFromTerm(directories);
161                    
162                    int l = pl.getLength();
163                    for (int i = 0; i < l; i++) {
164                            Property p = pl.getPropertyAt(i);
165                            String dir = p.getPath();
166                            String path = dir + "/" + fileName + extension;
167    
168                            try {
169                                    FileLocator.resolve(new URL(path));
170                                    containingDirectories = containingDirectories.append(factory
171                                                    .make("<str>", dir));
172                            } catch (MalformedURLException e) {
173                                    //System.err.println("TODO: non-URL used as path: " + path);
174                                    RuntimePlugin.getInstance().logException(
175                                                    "Malformed URL " + path, e);
176                            } catch (IOException e) {
177                                    /*
178                                     * TODO This exception occurs if the file could not be resolved.
179                                     * Perhaps we need a better solution for this.
180                                     */
181                            }
182                    }
183    
184                    if (containingDirectories.getLength() > 0) {
185                            return factory.make("file-found(<list>)", containingDirectories);
186                    }
187                    return factory.make("file-not-found");
188            }
189    
190            private InputStream getFileContentsFromOS(String path)
191                            throws FileNotFoundException {
192                    File f = new File(path);
193                    FileInputStream fis = null;
194    
195                    fis = new FileInputStream(f);
196                    //System.err.println("\nTODO: legacy absolute OS path used: " + path);
197    
198                    return fis;
199            }
200    
201            private ATerm getErrorSummary(String _description, String _subject) {
202                    Subject subject = errorFactory.makeSubject_Subject(_subject);
203                    SubjectList subjects = errorFactory.makeSubjectList(subject);
204                    errorapi.types.error.Error error = errorFactory.makeError_Error(
205                                    _description, subjects);
206                    ErrorList errors = errorFactory.makeErrorList(error);
207                    Summary summary = errorFactory.makeSummary_Summary("IOJ tool", "ioj",
208                                    errors);
209                    return summary.toTerm();
210            }
211    
212    }