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