1 package javaclients.simplereader;
  2 
  3 import java.io.File;
  4 import java.io.FileOutputStream;
  5 import java.io.IOException;
  6 import java.util.logging.Logger;
  7 
  8 import org.xmlBlaster.client.key.UpdateKey;
  9 import org.xmlBlaster.client.qos.UpdateQos;
 10 import org.xmlBlaster.util.EncodableData;
 11 import org.xmlBlaster.util.Global;
 12 import org.xmlBlaster.util.XmlBlasterException;
 13 import org.xmlBlaster.util.def.Constants;
 14 import org.xmlBlaster.util.def.ErrorCode;
 15 
 16 public class FileDumper {
 17    private static String ME = "FileDumper";
 18    private static Logger log = Logger.getLogger(FileDumper.class.getName());
 19    private Global glob;
 20    private String directoryName;
 21    /** forceBase64==false: ASCII dump for content if possible (XML embedable) */
 22    private boolean forceBase64 = false;
 23    
 24    public FileDumper(Global glob) throws XmlBlasterException {
 25       this.glob = glob;
 26       String defaultPath = System.getProperty("user.home") + System.getProperty("file.separator") + "FileDumper";
 27       this.directoryName = this.glob.getProperty().get("directoryName", defaultPath);
 28       initDirectory(null, "directoryName", this.directoryName);
 29       
 30       log.info("Dumping occurrences of topic '" + Constants.OID_DEAD_LETTER + "' to directory " + this.directoryName);
 31       this.forceBase64 = this.glob.getProperty().get("forceBase64", this.forceBase64);
 32    }
 33    
 34    /**
 35     * Dump dead message to hard disk. 
 36     * The file name is the receive timestamp of the message, for example
 37     * <tt>/home/xmlblast/tmp/2004-10-23_18_52_39_87.xml</tt>
 38     */                     
 39    public void dumpMessage(UpdateKey updateKey, byte[] content, UpdateQos updateQos) {
 40       try {
 41          String fn = updateQos.getRcvTime();
 42          String key = updateKey.toXml();
 43          String qos = updateQos.toXml();
 44          String oid = updateKey.getOid();
 45 
 46          fn = Global.getStrippedString(fn); // Strip chars like ":" so that fn is usable as a file name
 47          fn = fn + ".xml";
 48 
 49          initDirectory(null, "directoryName", this.directoryName); // In case somebody has removed it
 50          File to_file = new File(this.directoryName, fn);
 51 
 52          FileOutputStream to = new FileOutputStream(to_file);
 53          log.info("Dumping dead message to  '" + to_file.toString() + "'" );
 54 
 55          StringBuffer sb = new StringBuffer(qos.length() + key.length() + 1024);
 56          //sb.append("<?xml version='1.0' encoding='iso-8859-1'?>");
 57          //sb.append("<?xml version='1.0' encoding='utf-8' ?>");
 58 
 59          sb.append("\n  <!-- Dump of topic '").append(oid).append("' -->");
 60          sb.append("\n<xmlBlaster>");
 61          sb.append("\n <publish>");
 62          to.write(sb.toString().getBytes());
 63          sb.setLength(0);
 64 
 65          {
 66             sb.append(qos);
 67             sb.append(key);
 68             to.write(sb.toString().getBytes());
 69             sb.setLength(0);
 70 
 71             // TODO: Potential charset problem when not Base64 protected
 72             boolean doEncode = forceBase64;
 73             if (!forceBase64) {
 74                int len = content.length - 2;
 75                for (int i=0; i<len; i++) {
 76                   if (content[i] == (byte)']' && content[i+1] == (byte)']' && content[i+2] == (byte)'>') {
 77                      doEncode = true;
 78                      break;
 79                   }
 80                }
 81             }
 82 
 83             if (doEncode) {
 84                EncodableData data = new EncodableData("content", null, Constants.TYPE_BLOB, Constants.ENCODING_BASE64);
 85                data.setValue(content);
 86                data.setSize(content.length);
 87                to.write(data.toXml(" ").getBytes());
 88             }
 89             else {
 90                EncodableData data = new EncodableData("content", null, null, null);
 91                //String charSet = "UTF-8"; // "ISO-8859-1", "US-ASCII"
 92                //data.setValue(new String(content, charSet), null);
 93                data.setValueRaw(new String(content));
 94                data.forceCdata(true);
 95                data.setSize(content.length);
 96                to.write(data.toXml(" ").getBytes());
 97             }
 98          }
 99          {
100             //MsgUnitRaw msg = new MsgUnitRaw(key, content, qos);
101             //msg.toXml(" ", to);
102          }
103 
104          sb.append("\n </publish>");
105          sb.append("\n</xmlBlaster>");
106          to.write(sb.toString().getBytes());
107          to.close();
108       }
109       catch (Throwable e) {
110          log.severe("Dumping of message failed: " + updateQos.toXml() + updateKey.toXml() + new String(content));
111       }
112    }
113 
114    /**
115     * Returns the specified directory or null or if needed it will create one
116     * @param parent
117     * @param propName For logging only
118     * @param dirName
119     * @return
120     * @throws XmlBlasterException
121     */
122    private File initDirectory(File parent, String propName, String dirName) throws XmlBlasterException {
123       File dir = null;
124       if (dirName != null) {
125          File tmp = new File(dirName);
126          if (tmp.isAbsolute() || parent == null) {
127             dir = new File(dirName);
128          }
129          else {
130             dir = new File(parent, dirName);
131          }
132          if (!dir.exists()) {
133             String absDirName  = null; 
134             try {
135                absDirName = dir.getCanonicalPath();
136             }
137             catch (IOException ex) {
138                absDirName = dir.getAbsolutePath();
139             }
140             log.info("Constructor: directory '" + absDirName + "' does not yet exist. I will create it");
141             boolean ret = dir.mkdir();
142             if (!ret)
143                throw new XmlBlasterException(this.glob, ErrorCode.RESOURCE_FILEIO, ME, "could not create directory '" + absDirName + "'");
144          }
145          if (!dir.isDirectory()) {
146             throw new XmlBlasterException(this.glob, ErrorCode.RESOURCE_FILEIO, ME, "'" + dir.getAbsolutePath() + "' is not a directory");
147          }
148          if (!dir.canRead())
149             throw new XmlBlasterException(this.glob, ErrorCode.RESOURCE_FILEIO, ME + ".constructor", "no rights to read from the directory '" + dir.getAbsolutePath() + "'");
150          if (!dir.canWrite())
151             throw new XmlBlasterException(this.glob, ErrorCode.RESOURCE_FILEIO, ME + ".constructor", "no rights to write to the directory '" + dir.getAbsolutePath() + "'");
152       }
153       else {
154          log.info("Constructor: the '" + propName + "' property is not set. Instead of moving concerned entries they will be deleted");
155       }
156       return dir;
157    }
158 }


syntax highlighted by Code2HTML, v. 0.9.1