source: trunk/src/org/expeditee/gui/FrameIO.java@ 655

Last change on this file since 655 was 655, checked in by jts21, 10 years ago

Switch to using specialised objects for settings so they make more a bit more sense (now each setting is a single object instead of multiple, and setter functions and default values are less hackish)
Also added tooltips (help strings) to settings, will need to add a way of displaying these (maybe add the idea of a tooltip which is a text item which only appears when hovering over another item?)
Converted all settings over to new format, everything seems to be working fine

File size: 44.2 KB
Line 
1package org.expeditee.gui;
2
3import java.io.BufferedOutputStream;
4import java.io.BufferedReader;
5import java.io.BufferedWriter;
6import java.io.File;
7import java.io.FileInputStream;
8import java.io.FileNotFoundException;
9import java.io.FileOutputStream;
10import java.io.FileReader;
11import java.io.FileWriter;
12import java.io.IOException;
13import java.io.OutputStream;
14import java.io.OutputStreamWriter;
15import java.io.Writer;
16import java.sql.Time;
17import java.util.Collection;
18import java.util.HashMap;
19import java.util.LinkedList;
20
21import org.expeditee.actions.Actions;
22import org.expeditee.agents.ExistingFramesetException;
23import org.expeditee.io.Conversion;
24import org.expeditee.io.ExpReader;
25import org.expeditee.io.ExpWriter;
26import org.expeditee.io.FrameReader;
27import org.expeditee.io.FrameWriter;
28import org.expeditee.io.KMSReader;
29import org.expeditee.io.KMSWriter;
30import org.expeditee.items.Item;
31import org.expeditee.items.ItemUtils;
32import org.expeditee.items.PermissionPair;
33import org.expeditee.items.UserAppliedPermission;
34import org.expeditee.items.Text;
35import org.expeditee.network.FrameShare;
36import org.expeditee.settings.UserSettings;
37import org.expeditee.stats.Formatter;
38import org.expeditee.stats.Logger;
39import org.expeditee.stats.SessionStats;
40
41/**
42 * This class provides static methods for all saving and loading of Frames
43 * to\from disk. This class also handles any caching of previously loaded
44 * Frames.
45 *
46 * @author jdm18
47 *
48 */
49public class FrameIO {
50
51 private static final char FRAME_NAME_LAST_CHAR = 'A';
52
53 public static void changeParentFolder(String newFolder) {
54 PARENT_FOLDER = newFolder;
55 PUBLIC_PATH = PARENT_FOLDER + "public" + File.separator;
56 FRAME_PATH = PARENT_FOLDER + "framesets" + File.separator;
57 MESSAGES_PATH = PARENT_FOLDER + "messages" + File.separator;
58 TRASH_PATH = PARENT_FOLDER + "trash" + File.separator;
59 IMAGES_PATH = PARENT_FOLDER + IMAGES_FOLDER;
60 HELP_PATH = PARENT_FOLDER + "documentation" + File.separator;
61 DICT_PATH = PARENT_FOLDER + "dict" + File.separator;
62 PROFILE_PATH = PARENT_FOLDER + "profiles" + File.separator;
63 EXPORTS_DIR = PARENT_FOLDER + "exports" + File.separator;
64 STATISTICS_DIR = PARENT_FOLDER + "statistics" + File.separator;
65 LOGS_DIR = PARENT_FOLDER + "logs" + File.separator;
66 }
67
68 /**
69 * The default location for storing the framesets. Each frameset has its own
70 * subdirectory in this directory.
71 */
72 public static String IMAGES_FOLDER = "images" + File.separator;
73
74 public static String TRASH_PATH;
75
76 public static String PARENT_FOLDER;
77
78 public static String FRAME_PATH;
79
80 public static String MESSAGES_PATH;
81
82 public static String PUBLIC_PATH;
83
84 public static String IMAGES_PATH;
85
86 public static String HELP_PATH;
87
88 public static String TEMPLATES_PATH;
89
90 public static String DICT_PATH;
91
92 public static String PROFILE_PATH;
93
94 public static String EXPORTS_DIR;
95
96 public static String STATISTICS_DIR;
97
98 public static String LOGS_DIR;
99
100 private static final String INF_FILENAME = "frame.inf";
101
102 public static final String ILLEGAL_CHARS = ";:\\/?";
103
104 public static final int MAX_NAME_LENGTH = 64;
105
106 public static final int MAX_CACHE = 100;
107
108 private static HashMap<String, Frame> _Cache = new FrameCache();
109
110 // private static HashMap<String, String> _FramesetNameCache = new
111 // HashMap<String, String>();
112
113 private static boolean ENABLE_CACHE = true;
114
115 private static boolean _UseCache = true;
116
117 private static boolean _SuspendedCache = false;
118
119 // All methods are static, this should not be instantiated
120 private FrameIO() {
121 }
122
123 public static boolean isCacheOn() {
124 return _UseCache && ENABLE_CACHE;
125 }
126
127 public static void Precache(String framename) {
128 // if the cache is turned off, do nothing
129 if (!isCacheOn())
130 return;
131
132 // if the frame is already in the cache, do nothing
133 if (_Cache.containsKey(framename.toLowerCase()))
134 return;
135
136 // otherwise, load the frame and put it in the cache
137 Logger.Log(Logger.SYSTEM, Logger.LOAD, "Precaching " + framename + ".");
138
139 // do not display errors encountered to the user
140 // (they will be shown at load time)
141 MessageBay.supressMessages(true);
142 // loading automatically caches the frame is caching is turned on
143 LoadFromDisk(framename, null, false);
144 MessageBay.supressMessages(false);
145 }
146
147 /**
148 * Checks if a string is a representation of a positive integer.
149 *
150 * @param s
151 * @return true if s is a positive integer
152 */
153 public static boolean isPositiveInteger(String s) {
154 if (s == null || s.length() == 0)
155 return false;
156
157 for (int i = 0; i < s.length(); i++) {
158 if (!Character.isDigit(s.charAt(i)))
159 return false;
160 }
161 return true;
162 }
163
164 public static Frame LoadFrame(String frameName) {
165 return LoadFrame(frameName, null, false);
166 }
167
168 public static Frame LoadFrame(String frameName, String path) {
169 return LoadFrame(frameName, path, false);
170 }
171
172 public static Frame LoadFrame(String frameName, String path,
173 boolean ignoreAnnotations) {
174 if (!isValidFrameName(frameName))
175 return null;
176
177 String frameNameLower = frameName.toLowerCase();
178 // first try reading from cache
179 if (isCacheOn() && _Cache.containsKey(frameNameLower)) {
180 Logger.Log(Logger.SYSTEM, Logger.LOAD, "Loading " + frameName
181 + " from cache.");
182 Frame frame = _Cache.get(frameNameLower);
183 return frame;
184 }
185
186 Logger.Log(Logger.SYSTEM, Logger.LOAD, "Loading " + frameName
187 + " from disk.");
188
189 return LoadFromDisk(frameName, path, ignoreAnnotations);
190 }
191
192 public static BufferedReader LoadPublicFrame(String frameName) {
193 String fullPath = FrameIO.getFrameFullPathName(PUBLIC_PATH, frameName);
194
195 if (fullPath == null)
196 return null;
197
198 File frameFile = new File(fullPath);
199 if (frameFile.exists() && frameFile.canRead()) {
200 try {
201 return new BufferedReader(new FileReader(frameFile));
202 } catch (FileNotFoundException e) {
203 e.printStackTrace();
204 }
205 }
206 return null;
207 }
208
209 private static Frame LoadFromDisk(String framename, String knownPath,
210 boolean ignoreAnnotations) {
211 Frame loaded = null;
212
213 if (knownPath != null) {
214 loaded = LoadKnowPath(knownPath, framename);
215 } else {
216
217 for (String path : UserSettings.FrameDirs.get()) {
218 loaded = LoadKnowPath(path, framename);
219 if (loaded != null) {
220 break;
221 }
222 }
223 }
224
225 if (loaded == null && FrameShare.getInstance() != null) {
226 loaded = FrameShare.getInstance().loadFrame(framename, knownPath);
227 }
228
229 if (loaded != null) {
230 FrameUtils.Parse(loaded, true, ignoreAnnotations);
231 }
232
233 return loaded;
234 }
235
236 /**
237 * Gets a list of all the framesets available to the user
238 *
239 * @return a string containing a list of all the available framesets on
240 * separate lines
241 */
242 public static String getFramesetList() {
243 StringBuffer list = new StringBuffer();
244
245 for (String path : UserSettings.FrameDirs.get()) {
246 File files = new File(path);
247 if (!files.exists())
248 continue;
249 for (File f : (new File(path)).listFiles()) {
250 if (f.isDirectory()) {
251 list.append(f.getName()).append('\n');
252 }
253 }
254 }
255 // remove the final new line char
256 list.deleteCharAt(list.length() - 1);
257 return list.toString();
258 }
259
260 /**
261 * Gets the full path and file name of the frame.
262 *
263 * @param path-
264 * the directory in which to look for the frameset containing the
265 * frame.
266 * @param frameName-
267 * the name of the frame for which the path is being requested.
268 * @return null if the frame can not be located.
269 */
270 public static synchronized String getFrameFullPathName(String path,
271 String frameName) {
272 String source = path + Conversion.getFramesetName(frameName)
273 + File.separator;
274
275 File tester = new File(source);
276 if (!tester.exists())
277 return null;
278
279 // check for the new file name format
280 String fullPath = source + Conversion.getFrameNumber(frameName)
281 + ExpReader.EXTENTION;
282 tester = new File(fullPath);
283
284 if (tester.exists())
285 return fullPath;
286
287 // check for oldfile name format
288 fullPath = source + Conversion.getFramesetName(frameName) + "."
289 + Conversion.getFrameNumber(frameName);
290 tester = new File(fullPath);
291
292 if (tester.exists())
293 return fullPath;
294
295 return null;
296 }
297
298 public static boolean canAccessFrame(String frameName) {
299 Frame current = DisplayIO.getCurrentFrame();
300 // Just in case the current frame is not yet saved...
301 if (frameName.equals(current.getName())) {
302 FrameIO.SaveFrame(current, false, false);
303 current.change();
304 return true;
305 }
306
307 for (String path : UserSettings.FrameDirs.get()) {
308 if (getFrameFullPathName(path, frameName) != null)
309 return true;
310 }
311 return false;
312 }
313
314 public static Collection<String> searchFrame(String frameName,
315 String pattern, String path) {
316 String fullPath = null;
317 if (path == null) {
318 for (String possiblePath : UserSettings.FrameDirs.get()) {
319 fullPath = getFrameFullPathName(possiblePath, frameName);
320 if (fullPath != null)
321 break;
322 }
323 } else {
324 fullPath = getFrameFullPathName(path, frameName);
325 }
326 // If the frame was not located return null
327 if (fullPath == null)
328 return null;
329 Collection<String> results = new LinkedList<String>();
330 // Open the file and search the text items
331 try {
332 BufferedReader reader = new BufferedReader(new FileReader(fullPath));
333 String next;
334 while (reader.ready() && ((next = reader.readLine()) != null)) {
335 if (next.startsWith("T")) {
336 String toSearch = next.substring(2);
337 if (toSearch.toLowerCase().contains(pattern))
338 results.add(toSearch);
339 }
340 }
341 } catch (FileNotFoundException e) {
342 e.printStackTrace();
343 return null;
344 } catch (IOException e) {
345 e.printStackTrace();
346 }
347 return results;
348 }
349
350 private static Frame LoadKnowPath(String path, String frameName) {
351 String fullPath = getFrameFullPathName(path, frameName);
352 if (fullPath == null)
353 return null;
354
355 try {
356 FrameReader reader;
357
358 if (fullPath.endsWith(ExpReader.EXTENTION)) {
359 reader = new ExpReader(frameName);
360 } else {
361 reader = new KMSReader();
362 }
363 Frame frame = reader.readFrame(fullPath);
364
365 if (frame == null) {
366 MessageBay.errorMessage("Error: " + frameName
367 + " could not be successfully loaded.");
368 return null;
369 }
370
371 frame.setPath(path);
372
373 // do not put 0 frames or virtual frames into the cache
374 // Why are zero frames not put in the cache
375 if (_Cache.size() > MAX_CACHE)
376 _Cache.clear();
377
378 if (frame.getNumber() > 0 && isCacheOn())
379 _Cache.put(frameName.toLowerCase(), frame);
380
381 return frame;
382 } catch (IOException ioe) {
383 ioe.printStackTrace();
384 Logger.Log(ioe);
385 } catch (Exception e) {
386 e.printStackTrace();
387 Logger.Log(e);
388 MessageBay.errorMessage("Error: " + frameName
389 + " could not be successfully loaded.");
390 }
391
392 return null;
393 }
394
395 public static void Reload() {
396 // disable cache
397 boolean cache = _UseCache;
398
399 _UseCache = false;
400 Frame fresh = FrameIO.LoadFrame(DisplayIO.getCurrentFrame().getName());
401 _UseCache = cache;
402 if (_Cache.containsKey(fresh.getName().toLowerCase()))
403 addToCache(fresh);
404 DisplayIO.setCurrentFrame(fresh, false);
405 }
406
407 public static Frame LoadPrevious(Frame current) {
408 checkTDFC(current);
409
410 // the current name and number
411 String name = current.getFramesetName();
412 int num = current.getNumber() - 1;
413
414 // loop until a frame that exists is found
415 for (; num >= 0; num--) {
416 Frame f = LoadFrame(name + num, current.getPath());
417 if (f != null)
418 return f;
419 }
420
421 // if we did not find another Frame then this one must be the last one
422 // in the frameset
423 MessageBay
424 .displayMessageOnce("This is the first frame in the frameset");
425 return null;
426 }
427
428 /**
429 * Returns the next Frame in the current Frameset (The Frame with the next
430 * highest Frame number) If the current Frame is the last one in the
431 * Frameset, or an error occurs then null is returned.
432 *
433 * @return The Frame after this one in the current frameset, or null
434 */
435 public static Frame LoadNext(Frame current) {
436 checkTDFC(current);
437
438 // the current name and number
439 int num = current.getNumber() + 1;
440 int max = num + 1;
441 String name = current.getFramesetName();
442
443 // read the maximum from the INF file
444 try {
445 max = ReadINF(current.getPath(), current.getFramesetName(), false);
446 } catch (IOException ioe) {
447 MessageBay.errorMessage("Error loading INF file for frameset '"
448 + name + "'");
449 return null;
450 }
451
452 // loop until a frame that exists is found
453 for (; num <= max; num++) {
454 Frame f = LoadFrame(name + num, current.getPath());
455 if (f != null)
456 return f;
457 }
458
459 // if we did not find another Frame then this one must be the last one
460 // in the frameset
461 MessageBay.displayMessageOnce("This is the last frame in the frameset");
462 return null;
463 }
464
465 /**
466 * This method checks if the current frame has just been created with TDFC.
467 * If it has the frame is saved regardless of whether it has been edited or
468 * not and the TDFC item property is cleared. This is to ensure that the
469 * link is saved on the parent frame.
470 *
471 * @param current
472 */
473 public static void checkTDFC(Frame current) {
474 if (FrameUtils.getTdfcItem() != null) {
475 FrameUtils.setTdfcItem(null);
476 current.change();
477 }
478 }
479
480 public static Frame LoadLast(String framesetName, String path) {
481 // read the maximum from the INF file
482 int max;
483 try {
484 max = ReadINF(path, framesetName, false);
485 } catch (IOException ioe) {
486 MessageBay.errorMessage("Error loading INF file for frameset '"
487 + framesetName + "'");
488 return null;
489 }
490
491 // loop backwards until a frame that exists is found
492 for (int num = max; num > 0; num--) {
493 Frame f = LoadFromDisk(framesetName + num, path, false);
494 if (f != null)
495 return f;
496 }
497
498 // if we did not find another Frame then this one must be the last one
499 // in the frameset
500 MessageBay.displayMessage("This is the last frame in the frameset");
501 return null;
502 }
503
504 public static Frame LoadZero(String framesetName, String path) {
505 return LoadFrame(framesetName + 0);
506 }
507
508 public static Frame LoadZero() {
509 Frame current = DisplayIO.getCurrentFrame();
510 return LoadZero(current.getFramesetName(), current.getPath());
511 }
512
513 public static Frame LoadLast() {
514 Frame current = DisplayIO.getCurrentFrame();
515 return LoadLast(current.getFramesetName(), current.getPath());
516 }
517
518 public static Frame LoadNext() {
519 return LoadNext(DisplayIO.getCurrentFrame());
520 }
521
522 public static Frame LoadPrevious() {
523 return LoadPrevious(DisplayIO.getCurrentFrame());
524 }
525
526 /**
527 * Deletes the given Frame on disk and removes the cached Frame if there is
528 * one. Also adds the deleted frame into the deletedFrames frameset.
529 *
530 * @param toDelete
531 * The Frame to be deleted
532 * @return The name the deleted frame was changed to, or null if the delete
533 * failed
534 */
535 public static String DeleteFrame(Frame toDelete) throws IOException,
536 SecurityException {
537 if (toDelete == null)
538 return null;
539
540 // Dont delete the zero frame
541 if (toDelete.getNumber() == 0) {
542 throw new SecurityException("Deleting a zero frame is illegal");
543 }
544
545 // Dont delete the zero frame
546 if (!toDelete.isLocal()) {
547 throw new SecurityException("Attempted to delete remote frame");
548 }
549
550 SaveFrame(toDelete);
551
552 // Copy deleted frames to the DeletedFrames frameset
553 // get the last used frame in the destination frameset
554 final String DELETED_FRAMES = "DeletedFrames";
555 int lastNumber = FrameIO.getLastNumber(DELETED_FRAMES);
556 String framePath;
557 try {
558 // create the new frameset
559 Frame one = FrameIO.CreateFrameset(DELETED_FRAMES, toDelete
560 .getPath());
561 framePath = one.getPath();
562 lastNumber = 0;
563 } catch (Exception e) {
564 Frame zero = FrameIO.LoadFrame(DELETED_FRAMES + "0");
565 framePath = zero.getPath();
566 }
567
568 // get the fill path to determine which file version it is
569 String source = getFrameFullPathName(toDelete.getPath(), toDelete
570 .getName());
571
572 String oldFrameName = toDelete.getName().toLowerCase();
573 // Now save the frame in the new location
574 toDelete.setFrameset(DELETED_FRAMES);
575 toDelete.setFrameNumber(lastNumber + 1);
576 toDelete.setPath(framePath);
577 ForceSaveFrame(toDelete);
578
579 if (_Cache.containsKey(oldFrameName))
580 _Cache.remove(oldFrameName);
581
582 File del = new File(source);
583
584 java.io.FileInputStream ff = new java.io.FileInputStream(del);
585 ff.close();
586
587 if (del.delete()) {
588 return toDelete.getName();
589 }
590
591 return null;
592 }
593
594 /**
595 * Creates a new Frame in the given frameset and assigns it the given Title,
596 * which can be null. The newly created Frame is a copy of the frameset's .0
597 * file with the number updated based on the last recorded Frame name in the
598 * frameset's INF file.
599 *
600 * @param frameset
601 * The frameset to create the new Frame in
602 * @param frameTitle
603 * The title to assign to the newly created Frame (can be NULL).
604 * @return The newly created Frame.
605 */
606 public static synchronized Frame CreateFrame(String frameset,
607 String frameTitle, String templateFrame) throws RuntimeException {
608
609 if (!FrameIO.isValidFramesetName(frameset)) {
610 throw new RuntimeException(frameset
611 + " is not a valid frameset name");
612 }
613
614 int next = -1;
615
616 // disable caching of 0 frames
617 // Mike says: Why is caching of 0 frames being disabled?
618 /*
619 * Especially since 0 frames are not event put into the cache in the
620 * frist place
621 */
622 // SuspendCache();
623 /*
624 * Suspending the cache causes infinate loops when trying to load a zero
625 * frame which has a ao which contains an v or av which contains a link
626 * to the ao frame
627 */
628
629 String zeroFrameName = frameset + "0";
630 Frame destFramesetZero = LoadFrame(zeroFrameName);
631 if (destFramesetZero == null) {
632 throw new RuntimeException(zeroFrameName + " could not be found");
633 }
634
635 Frame template = null;
636 if (templateFrame == null) {
637 // load in frame.0
638 template = destFramesetZero;
639 } else {
640 template = LoadFrame(templateFrame);
641 if (template == null) {
642 throw new RuntimeException("LinkTemplate " + templateFrame
643 + " could not be found");
644 }
645 }
646
647 ResumeCache();
648
649 // read the next number from the INF file
650 try {
651 next = ReadINF(destFramesetZero.getPath(), frameset, true);
652 } catch (IOException ioe) {
653 ioe.printStackTrace();
654 throw new RuntimeException("INF file could not be read");
655 }
656
657 // Remove the old frame from the cashe then add the new one
658 // TODO figure out some way that we can put both in the cache
659 _Cache.remove(template.getName().toLowerCase());
660 // set the number and title of the new frame
661 template.setName(frameset, ++next);
662 template.setTitle(frameTitle);
663 // _Cache.put(template.getName().toLowerCase(), template);
664
665 Logger.Log(Logger.SYSTEM, Logger.TDFC, "Creating new frame: "
666 + template.getName() + " from TDFC");
667
668 template.setOwner(UserSettings.UserName.get());
669 template.reset();
670 template.resetDateCreated();
671
672 for (Item i : template.getItems()) {
673 if (ItemUtils.startsWithTag(i, ItemUtils.TAG_PARENT))
674 i.setLink(null);
675 }
676
677 // do auto shrinking of the title IF not in twin frames mode
678 Item titleItem = template.getTitleItem();
679
680 if (!DisplayIO.isTwinFramesOn()) {
681 if ((titleItem.getX() + 1) < template.getNameItem().getX()) {
682 while (titleItem.getSize() > Text.MINIMUM_FONT_SIZE
683 && titleItem.getBoundsWidth() + titleItem.getX() > template
684 .getNameItem().getX()) {
685 titleItem.setSize(titleItem.getSize() - 1);
686
687 }
688 } else {
689 System.out.println("Bad title x position: " + titleItem.getX());
690 }
691 }
692
693 // Assign a width to the title.
694 titleItem.setRightMargin(template.getNameItem().getX(), true);
695
696 return template;
697 }
698
699 public static void DisableCache() {
700 _UseCache = false;
701 }
702
703 public static void EnableCache() {
704 _UseCache = true;
705 }
706
707 public static void SuspendCache() {
708 if (_UseCache) {
709 DisableCache();
710 _SuspendedCache = true;
711 } else {
712 _SuspendedCache = false;
713 }
714 }
715
716 public static void ResumeCache() {
717 if (_SuspendedCache) {
718 EnableCache();
719 _SuspendedCache = false;
720 }
721 }
722
723 public static void RefreshCasheImages() {
724 SuspendCache();
725 for (Frame f : _Cache.values())
726 f.setBuffer(null);
727 ResumeCache();
728 }
729
730 /**
731 * Creates a new frameset using the given name. This includes creating a new
732 * subdirectory in the <code>FRAME_PATH</code> directory, Copying over the
733 * default.0 frame from the default frameset, copying the .0 Frame to make a
734 * .1 Frame, and creating the frameset's INF file.
735 *
736 * @param frameset
737 * The name of the Frameset to create
738 * @return The first Frame of the new Frameset (Frame.1)
739 */
740 public static Frame CreateFrameset(String frameset, String path)
741 throws Exception {
742 return CreateFrameset(frameset, path, false);
743 }
744
745 /**
746 * Tests if the given String is a 'proper' framename, that is, the String
747 * must begin with a character, end with a number with 0 or more letters and
748 * numbers in between.
749 *
750 * @param frameName
751 * The String to test for validity as a frame name
752 * @return True if the given framename is proper, false otherwise.
753 */
754 public static boolean isValidFrameName(String frameName) {
755
756 if (frameName == null || frameName.length() < 2)
757 return false;
758
759 int lastCharIndex = frameName.length() - 1;
760 // String must begin with a letter and end with a digit
761 if (!Character.isLetter(frameName.charAt(0))
762 || !Character.isDigit(frameName.charAt(lastCharIndex)))
763 return false;
764
765 // All the characters between first and last must be letters
766 // or digits
767 for (int i = 1; i < lastCharIndex; i++) {
768 if (!isValidFrameNameChar(frameName.charAt(i)))
769 return false;
770 }
771 return true;
772 }
773
774 private static boolean isValidFrameNameChar(char c) {
775 return Character.isLetterOrDigit(c) || c == '-';
776 }
777
778 /**
779 * Saves the given Frame to disk in the corresponding frameset directory.
780 * This is the same as calling SaveFrame(toSave, true)
781 *
782 * @param toSave
783 * The Frame to save to disk
784 */
785 public static String SaveFrame(Frame toSave) {
786 return SaveFrame(toSave, true);
787 }
788
789 /**
790 * Saves a frame.
791 *
792 * @param toSave
793 * the frame to save
794 * @param inc
795 * true if the frames counter should be incremented
796 * @return the text content of the frame
797 */
798 public static String SaveFrame(Frame toSave, boolean inc) {
799 return SaveFrame(toSave, inc, true);
800 }
801
802 /**
803 * Saves the given Frame to disk in the corresponding frameset directory, if
804 * inc is true then the saved frames counter is incremented, otherwise it is
805 * untouched.
806 *
807 * @param toSave
808 * The Frame to save to disk
809 * @param inc
810 * True if the saved frames counter should be incremented, false
811 * otherwise.
812 * @param checkBackup
813 * True if the frame should be checked for the back up tag
814 */
815 public static String SaveFrame(Frame toSave, boolean inc,
816 boolean checkBackup) {
817
818 // TODO When loading a frame maybe append onto the event history too-
819 // with a
820 // break to indicate the end of a session
821
822 if (toSave == null || !toSave.hasChanged() || toSave.isSaved()) {
823 return "";
824 }
825
826 // Dont save if the frame is protected and it exists
827 if (checkBackup && toSave.isReadOnly()) {
828 _Cache.remove(toSave.getName().toLowerCase());
829 return "";
830 }
831
832 /* Dont save the frame if it has the noSave tag */
833 if (toSave.hasAnnotation("nosave")) {
834 Actions.PerformActionCatchErrors(toSave, null, "Restore");
835 return "";
836 }
837
838 // Save frame that is not local through the Networking classes
839 // TODO
840 if (!toSave.isLocal()) {
841 return FrameShare.getInstance().saveFrame(toSave);
842 }
843
844 /* Format the frame if it has the autoFormat tag */
845 if (toSave.hasAnnotation("autoformat")) {
846 Actions.PerformActionCatchErrors(toSave, null, "Format");
847 }
848
849 /**
850 * Get the full path only to determine which format to use for saving
851 * the frame. At this stage use Exp format for saving Exp frames only.
852 * Later this will be changed so that KMS frames will be updated to the
853 * Exp format.
854 */
855 String fullPath = getFrameFullPathName(toSave.getPath(), toSave
856 .getName());
857
858 // Check if the frame exists
859 if (checkBackup && fullPath == null) {
860 // The first time a frame with the backup tag is saved, dont back it
861 // up
862 checkBackup = false;
863 }
864
865 FrameWriter writer = null;
866 int savedVersion;
867 try {
868 // if its a new frame or an existing Exp frame...
869 if (fullPath == null || fullPath.endsWith(ExpReader.EXTENTION)) {
870 writer = new ExpWriter();
871 savedVersion = ExpReader.getVersion(fullPath);
872 } else {
873 writer = new KMSWriter();
874 savedVersion = KMSReader.getVersion(fullPath);
875 }
876
877 // Check if the frame doesnt exist
878 // if (savedVersion < 0) {
879 // /*
880 // * This will happen if the user has two Expeditee's running at
881 // * once and closes the first. When the second one closes the
882 // * messages directory will have been deleted.
883 // */
884 // MessageBay
885 // .errorMessage("Could not save frame that does not exist: "
886 // + toSave.getName());
887 // return null;
888 // }
889
890 // Check if we are trying to save an out of date version
891 if (savedVersion > toSave.getVersion()
892 && !toSave.getFramesetName().equalsIgnoreCase(
893 MessageBay.MESSAGES_FRAMESET_NAME)) {
894 // remove this frame from the cache if it is there
895 // This will make sure links to the original are set correctly
896 _Cache.remove(toSave.getName().toLowerCase());
897 int nextnum = ReadINF(toSave.getPath(), toSave
898 .getFramesetName(), false) + 1;
899 SuspendCache();
900 Frame original = LoadFrame(toSave.getName());
901 toSave.setFrameNumber(nextnum);
902 ResumeCache();
903 // Put the modified version in the cache
904 addToCache(toSave);
905 // Show the messages alerting the user
906 Text originalMessage = new Text(-1);
907 originalMessage.setColor(MessageBay.ERROR_COLOR);
908 originalMessage.setText(original.getName()
909 + " was updated by another user.");
910 originalMessage.setLink(original.getName());
911 Text yourMessage = new Text(-1);
912 yourMessage.setColor(MessageBay.ERROR_COLOR);
913 yourMessage.setText("Your version was renamed "
914 + toSave.getName());
915 yourMessage.setLink(toSave.getName());
916 MessageBay.displayMessage(originalMessage);
917 MessageBay.displayMessage(yourMessage);
918 } else if (checkBackup
919 && ItemUtils.ContainsExactTag(toSave.getItems(),
920 ItemUtils.TAG_BACKUP)) {
921 SuspendCache();
922 String oldFramesetName = toSave.getFramesetName() + "-old";
923
924 Frame original = LoadFrame(toSave.getName());
925 if (original == null)
926 original = toSave;
927 int orignum = original.getNumber();
928
929 int nextnum = -1;
930 try {
931 nextnum = ReadINF(toSave.getPath(), oldFramesetName, false) + 1;
932 } catch (RuntimeException e) {
933 try {
934 CreateFrameset(oldFramesetName, toSave.getPath());
935 nextnum = 1;
936 } catch (Exception e1) {
937 e1.printStackTrace();
938 }
939 // e.printStackTrace();
940 }
941
942 if (nextnum > 0) {
943 original.setFrameset(oldFramesetName);
944 original.setFrameNumber(nextnum);
945 original.setPermission(new PermissionPair(UserAppliedPermission.copy));
946 original.change();
947 SaveFrame(original, false, false);
948 }
949
950 Item i = ItemUtils.FindExactTag(toSave.getItems(),
951 ItemUtils.TAG_BACKUP);
952 i.setLink(original.getName());
953 toSave.setFrameNumber(orignum);
954 ResumeCache();
955 }
956 // Update general stuff about frame
957 setSavedProperties(toSave);
958
959 // int oldMode = FrameGraphics.getMode();
960 // if (oldMode != FrameGraphics.MODE_XRAY)
961 // FrameGraphics.setMode(FrameGraphics.MODE_XRAY, true);
962 writer.writeFrame(toSave);
963 // FrameGraphics.setMode(oldMode, true);
964 toSave.setSaved();
965 if (inc) {
966 SessionStats.SavedFrame(toSave.getName());
967 }
968
969 // avoid out-of-sync frames (when in TwinFrames mode)
970 if (_Cache.containsKey(toSave.getName().toLowerCase()))
971 addToCache(toSave);
972
973 Logger.Log(Logger.SYSTEM, Logger.SAVE, "Saving " + toSave.getName()
974 + " to disk.");
975
976 // check that the INF file is not out of date
977 int last = ReadINF(toSave.getPath(), toSave.getFramesetName(),
978 false);
979 if (last <= toSave.getNumber())
980 WriteINF(toSave.getPath(), toSave.getFramesetName(), toSave
981 .getName());
982
983 // check if this was the profile frame (and thus needs
984 // re-parsing)
985 if (isProfileFrame(toSave)) {
986 Frame profile = FrameIO.LoadFrame(toSave.getFramesetName()
987 + "1");
988 assert (profile != null);
989 FrameUtils.ParseProfile(profile);
990 }
991 } catch (IOException ioe) {
992 ioe.printStackTrace();
993 ioe.getStackTrace();
994 Logger.Log(ioe);
995 return null;
996 }
997
998 return writer.getFileContents();
999 }
1000
1001 /**
1002 * @param toAdd
1003 */
1004 public static void addToCache(Frame toAdd) {
1005 _Cache.put(toAdd.getName().toLowerCase(), toAdd);
1006 }
1007
1008 /**
1009 * Checks if a frame is in the current user profile frameset.
1010 *
1011 * @param toCheck
1012 * the frame to check
1013 * @return true if the frame is in the current user profile frameset
1014 */
1015 public static boolean isProfileFrame(Frame toCheck) {
1016 if (toCheck.getNumber() == 0)
1017 return false;
1018 return toCheck.getPath().equals(PROFILE_PATH);
1019 // return toCheck.getFramesetName()
1020 // .equalsIgnoreCase(UserSettings.ProfileName);
1021 }
1022
1023 public static Frame LoadProfile(String userName) {
1024 return LoadFrame(userName + "1");
1025 }
1026
1027 public static Frame CreateNewProfile(String username) throws Exception {
1028 Frame profile = CreateFrameset(username, PROFILE_PATH, true);
1029 FrameUtils.CreateDefaultProfile(username, profile);
1030 return profile;
1031 }
1032
1033 /**
1034 * Reads the INF file that corresponds to the given Frame name
1035 *
1036 * @param framename
1037 * The Frame to lookup the INF file for
1038 * @throws IOException
1039 * Any exceptions encountered by the BufferedReader used to read
1040 * the INF.
1041 */
1042 public static int ReadINF(String path, String frameset, boolean update)
1043 throws IOException {
1044 assert (!frameset.endsWith("."));
1045 try {
1046 // read INF
1047 BufferedReader reader;
1048 try {
1049 // Check on the local drive
1050 reader = new BufferedReader(new FileReader(path
1051 + frameset.toLowerCase() + File.separator
1052 + INF_FILENAME));
1053 } catch (Exception e) {
1054 reader = new BufferedReader(new FileReader(path
1055 + frameset.toLowerCase() + File.separator
1056 + frameset.toLowerCase() + ".inf"));
1057 }
1058 String inf = reader.readLine();
1059 reader.close();
1060
1061 int next = Conversion.getFrameNumber(inf);
1062 // update INF file
1063 if (update) {
1064 try {
1065 WriteINF(path, frameset, frameset + (next + 1));
1066 } catch (IOException ioe) {
1067 ioe.printStackTrace();
1068 Logger.Log(ioe);
1069 }
1070 }
1071 return next;
1072 } catch (Exception e) {
1073 }
1074
1075 // Check peers
1076 return FrameShare.getInstance().getInfNumber(path, frameset, update);
1077 }
1078
1079 /**
1080 * Writes the given String out to the INF file corresponding to the current
1081 * frameset.
1082 *
1083 * @param toWrite
1084 * The String to write to the file.
1085 * @throws IOException
1086 * Any exception encountered by the BufferedWriter.
1087 */
1088 public static void WriteINF(String path, String frameset, String frameName)
1089 throws IOException {
1090 try {
1091 assert (!frameset.endsWith("."));
1092
1093 path += frameset.toLowerCase() + File.separator + INF_FILENAME;
1094
1095 BufferedWriter writer = new BufferedWriter(new FileWriter(path));
1096 writer.write(frameName);
1097 writer.close();
1098 } catch (Exception e) {
1099
1100 }
1101 }
1102
1103 public static boolean FrameIsCached(String name) {
1104 return _Cache.containsKey(name);
1105 }
1106
1107 /**
1108 * Gets a frame from the cache.
1109 *
1110 * @param name
1111 * The frame to get from the cache
1112 *
1113 * @return The frame from cache. Null if not cached.
1114 */
1115 public static Frame FrameFromCache(String name) {
1116 return _Cache.get(name);
1117 }
1118
1119 public static String ConvertToValidFramesetName(String toValidate) {
1120 assert (toValidate != null && toValidate.length() > 0);
1121
1122 StringBuffer result = new StringBuffer();
1123
1124 if (Character.isDigit(toValidate.charAt(0))) {
1125 result.append(FRAME_NAME_LAST_CHAR);
1126 }
1127
1128 boolean capital = false;
1129 for (int i = 0; i < toValidate.length()
1130 && result.length() < MAX_NAME_LENGTH; i++) {
1131 char cur = toValidate.charAt(i);
1132
1133 // capitalize all characters after spaces
1134 if (Character.isLetterOrDigit(cur)) {
1135 if (capital) {
1136 capital = false;
1137 result.append(Character.toUpperCase(cur));
1138 } else
1139 result.append(cur);
1140 } else {
1141 capital = true;
1142 }
1143 }
1144 assert (result.length() > 0);
1145 int lastCharIndex = result.length() - 1;
1146 if (!Character.isLetter(result.charAt(lastCharIndex))) {
1147 if (lastCharIndex == MAX_NAME_LENGTH - 1)
1148 result.setCharAt(lastCharIndex, FRAME_NAME_LAST_CHAR);
1149 else
1150 result.append(FRAME_NAME_LAST_CHAR);
1151 }
1152
1153 assert (isValidFramesetName(result.toString()));
1154 return result.toString();
1155 }
1156
1157 public static Frame CreateNewFrame(Item linker) throws RuntimeException {
1158 String title = linker.getName();
1159
1160 String templateLink = linker.getAbsoluteLinkTemplate();
1161 String framesetLink = linker.getAbsoluteLinkFrameset();
1162 String frameset = (framesetLink != null ? framesetLink : DisplayIO
1163 .getCurrentFrame().getFramesetName());
1164
1165 Frame newFrame = FrameIO.CreateFrame(frameset, title, templateLink);
1166 return newFrame;
1167 }
1168
1169 /**
1170 * Creates a new Frameset on disk, including a .0, .1, and .inf files. The
1171 * Default.0 frame is copied to make the initial .0 and .1 Frames
1172 *
1173 * @param name
1174 * The Frameset name to use
1175 * @return The name of the first Frame in the newly created Frameset (the .1
1176 * frame)
1177 */
1178 public static Frame CreateNewFrameset(String name) throws Exception {
1179 String path = DisplayIO.getCurrentFrame().getPath();
1180
1181 // if current frameset is profile directory change it to framesets
1182 if (path.equals(FrameIO.PROFILE_PATH)) {
1183 path = FrameIO.FRAME_PATH;
1184 }
1185
1186 Frame newFrame = FrameIO.CreateFrameset(name, path);
1187
1188 if (newFrame == null) {
1189 // Cant create directories if the path is readonly or there is no
1190 // space available
1191 newFrame = FrameIO.CreateFrameset(name, FrameIO.FRAME_PATH);
1192 }
1193
1194 if (newFrame == null) {
1195 // TODO handle running out of disk space here
1196 }
1197
1198 return newFrame;
1199 }
1200
1201 /**
1202 *
1203 * @param frameset
1204 * @return
1205 */
1206 public static int getLastNumber(String frameset) { // Rob thinks it might
1207 // have been
1208 // GetHighestNumExFrame
1209 // TODO minimise the number of frames being read in!!
1210 int num = -1;
1211
1212 Frame zero = LoadFrame(frameset + "0");
1213
1214 // the frameset does not exist (or has no 0 frame)
1215 if (zero == null)
1216 return -1;
1217
1218 try {
1219 num = ReadINF(zero.getPath(), frameset, false);
1220 } catch (IOException e) {
1221 // TODO Auto-generated catch block
1222 // e.printStackTrace();
1223 }
1224
1225 /*
1226 * Michael doesnt think the code below is really needed... it will just
1227 * slow things down when we are reading frames over a network***** for (;
1228 * num >= 0; num--) { System.out.println("This code is loading frames to
1229 * find the highest existing frame..."); if (LoadFrame(frameset + num) !=
1230 * null) break; }
1231 */
1232
1233 return num;
1234 }
1235
1236 /**
1237 * Checks if a given frameset is accessable.
1238 *
1239 * @param framesetName
1240 * @return
1241 */
1242 public static Boolean canAccessFrameset(String framesetName) {
1243 framesetName = framesetName.toLowerCase();
1244 for (String path : UserSettings.FrameDirs.get()) {
1245 if ((new File(path + framesetName)).exists())
1246 return true;
1247 }
1248 return false;
1249 }
1250
1251 public static Frame CreateFrameset(String frameset, String path,
1252 boolean recreate) throws Exception {
1253 String conversion = frameset + " --> ";
1254
1255 if (!isValidFramesetName(frameset)) {
1256 throw new Exception("Invalid frameset name");
1257 }
1258
1259 if (!recreate && FrameIO.canAccessFrameset(frameset)) {
1260 throw new ExistingFramesetException(frameset);
1261 }
1262
1263 conversion += frameset;
1264 Logger.Log(Logger.SYSTEM, Logger.NEW_FRAMESET, "Frameset Name: "
1265 + conversion);
1266 conversion = frameset;
1267
1268 /**
1269 * TODO: Update this to exclude any\all invalid filename characters
1270 */
1271 // ignore annotation character
1272 if (frameset.startsWith("@"))
1273 frameset = frameset.substring(1);
1274
1275 conversion += " --> " + frameset;
1276 Logger.Log(Logger.SYSTEM, Logger.NEW_FRAMESET, "Name: " + conversion);
1277
1278 // create the new Frameset directory
1279 File dir = new File(path + frameset.toLowerCase() + File.separator);
1280
1281 // If the directory doesnt already exist then create it...
1282 if (!dir.exists()) {
1283 // If the directory couldnt be created, then there is something
1284 // wrong... ie. The disk is full.
1285 if (!dir.mkdirs()) {
1286 return null;
1287 }
1288 }
1289
1290 // create the new INF file
1291 try {
1292 WriteINF(path, frameset, frameset + '1');
1293 } catch (IOException ioe) {
1294 ioe.printStackTrace();
1295 Logger.Log(ioe);
1296 }
1297
1298 SuspendCache();
1299 // copy the default .0 and .1 files
1300 Frame base = null;
1301 try {
1302 base = LoadFrame(UserSettings.DefaultFrame.get());
1303 } catch (Exception e) {
1304 }
1305 // The frame may not be accessed for various reasons... in all these
1306 // cases just create a new one
1307 if (base == null) {
1308 base = new Frame();
1309 }
1310
1311 ResumeCache();
1312
1313 base.reset();
1314 base.resetDateCreated();
1315 base.setFrameset(frameset);
1316 base.setFrameNumber(0);
1317 base.setTitle(base.getFramesetName() + "0");
1318 base.setPath(path);
1319 base.change();
1320 base.setOwner(UserSettings.UserName.get());
1321 SaveFrame(base, false);
1322
1323 base.reset();
1324 base.resetDateCreated();
1325 base.setFrameNumber(1);
1326 base.setTitle(frameset);
1327 base.change();
1328 base.setOwner(UserSettings.UserName.get());
1329 SaveFrame(base, true);
1330
1331 Logger.Log(Logger.SYSTEM, Logger.NEW_FRAMESET, "Created new frameset: "
1332 + frameset);
1333
1334 return base;
1335 }
1336
1337 /**
1338 * Tests if a frameset name is valid. That is it must begin and end with a
1339 * letter and contain only letters and digits in between.
1340 *
1341 * @param frameset
1342 * the name to be tested
1343 * @return true if the frameset name is valid
1344 */
1345 public static boolean isValidFramesetName(String frameset) {
1346 if (frameset == null) {
1347 return false;
1348 }
1349
1350 int nameLength = frameset.length();
1351 if (frameset.length() <= 0 || nameLength > MAX_NAME_LENGTH) {
1352 return false;
1353 }
1354
1355 int lastCharIndex = nameLength - 1;
1356
1357 if (!Character.isLetter(frameset.charAt(0))
1358 || !Character.isLetter(frameset.charAt(lastCharIndex)))
1359 return false;
1360
1361 for (int i = 1; i < lastCharIndex; i++) {
1362 if (!isValidFrameNameChar(frameset.charAt(i))) {
1363 return false;
1364 }
1365 }
1366 return true;
1367 }
1368
1369 public static boolean deleteFrameset(String framesetName) {
1370 return moveFrameset(framesetName, FrameIO.TRASH_PATH);
1371 }
1372
1373 public static boolean moveFrameset(String framesetName,
1374 String destinationFolder) {
1375 if (!FrameIO.canAccessFrameset(framesetName))
1376 return false;
1377 // Clear the cache
1378 _Cache.clear();
1379
1380 // Search all the available directories for the directory
1381 for (String path : UserSettings.FrameDirs.get()) {
1382 String source = path + framesetName.toLowerCase() + File.separator;
1383 File framesetDirectory = new File(source);
1384 // Once we have found the directory move it
1385 if (framesetDirectory.exists()) {
1386 String destPath = destinationFolder
1387 + framesetName.toLowerCase();
1388 int copyNumber = 1;
1389 File dest = new File(destPath + File.separator);
1390 // Create the destination folder if it doesnt already exist
1391 if (!dest.getParentFile().exists())
1392 dest.mkdirs();
1393 // If a frameset with the same name is already in the
1394 // destination add
1395 // a number to the end
1396 while (dest.exists()) {
1397 dest = new File(destPath + ++copyNumber + File.separator);
1398 }
1399 if (!framesetDirectory.renameTo(dest)) {
1400 for (File f : framesetDirectory.listFiles()) {
1401 if (!f.delete())
1402 return false;
1403 }
1404 if (!framesetDirectory.delete())
1405 return false;
1406 }
1407 return true;
1408 }
1409 }
1410 return false;
1411 }
1412
1413 public static boolean CopyFrameset(String framesetToCopy,
1414 String copiedFrameset) throws Exception {
1415 if (!FrameIO.canAccessFrameset(framesetToCopy))
1416 return false;
1417 if (FrameIO.canAccessFrameset(copiedFrameset))
1418 return false;
1419 // search through all the directories to find the frameset we are
1420 // copying
1421 for (String path : UserSettings.FrameDirs.get()) {
1422 String source = path + framesetToCopy.toLowerCase()
1423 + File.separator;
1424 File framesetDirectory = new File(source);
1425 if (framesetDirectory.exists()) {
1426 // copy the frameset
1427 File copyFramesetDirectory = new File(path
1428 + copiedFrameset.toLowerCase() + File.separator);
1429 if (!copyFramesetDirectory.mkdirs())
1430 return false;
1431 // copy each of the frames
1432 for (File f : framesetDirectory.listFiles()) {
1433 // Ignore hidden files
1434 if (f.getName().charAt(0) == '.')
1435 continue;
1436 String copyPath = copyFramesetDirectory.getAbsolutePath()
1437 + File.separator + f.getName();
1438 FrameIO.copyFile(f.getAbsolutePath(), copyPath);
1439 }
1440 return true;
1441 }
1442 }
1443 return false;
1444 }
1445
1446 /**
1447 * Copies a file from one location to another.
1448 *
1449 * @param existingFile
1450 * @param newFileName
1451 * @throws Exception
1452 */
1453 public static void copyFile(String existingFile, String newFileName)
1454 throws Exception {
1455 FileInputStream is = new FileInputStream(existingFile);
1456 FileOutputStream os = new FileOutputStream(newFileName, false);
1457 int data;
1458 while ((data = is.read()) != -1) {
1459 os.write(data);
1460 }
1461 os.flush();
1462 os.close();
1463 is.close();
1464 }
1465
1466 /**
1467 * Saves a frame regardless of whether or not the frame is marked as having
1468 * been changed.
1469 *
1470 * @param frame
1471 * the frame to save
1472 * @return the contents of the frame or null if it could not be saved
1473 */
1474 public static String ForceSaveFrame(Frame frame) {
1475 frame.change();
1476 return SaveFrame(frame, false);
1477 }
1478
1479 public static boolean isValidLink(String frameName) {
1480 return frameName == null || isPositiveInteger(frameName)
1481 || isValidFrameName(frameName);
1482 }
1483
1484 public static void SavePublicFrame(String peerName, String frameName,
1485 int version, BufferedReader packetContents) {
1486 // TODO handle versioning - add version to the header
1487 // Remote user uploads version based on an old version
1488
1489 // Remove it from the cache so that next time it is loaded we get the up
1490 // todate version
1491 _Cache.remove(frameName.toLowerCase());
1492
1493 // Save to file
1494 String filename = PUBLIC_PATH + Conversion.getFramesetName(frameName)
1495 + File.separator + Conversion.getFrameNumber(frameName)
1496 + ExpReader.EXTENTION;
1497
1498 File file = new File(filename);
1499 // Ensure the file exists
1500 if (file.exists()) {
1501 // Check the versions
1502 int savedVersion = ExpReader.getVersion(filename);
1503
1504 if (savedVersion > version) {
1505 // remove this frame from the cache if it is there
1506 // This will make sure links to the original are set correctly
1507 // _Cache.remove(frameName.toLowerCase());
1508
1509 int nextNum = 0;
1510 try {
1511 nextNum = ReadINF(PUBLIC_PATH, Conversion
1512 .getFramesetName(frameName), false) + 1;
1513 } catch (IOException e) {
1514 e.printStackTrace();
1515 }
1516
1517 String newName = Conversion.getFramesetName(frameName)
1518 + nextNum;
1519 filename = PUBLIC_PATH + Conversion.getFramesetName(frameName)
1520 + File.separator + nextNum + ExpReader.EXTENTION;
1521
1522 // Show the messages alerting the user
1523 Text originalMessage = new Text(-1);
1524 originalMessage.setColor(MessageBay.ERROR_COLOR);
1525 originalMessage.setText(frameName + " was edited by "
1526 + peerName);
1527 originalMessage.setLink(frameName);
1528 Text yourMessage = new Text(-1);
1529 yourMessage.setColor(MessageBay.ERROR_COLOR);
1530 yourMessage.setText("Their version was renamed " + newName);
1531 yourMessage.setLink(newName);
1532 MessageBay.displayMessage(originalMessage);
1533 MessageBay.displayMessage(yourMessage);
1534
1535 Frame editedFrame = FrameIO.LoadFrame(frameName);
1536
1537 FrameShare.getInstance().sendMessage(
1538 frameName + " was recently edited by "
1539 + editedFrame.getLastModifyUser(), peerName);
1540 FrameShare.getInstance().sendMessage(
1541 "Your version was renamed " + newName, peerName);
1542 }
1543 }
1544
1545 // Save the new version
1546 try {
1547 // FileWriter fw = new FileWriter(file);
1548
1549 // Open an Output Stream Writer to set encoding
1550 OutputStream fout = new FileOutputStream(file);
1551 OutputStream bout = new BufferedOutputStream(fout);
1552 Writer fw = new OutputStreamWriter(bout, "UTF-8");
1553
1554 String nextLine = null;
1555 while ((nextLine = packetContents.readLine()) != null) {
1556 fw.write(nextLine + '\n');
1557 }
1558 fw.flush();
1559 fw.close();
1560 MessageBay.displayMessage("Saved remote frame: " + frameName);
1561 } catch (IOException e) {
1562 MessageBay.errorMessage("Error remote saving " + frameName + ": "
1563 + e.getMessage());
1564 e.printStackTrace();
1565 }
1566 // } else {
1567 //
1568 //
1569 //
1570 // MessageBay
1571 // .errorMessage("Recieved save request for unknown public frame: "
1572 // + frameName);
1573 // }
1574 }
1575
1576 public static void setSavedProperties(Frame toSave) {
1577 toSave.setLastModifyDate(Formatter.getDateTime());
1578 toSave.setLastModifyUser(UserSettings.UserName.get());
1579 toSave.setVersion(toSave.getVersion() + 1);
1580 Time darkTime = new Time(SessionStats.getFrameDarkTime().getTime()
1581 + toSave.getDarkTime().getTime());
1582 Time activeTime = new Time(SessionStats.getFrameActiveTime().getTime()
1583 + toSave.getActiveTime().getTime());
1584 toSave.setDarkTime(darkTime);
1585 toSave.setActiveTime(activeTime);
1586 }
1587
1588}
Note: See TracBrowser for help on using the repository browser.