f@0: /* f@0: CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool f@0: f@0: Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) f@0: f@0: This program is free software: you can redistribute it and/or modify f@0: it under the terms of the GNU General Public License as published by f@0: the Free Software Foundation, either version 3 of the License, or f@0: (at your option) any later version. f@0: f@0: This program is distributed in the hope that it will be useful, f@0: but WITHOUT ANY WARRANTY; without even the implied warranty of f@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the f@0: GNU General Public License for more details. f@0: f@0: You should have received a copy of the GNU General Public License f@0: along with this program. If not, see . f@0: */ f@0: package uk.ac.qmul.eecs.ccmi.checkboxtree; f@0: f@0: import java.io.BufferedReader; f@0: import java.io.BufferedWriter; f@0: import java.io.File; f@0: import java.io.FileReader; f@0: import java.io.FileWriter; f@0: import java.io.IOException; f@0: import java.util.Collection; f@0: import java.util.Collections; f@0: import java.util.HashSet; f@0: import java.util.Iterator; f@0: import java.util.Set; f@0: f@0: /** f@0: * The {@code SetProperties} class represents a persistent set of properties. f@0: * The {@code SetProperties} can be saved to a stream or loaded from a stream. f@0: * f@0: * Unlike {@code java.util.Properties}, this class is not backed by a key-value map, but rather f@0: * by a {@code Set}. Therefore it only contains values. All the methods of this class are thread-safe, f@0: * but {@code iterator()}. In order to safely iterate on the Set, the iteration must happen in a block syncronized f@0: * on the Object returned by {@link #getMonitor()}. f@0: * f@0: * For a description of the methods of the {@code Set} interface, see {@code java.util.Set} f@0: * f@0: * @see java.util.Properties f@0: * @see java.util.Collections#synchronizedSet(Set) f@0: */ f@0: public class SetProperties implements Set { f@0: public SetProperties() { f@0: delegate = Collections.synchronizedSet(new HashSet()); f@0: } f@0: f@0: public SetProperties(Collection collection) { f@0: delegate = Collections.synchronizedSet(new HashSet(collection)); f@0: } f@0: f@0: public SetProperties(int initialCapacity) { f@0: delegate = Collections.synchronizedSet(new HashSet(initialCapacity)); f@0: } f@0: f@0: public SetProperties(int initialCapacity, float loadFactor){ f@0: delegate = Collections.synchronizedSet(new HashSet(initialCapacity, loadFactor)); f@0: } f@0: f@0: /* DELEGATE METHODS */ f@0: @Override f@0: public boolean add(String arg0) { f@0: return delegate.add(arg0); f@0: } f@0: f@0: @Override f@0: public boolean addAll(Collection arg0) { f@0: return delegate.addAll(arg0); f@0: } f@0: f@0: @Override f@0: public void clear() { f@0: delegate.clear(); f@0: } f@0: f@0: @Override f@0: public boolean contains(Object arg0) { f@0: return delegate.contains(arg0); f@0: } f@0: f@0: @Override f@0: public boolean containsAll(Collection arg0) { f@0: return delegate.containsAll(arg0); f@0: } f@0: f@0: @Override f@0: public boolean equals(Object arg0) { f@0: return delegate.equals(arg0); f@0: } f@0: f@0: @Override f@0: public int hashCode() { f@0: return delegate.hashCode(); f@0: } f@0: f@0: @Override f@0: public boolean isEmpty() { f@0: return delegate.isEmpty(); f@0: } f@0: f@0: @Override f@0: public Iterator iterator() { f@0: return delegate.iterator(); f@0: } f@0: f@0: @Override f@0: public boolean remove(Object arg0) { f@0: return delegate.remove(arg0); f@0: } f@0: f@0: @Override f@0: public boolean removeAll(Collection arg0) { f@0: return delegate.removeAll(arg0); f@0: } f@0: f@0: @Override f@0: public boolean retainAll(Collection arg0) { f@0: return delegate.retainAll(arg0); f@0: } f@0: f@0: @Override f@0: public int size() { f@0: return delegate.size(); f@0: } f@0: f@0: @Override f@0: public Object[] toArray() { f@0: return delegate.toArray(); f@0: } f@0: f@0: @Override f@0: public T[] toArray(T[] arg0) { f@0: return delegate.toArray(arg0); f@0: } f@0: f@0: /** f@0: * Stores the content of this set (strings) in a text file. The content can then be retrieved f@0: * by calling {@code load()} passing as argument the same file as this method. The strings f@0: * will be written on a row each. f@0: * f@0: * @param file A valid File where the content of this object will be stored f@0: * @param comments A comment string that will be added at the beginning of the file. f@0: * f@0: * @throws IOException if an exception occurs while writing the file f@0: */ f@0: public void store(File file, String comments) throws IOException{ f@0: synchronized(delegate){ f@0: if(file == null) f@0: throw new IllegalArgumentException("File cannot be null"); f@0: FileWriter fWriter = new FileWriter(file); f@0: BufferedWriter writer = new BufferedWriter(fWriter); f@0: if(comments != null){ f@0: writer.write(COMMENTS_ESCAPE+" "+comments); f@0: writer.newLine(); f@0: writer.newLine(); f@0: } f@0: f@0: for(String property : this){ f@0: writer.write(property); f@0: writer.newLine(); f@0: } f@0: writer.close(); f@0: } f@0: } f@0: f@0: /** f@0: * Loads the content of a file into this set. Whaen the file is read, each row is taken as an f@0: * entry of the set. f@0: * f@0: * @param file the file where to read the entries from f@0: * @throws IOException if an exception occurs while reading the file f@0: */ f@0: public void load(File file) throws IOException{ f@0: synchronized(delegate){ f@0: if(file == null) f@0: throw new IllegalArgumentException("File cannot be null"); f@0: FileReader fReader = new FileReader(file); f@0: BufferedReader reader = new BufferedReader(fReader); f@0: String line; f@0: while((line = reader.readLine()) != null){ f@0: if(!line.isEmpty() && !line.trim().startsWith(COMMENTS_ESCAPE)) f@0: add(line); f@0: } f@0: reader.close(); f@0: } f@0: } f@0: f@0: /** f@0: * Returns the Object all the methods (but {@code iterator()} of this {@code Set} are synchronized on. It can be used f@0: * to safely iterate on this object without incurring in a race condition f@0: * f@0: * @return an {@code Object} to be used as synchronization monitor f@0: * f@0: * @see java.util.Collections#synchronizedSet(Set) f@0: */ f@0: public Object getMonitor(){ f@0: return delegate; f@0: } f@0: f@0: private Set delegate; f@0: private static String COMMENTS_ESCAPE = "#"; f@0: }