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 extends String> 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 extends String> 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: }