//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// MicroSafe source file
// Copyright (c) 2006 Elmar Sonnenschein / esoco GmbH
// Last Change: 17.10.2006 by eso
//
// MicroSafe is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// MicroSafe is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// MicroSafe; if not, write to the Free Software Foundation, Inc., 59 Temple
// Place, Suite 330, Boston, MA 02111-1307 USA or use the contact information
// from the GNU website http://www.gnu.org
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
package de.esoco.microsafe.model;
import de.esoco.j2me.model.BasicHierarchyNode;
import de.esoco.j2me.model.HierarchyNode;
import de.esoco.j2me.model.NodeAccessException;
import de.esoco.j2me.storage.HierarchicalStorage;
import de.esoco.j2me.storage.StorageException;
import de.esoco.j2me.util.Assert;
import de.esoco.j2me.util.ProgressMonitor;
import de.esoco.microsafe.MicroSafe;
import de.esoco.microsafe.crypto.CryptoHandler;
import java.io.IOException;
import org.bouncycastle.crypto.CryptoException;
/********************************************************************
* Subclass for nodes in a MicroSafeModel.
*
* @author eso
*/
public class MicroSafeNode extends EncryptableNode
{
//~ Constructors -----------------------------------------------------------
/***************************************
* Constructor, simply calls the same super constructor.
*
* @see BasicHierarchyNode#BasicHierarchyNode(BasicHierarchyNode, String,
* byte[])
*/
public MicroSafeNode(MicroSafeNode rParent, String sTitle, byte[] rData)
{
super(rParent, sTitle, rData);
}
//~ Methods ----------------------------------------------------------------
/***************************************
* Overloaded to initialize the progress monitor before calling the super
* implementation.
*
* @see EncryptableNode#insertChild(HierarchyNode, int)
*/
public void insertChild(HierarchyNode rChild, int nIndex)
throws NodeAccessException, StorageException
{
initProgressMonitor(((MicroSafeNode) rChild).getTotalChildCount() + 1,
MicroSafe.getString("RsStore"));
try
{
super.insertChild(rChild, nIndex);
}
finally
{
resetProgressMonitor();
}
}
/***************************************
* Overloaded to initialize the progress monitor before calling the super
* implementation.
*
* @see de.esoco.j2me.model.MutableHierarchyNode#removeChild(int)
*/
public void removeChild(int nIndex) throws StorageException
{
initProgressMonitor(((MicroSafeNode) getChild(nIndex))
.getTotalChildCount() + 1,
MicroSafe.getString("RsRemove"));
try
{
super.removeChild(nIndex);
}
finally
{
resetProgressMonitor();
}
}
/***************************************
* Overloaded to initialize the progress monitor (if it has been set on the
* model) with the number of child nodes. This will be done before
* super.setEncryption() will be invoked. The monitor will then be notified
* by the encrypt() and decrypt() methods of each child node. In case of
* errors (i.e. exceptions) the monitor will be reset.
*
* @param bEncrypt TRUE to enable encryption, FALSE to disable
*
* @see EncryptableNode#setEncryption(boolean)
*/
public void setEncryption(boolean bEncrypt) throws CryptoException,
StorageException
{
String sKey = (bEncrypt ? "RsEncrypt" : "RsDecrypt");
int n = getTotalChildCount() + 1;
initProgressMonitor(n, MicroSafe.getString(sKey));
try
{
super.setEncryption(bEncrypt);
}
finally
{
resetProgressMonitor();
}
}
/***************************************
* @see EncryptableNode#changeEncryption(CryptoHandler)
*/
protected void changeEncryption(CryptoHandler rNewCrypto)
throws CryptoException, StorageException
{
int n = getTotalChildCount() + 1;
// if a new handler is set all nodes will possibly be re-encrypted;
// therefore double the node processing count because decrypt() AND
// encrypt() are called which both notify the progress monitor
if (rNewCrypto != null)
{
n *= 2;
}
initProgressMonitor(n, MicroSafe.getString("RsProcess"));
try
{
super.changeEncryption(rNewCrypto);
}
finally
{
resetProgressMonitor();
}
}
/***************************************
* Overloaded to notify the progress monitor (if available) after the super
* method has been invoked.
*
* @see EncryptableNode#decrypt(CryptoHandler, boolean)
*/
protected void decrypt(CryptoHandler rCrypto, boolean bKeepFlag)
throws CryptoException, StorageException
{
super.decrypt(rCrypto, bKeepFlag);
notifyProgressMonitor();
}
/***************************************
* Overloaded to notify the progress monitor (if available) after the super
* method has been invoked.
*
* @see BasicHierarchyNode#deleteFromStorage(HierarchicalStorage)
*/
protected void deleteFromStorage(HierarchicalStorage rStorage)
throws StorageException
{
super.deleteFromStorage(rStorage);
notifyProgressMonitor();
}
/***************************************
* Overloaded to notify the progress monitor (if available) after the super
* method has been invoked.
*
* @see EncryptableNode#encrypt(CryptoHandler, boolean)
*/
protected void encrypt(CryptoHandler rCrypto, boolean bOnlyIfFlagSet)
throws CryptoException, StorageException
{
super.encrypt(rCrypto, bOnlyIfFlagSet);
notifyProgressMonitor();
}
/***************************************
* Returns the progress monitor of the root node.
*
* @return The ProgressMonitor instance or NULL if none exists
*/
protected ProgressMonitor getProgressMonitor()
{
HierarchyNode rRoot = getRoot();
if ((rRoot != null) && (rRoot instanceof MicroSafeModel))
{
return ((MicroSafeModel) rRoot).getProgressMonitor();
}
else
{
return null;
}
}
/***************************************
* Initializes the model's progress monitor to display the progress for a
* certain number of nodes.
*
* @param nCount The number of nodes that will be processed
* @param sMessage A message to display in the progress monitor or NULL
*/
protected void initProgressMonitor(int nCount, String sMessage)
{
ProgressMonitor m = getProgressMonitor();
if (m != null)
{
m.init(nCount, sMessage);
}
}
/***************************************
* Overloaded to return instances of MicroSafeNode.
*
* @see BasicHierarchyNode#newChildNode(String)
*/
protected BasicHierarchyNode newChildNode(String sTitle)
{
return new MicroSafeNode(null, sTitle, null);
}
/***************************************
* Internal method to notify the model's progress monitor (if one has been
* set) of a single progress step. This method will be called by the methods
* of all nodes that are part of a long-term task like encryption.
*/
protected void notifyProgressMonitor()
{
ProgressMonitor m = getProgressMonitor();
if (m != null)
{
m.advance(1);
}
}
/***************************************
* Overloaded to load additional node fields (currently three reserved byte
* values).
*
* @see BasicHierarchyNode#readFields(HierarchicalStorage)
*/
protected int readFields(HierarchicalStorage rStorage)
throws StorageException, IOException
{
int nResult = super.readFields(rStorage);
// Read reserved bytes
int nRes1 = rStorage.readByte();
int nRes2 = rStorage.readByte();
// And check
if (MicroSafe.DEBUG)
{
Assert.notFalse((nRes1 == 0) && (nRes2 == 0),
"Reserved fields mismatch(0.0 expected): " + nRes1 +
"." + nRes2);
}
return nResult;
}
/***************************************
* Overloaded to notify the progress monitor (if available) after the super
* method has been invoked.
*
* @see BasicHierarchyNode#readFrom(HierarchicalStorage)
*/
protected int readFrom(HierarchicalStorage rStorage)
throws StorageException, IOException
{
int nResult = super.readFrom(rStorage);
notifyProgressMonitor();
return nResult;
}
/***************************************
* Resets the model's progress monitor after a processing of nodes has
* finished.
*/
protected void resetProgressMonitor()
{
ProgressMonitor m = getProgressMonitor();
if (m != null)
{
m.reset();
}
}
/***************************************
* Overloaded to write additional node fields (currently three reserved
* values).
*
* @see BasicHierarchyNode#writeFields(HierarchicalStorage)
*/
protected void writeFields(HierarchicalStorage rStorage)
throws StorageException, IOException
{
super.writeFields(rStorage);
// Reserved bytes
rStorage.writeByte((byte) 0);
rStorage.writeByte((byte) 0);
}
/***************************************
* Overloaded to notify the progress monitor (if available) after the super
* method has been invoked.
*
* @see BasicHierarchyNode#writeTo(HierarchicalStorage)
*/
protected void writeTo(HierarchicalStorage rStorage)
throws StorageException, IOException
{
super.writeTo(rStorage);
notifyProgressMonitor();
}
}