diff --git a/BlueBerry/Bundles/org.blueberry.core.runtime/src/berryIPreferences.h b/BlueBerry/Bundles/org.blueberry.core.runtime/src/berryIPreferences.h index 9dcd078b9f..210a065298 100644 --- a/BlueBerry/Bundles/org.blueberry.core.runtime/src/berryIPreferences.h +++ b/BlueBerry/Bundles/org.blueberry.core.runtime/src/berryIPreferences.h @@ -1,705 +1,705 @@ /*=================================================================== BlueBerry Platform Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef BERRYIPREFERENCES_H_ #define BERRYIPREFERENCES_H_ #include #include "berryObject.h" #include "berryBackingStoreException.h" namespace berry { /** * A node in a hierarchical collection of preference data. * *

* This interface allows applications to store and retrieve user and system * preference data. This data is stored persistently in an * implementation-dependent backing store. Typical implementations include flat * files, OS-specific registries, directory servers and SQL databases. * *

* For each bundle, there is a separate tree of nodes for each user, and one for * system preferences. The precise description of "user" and "system" will vary * from one bundle to another. Typical information stored in the user preference * tree might include font choice, and color choice for a bundle which interacts * with the user via a servlet. Typical information stored in the system * preference tree might include installation data, or things like high score * information for a game program. * *

* Nodes in a preference tree are named in a similar fashion to directories in a * hierarchical file system. Every node in a preference tree has a node name * (which is not necessarily unique), a unique absolute path name , * and a path name relative to each ancestor including itself. * *

* The root node has a node name of the empty QString object (""). * Every other node has an arbitrary node name, specified at the time it is * created. The only restrictions on this name are that it cannot be the empty * string, and it cannot contain the slash character ('/'). * *

* The root node has an absolute path name of "/". Children of the * root node have absolute path names of "/" + <node name> * . All other nodes have absolute path names of <parent's absolute * path name> + "/" + <node name> . Note that * all absolute path names begin with the slash character. * *

* A node n 's path name relative to its ancestor a is simply the * string that must be appended to a 's absolute path name in order to * form n 's absolute path name, with the initial slash character (if * present) removed. Note that: *

* *

* Note finally that: *

* *

* Each Preference node has zero or more properties associated with * it, where a property consists of a name and a value. The bundle writer is * free to choose any appropriate names for properties. Their values can be of * type QString,long,int,bool, * std::vector,float, or double but they can * always be accessed as if they were QString objects. * *

* All node name and property name comparisons are case-sensitive. * *

* All of the methods that modify preference data are permitted to operate * asynchronously; they may return immediately, and changes will eventually * propagate to the persistent backing store, with an implementation-dependent * delay. The flush method may be used to synchronously force updates * to the backing store. * *

* Implementations must automatically attempt to flush to the backing store any * pending updates for a bundle's preferences when the bundle is stopped or * otherwise ungets the IPreferences Service. * *

* The methods in this class may be invoked concurrently by multiple threads in * a single Java Virtual Machine (JVM) without the need for external * synchronization, and the results will be equivalent to some serial execution. * If this class is used concurrently by multiple JVMs that store their * preference data in the same backing store, the data store will not be * corrupted, but no other guarantees are made concerning the consistency of the * preference data. * * * @version $Revision$ */ struct org_blueberry_core_runtime_EXPORT IPreferences : virtual public Object { berryObjectMacro(berry::IPreferences) virtual ~IPreferences(); /** * Associates the specified value with the specified key in this node. * * @param key key with which the specified value is to be associated. * @param value value to be associated with the specified key. * @throws NullPointerException if key or value is * null. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. */ virtual void Put(const QString& key, const QString& value) = 0; /** * Returns the value associated with the specified key in this * node. Returns the specified default if there is no value associated with * the key, or the backing store is inaccessible. * * @param key key whose associated value is to be returned. * @param def the value to be returned in the event that this node has no * value associated with key or the backing store is * inaccessible. * @return the value associated with key, or def if * no value is associated with key. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @throws NullPointerException if key is null. (A * null default is permitted.) */ virtual QString Get(const QString& key, const QString& def) const = 0; /** * Removes the value associated with the specified key in this * node, if any. * * @param key key whose mapping is to be removed from this node. * @see #get(const QString&,const QString&) * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. */ virtual void Remove(const QString& key) = 0; /** * Removes all of the properties (key-value associations) in this node. This * call has no effect on any descendants of this node. * * @throws BackingStoreException if this operation cannot be completed due * to a failure in the backing store, or inability to communicate * with it. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #remove(const QString&) */ virtual void Clear() = 0; /** * Associates a QString object representing the specified * int value with the specified key in this node. The * associated string is the one that would be returned if the int * value were passed to Integer.toString(int). This method is * intended for use in conjunction with {@link #getInt}method. * *

* Implementor's note: it is not necessary that the property value * be represented by a QString object in the backing store. If the * backing store supports integer values, it is not unreasonable to use * them. This implementation detail is not visible through the * IPreferences API, which allows the value to be read as an * int (with getInt or a QString (with * get) type. * * @param key key with which the string form of value is to be associated. * @param value value whose string form is to be associated with * key. * @throws NullPointerException if key is null. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #getInt(const QString&,int) */ virtual void PutInt(const QString& key, int value) = 0; /** * Returns the int value represented by the QString * object associated with the specified key in this node. The * QString object is converted to an int as by * Integer.parseInt(QString). Returns the specified default if * there is no value associated with the key, the backing store * is inaccessible, or if Integer.parseInt(QString) would throw a * NumberFormatException if the associated value were * passed. This method is intended for use in conjunction with the * {@link #putInt}method. * * @param key key whose associated value is to be returned as an * int. * @param def the value to be returned in the event that this node has no * value associated with key or the associated value * cannot be interpreted as an int or the backing store is * inaccessible. * @return the int value represented by the QString * object associated with key in this node, or * def if the associated value does not exist or cannot * be interpreted as an int type. * @throws NullPointerException if key is null. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #putInt(const QString&,int) * @see #get(const QString&,const QString&) */ virtual int GetInt(const QString& key, int def) const = 0; /** * Associates a QString object representing the specified * long value with the specified key in this node. The * associated QString object is the one that would be returned if * the long value were passed to Long.toString(long). * This method is intended for use in conjunction with the {@link #getLong} * method. * *

* Implementor's note: it is not necessary that the value * be represented by a QString type in the backing store. If the * backing store supports long values, it is not unreasonable to * use them. This implementation detail is not visible through the * IPreferences API, which allows the value to be read as a * long (with getLong or a QString (with * get) type. * * @param key key with which the string form of value * is to be associated. * @param value value whose string form is to be associated with * key. * @throws NullPointerException if key is null. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #getLong(const QString&,long) */ virtual void PutLong(const QString& key, long value) = 0; /** * Returns the long value represented by the QString * object associated with the specified key in this node. The * QString object is converted to a long as by * Long.parseLong(QString). Returns the specified default if * there is no value associated with the key, the backing store * is inaccessible, or if Long.parseLong(QString) would throw a * NumberFormatException if the associated value were * passed. This method is intended for use in conjunction with the * {@link #putLong}method. * * @param key key whose associated value is to be returned as a * long value. * @param def the value to be returned in the event that this node has no * value associated with key or the associated value * cannot be interpreted as a long type or the backing * store is inaccessible. * @return the long value represented by the QString * object associated with key in this node, or * def if the associated value does not exist or cannot * be interpreted as a long type. * @throws NullPointerException if key is null. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #putLong(const QString&,long) * @see #get(const QString&,const QString&) */ virtual long GetLong(const QString& key, long def) const = 0; /** * Associates a QString object representing the specified * bool value with the specified key in this node. The * associated string is "true" if the value is true, and "false" * if it is false. This method is intended for use in * conjunction with the {@link #getBool}method. * *

* Implementor's note: it is not necessary that the value be * represented by a string in the backing store. If the backing store * supports bool values, it is not unreasonable to use them. * This implementation detail is not visible through the IPreferences * API, which allows the value to be read as a bool * (with getBool) or a QString (with get) * type. * * @param key key with which the string form of value is to be * associated. * @param value value whose string form is to be associated with * key. * @throws NullPointerException if key is null. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #getBool(const QString&,bool) * @see #get(const QString&,const QString&) */ virtual void PutBool(const QString& key, bool value) = 0; /** * Returns the bool value represented by the QString * object associated with the specified key in this node. Valid * strings are "true", which represents true, and "false", which * represents false. Case is ignored, so, for example, "TRUE" * and "False" are also valid. This method is intended for use in * conjunction with the {@link #putBool}method. * *

* Returns the specified default if there is no value associated with the * key, the backing store is inaccessible, or if the associated * value is something other than "true" or "false", ignoring case. * * @param key key whose associated value is to be returned as a * bool. * @param def the value to be returned in the event that this node has no * value associated with key or the associated value * cannot be interpreted as a bool or the backing store * is inaccessible. * @return the bool value represented by the std::string * object associated with key in this node, or * null if the associated value does not exist or cannot * be interpreted as a bool. * @throws NullPointerException if key is null. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #get(const QString&,const QString&) * @see #putBool(const QString&,bool) */ virtual bool GetBool(const QString& key, bool def) const = 0; /** * Associates a QString object representing the specified * float value with the specified key in this node. * The associated QString object is the one that would be returned * if the float value were passed to * Float.toString(float). This method is intended for use in * conjunction with the {@link #getFloat}method. * *

* Implementor's note: it is not necessary that the value be * represented by a string in the backing store. If the backing store * supports float values, it is not unreasonable to use them. * This implementation detail is not visible through the IPreferences * API, which allows the value to be read as a float (with * getFloat) or a QString (with get) type. * * @param key key with which the string form of value is to be * associated. * @param value value whose string form is to be associated with * key. * @throws NullPointerException if key is null. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #getFloat(const QString&,float) */ virtual void PutFloat(const QString& key, float value) = 0; /** * Returns the float value represented by the QString * object associated with the specified key in this node. The * QString object is converted to a float value as by * Float.parseFloat(QString). Returns the specified default if * there is no value associated with the key, the backing store * is inaccessible, or if Float.parseFloat(QString) would throw a * NumberFormatException if the associated value were passed. * This method is intended for use in conjunction with the {@link #putFloat} * method. * * @param key key whose associated value is to be returned as a * float value. * @param def the value to be returned in the event that this node has no * value associated with key or the associated value * cannot be interpreted as a float type or the backing * store is inaccessible. * @return the float value represented by the string associated * with key in this node, or def if the * associated value does not exist or cannot be interpreted as a * float type. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @throws NullPointerException if key is null. * @see #putFloat(const QString&,float) * @see #get(const QString&,const QString&) */ virtual float GetFloat(const QString& key, float def) const = 0; /** * Associates a QString object representing the specified * double value with the specified key in this node. * The associated QString object is the one that would be returned * if the double value were passed to * Double.toString(double). This method is intended for use in * conjunction with the {@link #getDouble}method * *

* Implementor's note: it is not necessary that the value be * represented by a string in the backing store. If the backing store * supports double values, it is not unreasonable to use them. * This implementation detail is not visible through the IPreferences * API, which allows the value to be read as a double (with * getDouble) or a QString (with get) * type. * * @param key key with which the string form of value is to be * associated. * @param value value whose string form is to be associated with * key. * @throws NullPointerException if key is null. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #getDouble(const QString&,double) */ virtual void PutDouble(const QString& key, double value) = 0; /** * Returns the double value represented by the QString * object associated with the specified key in this node. The * QString object is converted to a double value as by * Double.parseDouble(QString). Returns the specified default if * there is no value associated with the key, the backing store * is inaccessible, or if Double.parseDouble(QString) would throw * a NumberFormatException if the associated value were passed. * This method is intended for use in conjunction with the * {@link #putDouble}method. * * @param key key whose associated value is to be returned as a * double value. * @param def the value to be returned in the event that this node has no * value associated with key or the associated value * cannot be interpreted as a double type or the backing * store is inaccessible. * @return the double value represented by the QString * object associated with key in this node, or * def if the associated value does not exist or cannot * be interpreted as a double type. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the the {@link #removeNode()}method. * @throws NullPointerException if key is null. * @see #putDouble(const QString&,double) * @see #get(const QString&,const QString&) */ virtual double GetDouble(const QString& key, double def) const = 0; /** * Associates a QByteArray object representing the specified * QByteArray with the specified key in this node. The * associated QByteArray object is stored in Base64 encoding. * This method is intended for use in conjunction with the * {@link #getByteArray}method. * * @param key key with which the string form of value * is to be associated. * @param value value whose string form is to be associated with * key. * @throws NullPointerException if key or value is * null. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #GetByteArray(const QString&,const QByteArray&) * @see #Get(const QString&,const QString&) */ virtual void PutByteArray(const QString& key, const QByteArray& value) = 0; /** * Returns the QByteArray value represented by the QString * object associated with the specified key in this node. Valid * QString objects are Base64 encoded binary data, as * defined in RFC 2045 , * Section 6.8, with one minor change: the string must consist solely of * characters from the Base64 Alphabet ; no newline characters or * extraneous characters are permitted. This method is intended for use in * conjunction with the {@link #putByteArray}method. * *

* Returns the specified default if there is no value associated with the * key, the backing store is inaccessible, or if the associated * value is not a valid Base64 encoded byte array (as defined above). * * @param key key whose associated value is to be returned as a * std::vector object. * @param def the value to be returned in the event that this node has no * value associated with key or the associated value * cannot be interpreted as a std::vector type, or the backing * store is inaccessible. * @return the std::vector value represented by the QString * object associated with key in this node, or * def if the associated value does not exist or cannot * be interpreted as a std::vector. * @throws NullPointerException if key is null. (A * null value for def is permitted.) * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #get(const QString&,const QString&) * @see #putByteArray(const QString&,std::vector) */ virtual QByteArray GetByteArray(const QString& key, const QByteArray& def) const = 0; /** * Returns all of the keys that have an associated value in this node. (The * returned array will be of size zero if this node has no preferences and * not null!) * * @return an array of the keys that have an associated value in this node. * @throws BackingStoreException if this operation cannot be completed due * to a failure in the backing store, or inability to communicate * with it. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. */ virtual QStringList Keys() const = 0; /** * Returns the names of the children of this node. (The returned array will * be of size zero if this node has no children and not null!) * * @return the names of the children of this node. * @throws BackingStoreException if this operation cannot be completed due * to a failure in the backing store, or inability to communicate * with it. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. */ virtual QStringList ChildrenNames() const = 0; /** * Returns the parent of this node, or null if this is the root. * * @return the parent of this node. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. */ virtual IPreferences::Pointer Parent() const = 0; /** * Returns a named IPreferences object (node), creating it and any * of its ancestors if they do not already exist. Accepts a relative or * absolute pathname. Absolute pathnames (which begin with '/') * are interpreted relative to the root of this node. Relative pathnames * (which begin with any character other than '/') are * interpreted relative to this node itself. The empty string ("") * is a valid relative pathname, referring to this node itself. * *

* If the returned node did not exist prior to this call, this node and any * ancestors that were created by this call are not guaranteed to become * persistent until the flush method is called on the returned * node (or one of its descendants). * * @param pathName the path name of the IPreferences object to * return. * @return the specified IPreferences object. * @throws IllegalArgumentException if the path name is invalid. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @throws NullPointerException if path name is null. * @see #flush() */ virtual IPreferences::Pointer Node(const QString& pathName) = 0; /** * Returns true if the named node exists. Accepts a relative or absolute * pathname. Absolute pathnames (which begin with '/') are * interpreted relative to the root of this node. Relative pathnames (which * begin with any character other than '/') are interpreted * relative to this node itself. The pathname "" is valid, and * refers to this node itself. * *

* If this node (or an ancestor) has already been removed with the * {@link #removeNode()}method, it is legal to invoke this method, * but only with the pathname ""; the invocation will return * false. Thus, the idiom p.nodeExists("") may be * used to test whether p has been removed. * * @param pathName the path name of the node whose existence is to be * checked. * @return true if the specified node exists. * @throws BackingStoreException if this operation cannot be completed due * to a failure in the backing store, or inability to communicate * with it. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method and * pathname is not the empty string (""). * @throws IllegalArgumentException if the path name is invalid (i.e., it * contains multiple consecutive slash characters, or ends with a * slash character and is more than one character long). */ virtual bool NodeExists(const QString& pathName) const = 0; /** * Removes this node and all of its descendants, invalidating any properties * contained in the removed nodes. Once a node has been removed, attempting * any method other than name(),absolutePath() or * nodeExists("") on the corresponding IPreferences * instance will fail with an IllegalStateException. (The * methods defined on Object can still be invoked on a node after * it has been removed; they will not throw IllegalStateException.) * *

* The removal is not guaranteed to be persistent until the flush * method is called on the parent of this node. * * @throws IllegalStateException if this node (or an ancestor) has already * been removed with the {@link #removeNode()}method. * @throws BackingStoreException if this operation cannot be completed due * to a failure in the backing store, or inability to communicate * with it. * @see #flush() */ - virtual void RemoveNode() throw(Poco::Exception, BackingStoreException) = 0; + virtual void RemoveNode() = 0; /** * Returns this node's name, relative to its parent. * * @return this node's name, relative to its parent. */ virtual QString Name() const = 0; /** * Returns this node's absolute path name. Note that: *

* * @return this node's absolute path name. */ virtual QString AbsolutePath() const = 0; /** * Forces any changes in the contents of this node and its descendants to * the persistent store. * *

* Once this method returns successfully, it is safe to assume that all * changes made in the subtree rooted at this node prior to the method * invocation have become permanent. * *

* Implementations are free to flush changes into the persistent store at * any time. They do not need to wait for this method to be called. * *

* When a flush occurs on a newly created node, it is made persistent, as * are any ancestors (and descendants) that have yet to be made persistent. * Note however that any properties value changes in ancestors are not * guaranteed to be made persistent. * * @throws BackingStoreException if this operation cannot be completed due * to a failure in the backing store, or inability to communicate * with it. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #sync() */ virtual void Flush() = 0; /** * Ensures that future reads from this node and its descendants reflect any * changes that were committed to the persistent store (from any VM) prior * to the sync invocation. As a side-effect, forces any changes * in the contents of this node and its descendants to the persistent store, * as if the flush method had been invoked on this node. * * @throws BackingStoreException if this operation cannot be completed due * to a failure in the backing store, or inability to communicate * with it. * @throws IllegalStateException if this node (or an ancestor) has been * removed with the {@link #removeNode()}method. * @see #flush() */ virtual void Sync() = 0; }; } // namespace berry #endif /*BERRYIPREFERENCES_H_*/ diff --git a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.cpp b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.cpp index 49865b120f..eada2963ef 100644 --- a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.cpp +++ b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.cpp @@ -1,505 +1,505 @@ /*=================================================================== BlueBerry Platform Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "berryPreferences.h" #include "berryAbstractPreferencesStorage.h" #include #include namespace berry { Preferences::Preferences(const PropertyMap& _Properties , const QString& _Name , Preferences* _Parent , AbstractPreferencesStorage* _Storage) : m_Properties(_Properties) , m_Path(_Parent ? _Parent->AbsolutePath() + (_Parent->AbsolutePath() == "/" ? "": "/") + _Name : "/") , m_Name(_Name) , m_Parent(_Parent) , m_Root(_Parent ? _Parent->m_Root : this) , m_Removed(false) , m_Storage(_Storage) { // root node if parent is 0 if (_Parent != 0) { // save as child in parent _Parent->m_Children.push_back(Preferences::Pointer(this)); } } bool Preferences::Has(const QString& key ) const { QMutexLocker scopedMutex(&m_Mutex); return this->Has_unlocked(key); } bool Preferences::Has_unlocked(const QString& key ) const { return (m_Properties.find(key) != m_Properties.end()); } bool Preferences::IsDirty() const { QMutexLocker scopedMutex(&m_Mutex); bool dirty = m_Dirty; for (ChildrenList::const_iterator it = m_Children.begin() ; it != m_Children.end(); ++it) { // break condition: if one node is dirty the whole tree is dirty if(dirty) break; else dirty = (*it)->IsDirty(); } return dirty; } QString Preferences::ToString() const { return QString("Preferences[") + m_Path + "]"; } bool Preferences::Equals(const Preferences* rhs) const { if(rhs == 0) return false; return (this->m_Path == rhs->m_Path); } Preferences::PropertyMap Preferences::GetProperties() const { QMutexLocker scopedMutex(&m_Mutex); return m_Properties; } Preferences::ChildrenList Preferences::GetChildren() const { QMutexLocker scopedMutex(&m_Mutex); return m_Children; } QString Preferences::AbsolutePath() const { return m_Path; } QStringList Preferences::ChildrenNames() const { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); QStringList names; for (ChildrenList::const_iterator it = m_Children.begin() ; it != m_Children.end(); ++it) { names.push_back((*it)->Name()); } return names; } AbstractPreferencesStorage* Preferences::GetStorage() const { return m_Storage; } void Preferences::Clear() { { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); m_Properties.clear(); } this->SetDirty(true); } void Preferences::Flush() { m_Storage->Flush(this); // if something is written, make the tree undirty // there is a race condition here: after flushing, another thread // could modify this object before we can set dirty to false, // but we cannot hold a lock before flushing because the operation // will call other methods on this object, which would lead // to a recursive lock. this->SetDirty(false); } QString Preferences::Get(const QString& key, const QString& def) const { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); return this->Has_unlocked(key) ? m_Properties[key] : def; } bool Preferences::GetBool(const QString& key, bool def) const { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); return this->Has_unlocked(key) ? (m_Properties[key] == "true" ? true: false) : def; } QByteArray Preferences::GetByteArray(const QString& key, const QByteArray& def) const { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); return this->Has_unlocked(key) ? QByteArray::fromBase64(m_Properties[key].toLatin1()) : def; } double Preferences::GetDouble(const QString& key, double def) const { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); return this->Has_unlocked(key) ? m_Properties[key].toDouble() : def; } float Preferences::GetFloat(const QString& key, float def) const { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); return this->Has_unlocked(key) ? m_Properties[key].toFloat() : def; } int Preferences::GetInt(const QString& key, int def) const { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); return this->Has_unlocked(key) ? m_Properties[key].toInt() : def; } long Preferences::GetLong(const QString& key, long def) const { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); return this->Has_unlocked(key) ? m_Properties[key].toLong() : def; } QStringList Preferences::Keys() const { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); return m_Properties.keys(); } QString Preferences::Name() const { return m_Name; } IPreferences::Pointer Preferences::Node(const QString& path) { QMutexLocker scopedMutex(&m_Mutex); return this->Node_unlocked(path); } Preferences::Pointer Preferences::Node_unlocked(const QString& path) { QString pathName = path; AssertValid_unlocked(); AssertPath_unlocked(pathName); Preferences::Pointer node; // self reference if(pathName == "") return Preferences::Pointer(this); // absolute path else if(pathName[0] == '/') { pathName = pathName.mid(1); // call root with this relative path if (this == m_Root) return m_Root->Node_unlocked(pathName); else return m_Root->Node(pathName).Cast(); } // relative path else { // check if pathName contains anymore names QString name = pathName; // create new child nodes as long as there are names in the path int pos = pathName.indexOf('/'); // cut from the beginning if(pos != -1) { name = pathName.left(pos); pathName = pathName.mid(pos+1); } // now check if node exists->if not: make new for (ChildrenList::iterator it = m_Children.begin() ; it != m_Children.end(); it++) { // node found if((*it)->Name() == name && (*it)->IsRemoved() == false) { node = *it; break; } } // node not found create new one if(node.IsNull()) { // the new node automatically pushes itself into the children array of *this* Preferences::Pointer newNode(new Preferences(PropertyMap(), name, this, m_Storage)); node = newNode.GetPointer(); // this branch is dirty now -> prefs must be rewritten persistently this->SetDirty_unlocked(true); } // call Node() again if there are any names left on the path if(pos != -1) { if (this == node.GetPointer()) node = node->Node_unlocked(pathName); else node = node->Node(pathName).Cast(); } } return node; } bool Preferences::NodeExists(const QString& path) const { QString pathName = path; QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); AssertPath_unlocked(pathName); bool nodeExists = false; // absolute path if(pathName[0] == '/') { pathName = pathName.mid(1); // call root with this relative path return m_Root->NodeExists(pathName); } // relative path else { // check if pathName contains anymore names QString name = pathName; // create new child nodes as long as there are names in the path int pos = pathName.indexOf("/"); // cut from the beginning if(pos != -1) { name = pathName.left(pos); pathName = pathName.mid(pos+1); } // now check if node exists->if not: make new for (ChildrenList::const_iterator it = m_Children.begin() ; it != m_Children.end(); it++) { // node found if((*it)->Name() == name) { // call recursively if more names on the path exist if(pos != -1) nodeExists = (*it)->NodeExists(pathName); else nodeExists = true; break; } } } return nodeExists; } void Preferences::Put(const QString& key, const QString& value) { { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); m_Properties[key] = value; } this->SetDirty(true); } void Preferences::PutByteArray(const QString& key, const QByteArray& value) { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); this->Put(key, value.toBase64().data()); } void Preferences::PutBool(const QString& key, bool value) { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); this->Put(key, value ? "true" : "false"); } void Preferences::PutDouble(const QString& key, double value) { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); this->Put(key, QString::number(value)); } void Preferences::PutFloat(const QString& key, float value) { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); this->Put(key, QString::number(value)); } void Preferences::PutInt(const QString& key, int value) { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); this->Put(key, QString::number(value)); } void Preferences::PutLong(const QString& key, long value) { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); this->Put(key, QString::number(value)); } void Preferences::Remove(const QString& key) { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); PropertyMap::iterator it = m_Properties.find(key); if(it != m_Properties.end()) m_Properties.erase(it); } - void Preferences::RemoveNode() throw(Poco::Exception, BackingStoreException) + void Preferences::RemoveNode() { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); this->SetRemoved_unlocked(true); m_Parent->m_Children.erase(std::find(m_Parent->m_Children.begin(), m_Parent->m_Children.end(), Preferences::Pointer(this))); } - void Preferences::Sync() throw(Poco::Exception, BackingStoreException) + void Preferences::Sync() { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); this->Flush(); } void Preferences::AssertValid_unlocked() const { if(m_Removed) { throw ctkIllegalStateException(QString("no node at '") + m_Path + "'"); } } void Preferences::AssertPath_unlocked(const QString& pathName) { if(pathName.indexOf("//") != -1) { throw ctkInvalidArgumentException(QString("Illegal // in m_Path m_Name '") + pathName + "'"); } int strLength = pathName.size(); if(strLength > 1 && pathName[strLength-1] == '/') { throw ctkInvalidArgumentException(QString("Trailing / in m_Path m_Name '") + pathName + "'"); } } IPreferences::Pointer Preferences::Parent() const { QMutexLocker scopedMutex(&m_Mutex); AssertValid_unlocked(); return IPreferences::Pointer(m_Parent); } void Preferences::SetDirty( bool _Dirty ) { { QMutexLocker scopedMutex(&m_Mutex); m_Dirty = _Dirty; } if(_Dirty) { this->OnChanged.Send(this); } } void Preferences::SetDirty_unlocked( bool _Dirty ) { m_Dirty = _Dirty; if(_Dirty) this->OnChanged.Send(this); /* for (ChildrenList::iterator it = m_Children.begin() ; it != m_Children.end(); ++it) { (*it)->SetDirty(_Dirty); } */ } void Preferences::SetRemoved( bool _Removed ) { QMutexLocker scopedMutex(&m_Mutex); this->SetRemoved_unlocked(_Removed); } void Preferences::SetRemoved_unlocked( bool _Removed ) { m_Removed = _Removed; for (ChildrenList::iterator it = m_Children.begin() ; it != m_Children.end(); ++it) { (*it)->SetRemoved(_Removed); } } /* Preferences::ChildrenList& Preferences::GetChildren() const { return m_Children; }*/ bool Preferences::IsRemoved() const { QMutexLocker scopedMutex(&m_Mutex); return m_Removed; } Preferences::~Preferences() { } } diff --git a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.h b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.h index 983019a09b..0922e94b19 100644 --- a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.h +++ b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPreferences.h @@ -1,325 +1,325 @@ /*=================================================================== BlueBerry Platform Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef BERRYPREFERENCES_H_ #define BERRYPREFERENCES_H_ #include #include "berryIBerryPreferences.h" #include #include namespace berry { class AbstractPreferencesStorage; /// /// Implementation of the OSGI Preferences Interface. /// Wraps a DOMNode. /// class org_blueberry_core_runtime_EXPORT Preferences: public IBerryPreferences { public: /// /// For use with berry::SmartPtr /// berryObjectMacro(berry::Preferences); /// /// Maps a string key to a string value /// typedef QHash PropertyMap; /// /// The list of Child nodes /// typedef QList ChildrenList; /// /// Constructs a new preference node. /// \param _Properties the key->value pairs of this preference node /// \param _Path the absolute path to this node, e.g. "/general/editors/font" /// \param _Name the name of this node, e.g. "font" /// \param _FileName the absolute path to the file in which this preferences tree will be saved to /// \param _Parent the parent node or 0 if this is the root /// \param _Root the root of this preference tree /// Preferences(const PropertyMap& _Properties , const QString& _Name , Preferences* _Parent , AbstractPreferencesStorage* _Storage); /// /// Nothing to do here /// virtual ~Preferences(); /// /// Prints out the absolute path of the preference node. /// QString ToString() const; /// /// Returns if this node and his silblings have to be rewritten persistently /// bool IsDirty() const; /// /// Returns if this node is removed /// bool IsRemoved() const; /// /// Returns if this node has property with a specific key /// bool Has(const QString& key) const; /// /// Returns true if the absolute paths are the same /// bool Equals(const Preferences* rhs) const; /// /// Returns all Properties as map. /// PropertyMap GetProperties() const; /// /// Returns a reference to the children list in order to add or remove nodes. /// *ATTENTION*: Should only be used /// when constructing the preferences tree from a persistent location. Normally, one would /// only use the IPreferences methods /// ChildrenList GetChildren() const; //# Begin of IPreferences methods /// /// \see IPreferences::AbsolutePath() /// virtual QString AbsolutePath() const; /// /// \see IPreferences::ChildrenNames() /// virtual QStringList ChildrenNames() const; /// /// \see IPreferences::ChildrenNames() /// virtual AbstractPreferencesStorage* GetStorage() const; /// /// \see IPreferences::Clear() /// virtual void Clear(); /// /// \see IPreferences::Flush() /// virtual void Flush(); /// /// \see IPreferences::Get() /// virtual QString Get(const QString& key, const QString& def) const; /// /// \see IPreferences::GetBool() /// virtual bool GetBool(const QString& key, bool def) const; /// /// \see IPreferences::GetByteArray() /// virtual QByteArray GetByteArray(const QString& key, const QByteArray& def) const; /// /// \see IPreferences::GetDouble() /// virtual double GetDouble(const QString& key, double def) const; /// /// \see IPreferences::GetFloat() /// virtual float GetFloat(const QString& key, float def) const; /// /// \see IPreferences::GetInt() /// virtual int GetInt(const QString& key, int def) const; /// /// \see IPreferences::GetLong() /// virtual long GetLong(const QString& key, long def) const; /// /// \see IPreferences::Keys() /// QStringList Keys() const; /// /// \see IPreferences::Name() /// virtual QString Name() const; /// /// \see IPreferences::Node() /// virtual IPreferences::Pointer Node(const QString& pathName); /// /// \see IPreferences::NodeExists() /// virtual bool NodeExists(const QString& pathName) const; /// /// \see IPreferences::Parent() /// virtual IPreferences::Pointer Parent() const; /// /// \see IPreferences::Put() /// virtual void Put(const QString& key, const QString& value); /// /// \see IPreferences::PutByteArray() /// virtual void PutByteArray(const QString& key, const QByteArray& value); /// /// \see IPreferences::PutBool() /// virtual void PutBool(const QString& key, bool value); /// /// \see IPreferences::PutDouble() /// virtual void PutDouble(const QString& key, double value); /// /// \see IPreferences::Sync() /// virtual void PutFloat(const QString& key, float value); /// /// \see IPreferences::PutInt() /// virtual void PutInt(const QString& key, int value); /// /// \see IPreferences::PutLong() /// virtual void PutLong(const QString& key, long value); /// /// \see IPreferences::Remove() /// virtual void Remove(const QString& key); /// /// \see IPreferences::RemoveNode() /// - virtual void RemoveNode() throw(Poco::Exception, BackingStoreException); + virtual void RemoveNode(); /// /// \see IPreferences::Sync() /// - virtual void Sync() throw(Poco::Exception, BackingStoreException); + virtual void Sync(); //# End of IPreferences methods protected: /// /// Checks if this node is about to be removed. /// \throws IllegalStateException /// void AssertValid_unlocked() const; /// /// Checks a path value for validity. /// \throws invalid_argument /// static void AssertPath_unlocked(const QString& pathName); // /// // /// Converts any value to a string (using stream operator "<<") // /// // template // static QString ToString(const T& obj, int precision = 12 ) // { // std::ostringstream s; // std::locale C("C"); // s.imbue(C); // s.precision(precision); s << obj; return s.str(); // } bool Has_unlocked(const QString& key) const; Preferences::Pointer Node_unlocked(const QString& pathName); /// /// Sets the dirty flag recursively on all child nodes. /// void SetDirty(bool _Dirty); void SetDirty_unlocked(bool _Dirty); /// /// Sets the removed flag recursively on all child nodes. /// void SetRemoved(bool _Removed); void SetRemoved_unlocked(bool _Removed); protected: /// /// Holds all Key/Value Pairs. /// QHash m_Properties; /// /// Holds all child nodes (explicit ownership). /// QList m_Children; /// /// Saves the absolute path of this node (calculated in the constructor) /// const QString m_Path; /// /// Saves the name of this node (set when read from backend) /// const QString m_Name; /// /// Saves the parent of this node /// Preferences* const m_Parent; /// /// Saves the root of this tree /// Preferences* const m_Root; /// /// Saves if something changed on this branch. /// Meaning that you would have to rewrite it. /// bool m_Dirty; /// /// Saves if this Node is removed (will not be saved to the backend). /// bool m_Removed; /// /// A storage to call the flush method. /// AbstractPreferencesStorage* const m_Storage; /// /// A mutex to avoid concurrency crashes. Mutable because we need to use Mutex::lock() in const functions /// mutable QMutex m_Mutex; }; } #endif /* BERRYPREFERENCES_H_ */