create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / gui / help / tours / SlideSetLoader.java
1 package net.sf.openrocket.gui.help.tours;
2
3 import java.io.FileNotFoundException;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.InputStreamReader;
7 import java.io.Reader;
8 import java.util.ArrayList;
9 import java.util.List;
10 import java.util.Locale;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
13
14 import net.sf.openrocket.util.BugException;
15
16 /**
17  * Class that loads a slide set from a file.
18  * 
19  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
20  */
21 public class SlideSetLoader {
22         
23         private static final Pattern NEW_SLIDE_PATTERN = Pattern.compile("^\\[(.*)\\]$");
24         
25         private final String baseDir;
26         private TextLineReader source;
27         private Locale locale;
28         
29         
30
31
32         /**
33          * Constructor.
34          * 
35          * @param baseDir       The base directory from which to load from.  It is prepended to the loaded
36          *                                      file names and image file names.
37          */
38         public SlideSetLoader(String baseDir) {
39                 this(baseDir, Locale.getDefault());
40         }
41         
42         
43         /**
44          * Constructor.
45          * 
46          * @param baseDir       The base directory from which to load from.  It is prepended to the loaded
47          *                                      file names and image file names.
48          * @param locale        The locale for which the files are loaded.
49          */
50         public SlideSetLoader(String baseDir, Locale locale) {
51                 if (baseDir.length() > 0 && !baseDir.endsWith("/")) {
52                         baseDir = baseDir + "/";
53                 }
54                 this.baseDir = baseDir;
55                 this.locale = locale;
56         }
57         
58         
59         /**
60          * Load a slide set from a file.  The base directory is prepended to the
61          * file name first.
62          * 
63          * @param filename              the file to read in the base directory.
64          * @return                              the slide set
65          */
66         public SlideSet load(String filename) throws IOException {
67                 String file = baseDir + filename;
68                 InputStream in = getLocalizedFile(file);
69                 
70                 try {
71                         InputStreamReader reader = new InputStreamReader(in, "UTF-8");
72                         return load(reader);
73                 } finally {
74                         in.close();
75                 }
76         }
77         
78         
79         private InputStream getLocalizedFile(String filename) throws IOException {
80                 for (String file : generateLocalizedFiles(filename)) {
81                         InputStream in = ClassLoader.getSystemResourceAsStream(file);
82                         if (in != null) {
83                                 return in;
84                         }
85                 }
86                 throw new FileNotFoundException("File '" + filename + "' not found.");
87         }
88         
89         private List<String> generateLocalizedFiles(String filename) {
90                 String base, ext;
91                 int index = filename.lastIndexOf('.');
92                 if (index >= 0) {
93                         base = filename.substring(0, index);
94                         ext = filename.substring(index);
95                 } else {
96                         base = filename;
97                         ext = "";
98                 }
99                 
100
101                 List<String> list = new ArrayList<String>();
102                 list.add(base + "_" + locale.getLanguage() + "_" + locale.getCountry() + "_" + locale.getVariant() + ext);
103                 list.add(base + "_" + locale.getLanguage() + "_" + locale.getCountry() + ext);
104                 list.add(base + "_" + locale.getLanguage() + ext);
105                 list.add(base + ext);
106                 return list;
107         }
108         
109         
110         /**
111          * Load slide set from a reader.
112          * 
113          * @param reader        the reader to read from.
114          * @return                      the slide set.
115          */
116         public SlideSet load(Reader reader) throws IOException {
117                 source = new TextLineReader(reader);
118                 
119                 // Read title and description
120                 String title = source.next();
121                 StringBuilder desc = new StringBuilder();
122                 while (!nextLineStartsSlide()) {
123                         if (desc.length() > 0) {
124                                 desc.append('\n');
125                         }
126                         desc.append(source.next());
127                 }
128                 
129                 // Create the slide set
130                 SlideSet set = new SlideSet();
131                 set.setTitle(title);
132                 set.setDescription(desc.toString());
133                 
134
135                 // Read the slides
136                 while (source.hasNext()) {
137                         Slide s = readSlide();
138                         set.addSlide(s);
139                 }
140                 
141                 return set;
142         }
143         
144         
145         private Slide readSlide() {
146                 
147                 String imgLine = source.next();
148                 Matcher matcher = NEW_SLIDE_PATTERN.matcher(imgLine);
149                 if (!matcher.matches()) {
150                         throw new BugException("Line did not match new slide pattern: " + imgLine);
151                 }
152                 
153                 String imageFile = matcher.group(1);
154                 
155                 StringBuffer desc = new StringBuffer();
156                 while (source.hasNext() && !nextLineStartsSlide()) {
157                         if (desc.length() > 0) {
158                                 desc.append('\n');
159                         }
160                         desc.append(source.next());
161                 }
162                 
163                 return new Slide(baseDir + imageFile, desc.toString());
164         }
165         
166         
167
168         private boolean nextLineStartsSlide() {
169                 return NEW_SLIDE_PATTERN.matcher(source.peek()).matches();
170         }
171         
172
173 }