    001    package ifs.util;
    002
    003    import java.io.*;
    004    import java.util.*;
    005
    006    /** A class for reading prolog files.
    007     *
    008     * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
    009     * @version 1.0
    010     */
    011    public class PrologFile implements Iterator {
    012        private java.io.BufferedReader iBufferedReader = null;
    013        private Term iNextTerm = null;
    014
    015        public PrologFile(String file) throws java.io.IOException {
    016            iBufferedReader = new BufferedReader(new FileReader(file));
    017            iNextTerm = (iBufferedReader.ready()?readTerm(new SpecialReader(iBufferedReader)):null);
    018            if (iNextTerm==null) iBufferedReader.close(); else iBufferedReader.readLine();
    019        }
    020
    021        /** Reads a prolog file. It returns a set of terms */
    022        public static Vector readTermsFromStream(java.io.InputStream is, String term) throws java.io.IOException {
    023            BufferedReader br = new BufferedReader(new InputStreamReader(is));
    024            Vector ret = new Vector();
    025            //int x=0;
    026            while (br.ready()) {
    027                Term t = readTerm(new SpecialReader(br));
    028                //System.out.println(t);
    029                //x++;
    030                //if (x>10) break;
    031                if (t!=null && t.getText()!=null && t.getText().startsWith(term)) {
    032                    ret.addElement(t);
    033                }
    034                br.readLine();
    035            }
    036            br.close();
    037            return ret;
    038        }
    039
    040        /** Writes a set of terms. */
    041        public static void writeTerms(PrintWriter pw, Vector terms) throws java.io.IOException {
    042            for (Enumeration e=terms.elements();e.hasMoreElements();) {
    043                Term t = (Term)e.nextElement();
    044                writeTerm(pw,t);
    045            }
    046        }
    047
    048        /** reads a term */
    049        private static Term readTerm( SpecialReader is) throws IOException {
    050            StringBuffer text=new StringBuffer();
    051            Vector content = null;
    052            int i;
    053            if ((i = is.read())>=0) {
    054                while ((char)i=='%' || (char)i==':') {
    055                    do {
    056                        i=is.read();
    057                    } while (i>=0 && !( i==0x0d || i==0x0a ));
    058                    i=is.read();
    059                    if (i>=0 && (i==0x0d || i==0x0a )) i=is.read();
    060                }
    061                if (i>=0) is.flush((char)i);
    062            }
    063            char prev = (char)i;
    064            if (i>=0) while ((i = is.read())>=0) {
    065                char ch = (char)i;
    066                if (ch=='\n' || ch=='\r')
    067                    if (prev=='.') break; else continue;
    068                if (ch=='(' || ch=='[') {
    069                    content = new Vector();
    070                    content.addElement(readTerm(is));
    071                } else if (content==null && (ch==',' || ch==')' || ch==']')) {
    072                    is.flush(ch);
    073                    break;
    074                } else if (ch==',') content.addElement(readTerm(is));
    075                else if (ch==')' || ch==']') break;
    076                else text.append(ch);
    077                prev = ch;
    078            } else return null;
    079            Term ret =  new Term(text.toString().trim(),content);
    080            return ret;
    081        }
    082
    083        /** writes a term */
    084        private static void writeTerm( PrintWriter pw, Term t) {
    085            pw.println(t.toString()+".");
    086        }
    087
    088
    089        public boolean hasNext() {
    090            return iNextTerm!=null;
    091        }
    092
    093        public Object next() {
    094            Term ret = iNextTerm;
    095            try {
    096                iNextTerm = (iBufferedReader.ready()?readTerm(new SpecialReader(iBufferedReader)):null);
    097            } catch (java.io.IOException x) {
    098                iNextTerm = null;
    099            }
    100            try {
    101                if (iNextTerm==null) iBufferedReader.close(); else iBufferedReader.readLine();
    102            } catch (java.io.IOException x) {}
    103            return ret;
    104        }
    105
    106        public void remove() {
    107        }
    108
    109        /** Flushable reader -- extension of java.io.Reader */
    110        private static class SpecialReader {
    111            /** reader */
    112            private Reader iReader = null;
    113            /** flushed characters */
    114            private StringBuffer iFlushedChars = new StringBuffer();
    115
    116            /** constructor */
    117            public SpecialReader(Reader r) {
    118                iReader = r;
    119            }
    120
    121            /** reads a byte */
    122            public int read() throws java.io.IOException {
    123                if (iFlushedChars.length()==0) return iReader.read();
    124                char ret=iFlushedChars.charAt(0);
    125                iFlushedChars.deleteCharAt(0);
    126                return ret;
    127            }
    128
    129            /** flush (return to stream) a character */
    130            public void flush(char ch) {
    131                iFlushedChars.insert(0,ch);
    132            }
    133        }
    134
    135        /** Term -- it can contain a text and a content (set of terms) */
    136        public static class Term {
    137            /** text */
    138            private String iText = null;
    139            /** content */
    140            private Vector iContent = null;
    141
    142            public boolean equals(Object o) {
    143                if (o==null || !(o instanceof Term)) return false;
    144                Term t = (Term)o;
    145                if (iText==null && t.iText!=null) return false;
    146                if (iText!=null && t.iText==null) return false;
    147                if (iText!=null && !iText.equals(t.iText)) return false;
    148                if (iContent==null && t.iContent!=null) return false;
    149                if (iContent!=null && t.iContent==null) return false;
    150                if (iContent!=null && !iContent.equals(t.iContent)) return false;
    151                return true;
    152            }
    153
    154            /** constructor */
    155            public Term(String text) {
    156                iText = text;
    157                iContent = null;
    158            }
    159
    160            /** constructor */
    161            public Term(Vector content) {
    162                iText = null;
    163                iContent = content;
    164            }
    165
    166            /** constructor */
    167            public Term(String text, Vector content) {
    168                iText = text;
    169                iContent = content;
    170            }
    171
    172            /** constructor */
    173            public Term(String text, Term[] content) {
    174                iText = text;
    175                if (content==null) {
    176                    iContent = null;
    177                } else {
    178                    iContent = new Vector();
    179                    for (int i=0;i<content.length;i++)
    180                        iContent.addElement(content[i]);
    181                }
    182            }
    183
    184            /** constructor */
    185            public Term(Term[] content) {
    186                this(null,content);
    187            }
    188
    189            /** return text */
    190            public String getText() {
    191                return iText;
    192            }
    193
    194            /** return content */
    195            public Vector getContent() {
    196                return iContent;
    197            }
    198
    199            /** content size */
    200            public int size() {
    201                return (iContent==null?-1:iContent.size());
    202            }
    203
    204            /** return text as int */
    205            public int toInt() {
    206                return Integer.parseInt(iText);
    207            }
    208
    209            /** return text as long */
    210            public long toLong() {
    211                return Long.parseLong(iText);
    212            }
    213
    214            /** return text as fouble */
    215            public double toDouble() {
    216                return Double.parseDouble(iText);
    217            }
    218
    219            /** return text as boolean */
    220            public boolean toBoolean() {
    221                return (toInt()!=0);
    222            }
    223
    224            /** return content as boolean array */
    225            public boolean[] toBooleanArray() {
    226                if (iContent.size()==1 && iContent.elementAt(0).toString().length()==0) return new boolean[] {};
    227                boolean[] ret = new boolean[iContent.size()];
    228                for (int i=0;i<ret.length;i++) {
    229                    ret[i]=elementAt(i).toBoolean();
    230                }
    231                return ret;
    232            }
    233
    234            /** return content as string array */
    235            public String[] toStringArray() {
    236                if (iContent.size()==1 && iContent.elementAt(0).toString().length()==0) return new String[] {};
    237                String[] ret = new String[iContent.size()];
    238                for (int i=0;i<ret.length;i++) {
    239                    Term t = elementAt(i);
    240                    ret[i]=(t.getText().length()>0?t.toString():t.elementAt(0).toString());
    241                }
    242                return ret;
    243            }
    244
    245            /** return content as int array */
    246            public int[] toIntArray() {
    247                //System.err.println("ToIntArray: "+this);
    248                if (iContent.size()==1 && iContent.elementAt(0).toString().length()==0) return new int[] {};
    249                int[] ret = new int[iContent.size()];
    250                for (int i=0;i<ret.length;i++) {
    251                    Term t = elementAt(i);
    252                    ret[i]=(t.getText().length()>0?Integer.parseInt(t.getText()):t.elementAt(0).toInt());
    253                    //System.err.println("  "+i+" .. "+ret[i]);
    254                }
    255                return ret;
    256            }
    257
    258            /** idx-th element of content */
    259            public Term elementAt(int idx) {
    260                try {
    261                    return (Term)iContent.elementAt(idx);
    262                } catch (Exception e) {
    263                    return null;
    264                }
    265            }
    266
    267            /** element of content named name*/
    268            public Term element(String name) {
    269                try {
    270                    for (Enumeration i=iContent.elements();i.hasMoreElements();) {
    271                        Term t = (Term)i.nextElement();
    272                        if (t.getText()!=null && t.getText().equals(name)) return t;
    273                    }
    274                    return null;
    275                } catch (Exception e) {
    276                    return null;
    277                }
    278            }
    279
    280            /** index of element of content named name*/
    281            public int indexOf(String name) {
    282                try {
    283                    int idx=0;
    284                    for (Enumeration i=iContent.elements();i.hasMoreElements();) {
    285                        Term t = (Term)i.nextElement();
    286                        if (t.getText()!=null && t.getText().equals(name)) return idx;
    287                        idx++;
    288                    }
    289                    return -1;
    290                } catch (Exception e) {
    291                    return -1;
    292                }
    293            }
    294
    295            /** string representation of term */
    296            public String toString() {
    297                boolean isArray = (iText==null || iText.length()==0);
    298                StringBuffer sb = new StringBuffer(isArray?"":iText);
    299                if (iContent!=null) {
    300                    sb.append(isArray?"[":"(");
    301                    for (Enumeration e=iContent.elements();e.hasMoreElements();) {
    302                        sb.append(e.nextElement().toString());
    303                        sb.append(e.hasMoreElements()?",":"");
    304                    }
    305                    sb.append(isArray?"]":")");
    306                }
    307                return sb.toString();
    308            }
    309
    310            public Object clone() {
    311                return new Term(iText==null?null:new String(iText),iContent==null?iContent:(Vector)iContent.clone());
    312            }
    313        }
    314    }