Normand Briere
2018-07-07 e416acb9b012b17d1efe49ad2199ea7132d874d1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package timeflow.format.file;
 
import timeflow.model.*;
import timeflow.data.db.*;
import timeflow.data.time.*;
import timeflow.format.field.*;
 
import timeflow.util.*;
 
import java.io.*;
import java.net.URL;
import java.util.*;
 
public class TimeflowFormat implements Import, Export
{
   private static final String END_OF_SCHEMA="#TIMEFLOW\tend-metadata";
   private static final String END_OF_METADATA="#TIMEFLOW\t====== End of Header. Data below is in tab-delimited format. =====";
   public ActDB readFile(String fileName, PrintStream messages) throws Exception
   {
       return read(new File(fileName), messages);
   }
   
   public static ActDB read(File file, PrintStream out) throws Exception
   {
       String text=IO.read(file.getAbsolutePath());        
       DelimitedText quote=new DelimitedText('\t');
       Iterator<String[]> lines=quote.read(text).iterator();
       
 
       ActDB db=null;
       List<String> fieldNames=new ArrayList<String>();
       List<Class> fieldTypes=new ArrayList<Class>();
       List<Integer> fieldSizes=new ArrayList<Integer>();
       String source="[unknown]", description="";
       for (;;)
       {
           String[] t=lines.next();
 
           if (t[1].equals("field"))
           {
               fieldNames.add(t[2]);
               fieldTypes.add(FieldFormatCatalog.javaClass(t[3]));
               if (t.length>4)
               {
                   fieldSizes.add(Integer.parseInt(t[4]));
               }
               else
                   fieldSizes.add(-1);
           }
           else if (t[1].equals("source"))
           {
               source=t[2];
           }
           else if (t[1].equals("description"))
           {
               description=t[2];
               
           }
           else if (t[1].equals("end-metadata"))
               break;
       }
       db=new ArrayDB((String[])fieldNames.toArray(new String[0]), 
                        (Class[])fieldTypes.toArray(new Class[0]), source);
       db.setDescription(description);
       for (int i=0; i<fieldNames.size(); i++)
           if (fieldSizes.get(i)>0)
               db.getField(fieldNames.get(i)).setRecommendedSize(fieldSizes.get(i));
       for (;;)
       {
           String[] t=lines.next();
           if (t[1].startsWith("==="))
               break;        
           if (t[1].equals("alias"))
               db.setAlias(db.getField(t[3]), t[2]);
       }
       
       // note: in some cases headers may be in a different order than in
       // metadata section, so we will read these.
       String[] headers=lines.next();
       if (headers.length!=fieldNames.size())
           throw new IllegalArgumentException("Different number of headers than fields!");
       
       
       while (lines.hasNext())
       {
           String[] t=lines.next();
           Act a=db.createAct();
           for (int i=0; i<t.length; i++)
           {
               Field f=db.getField(headers[i]);
               FieldFormat format=FieldFormatCatalog.getFormat(f.getType());
               a.set(f, format.parse(t[i]));
           }
       }
       
       return db;
   }
   
   public static void write(ActList acts, BufferedWriter bw) throws IOException
   {
       ActDB db=acts.getDB();
       
       PrintWriter out=new PrintWriter(bw);
       
       DelimitedText tab=new DelimitedText('\t');
       
       // Write version
       out.println("#TIMEFLOW\tformat version\t1");
       
       // Write source of data.
       out.println("#TIMEFLOW\tsource\t"+tab.write(db.getSource()));
       
       // Write description of data.
       out.println("#TIMEFLOW\tdescription\t"+tab.write(db.getDescription()));
       
       // Write schema.
       List<Field> fields=db.getFields();
       for (Field f: fields)
       {
           String recSize=f.getRecommendedSize()<=0 ? "" : "\t"+f.getRecommendedSize();
           out.println("#TIMEFLOW\tfield\t"+tab.write(f.getName())+
                       "\t"+FieldFormatCatalog.humanName(f.getType())+recSize);
       }
       
       out.println(END_OF_SCHEMA);
       
       // Write column mappings.
       List<String> aliases=DBUtils.getFieldAliases(db);
       for (String a:aliases)
           out.println("#TIMEFLOW\talias\t"+a+"\t"+tab.write(db.getField(a).getName()));
       
       // Write end of header indicator
       out.println(END_OF_METADATA);
       
       // Write data!
       new DelimitedFormat('\t').writeDelimited(db, acts, out);
       
       out.flush();
       out.close();
   }
   
   public static void main(String[] args) throws Exception
   {
       System.out.println("Reading");
       ActDB db=read(new File("test/monet.txt"), System.out);
       System.out.println("# lines: "+db.size());
   }
 
   @Override
   public String getName() {
       return "TimeFlow Format";
   }
 
   @Override
   public ActDB importFile(File file) throws Exception {
       return read(file, System.out);
   }
 
   @Override
   public void export(TFModel model, BufferedWriter out) throws Exception {
       write(model.getDB().all(), out);
   }
}