View Javadoc

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