View Javadoc

1   /*
2    * Copyright 2008-2010 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package de.smartics.maven.issues.cache;
18  
19  import java.io.File;
20  import java.util.HashMap;
21  import java.util.Map;
22  import java.util.WeakHashMap;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.eclipse.mylyn.tasks.core.data.TaskData;
27  
28  /**
29   * Local cache for task data retrieved from the remote Task repository. The
30   * cache is useful for multi project reports where the same tasks will be
31   * retrieved for each sub project. Instead of connecting to the remote
32   * repository the report renderer will try to read the local stored information.
33   * This information is either cached in-memory or on a secondary storage medium
34   * (defaults to an XML file on the file system).
35   *
36   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
37   * @version $Revision:591 $
38   */
39  public class TaskDataCache
40  {
41    // ********************************* Fields *********************************
42  
43    // --- constants ------------------------------------------------------------
44  
45    /**
46     * Reference to the logger for this class.
47     */
48    private final Log log = LogFactory.getLog(TaskDataCache.class);
49  
50    // --- members --------------------------------------------------------------
51  
52    /**
53     * The in-memory cache of the {@link TaskData tasks} fetched from the remote
54     * repository.
55     * <p>
56     * The key is the unique identifier of the task, the value the task
57     * information.
58     * </p>
59     */
60    private final Map<String, TaskData> cache;
61  
62    /**
63     * The storage handler to make task data instances persistent. The task store
64     * has a value of <code>null</code> if no persistent store is used (i.e.
65     * <code>usePersistentStore</code> is <code>false</code>.
66     */
67    private final TaskDataStore taskStore;
68  
69    /**
70     * The flag to indicate whether to use a persistent store (<code>true</code>)
71     * or not (<code>false</code>). If the persistent store is used each task is
72     * stored to the specified path.
73     */
74    private final boolean usePersistentStore;
75  
76    // ****************************** Initializer *******************************
77  
78    // ****************************** Constructors ******************************
79  
80    /**
81     * Convenience constructor to create a cache where all tasks are stored
82     * in-memory.
83     */
84    public TaskDataCache()
85    {
86      this((TaskDataStore) null);
87    }
88  
89    /**
90     * Convenience constructor to create a file based task data store to write to
91     * the given location.
92     *
93     * @param persistentStoreDirectory the reference to the directory to store the
94     *          individual task files. If this value is <code>null</code> the
95     *          tasks will only be stored in-memory with a strong hash map. If
96     *          not-<code>null</code>, a weak hash map is used and tasks that are
97     *          removed from memory are written to this location.
98     */
99    public TaskDataCache(final File persistentStoreDirectory)
100   {
101     this(persistentStoreDirectory != null ? new XmlTaskDataStore(
102         persistentStoreDirectory) : null);
103   }
104 
105   /**
106    * Default constructor.
107    *
108    * @param taskStore the reference to the task store to store the individual
109    *          task data. If this value is <code>null</code> the tasks will only
110    *          be stored in-memory with a strong hash map. If not-
111    *          <code>null</code>, a weak hash map is used and tasks that are
112    *          removed from memory are written to this store.
113    */
114   public TaskDataCache(final TaskDataStore taskStore)
115   {
116     this.usePersistentStore = (taskStore != null);
117     if (usePersistentStore)
118     {
119       this.taskStore = taskStore;
120       cache = new WeakHashMap<String, TaskData>();
121     }
122     else
123     {
124       this.taskStore = null;
125       cache = new HashMap<String, TaskData>();
126     }
127   }
128 
129   // ****************************** Inner Classes *****************************
130 
131   // ********************************* Methods ********************************
132 
133   // --- init -----------------------------------------------------------------
134 
135   // --- get&set --------------------------------------------------------------
136 
137   // --- business -------------------------------------------------------------
138 
139   /**
140    * Returns the task uniquely references by the given identifier.
141    *
142    * @param id the unique identifier of the task.
143    * @return the requested task.
144    */
145   public TaskData getTask(final String id)
146   {
147     TaskData task = cache.get(id);
148     if (task == null && usePersistentStore)
149     {
150       try
151       {
152         task = taskStore.load(id);
153         cache.put(id, task);
154       }
155       catch (final PersistenceException e)
156       {
157         if (log.isDebugEnabled())
158         {
159           log.debug("Cannot load task '" + id + "' from persistency layer.", e);
160         }
161       }
162     }
163     return task;
164   }
165 
166   /**
167    * Adds the task to the cache. The task can be retrieved by
168    * {@link #getTask(String)} by passing in the identifier of the task (
169    * {@link TaskData#getTaskId()}).
170    *
171    * @param task the task information to cache.
172    */
173   public void addTask(final TaskData task)
174   {
175     final String id = task.getTaskId();
176     cache.put(id, task);
177     if (usePersistentStore)
178     {
179       try
180       {
181         taskStore.persist(task);
182       }
183       catch (final PersistenceException e)
184       {
185         if (log.isDebugEnabled())
186         {
187           log.debug("Cannot persist task '" + id + "'.", e);
188         }
189       }
190     }
191   }
192 
193   // --- object basics --------------------------------------------------------
194 
195 }