Package net.sf.xbus.base.deletedMessageStore

Source Code of net.sf.xbus.base.deletedMessageStore.DeletedMessageStore

package net.sf.xbus.base.deletedMessageStore;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Enumeration;
import java.util.Hashtable;

import net.sf.xbus.application.Adapter;
import net.sf.xbus.application.PostProcessor;
import net.sf.xbus.base.core.Constants;
import net.sf.xbus.base.core.TAManager;
import net.sf.xbus.base.core.XException;
import net.sf.xbus.base.core.config.Configuration;
import net.sf.xbus.base.core.trace.Trace;
import net.sf.xbus.base.xbussystem.XBUSSystem;
import net.sf.xbus.base.xml.XDomSupport;
import net.sf.xbus.base.xml.XMLHelper;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
* <code>DeletedMessageStore</code> manages the saving of messages before they
* are deleted in case of an error.
* <p>
* It implements a <b>Singleton </b> pattern, where there is one instance per
* thread.
*/
public class DeletedMessageStore
{
  private static final String SECTION = "DeletedMessageStore";

  private static Hashtable mDeletedMessageStores = new Hashtable();

  private static final Object classLock = DeletedMessageStore.class;

  private Object mMessage = null;

  private XBUSSystem mSystem = null;

  private DeletedMessageStore()
  {
    mDeletedMessageStores.put(Thread.currentThread().getName(), this);
  }

  /**
   * Returns an instance of the <code>DeletedMessageStore</code>. A new
   * instance will be created if there is none existing for this thread.
   *
   * @return an instance of the <code>DeletedMessageStore</code>
   */
  public static DeletedMessageStore getInstance()
  {
    synchronized (classLock)
    {
      DeletedMessageStore dmStore = (DeletedMessageStore) mDeletedMessageStores
          .get(Thread.currentThread().getName());

      if (dmStore == null)
      {
        dmStore = new DeletedMessageStore();
      }
      return dmStore;
    }
  }

  /**
   * Set the message that shall be saved. The XML file will contain the
   * <code>String</code> representation of this object.
   *
   * @param message
   *            the message to be saved
   */
  public void setMessage(Object message)
  {
    mMessage = message;
  }

  /**
   * Sets the system that has received the message.
   *
   * @param system
   *            the receiving message
   */
  public void setSystem(XBUSSystem system)
  {
    mSystem = system;
  }

  /**
   * Writes the name of the system, its additional addresses and the message
   * into a XML file. The name of the directory is read out of the
   * configuration. The filename is
   * <code><i>system.getCompleteName()</i>.xml.<i>timestamp</i></code>.
   *
   * @return true if the writing has been successful, false if there has been
   *         a problem
   */
  public boolean writeMessage()
  {
    try
    {
      if (getEnabled(mSystem))
      {
        writeFile(buildXML(mMessage, mSystem), mSystem, getDirectory());
      }
      return true;
    }
    catch (XException e)
    {
      Trace.error("Problem while writing to DeletedMessageStore");
      return false;
    }
  }

  /**
   * Reads the name of all files containing deleted messages.
   *
   * @return an array with the name of all files containing deleted messages
   * @throws XException
   *             if any error occures
   */
  public static String[] getDeletedMessageFilenames() throws XException
  {
    File[] files = new File(getDirectory()).listFiles();

    String[] retArray = new String[files.length];
    for (int i = 0; i < retArray.length; i++)
    {
      retArray[i] = files[i].getName();
    }
    return retArray;
  }

