View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.util.store;
8   
9   import org.mule.api.lifecycle.InitialisationException;
10  import org.mule.api.store.ObjectStoreException;
11  import org.mule.util.FileUtils;
12  import org.mule.util.IOUtils;
13  import org.mule.util.StringUtils;
14  
15  import java.io.File;
16  import java.io.FileInputStream;
17  import java.io.FileOutputStream;
18  import java.io.IOException;
19  import java.io.Serializable;
20  import java.util.Iterator;
21  import java.util.Map;
22  import java.util.Properties;
23  
24  /**
25   * A Simple object store that stores String objects by key to a text file. This store
26   * is only suitable for storing simple key value pair strings. This store is backed
27   * by an in-memory store and supports the ability to expire and apply TTL to objects
28   * in the store.
29   */
30  public class TextFileObjectStore extends InMemoryObjectStore<String>
31  {
32      protected File fileStore;
33      protected String directory;
34      protected String encoding;
35  
36      private FileOutputStream output;
37  
38      @Override
39      public void initialise() throws InitialisationException
40      {
41          super.initialise();
42          if (encoding == null)
43          {
44              encoding = context.getConfiguration().getDefaultEncoding();
45          }
46  
47          if (directory == null)
48          {
49              directory = context.getConfiguration().getWorkingDirectory() + "/objectstore";
50          }
51  
52          try
53          {
54              File dir = FileUtils.openDirectory(directory);
55              fileStore = new File(dir, name + ".dat");
56              if (fileStore.exists())
57              {
58                  loadFromStore();
59              }
60          }
61          catch (Exception e)
62          {
63              throw new InitialisationException(e, this);
64          }
65      }
66  
67      protected synchronized void loadFromStore() throws Exception
68      {
69          Properties props = new Properties();
70          props.load(new FileInputStream(fileStore));
71  
72          for (Map.Entry<Object, Object> entry : props.entrySet())
73          {
74              super.store(entry.getKey().toString(), entry.getValue().toString());
75          }
76      }
77  
78      @Override
79      public void store(Serializable id, String item) throws ObjectStoreException
80      {
81          super.store(id, item);
82  
83          try
84          {
85              if (output == null)
86              {
87                  output = new FileOutputStream(fileStore, true);
88              }
89  
90              StringBuffer buf = new StringBuffer();
91              buf.append(id).append("=").append(item.toString()).append(IOUtils.LINE_SEPARATOR);
92              output.write(buf.toString().getBytes());
93          }
94          catch (IOException iox)
95          {
96              throw new ObjectStoreException(iox);
97          }
98      }
99  
100     public String getDirectory()
101     {
102         return directory;
103     }
104 
105     public void setDirectory(String directory)
106     {
107         this.directory = directory;
108     }
109 
110     public String getEncoding()
111     {
112         return encoding;
113     }
114 
115     public void setEncoding(String encoding)
116     {
117         this.encoding = encoding;
118     }
119 
120     @Override
121     public synchronized void dispose()
122     {
123         Properties props = new Properties();
124 
125         for (Iterator<?> iterator = super.store.values().iterator(); iterator.hasNext();)
126         {
127             StoredObject<?> storedObject = (StoredObject<?>) iterator.next();
128             props.put(storedObject.getId(), storedObject.getItem());
129         }
130 
131         if (output == null)
132         {
133             try
134             {
135                 output = new FileOutputStream(fileStore, false);
136                 props.store(output, StringUtils.EMPTY);
137                 IOUtils.closeQuietly(output);
138             }
139             catch (IOException e)
140             {
141                 logger.error(e.getMessage(), e);
142             }
143         }
144         else
145         {
146             IOUtils.closeQuietly(output);
147         }
148 
149         super.dispose();
150     }
151 }