weaver 2004/10/29 06:57:59
Modified: components/prefs/src/java/org/apache/jetspeed/prefs/impl
PreferencesImpl.java PreferencesFactoryImpl.java
PropertyManagerImpl.java
Added: components/prefs/src/java/org/apache/jetspeed/prefs/impl
PersistenceBrokerPreferencesProvider.java
Removed: components/prefs/src/java/org/apache/jetspeed/prefs/impl
PreferencesProviderImpl.java CommonQueries.java
Log:
see: http://nagoya.apache.org/jira/browse/JS2-144
- Refactored prefs
Revision Changes Path
1.17 +126 -372
jakarta-jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java
Index: PreferencesImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesImpl.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- PreferencesImpl.java 25 Oct 2004 19:39:54 -0000 1.16
+++ PreferencesImpl.java 29 Oct 2004 13:57:59 -0000 1.17
@@ -24,21 +24,24 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.jetspeed.components.persistence.store.PersistenceStore;
+import org.apache.jetspeed.prefs.FailedToCreateNodeException;
+import org.apache.jetspeed.prefs.NodeAlreadyExistsException;
+import org.apache.jetspeed.prefs.NodeDoesNotExistException;
import org.apache.jetspeed.prefs.PreferencesProvider;
import org.apache.jetspeed.prefs.PropertyException;
import org.apache.jetspeed.prefs.om.Node;
import org.apache.jetspeed.prefs.om.Property;
import org.apache.jetspeed.prefs.om.PropertyKey;
-import org.apache.jetspeed.prefs.om.impl.NodeImpl;
import org.apache.jetspeed.prefs.om.impl.PropertyImpl;
import org.apache.jetspeed.prefs.om.impl.PropertyKeyImpl;
/**
- * <p>[EMAIL PROTECTED] Preferences} implementation relying on Jetspeed
- * OJB based persistence plugin.</p>
- *
- * @author <a href="mailto:[EMAIL PROTECTED]">David Le Strat</a>
+ * <p>S
+ * [EMAIL PROTECTED] Preferences}implementation relying on Jetspeed OJB based
persistence
+ * plugin.
+ * </p>
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">David Le Strat </a>
*/
public class PreferencesImpl extends AbstractPreferences
{
@@ -49,234 +52,76 @@
/** System <tt>Preferences</tt> node type. */
public static final int SYSTEM_NODE_TYPE = 1;
-
-
- /** Common queries. **/
- private CommonQueries commonQueries;
-
- /** BackingStore availability flag. */
- private boolean isBackingStoreAvailable = true;
-
- /** The current node id. */
- private long nodeId = -1;
-
/** The current <code>Node</code> object. */
private Node node = null;
- /** The current node type. */
- private int nodeType = -1;
-
/** Logger. */
private static final Log log = LogFactory.getLog(PreferencesImpl.class);
- // Constants used to interpret returns of functions.
- private static final int ARRAY_SIZE = 4;
- private static final int NODE_ID = 0;
- private static final int NODE = 1;
- private static final int ERROR_CODE = 2;
- private static final int DISPOSITION = 3;
- private static final int DISPOSITION_NEW_NODE = 0;
- private static final int DISPOSITION_EXISTING_NODE = 1;
- private static final int ERROR_SUCCESS = 0;
- private static final int ERROR_NODE_NOT_FOUND = 1;
- private static final int ERROR_NODE_ALREADY_EXISTS = 2;
- private static final int ERROR_NODE_CREATION_FAILED = 3;
- private static final int ERROR_PARENT_NOT_FOUND = 4;
-
- protected PersistenceStore persistenceStore;
+ protected static PreferencesProvider prefsProvider;
- protected PreferencesProvider prefProvider;
-
- static PreferencesImpl systemRoot;
- static PreferencesImpl userRoot;
+ static PreferencesImpl systemRoot;
+ static PreferencesImpl userRoot;
+
/**
- * <p>Constructs a root node in the underlying
- * datastore if they have not yet been created.</p>
- * <p>Logs a warning if the underlying datastore is
- * unavailable.</p>
- * @param parent The parent object.
- * @param nodeName The node name.
- * @param nodeType The node type.
+ * <p>
+ * Constructs a root node in the underlying datastore if they have not yet
+ * been created.
+ * </p>
+ * <p>
+ * Logs a warning if the underlying datastore is unavailable.
+ * </p>
+ *
+ * @param parent
+ * The parent object.
+ * @param nodeName
+ * The node name.
+ * @param nodeType
+ * The node type.
*/
- public PreferencesImpl(PreferencesImpl parent, String nodeName, int nodeType)
+ public PreferencesImpl( PreferencesImpl parent, String nodeName, int nodeType )
throws IllegalStateException
{
super(parent, nodeName);
-
- if (log.isDebugEnabled())
- log.debug("Constructing node: " + nodeName);
- prefProvider = PreferencesProviderImpl.prefProvider;
- persistenceStore = prefProvider.getPersistenceStore();
- this.commonQueries = new CommonQueries(persistenceStore);
-
- this.nodeType = nodeType;
- long[] result = createPrefNode(parent, nodeName, nodeType,
this.absolutePath());
- if (result[ERROR_CODE] != ERROR_SUCCESS)
- {
- String warning =
- "Could not create node " + nodeName + " of type " + nodeType + ".
Returned error code " + result[ERROR_CODE];
- if (log.isWarnEnabled())
- {
- log.warn(warning);
- }
- // Backing store is not available.
- isBackingStoreAvailable = false;
- return;
- }
- // Check if a new node.
- newNode = (result[DISPOSITION] == DISPOSITION_NEW_NODE);
-
- }
-
- /**
- * <p>Create a new preference node in the backing store.</p>
- * @param parent The parent node.
- * @param nodeName The node name.
- * @param nodeType The node type.
- * @param fullPath The node full path.
- * @return The operation status code.
- */
- private long[] createPrefNode(PreferencesImpl parent, String nodeName, int
nodeType, String fullPath)
- {
- long[] result = new long[ARRAY_SIZE];
- Long parentNodeId = null;
-
- if (null != parent)
+
+ try
{
- if (log.isDebugEnabled())
- log.debug("Current node parent: " + parent.nodeId);
- // Get child node
- Object[] nodeFromParentRetrievalResult = getChildNode(new
Long(parent.nodeId), nodeName, new Integer(nodeType));
- if (((Long) nodeFromParentRetrievalResult[ERROR_CODE]).intValue() ==
ERROR_SUCCESS)
+ if (parent != null)
{
- result[NODE_ID] = ((Long)
nodeFromParentRetrievalResult[NODE_ID]).intValue();
- result[ERROR_CODE] = ERROR_SUCCESS;
- result[DISPOSITION] = DISPOSITION_EXISTING_NODE;
- return result;
+ this.node = prefsProvider.createNode(parent.getNode(), nodeName,
nodeType, this.absolutePath());
}
else
{
- parentNodeId = new Long(parent.nodeId);
+ this.node = prefsProvider.createNode(null, nodeName, nodeType,
this.absolutePath());
}
+ newNode = true;
}
- // Check if node exists.
- Object[] nodeRetrievalResult = getNode(fullPath, nodeType);
- if (((Long) nodeRetrievalResult[ERROR_CODE]).intValue() == ERROR_SUCCESS)
- {
- result[NODE_ID] = ((Long) nodeRetrievalResult[NODE_ID]).intValue();
- result[ERROR_CODE] = ERROR_SUCCESS;
- result[DISPOSITION] = DISPOSITION_EXISTING_NODE;
- return result;
- }
-
- // If does not exist, create.
- Node nodeObj = new NodeImpl(parentNodeId, nodeName, nodeType, fullPath);
- if (log.isDebugEnabled())
- log.debug("New node: " + nodeObj.toString());
- PersistenceStore store = getPersistenceStore();
- try
+ catch (FailedToCreateNodeException e)
{
- store.lockForWrite(nodeObj);
- store.getTransaction().checkpoint();
-
- result[NODE_ID] = nodeObj.getNodeId();
- result[ERROR_CODE] = ERROR_SUCCESS;
- result[DISPOSITION] = DISPOSITION_NEW_NODE;
-
- this.nodeId = nodeObj.getNodeId();
- this.node = nodeObj;
+ IllegalStateException ise = new IllegalStateException("Failed to create
new Preferences of type "
+ + nodeType + " for path " + this.absolutePath());
+ ise.initCause(e);
+ throw ise;
}
- catch (Exception e)
+ catch (NodeAlreadyExistsException e)
{
- String msg = "Unable to store Node.";
- log.error(msg, e);
- store.getTransaction().rollback();
-
- result[ERROR_CODE] = ERROR_NODE_CREATION_FAILED;
- }
-
- return result;
- }
-
- /**
- * <p>Get the node id from the full path.</p>
- * @param fullPath The full path.
- * @param nodeType The node type.
- * @return An array of value returned including:
- * <ul>
- * <li>At index NODE_ID: The node id.</li>
- * <li>At index NODE: The node object.</li>
- * <li>At index ERROR_CODE: The error code.</li>
- * </ul>
- */
- private Object[] getNode(String fullPath, int nodeType)
- {
- Object[] result = new Object[ARRAY_SIZE];
- if (log.isDebugEnabled())
- log.debug("Getting node: [[nodeId, " + this.nodeId + "], [fullPath, " +
fullPath + "], [nodeType, " + nodeType + "]]");
-
- if (this.nodeId != -1 && (null != this.node))
- {
- result[NODE_ID] = new Long(this.nodeId);
- result[NODE] = this.node;
- result[ERROR_CODE] = new Long(ERROR_SUCCESS);
- return result;
- }
-
- PersistenceStore store = getPersistenceStore();
- Node nodeObj = (Node)
store.getObjectByQuery(commonQueries.newNodeQueryByPathAndType(fullPath, new
Integer(nodeType)));
- if (null != nodeObj)
- {
- result[NODE_ID] = new Long(nodeObj.getNodeId());
- result[NODE] = nodeObj;
- result[ERROR_CODE] = new Long(ERROR_SUCCESS);
- if (log.isDebugEnabled())
- log.debug("Found node: " + nodeObj.getFullPath());
- this.node = nodeObj;
- this.nodeId = nodeObj.getNodeId();
- return result;
- }
- else
- {
- result[ERROR_CODE] = new Long(ERROR_NODE_NOT_FOUND);
- return result;
+ try
+ {
+ node = prefsProvider.getNode(this.absolutePath(), nodeType);
+ newNode = false;
+ }
+ catch (NodeDoesNotExistException e1)
+ {
+ // If we get this at this point something is very wrong
+ IllegalStateException ise = new IllegalStateException("Unable to
create node for Preferences of type "+nodeType+" for path "+this.absolutePath() +
+ ". If you see this exception at this, it more than
likely means that the Preferences backing store is corrupt.");
+ ise.initCause(e1);
+ throw ise;
+ }
}
- }
- /**
- * <p>Get the child node from the parent node.</p>
- * @param parentIdObject The parent node id.
- * @return An array of value returned including:
- * <ul>
- * <li>At index NODE_ID: The node id.</li>
- * <li>At index NODE: The node object.</li>
- * <li>At index ERROR_CODE: The error code.</li>
- * </ul>
- */
- private Object[] getChildNode(Long parentIdObject, String nodeName, Integer
nodeType)
- {
- Object[] result = new Object[ARRAY_SIZE];
- PersistenceStore store = getPersistenceStore();
- Node nodeObj =
- (Node)
store.getObjectByQuery(commonQueries.newNodeQueryByParentIdNameAndType(parentIdObject,
nodeName, nodeType));
- if (null != nodeObj)
- {
- result[NODE_ID] = new Long(nodeObj.getNodeId());
- result[NODE] = nodeObj;
- result[ERROR_CODE] = new Long(ERROR_SUCCESS);
- if (log.isDebugEnabled())
- log.debug("Found child node: " + nodeObj.getFullPath());
- this.nodeId = nodeObj.getNodeId();
- this.node = nodeObj;
- return result;
- }
- else
- {
- result[ERROR_CODE] = new Long(ERROR_NODE_NOT_FOUND);
- return result;
- }
}
/**
@@ -284,20 +129,8 @@
*/
public String[] childrenNamesSpi() throws BackingStoreException
{
- Object[] parentResult = getNode(this.absolutePath(), this.nodeType);
-
- if (((Long) parentResult[ERROR_CODE]).intValue() != ERROR_SUCCESS)
- {
- String warning = "Could not get node id. Returned error code " +
parentResult[ERROR_CODE];
- if (log.isWarnEnabled())
- {
- log.warn(warning);
- }
- throw new BackingStoreException(warning);
- }
+ Collection nodes = prefsProvider.getChildren(getNode());
- PersistenceStore store = getPersistenceStore();
- Collection nodes =
store.getCollectionByQuery(commonQueries.newNodeQueryByParentId(parentResult[NODE_ID]));
if (null != nodes)
{
ArrayList childrenNames = new ArrayList(nodes.size());
@@ -310,7 +143,8 @@
}
else
{
- // The returned array is of size zero if this node has no preferences.
+ // The returned array is of size zero if this node has no
+ // preferences.
return new String[0];
}
}
@@ -318,9 +152,9 @@
/**
* @see java.util.prefs.Preferences#childSpi(java.lang.String)
*/
- public AbstractPreferences childSpi(String name)
+ public AbstractPreferences childSpi( String name )
{
- return new PreferencesImpl(this, name, this.nodeType);
+ return new PreferencesImpl(this, name, node.getNodeType());
}
/**
@@ -328,40 +162,28 @@
*/
public void flushSpi() throws BackingStoreException
{
- if(persistenceStore.getTransaction().isOpen())
- {
- persistenceStore.getTransaction().commit();
- }
+ prefsProvider.storeNode(this.node);
}
/**
* @see java.util.prefs.Preferences#getSpi(java.lang.String)
*/
- public String getSpi(String key)
+ public String getSpi( String key )
{
- String value = null;
- Object[] nodeResult = getNode(this.absolutePath(), this.nodeType);
- if (((Long) nodeResult[ERROR_CODE]).intValue() != ERROR_SUCCESS)
- {
- log.error("Could not get node id. Returned error code " +
nodeResult[ERROR_CODE]);
- return value;
- }
+ Collection properties = node.getNodeProperties();
- // Get the property set def.
- Node nodeObj = (Node) nodeResult[NODE];
- Collection properties = nodeObj.getNodeProperties();
- if (log.isDebugEnabled())
- log.debug("Node properties: " + properties.size());
for (Iterator i = properties.iterator(); i.hasNext();)
{
Property curProp = (Property) i.next();
if (curProp.getPropertyKey().getPropertyKeyName().equals(key))
{
- value =
curProp.getPropertyValue(curProp.getPropertyKey().getPropertyKeyType());
+ return
curProp.getPropertyValue(curProp.getPropertyKey().getPropertyKeyType());
}
}
- return value;
+
+ //prop not found
+ return null;
}
/**
@@ -371,51 +193,34 @@
{
ArrayList propertyNames = new ArrayList();
- PersistenceStore store = getPersistenceStore();
- Node nodeObj = (Node)
store.getObjectByQuery(commonQueries.newNodeQueryById(new Long(this.nodeId)));
- if (null != nodeObj)
+ Collection propCol = node.getNodeProperties();
+ if ((null != propCol) && propCol.size() > 0)
{
- if (log.isDebugEnabled())
- log.debug("Fetching keys for node: " + nodeObj.toString());
-
- Collection propCol = nodeObj.getNodeProperties();
- if ((null != propCol) && propCol.size() > 0)
+ for (Iterator j = propCol.iterator(); j.hasNext();)
{
- for (Iterator j = propCol.iterator(); j.hasNext();)
- {
- Property curprop = (Property) j.next();
-
propertyNames.add(curprop.getPropertyKey().getPropertyKeyName());
- }
+ Property curprop = (Property) j.next();
+ propertyNames.add(curprop.getPropertyKey().getPropertyKeyName());
}
- else
- {
- log.error("Could not retrieve property keys for node " +
nodeObj.getFullPath());
- }
- }
- return (String[]) propertyNames.toArray(new String[0]);
+ }
+
+ return (String[]) propertyNames.toArray(new String[propertyNames.size()]);
}
/**
- * @see java.util.prefs.Preferences#putSpi(java.lang.String, java.lang.String)
- * <p>In addition to java.util.prefs.Preferences, this implementation
- * is enforcing that node used as property sets have been defined
- * as such and that only the keys defined associated to the property
- * set can be added as properties of the current node.</p>
+ * @see java.util.prefs.Preferences#putSpi(java.lang.String,
+ * java.lang.String)
+ * <p>
+ * In addition to java.util.prefs.Preferences, this implementation is
+ * enforcing that node used as property sets have been defined as such
+ * and that only the keys defined associated to the property set can be
+ * added as properties of the current node.
+ * </p>
*/
- public void putSpi(String key, String value)
+ public void putSpi( String key, String value )
{
- Object[] nodeResult = getNode(this.absolutePath(), this.nodeType);
-
- if (((Long) nodeResult[ERROR_CODE]).intValue() != ERROR_SUCCESS)
- {
- log.error("Could not get node id. Returned error code " +
nodeResult[ERROR_CODE]);
- return;
- }
-
- // Get the property set def.
- Node nodeObj = (Node) nodeResult[NODE];
- Collection nodeKeys = nodeObj.getNodeKeys();
- Collection properties = nodeObj.getNodeProperties();
+
+ Collection nodeKeys = node.getNodeKeys();
+ Collection properties = node.getNodeProperties();
if (null == properties)
{
log.error("Could not retrieve node property: [key: " + key + ", value:"
+ value + "]");
@@ -438,11 +243,11 @@
curProp.setPropertyValue(curProp.getPropertyKey().getPropertyKeyType(), value);
curProp.setModifiedDate(new Timestamp(System.currentTimeMillis()));
}
-
+
}
- // The property does not already exist. Create a new property, if
+ // The property does not already exist. Create a new property, if
// the property key exits and is associated to this node.
- if (prefProvider.isPropertyManagerEnabled() && !foundProp)
+ if (prefsProvider.isPropertyManagerEnabled() && !foundProp)
{
for (Iterator i = nodeKeys.iterator(); i.hasNext();)
{
@@ -453,46 +258,28 @@
if (log.isDebugEnabled())
log.debug("New property value: [" + key + ", " + value +
"]");
- properties.add(
- new PropertyImpl(nodeObj.getNodeId(),
curpk.getPropertyKeyId(), curpk, curpk.getPropertyKeyType(), value));
+ properties.add(new PropertyImpl(node.getNodeId(),
curpk.getPropertyKeyId(), curpk, curpk
+ .getPropertyKeyType(), value));
}
}
}
- else if (!prefProvider.isPropertyManagerEnabled() && !foundProp)
+ else if (!prefsProvider.isPropertyManagerEnabled() && !foundProp)
{
foundKey = true;
PropertyKey pKey = new PropertyKeyImpl(key, Property.STRING_TYPE);
- properties.add(
- new PropertyImpl(nodeObj.getNodeId(), pKey.getPropertyKeyId(),
pKey, pKey.getPropertyKeyType(), value));
-
+ properties.add(new PropertyImpl(node.getNodeId(),
pKey.getPropertyKeyId(), pKey, pKey
+ .getPropertyKeyType(), value));
+
}
-
+
if (!foundKey)
{
if (log.isWarnEnabled())
log.warn(PropertyException.PROPERTYKEY_NOT_FOUND);
return;
}
- // Update node.
- PersistenceStore store = getPersistenceStore();
- if (log.isDebugEnabled())
- log.debug("Updated properties: " + properties.size());
-
- try
- {
- store.lockForWrite(nodeObj);
-
- nodeObj.setModifiedDate(new Timestamp(System.currentTimeMillis()));
- if (log.isDebugEnabled())
- log.debug("Node for update: " + nodeObj.toString());
- store.getTransaction().checkpoint();
- }
- catch (Exception e)
- {
- String msg = "Unable to update Node.";
- log.error(msg, e);
- store.getTransaction().rollback();
- }
+
+ prefsProvider.storeNode(node);
}
@@ -500,53 +287,16 @@
* @see java.util.prefs.Preferences#removeNodeSpi()
*/
public void removeNodeSpi() throws BackingStoreException
- {
- if (log.isDebugEnabled())
- log.debug("Attempting to remove node: " + this.absolutePath());
- Object[] nodeResult = getNode(this.absolutePath(), this.nodeType);
-
- if (((Long) nodeResult[ERROR_CODE]).intValue() != ERROR_SUCCESS)
- {
- String warning = "Could not get node id. Returned error code " +
nodeResult[ERROR_CODE];
- if (log.isWarnEnabled())
- {
- log.warn(warning);
- }
- throw new BackingStoreException(warning);
- }
- PersistenceStore store = getPersistenceStore();
- try
- {
- Node nodeObj = (Node) nodeResult[NODE];
- if (log.isDebugEnabled())
- log.debug("Remove node: " + nodeObj.getNodeName());
- store.deletePersistent(nodeObj);
- store.getTransaction().checkpoint();
- }
- catch (Exception e)
- {
- String msg = "Unable to remove Node.";
- log.error(msg, e);
- store.getTransaction().rollback();
- }
+ {
+ prefsProvider.removeNode(node);
}
/**
* @see java.util.prefs.Preferences#removeSpi(java.lang.String)
*/
- public void removeSpi(String key)
+ public void removeSpi( String key )
{
- Object[] nodeResult = getNode(this.absolutePath(), this.nodeType);
-
- if (((Long) nodeResult[ERROR_CODE]).intValue() != ERROR_SUCCESS)
- {
- log.error("Could not get node id. Returned error code " +
nodeResult[ERROR_CODE]);
- return;
- }
-
- // Get the property set def.
- Node nodeObj = (Node) nodeResult[NODE];
- Collection properties = nodeObj.getNodeProperties();
+ Collection properties = node.getNodeProperties();
for (Iterator i = properties.iterator(); i.hasNext();)
{
@@ -557,20 +307,9 @@
i.remove();
}
}
+
// Update node.
- PersistenceStore store = getPersistenceStore();
- try
- {
- store.lockForWrite(nodeObj);
- nodeObj.setModifiedDate(new Timestamp(System.currentTimeMillis()));
- store.getTransaction().checkpoint();
- }
- catch (Exception e)
- {
- String msg = "Unable to update Node.";
- log.error(msg, e);
- store.getTransaction().rollback();
- }
+ prefsProvider.storeNode(node);
}
/**
@@ -582,14 +321,29 @@
}
/**
- * <p>Utility method to get the persistence store and initiate
- * the transaction if not open.</p>
- * @return The persistence store.
+ *
+ * <p>
+ * getNode
+ * </p>
+ *
+ * @return
*/
- protected PersistenceStore getPersistenceStore()
+ public Node getNode()
{
-
- return persistenceStore;
+ return node;
}
-
-}
+
+ /**
+ *
+ * <p>
+ * setPreferencesProvider
+ * </p>
+ * Sets the <code>org.apache.jetspeed.prefs.PreferencesProvider</code> that
+ * will support backing store operations for all <code>PreferencesImpls</code>
+ * @param prefsProvider
+ */
+ public static void setPreferencesProvider(PreferencesProvider prefsProvider)
+ {
+ PreferencesImpl.prefsProvider = prefsProvider;
+ }
+}
\ No newline at end of file
1.4 +38 -2
jakarta-jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java
Index: PreferencesFactoryImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PreferencesFactoryImpl.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- PreferencesFactoryImpl.java 21 Jun 2004 17:53:08 -0000 1.3
+++ PreferencesFactoryImpl.java 29 Oct 2004 13:57:59 -0000 1.4
@@ -17,6 +17,9 @@
import java.util.prefs.Preferences;
import java.util.prefs.PreferencesFactory;
+import org.apache.jetspeed.prefs.PreferencesException;
+import org.apache.jetspeed.prefs.PreferencesProvider;
+
/**
* <p>[EMAIL PROTECTED] java.util.prefs.PreferencesFactory} implementation to
* return [EMAIL PROTECTED] PreferencesImpl}.</p>
@@ -25,9 +28,17 @@
*/
public class PreferencesFactoryImpl implements PreferencesFactory
{
-
+
+
+ protected static PreferencesProvider prefsProvider;
+
+ public PreferencesFactoryImpl()
+ {
+ super();
+ System.setProperty("java.util.prefs.PreferencesFactory",
getClass().getName());
+ }
+
-
/**
* @see java.util.prefs.PreferencesFactory#systemRoot()
@@ -44,5 +55,30 @@
{
return PreferencesImpl.userRoot;
}
+
+ public void init() throws Exception
+ {
+ try
+ {
+ PreferencesImpl.setPreferencesProvider(prefsProvider);
+ PreferencesImpl.systemRoot = new PreferencesImpl(null, "",
PreferencesImpl.SYSTEM_NODE_TYPE);
+ PreferencesImpl.userRoot = new PreferencesImpl(null, "",
PreferencesImpl.USER_NODE_TYPE);
+ }
+ catch(Throwable e)
+ {
+ throw new PreferencesException("Failed to initialize prefs api.
"+e.toString());
+ }
+ }
+
+
+ public PreferencesProvider getPrefsProvider()
+ {
+ return prefsProvider;
+ }
+
+ public void setPrefsProvider( PreferencesProvider prefsProvider )
+ {
+ this.prefsProvider = prefsProvider;
+ }
}
1.10 +128 -199
jakarta-jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PropertyManagerImpl.java
Index: PropertyManagerImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PropertyManagerImpl.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- PropertyManagerImpl.java 16 Jul 2004 19:29:09 -0000 1.9
+++ PropertyManagerImpl.java 29 Oct 2004 13:57:59 -0000 1.10
@@ -22,9 +22,9 @@
import java.util.Map;
import java.util.prefs.Preferences;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jetspeed.components.persistence.store.PersistenceStore;
+import org.apache.jetspeed.prefs.NodeDoesNotExistException;
+import org.apache.jetspeed.prefs.PreferencesException;
+import org.apache.jetspeed.prefs.PreferencesProvider;
import org.apache.jetspeed.prefs.PropertyException;
import org.apache.jetspeed.prefs.PropertyManager;
import org.apache.jetspeed.prefs.om.Node;
@@ -32,6 +32,7 @@
import org.apache.jetspeed.prefs.om.PropertyKey;
import org.apache.jetspeed.prefs.om.impl.PropertyKeyImpl;
import org.apache.jetspeed.util.ArgUtil;
+import org.springframework.orm.ojb.support.PersistenceBrokerDaoSupport;
/**
* <p>
@@ -41,277 +42,205 @@
*
* @author <a href="mailto:[EMAIL PROTECTED]">David Le Strat </a>
*/
-public class PropertyManagerImpl implements PropertyManager
+public class PropertyManagerImpl extends PersistenceBrokerDaoSupport implements
PropertyManager
{
- private static final Log log = LogFactory.getLog(PropertyManagerImpl.class);
-
/** User <tt>Preferences<tt> node type. */
private static final int USER_NODE_TYPE = 0;
/** System <tt>Preferences</tt> node type. */
private static final int SYSTEM_NODE_TYPE = 1;
- /** Common queries. * */
- private CommonQueries commonQueries;
-
- private PersistenceStore persistenceStore;
-
-
+ protected PreferencesProvider prefsProvider;
/**
* <p>
- * Constructor providing access to the persistence component.
+ * Constructor providing access to the PreferencesProvider component.
* </p>
*/
- public PropertyManagerImpl(PersistenceStore persistenceStore)
+ public PropertyManagerImpl( PreferencesProvider prefsProvider )
{
- if (persistenceStore == null)
- {
- throw new IllegalArgumentException("persistenceStore cannot be null for
PropertyManagerImpl");
- }
-
-
-
- this.persistenceStore = persistenceStore;
- this.commonQueries = new CommonQueries(persistenceStore);
+ super();
+ this.prefsProvider = prefsProvider;
}
/**
* @see
org.apache.jetspeed.prefs.PropertyManager#addPropertyKeys(java.util.prefs.Preferences,
* java.util.Map)
*/
- public void addPropertyKeys(Preferences prefNode, Map propertyKeysMap) throws
PropertyException
+ public void addPropertyKeys( Preferences prefNode, Map propertyKeysMap ) throws
PropertyException,
+ PreferencesException
{
ArgUtil.notNull(new Object[]{prefNode, propertyKeysMap}, new
String[]{"prefNode", "propertyKeysMap",},
"addPropertyKeys(java.util.prefs.Preferences,
java.util.Collection)");
- Node nodeObj;
- if (prefNode.isUserNode())
- {
- nodeObj = (Node)
persistenceStore.getObjectByQuery(commonQueries.newNodeQueryByPathAndType(prefNode
- .absolutePath(), new Integer(USER_NODE_TYPE)));
- }
- else
- {
- nodeObj = (Node)
persistenceStore.getObjectByQuery(commonQueries.newNodeQueryByPathAndType(prefNode
- .absolutePath(), new Integer(SYSTEM_NODE_TYPE)));
- }
- if (null != nodeObj)
- {
- // Get the existing property keys.
- Collection propertyKeys = nodeObj.getNodeKeys();
- ArrayList newPropertyKeys = new ArrayList(propertyKeysMap.size());
- for (Iterator i = propertyKeysMap.keySet().iterator(); i.hasNext();)
+ Node nodeObj = getNode(prefNode);
+
+ // Get the existing property keys.
+ Collection propertyKeys = nodeObj.getNodeKeys();
+ ArrayList newPropertyKeys = new ArrayList(propertyKeysMap.size());
+ for (Iterator i = propertyKeysMap.keySet().iterator(); i.hasNext();)
+ {
+ boolean foundKey = false;
+ String currentPropertyKeyName = (String) i.next();
+ for (Iterator j = propertyKeys.iterator(); j.hasNext();)
{
- boolean foundKey = false;
- String currentPropertyKeyName = (String) i.next();
- for (Iterator j = propertyKeys.iterator(); j.hasNext();)
- {
- PropertyKey existingPpk = (PropertyKey) j.next();
- if
(propertyKeysMap.containsKey(existingPpk.getPropertyKeyName()))
- {
- if (log.isDebugEnabled())
- log.debug("Existing Property: " + (String)
propertyKeysMap.get(currentPropertyKeyName));
- foundKey = true;
- newPropertyKeys.add(existingPpk);
- break;
- }
- }
- if (!foundKey)
+ PropertyKey existingPpk = (PropertyKey) j.next();
+ if (propertyKeysMap.containsKey(existingPpk.getPropertyKeyName()))
{
- if (log.isDebugEnabled())
- log.debug("New Property: " + currentPropertyKeyName);
- PropertyKey ppk = new PropertyKeyImpl(currentPropertyKeyName,
((Integer) propertyKeysMap
- .get(currentPropertyKeyName)).intValue());
- newPropertyKeys.add(ppk);
+ if (logger.isDebugEnabled())
+ logger.debug("Existing Property: " + (String)
propertyKeysMap.get(currentPropertyKeyName));
+ foundKey = true;
+ newPropertyKeys.add(existingPpk);
+ break;
}
}
-
- // Add the properties keys.
- try
- {
- if (log.isDebugEnabled())
- log.debug("Node: " + nodeObj.toString());
- if (log.isDebugEnabled())
- log.debug("Node property keys: " + newPropertyKeys.toString());
- persistenceStore.lockForWrite(nodeObj);
- nodeObj.setNodeKeys(newPropertyKeys);
- nodeObj.setModifiedDate(new Timestamp(System.currentTimeMillis()));
- persistenceStore.getTransaction().checkpoint();
- }
- catch (Exception e)
+ if (!foundKey)
{
- String msg = "Unable to lock Node for update.";
- log.error(msg, e);
- persistenceStore.getTransaction().rollback();
- throw new PropertyException(msg, e);
+ if (logger.isDebugEnabled())
+ logger.debug("New Property: " + currentPropertyKeyName);
+ PropertyKey ppk = new PropertyKeyImpl(currentPropertyKeyName,
((Integer) propertyKeysMap
+ .get(currentPropertyKeyName)).intValue());
+ newPropertyKeys.add(ppk);
}
}
- else
- {
- throw new PropertyException(PropertyException.NODE_NOT_FOUND);
- }
+
+ // Add the properties keys.
+
+ if (logger.isDebugEnabled())
+ logger.debug("Node: " + nodeObj.toString());
+ if (logger.isDebugEnabled())
+ logger.debug("Node property keys: " + newPropertyKeys.toString());
+
+ nodeObj.setNodeKeys(newPropertyKeys);
+ nodeObj.setModifiedDate(new Timestamp(System.currentTimeMillis()));
+ prefsProvider.storeNode(nodeObj);
+
}
+
/**
+ * @throws PreferencesException
* @see
org.apache.jetspeed.prefs.PropertyManager#getPropertyKeys(java.util.prefs.Preferences)
*/
- public Map getPropertyKeys(Preferences prefNode)
+ public Map getPropertyKeys( Preferences prefNode ) throws PreferencesException
{
ArgUtil.notNull(new Object[]{prefNode}, new String[]{"prefNode"},
"getPropertyKeys(java.util.prefs.Preferences)");
- Node nodeObj;
- if (prefNode.isUserNode())
- {
- nodeObj = (Node)
persistenceStore.getObjectByQuery(commonQueries.newNodeQueryByPathAndType(prefNode
- .absolutePath(), new Integer(USER_NODE_TYPE)));
- }
- else
- {
- nodeObj = (Node)
persistenceStore.getObjectByQuery(commonQueries.newNodeQueryByPathAndType(prefNode
- .absolutePath(), new Integer(SYSTEM_NODE_TYPE)));
- }
- if (null != nodeObj)
- {
- Collection keys = nodeObj.getNodeKeys();
- HashMap propertyKeysMap = new HashMap(keys.size());
- for (Iterator i = keys.iterator(); i.hasNext();)
- {
- PropertyKey curpk = (PropertyKey) i.next();
- propertyKeysMap.put(curpk.getPropertyKeyName(), new
Integer(curpk.getPropertyKeyType()));
- }
- return propertyKeysMap;
- }
- else
+ Node nodeObj = getNode(prefNode);
+
+ Collection keys = nodeObj.getNodeKeys();
+ HashMap propertyKeysMap = new HashMap(keys.size());
+ for (Iterator i = keys.iterator(); i.hasNext();)
{
- return new HashMap(0);
+ PropertyKey curpk = (PropertyKey) i.next();
+ propertyKeysMap.put(curpk.getPropertyKeyName(), new
Integer(curpk.getPropertyKeyType()));
}
+ return propertyKeysMap;
+
}
/**
+ * @throws PreferencesException
* @see
org.apache.jetspeed.prefs.PropertyManager#removePropertyKeys(java.util.prefs.Preferences,
* java.util.Collection)
*/
- public void removePropertyKeys(Preferences prefNode, Collection propertyKeys)
throws PropertyException
+ public void removePropertyKeys( Preferences prefNode, Collection propertyKeys )
throws PropertyException,
+ PreferencesException
{
ArgUtil.notNull(new Object[]{prefNode, propertyKeys}, new
String[]{"prefNode", "propertyKeys"},
"removePropertyKeys(java.util.prefs.Preferences,
java.util.Collection)");
- Node nodeObj;
- if (prefNode.isUserNode())
- {
- nodeObj = (Node)
persistenceStore.getObjectByQuery(commonQueries.newNodeQueryByPathAndType(prefNode
- .absolutePath(), new Integer(USER_NODE_TYPE)));
- }
- else
- {
- nodeObj = (Node)
persistenceStore.getObjectByQuery(commonQueries.newNodeQueryByPathAndType(prefNode
- .absolutePath(), new Integer(SYSTEM_NODE_TYPE)));
- }
- if (null != nodeObj)
+ Node nodeObj = getNode(prefNode);
+
+ Collection properties = nodeObj.getNodeProperties();
+ ArrayList newProperties = new ArrayList(properties.size());
+ Collection keys = nodeObj.getNodeKeys();
+ ArrayList newKeys = new ArrayList(keys.size());
+ for (Iterator i = properties.iterator(); i.hasNext();)
{
- Collection properties = nodeObj.getNodeProperties();
- ArrayList newProperties = new ArrayList(properties.size());
- Collection keys = nodeObj.getNodeKeys();
- ArrayList newKeys = new ArrayList(keys.size());
- for (Iterator i = properties.iterator(); i.hasNext();)
- {
- Property curProp = (Property) i.next();
- PropertyKey curPropKey = (PropertyKey) curProp.getPropertyKey();
- if ((null != curPropKey) &&
(!propertyKeys.contains(curProp.getPropertyKey().getPropertyKeyName())))
- {
- newProperties.add(curProp);
- }
- }
- for (Iterator j = newKeys.iterator(); j.hasNext();)
- {
- PropertyKey curPropKey = (PropertyKey) j.next();
- if (!propertyKeys.contains(curPropKey.getPropertyKeyName()))
- {
- newKeys.add(curPropKey);
- }
- }
- // Remove the properties keys.
- try
+ Property curProp = (Property) i.next();
+ PropertyKey curPropKey = (PropertyKey) curProp.getPropertyKey();
+ if ((null != curPropKey) &&
(!propertyKeys.contains(curProp.getPropertyKey().getPropertyKeyName())))
{
- persistenceStore.lockForWrite(nodeObj);
- nodeObj.setNodeKeys(newKeys);
- nodeObj.setNodeProperties(newProperties);
- nodeObj.setModifiedDate(new Timestamp(System.currentTimeMillis()));
- persistenceStore.getTransaction().checkpoint();
- }
- catch (Exception e)
- {
- String msg = "Unable to lock Node for update.";
- log.error(msg, e);
- persistenceStore.getTransaction().rollback();
- throw new PropertyException(msg, e);
+ newProperties.add(curProp);
}
}
- else
+ for (Iterator j = newKeys.iterator(); j.hasNext();)
{
- throw new PropertyException(PropertyException.NODE_NOT_FOUND);
+ PropertyKey curPropKey = (PropertyKey) j.next();
+ if (!propertyKeys.contains(curPropKey.getPropertyKeyName()))
+ {
+ newKeys.add(curPropKey);
+ }
}
+ // Remove the properties keys.
+
+ nodeObj.setNodeKeys(newKeys);
+ nodeObj.setNodeProperties(newProperties);
+ nodeObj.setModifiedDate(new Timestamp(System.currentTimeMillis()));
+ prefsProvider.storeNode(nodeObj);
+
}
/**
+ * @throws PreferencesException
* @see
org.apache.jetspeed.prefs.PropertyManager#updatePropertyKey(java.lang.String,
* java.util.prefs.Preferences, java.util.Map)
*/
- public void updatePropertyKey(String oldPropertyKeyName, Preferences prefNode,
Map newPropertyKey)
- throws PropertyException
+ public void updatePropertyKey( String oldPropertyKeyName, Preferences prefNode,
Map newPropertyKey )
+ throws PropertyException, PreferencesException
{
ArgUtil.notNull(new Object[]{oldPropertyKeyName, prefNode, newPropertyKey},
new String[]{"oldPropertyKeyName",
"prefNode", "newPropertyKey"},
"updatePropertyKey(java.lang.String, java.util.prefs.Preferences,
java.util.Map)");
- Node nodeObj;
- if (prefNode.isUserNode())
- {
- nodeObj = (Node)
persistenceStore.getObjectByQuery(commonQueries.newNodeQueryByPathAndType(prefNode
- .absolutePath(), new Integer(USER_NODE_TYPE)));
- }
- else
- {
- nodeObj = (Node)
persistenceStore.getObjectByQuery(commonQueries.newNodeQueryByPathAndType(prefNode
- .absolutePath(), new Integer(SYSTEM_NODE_TYPE)));
- }
- if (null != nodeObj)
+ Node nodeObj = getNode(prefNode);
+
+ Collection keys = nodeObj.getNodeKeys();
+ for (Iterator i = keys.iterator(); i.hasNext();)
{
- Collection keys = nodeObj.getNodeKeys();
- for (Iterator i = keys.iterator(); i.hasNext();)
+ PropertyKey curPropKey = (PropertyKey) i.next();
+ if (curPropKey.getPropertyKeyName().equals(oldPropertyKeyName))
{
- PropertyKey curPropKey = (PropertyKey) i.next();
- if (curPropKey.getPropertyKeyName().equals(oldPropertyKeyName))
+ for (Iterator j = newPropertyKey.keySet().iterator(); j.hasNext();)
{
- for (Iterator j = newPropertyKey.keySet().iterator();
j.hasNext();)
- {
- String newKey = (String) j.next();
- // Update the property key.
- try
- {
- persistenceStore.lockForWrite(curPropKey);
- curPropKey.setPropertyKeyName(newKey);
- curPropKey.setPropertyKeyType(((Integer)
newPropertyKey.get(newKey)).intValue());
- curPropKey.setModifiedDate(new
Timestamp(System.currentTimeMillis()));
- if (log.isDebugEnabled())
- log.debug("Updated property key: " +
curPropKey.toString());
- persistenceStore.getTransaction().checkpoint();
- }
- catch (Exception e)
- {
- String msg = "Unable to lock Node for update.";
- log.error(msg, e);
- persistenceStore.getTransaction().rollback();
- throw new PropertyException(msg, e);
- }
- }
+ String newKey = (String) j.next();
+ // Update the property key.
+
+ curPropKey.setPropertyKeyName(newKey);
+ curPropKey.setPropertyKeyType(((Integer)
newPropertyKey.get(newKey)).intValue());
+ curPropKey.setModifiedDate(new
Timestamp(System.currentTimeMillis()));
+ if (logger.isDebugEnabled())
+ logger.debug("Updated property key: " +
curPropKey.toString());
+
+ getPersistenceBrokerTemplate().store(curPropKey);
+
}
}
}
+
+ }
+
+ /**
+ * <p>
+ * getNode
+ * </p>
+ *
+ * @param prefNode
+ * @return @throws
+ * NodeDoesNotExistException
+ */
+ protected Node getNode( Preferences prefNode ) throws NodeDoesNotExistException
+ {
+ Node nodeObj;
+ if (prefNode.isUserNode())
+ {
+ nodeObj = prefsProvider.getNode(prefNode.absolutePath(),
USER_NODE_TYPE);
+ }
else
{
- throw new PropertyException(PropertyException.NODE_NOT_FOUND);
+ nodeObj = prefsProvider.getNode(prefNode.absolutePath(),
SYSTEM_NODE_TYPE);
}
+ return nodeObj;
}
}
1.1
jakarta-jetspeed-2/components/prefs/src/java/org/apache/jetspeed/prefs/impl/PersistenceBrokerPreferencesProvider.java
Index: PersistenceBrokerPreferencesProvider.java
===================================================================
/*
* Copyright 2000-2001,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jetspeed.prefs.impl;
import java.util.Collection;
import org.apache.jetspeed.components.dao.InitablePersistenceBrokerDaoSupport;
import org.apache.jetspeed.page.document.NodeNotFoundException;
import org.apache.jetspeed.prefs.FailedToCreateNodeException;
import org.apache.jetspeed.prefs.NodeAlreadyExistsException;
import org.apache.jetspeed.prefs.NodeDoesNotExistException;
import org.apache.jetspeed.prefs.PreferencesException;
import org.apache.jetspeed.prefs.PreferencesProvider;
import org.apache.jetspeed.prefs.om.Node;
import org.apache.jetspeed.prefs.om.impl.NodeImpl;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.query.QueryFactory;
/**
* <p>
* PersistenceBrokerPreferencesProvider
* </p>
* <p>
*
* </p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Scott T. Weaver </a>
* @version $Id: PersistenceBrokerPreferencesProvider.java,v 1.1 2004/10/29 13:57:59
weaver Exp $
*
*/
public class PersistenceBrokerPreferencesProvider extends
InitablePersistenceBrokerDaoSupport implements PreferencesProvider
{
private boolean enablePropertyManager;
/**
*
* @param repository Location of repository mapping file. Must be available
within the classpath.
* @param prefsFactoryImpl <code>java.util.prefs.PreferencesFactory</code>
implementation to use.
* @param enablePropertyManager Whether or not we chould be suing the property
manager.
* @throws ClassNotFoundException if the <code>prefsFactoryImpl</code> argument
does not reperesent
* a Class that exists in the current classPath.
*/
public PersistenceBrokerPreferencesProvider(String repositoryPath, boolean
enablePropertyManager) throws ClassNotFoundException
{
super(repositoryPath);
this.enablePropertyManager = enablePropertyManager;
}
/**
* <p>
* Get the node id from the full path.
* </p>
*
* @param fullPath
* The full path.
* @param nodeType
* The node type.
* @return An array of value returned including:
* @throws NodeNotFoundException
* if the node does not exist
*
*/
public Node getNode( String fullPath, int nodeType ) throws
NodeDoesNotExistException
{
Criteria c = new Criteria();
c.addEqualTo("fullPath", fullPath);
c.addEqualTo("nodeType", new Integer(nodeType));
Query query = QueryFactory.newQuery(NodeImpl.class, c);
Node nodeObj = (Node) getPersistenceBrokerTemplate().getObjectByQuery(query);
if (null != nodeObj)
{
return nodeObj;
}
else
{
throw new NodeDoesNotExistException("No node of type " + nodeType +
"found at path: " + fullPath);
}
}
/**
*
* <p>
* nodeExists
* </p>
*
* @param fullPath
* @param nodeType
* @return
*/
public boolean nodeExists( String fullPath, int nodeType )
{
try
{
getNode(fullPath, nodeType);
return true;
}
catch (NodeDoesNotExistException e)
{
return false;
}
}
/**
* <p>
* Create a new preference node in the backing store.
* </p>
*
* @param parent
* The parent node.
* @param nodeName
* The node name.
* @param nodeType
* The node type.
* @param fullPath
* The node full path.
* @return the newly created node
* @throws NodeAlreadyExistsException if a node of the same type having the same
path
* already exists.
*/
public Node createNode( Node parent, String nodeName, int nodeType, String
fullPath )
throws FailedToCreateNodeException, NodeAlreadyExistsException
{
if (nodeExists(fullPath, nodeType))
{
throw new NodeAlreadyExistsException("Node of type "+nodeType+" already
exists at path "+fullPath);
}
else
{
Long parentNodeId = null;
if (null != parent)
{
parentNodeId = new Long(parent.getNodeId());
}
Node nodeObj = new NodeImpl(parentNodeId, nodeName, nodeType, fullPath);
try
{
getPersistenceBrokerTemplate().store(nodeObj);
return nodeObj;
}
catch (Exception e)
{
throw new FailedToCreateNodeException("Failed to create node of type
"+nodeType+" for the path "+fullPath+". "+e.toString(), e);
}
}
}
/**
*
* <p>
* getChildren
* </p>
*
* @see
org.apache.jetspeed.prefs.PreferencesProvider#getChildren(org.apache.jetspeed.prefs.om.Node)
* @param parentNode
* @return
*/
public Collection getChildren( Node parentNode )
{
Criteria c = new Criteria();
c.addEqualTo("parentNodeId", new Long(parentNode.getNodeId()));
Query query = QueryFactory.newQuery(NodeImpl.class, c);
return getPersistenceBrokerTemplate().getCollectionByQuery(query);
}
public void storeNode( Node node )
{
getPersistenceBrokerTemplate().store(node);
}
public void removeNode( Node node )
{
getPersistenceBrokerTemplate().delete(node);
}
/**
* <p>
* isPropertyManagerEnabled
* </p>
*
* @see org.apache.jetspeed.prefs.PreferencesProvider#isPropertyManagerEnabled()
* @return
*/
public boolean isPropertyManagerEnabled()
{
return this.enablePropertyManager;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]