  /**
   * Reads a deleted message and makes a new attempt to send it to its
   * destinations.
   *
   * @param filename
   *            the name of a file containing a deleted message
   * @return a message of success or failure
   */
  public static String resendDeletedMessage(String filename)
  {
    StringBuffer retString = new StringBuffer();
    TAManager taManager = null;

    Trace.info("Resending message from " + filename);

    /*
     * Reading and parsing the deleted message
     */
    try
    {
      Document messageDom = XMLHelper.parseXML(readFile(getDirectory()
          + Constants.FILE_SEPERATOR + filename), null, null);
      XBUSSystem source = new XBUSSystem(messageDom.getFirstChild()
          .getNodeName());
      NodeList addresses = messageDom.getElementsByTagName("Address");
      Node address = null;
      String attrName = null;
      String addressValue = null;
      for (int i = 0; i < addresses.getLength(); i++)
      {
        address = addresses.item(i);
        if ((attrName = XMLHelper.getAttribute(address, "name")) == null)
        {
          throw new XException(Constants.LOCATION_INTERN,
              Constants.LAYER_BASE,
              Constants.PACKAGE_BASE_DELETEDMESSAGESTORE, "1");
        }
        if ((addressValue = XMLHelper.getNodeText(address)) == null)
        {
          throw new XException(Constants.LOCATION_INTERN,
              Constants.LAYER_BASE,
              Constants.PACKAGE_BASE_DELETEDMESSAGESTORE, "2");
        }
        source.setAddress(attrName, addressValue);
      }

      NodeList data = messageDom.getElementsByTagName("Data");
      String request = null;
      if (data.getLength() > 0)
      {
        Node messageNode = messageDom.getElementsByTagName("Data")
            .item(0);
        Node dataNode = null;
        if ((dataNode = messageNode.getFirstChild()) != null)
        {
          request = dataNode.getNodeValue();
        }
      }
      if (request == null)
      {
        throw new XException(Constants.LOCATION_INTERN,
            Constants.LAYER_BASE,
            Constants.PACKAGE_BASE_DELETEDMESSAGESTORE, "3");
      }

      /*
       * Resending the message
       */
      taManager = TAManager.getInstance();
      taManager.clearManager();
      taManager.begin();

      Adapter adapter = new Adapter();
      adapter.callApplication(source, request, Constants.TYPE_TEXT);
      Object responseObject = adapter.getResponse();
      if (Constants.RC_OK.equals(adapter.getReturncode()))
      {
        taManager.commit();
        PostProcessor.start(source, responseObject,
            Constants.POSTPROCESSING_PERSYSTEM);
        Trace.info("End resending " + source.getCompleteName());
        Trace.info("-----------------------------");
        retString.append("Message from ").append(
            source.getCompleteName()).append(
            " successfully resent!");

        File messageFile = new File(getDirectory()
            + Constants.FILE_SEPERATOR + filename);
        if (messageFile.delete())
        {
          retString.append("<br>");
          retString.append("File ").append(filename).append(
              " has been deleted.");
        }
        else
        {
          retString.append("<br />");
          retString.append("File ").append(filename).append(
              " cannot be deleted.");
        }
      }
      else
      {
        taManager.rollback();
        Trace.info("Error while resending " + source.getCompleteName());
        Trace.info("-----------------------------");
        retString.append("Error while resending ").append(
            source.getCompleteName()).append("<br>").append(
            "Reason: ").append(adapter.getErrormessage()).append(
            "<br>").append("File ").append(filename).append(
            " has not been deleted.");
      }
    }
    catch (Exception t)
    {
      Trace.info("Error while resending " + filename);
      Trace.info("-----------------------------");
      retString.append("Error while resending ").append(filename).append(
          "<br>").append("Reason: ").append(t.getMessage()).append(
          "<br>").append("File ").append(filename).append(
          " has not been deleted.");
    }
    finally
    {
      if (taManager != null)
      {
        taManager.close();
      }
    }

    return retString.toString();

  }

  private static boolean getEnabled(XBUSSystem system) throws XException
  {
    Configuration config = Configuration.getInstance();
    return config.getValueAsBooleanOptional(Constants.CHAPTER_BASE,
        SECTION, "Enabled")
        || config.getValueAsBooleanOptional(Constants.CHAPTER_SYSTEM,
            system.getName(), "UseDeletedMessageStore");
  }

