1 | /** | | 1 | /** |
2 | * Saves the database to file. Two boolean values indicate whether | | 2 | * Saves the database to file, including only the entries included in the |
3 | * only entries with a nonzero Globals.SEARCH value and only | | 3 | * supplied input array bes. |
4 | * entries with a nonzero Globals.GROUPSEARCH value should be | | 4 | * |
5 | * saved. This can be used to let the user save only the results of | | 5 | * @return A List containing warnings, if any. |
6 | * a search. False and false means all entries are saved. | | 6 | */ |
7 | */ | | 7 | @SuppressWarnings("unchecked") |
8 | public static SaveSession saveDatabase(BibtexDatabase database, | | 8 | public static SaveSession savePartOfDatabase(BibtexDatabase database, MetaData metaData, |
9 | MetaData metaData, File file, JabRefPreferences prefs, | | 9 | File file, JabRefPreferences prefs, BibtexEntry[] bes, String encoding) throws SaveException |
10 | boolean checkSearch, boolean checkGroup, String encoding, boolean suppressBackup) | | 10 | { |
11 | throws SaveException { | | 11 | |
12 | | | 12 | TreeMap<String, BibtexEntryType> types = new TreeMap<String, BibtexEntryType>(); // Map |
13 | TreeMap<String, BibtexEntryType> types = new TreeMap<String, BibtexEntryType>(); | | 13 | // to |
14 | | | 14 | // collect |
15 | boolean backup = prefs.getBoolean("backup"); | | 15 | // entry |
16 | if (suppressBackup) | | 16 | // type |
17 | backup = false; | | 17 | // definitions |
18 | | | 18 | // that we must save along with entries using them. |
19 | SaveSession session; | | 19 | |
20 | BibtexEntry exceptionCause = null; | | 20 | BibtexEntry be = null; |
21 | try { | | 21 | boolean backup = prefs.getBoolean("backup"); |
22 | session = new SaveSession(file, encoding, backup); | | 22 | |
23 | } catch (Throwable e) { | | 23 | SaveSession session; |
24 | if (encoding != null) { | | 24 | try { |
25 | System.err.println("Error from encoding: '" + encoding + "' Len: " + encoding.length()); | | 25 | session = new SaveSession(file, encoding, backup); |
26 | } | | 26 | } catch (IOException e) { |
27 | // we must catch all exceptions to be able notify users that | | 27 | throw new SaveException(e.getMessage()); |
28 | // saving failed, no matter what the reason was | | 28 | } |
29 | // (and they won't just quit JabRef thinking | | 29 | |
30 | // everyting worked and loosing data) | | 30 | try |
31 | e.printStackTrace(); | | 31 | { |
32 | throw new SaveException(e.getMessage()); | | 32 | |
33 | } | | 33 | // Define our data stream. |
34 | | | 34 | VerifyingWriter fw = session.getWriter(); |
35 | try { | | 35 | |
36 | | | 36 | // Write signature. |
37 | // Get our data stream. This stream writes only to a temporary file, | | 37 | writeBibFileHeader(fw, encoding); |
38 | // until committed. | | 38 | |
39 | VerifyingWriter fw = session.getWriter(); | | 39 | // Write preamble if there is one. |
40 | | | 40 | writePreamble(fw, database.getPreamble()); |
41 | // Write signature. | | 41 | |
42 | writeBibFileHeader(fw, encoding); | | 42 | // Write strings if there are any. |
43 | | | 43 | writeStrings(fw, database); |
44 | // Write preamble if there is one. | | 44 | |
45 | writePreamble(fw, database.getPreamble()); | | 45 | // Write database entries. Take care, using CrossRefEntry- |
46 | | | 46 | // Comparator, that referred entries occur after referring |
47 | // Write strings if there are any. | | 47 | // ones. Apart from crossref requirements, entries will be |
48 | writeStrings(fw, database); | | 48 | // sorted as they appear on the screen. |
49 | | | 49 | |
50 | // Write database entries. Take care, using CrossRefEntry- | | 50 | List<Comparator<BibtexEntry>> comparators = getSaveComparators(true); |
51 | // Comparator, that referred entries occur after referring | | 51 | |
52 | // ones. Apart from crossref requirements, entries will be | | 52 | // Use glazed lists to get a sorted view of the entries: |
53 | // sorted as they appear on the screen. | | 53 | BasicEventList entryList = new BasicEventList(); |
54 | List<BibtexEntry> sorter = getSortedEntries(database, null, true); | | 54 | SortedList sorter = new SortedList(entryList, new FieldComparatorStack<BibtexEntry>(comparators)); |
55 | | | 55 | |
56 | FieldFormatter ff = new LatexFieldFormatter(); | | 56 | if ((bes != null) && (bes.length > 0)) |
57 | | | 57 | for (int i=0; i<bes.length; i++) { |
58 | for (BibtexEntry be : sorter) { | | 58 | sorter.add(bes[i]); |
59 | exceptionCause = be; | | 59 | } |
60 | | | 60 | |
61 | // Check if we must write the type definition for this | | 61 | FieldFormatter ff = new LatexFieldFormatter(); |
62 | // entry, as well. Our criterion is that all non-standard | | 62 | |
63 | // types (*not* customized standard types) must be written. | | 63 | for (Iterator<BibtexEntry> i = sorter.iterator(); i.hasNext();) |
64 | BibtexEntryType tp = be.getType(); | | 64 | { |
65 | | | 65 | be = (i.next()); |
66 | if (BibtexEntryType.getStandardType(tp.getName()) == null) { | | 66 | |
67 | types.put(tp.getName(), tp); | | 67 | // Check if we must write the type definition for this |
68 | } | | 68 | // entry, as well. Our criterion is that all non-standard |
69 | | | 69 | // types (*not* customized standard types) must be written. |
70 | // Check if the entry should be written. | | 70 | BibtexEntryType tp = be.getType(); |
71 | boolean write = true; | | 71 | if (BibtexEntryType.getStandardType(tp.getName()) == null) { |
72 | | | 72 | types.put(tp.getName(), tp); |
73 | if (checkSearch && !nonZeroField(be, BibtexFields.SEARCH)) { | | 73 | } |
74 | write = false; | | 74 | |
75 | } | | 75 | be.write(fw, ff, true); |
76 | | | 76 | fw.write(Globals.NEWLINE); |
77 | if (checkGroup && !nonZeroField(be, BibtexFields.GROUPSEARCH)) { | | 77 | } |
78 | write = false; | | 78 | |
79 | } | | 79 | // Write meta data. |
80 | | | 80 | if (metaData != null) |
81 | if (write) { | | 81 | { |
82 | be.write(fw, ff, true); | | 82 | metaData.writeMetaData(fw); |
83 | fw.write(Globals.NEWLINE); | | 83 | } |
84 | } | | 84 | |
85 | } | | 85 | // Write type definitions, if any: |
86 | | | 86 | if (types.size() > 0) { |
87 | // Write meta data. | | 87 | for (Iterator<String> i=types.keySet().iterator(); i.hasNext();) { |
88 | if (metaData != null) { | | 88 | CustomEntryType tp = (CustomEntryType)types.get(i.next()); |
89 | metaData.writeMetaData(fw); | | 89 | tp.save(fw); |
90 | } | | 90 | fw.write(Globals.NEWLINE); |
91 | | | 91 | } |
92 | // Write type definitions, if any: | | 92 | |
93 | if (types.size() > 0) { | | 93 | } |
94 | for (Iterator<String> i = types.keySet().iterator(); i | | 94 | |
95 | .hasNext();) { | | 95 | fw.close(); |
96 | BibtexEntryType type = types.get(i.next()); | | 96 | } |
97 | if (type instanceof CustomEntryType) { | | 97 | catch (Throwable ex) |
98 | CustomEntryType tp = (CustomEntryType)type; | | 98 | { |
99 | tp.save(fw); | | 99 | try { |
100 | fw.write(Globals.NEWLINE); | | 100 | session.cancel(); |
101 | } | | 101 | //repairAfterError(file, backup, status); |
102 | } | | 102 | } catch (IOException e) { |
103 | | | 103 | // Argh, another error? Can we do anything? |
104 | } | | 104 | e.printStackTrace(); |
105 | | | 105 | throw new SaveException(ex.getMessage()+"\n"+ |
106 | fw.close(); | | 106 | Globals.lang("Warning: could not complete file repair; your file may " |
107 | } catch (Throwable ex) { | | 107 | +"have been corrupted. Error message")+": "+e.getMessage()); |
108 | ex.printStackTrace(); | | 108 | } |
109 | try { | | 109 | throw new SaveException(ex.getMessage(), be); |
110 | session.cancel(); | | 110 | } |
111 | // repairAfterError(file, backup, INIT_OK); | | 111 | |
112 | } catch (IOException e) { | | 112 | return session; |
113 | // Argh, another error? Can we do anything? | | 113 | |
114 | e.printStackTrace(); | | 114 | } |
115 | throw new SaveException(ex.getMessage()+"\n"+ | | | |
116 | Globals.lang("Warning: could not complete file repair; your file may " | | | |
117 | +"have been corrupted. Error message")+": "+e.getMessage()); | | | |
118 | | | | |
119 | } | | | |
120 | throw new SaveException(ex.getMessage(), exceptionCause); | | | |
121 | } | | | |
122 | | | | |
123 | return session; | | | |
124 | | | | |
125 | | | | |
126 | } | | | |