  /**
   * Reads the name of the directory of the deleted messages out of the
   * configuration.
   *
   * @return the name of the directory containing the deleted messages
   * @throws XException
   *             if any error occures
   */
  public static String getDirectory() throws XException
  {
    return Configuration.getInstance().getValue(Constants.CHAPTER_BASE,
        SECTION, "Directory");
  }

  private void writeFile(String message, XBUSSystem system, String directory)
      throws XException
  {
    String fileName = new StringBuffer(directory).append(
        Constants.FILE_SEPERATOR).append(system.getCompleteName())
        .append(Constants.getDateAsString()).append(".xml").toString();

    BufferedWriter buffOut = null;
    try
    {
      buffOut = new BufferedWriter(new OutputStreamWriter(
          new FileOutputStream(fileName), Constants.getXMLEncoding()));
      buffOut.write(message);
      buffOut.close();
    }
    catch (IOException e)
    {
      throw new XException(Constants.LOCATION_EXTERN,
          Constants.LAYER_BASE,
          Constants.PACKAGE_BASE_DELETEDMESSAGESTORE, "0", e);
    }
    finally
    {
      if (buffOut != null)
      {
        try
        {
          buffOut.close();
        }
        catch (IOException e1)
        {
          throw new XException(Constants.LOCATION_EXTERN,
              Constants.LAYER_BASE,
              Constants.PACKAGE_BASE_DELETEDMESSAGESTORE, "0", e1);
        }
      }
    }
  }

  private String buildXML(Object message, XBUSSystem system)
      throws XException
  {
    Document doc = XMLHelper.getDocumentBuilder("Default", null)
        .newDocument();

    Element root = doc.createElement(XDomSupport.makeTagNameValid(system
        .getName()));
    doc.appendChild(root);

    Hashtable addresses = system.getAddresses();
    if (!addresses.isEmpty())
    {
      Element addressesNode = doc.createElement("Addresses");
      String address = null;
      Element addressNode = null;
      for (Enumeration keys = addresses.keys(); keys.hasMoreElements();)
      {
        address = (String) keys.nextElement();
        addressNode = doc.createElement("Address");
        addressNode.setAttribute("name", address);
        addressNode.appendChild(doc.createTextNode((String) addresses
            .get(address)));
        addressesNode.appendChild(addressNode);
      }
      root.appendChild(addressesNode);
    }

    Element data = doc.createElement("Data");
    data.appendChild(doc.createCDATASection(message.toString()));
    root.appendChild(data);

    return XMLHelper.serializeXML(doc, null);
  }

  /**
   * Reads a file.
   *
   * @param filename
   *            the name of the file including the directory
   * @return the content of the file
   */
  static private String readFile(String filename) throws XException
  {
    StringBuffer retBuffer = new StringBuffer();
    File sourceFile = new File(filename);
    String zeile;
    BufferedReader buffReader = null;

    try
    {
      buffReader = new BufferedReader(new InputStreamReader(
          new FileInputStream(sourceFile)));

      if ((zeile = buffReader.readLine()) != null)
      {
        retBuffer.append(zeile);
      } // if((zeile = buffReader.readLine()) != null)

      while ((zeile = buffReader.readLine()) != null)
      {
        retBuffer.append(Constants.LINE_SEPERATOR);
        retBuffer.append(zeile);
      } // while ((zeile = buffReader.readLine()) != null)
    }
    catch (IOException e)
    {
      throw new XException(Constants.LOCATION_EXTERN,
          Constants.LAYER_BASE,
          Constants.PACKAGE_BASE_DELETEDMESSAGESTORE, "0", e);
    }
    finally
    {
      if (buffReader != null)
      {
        try
        {
          buffReader.close();
        }
        catch (IOException e1)
        {
          // do nothing
        }
      }
    }

    return retBuffer.toString();
  }

}
TOP

Related Classes of net.sf.xbus.base.deletedMessageStore.DeletedMessageStore

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.