1 | /** |
2 | * |
3 | */ |
4 | package de.uka.ipd.sdq.sensorframework.dao.file; |
5 | |
6 | import org.eclipse.core.runtime.IStatus; |
7 | |
8 | import de.uka.ipd.sdq.sensorframework.SensorFrameworkPluginActivator; |
9 | import de.uka.ipd.sdq.sensorframework.entities.dao.IDAOFactory; |
10 | import de.uka.ipd.sdq.sensorframework.entities.dao.IExperimentDAO; |
11 | import de.uka.ipd.sdq.sensorframework.entities.dao.IExperimentRunDAO; |
12 | import de.uka.ipd.sdq.sensorframework.entities.dao.IMeasurementDAO; |
13 | import de.uka.ipd.sdq.sensorframework.entities.dao.ISensorDAO; |
14 | import de.uka.ipd.sdq.sensorframework.entities.dao.IStateDAO; |
15 | |
16 | /** |
17 | * @author Ihssane El-Oudghiri |
18 | * |
19 | * A Data Access Object (DAO) is used to abstract and encapsulate all access to |
20 | * the data source. The DAO manages the connection with the data source to |
21 | * obtain and store data. The DAO pattern can be made highly flexible by |
22 | * adopting the Factory Method pattern. This class represents the DAOFactory and |
23 | * provides methods to create DAOs. The used data sources are files. |
24 | * |
25 | */ |
26 | public class FileDAOFactory implements IDAOFactory { |
27 | |
28 | /** |
29 | * Constants for the filenames used to store the entities |
30 | */ |
31 | public static final String EXP_FILE_NAME_PREFIX = "experiment"; |
32 | public static final String EXPRUN_FILE_NAME_PREFIX = "exprun"; |
33 | public static final String SENSOR_FILE_NAME_PREFIX = "sensor"; |
34 | public static final String STATE_FILE_NAME_PREFIX = "state"; |
35 | public static final String IDGEN_FILE_NAME_PREFIX = "id_generator"; |
36 | public static final String SUFFIX = ".ser"; |
37 | |
38 | /** |
39 | * DAOs for single entity classes |
40 | */ |
41 | private IExperimentDAO experimentDAO; |
42 | private IExperimentRunDAO experimentRunDAO; |
43 | private ISensorDAO sensorDAO; |
44 | private IStateDAO stateDAO; |
45 | |
46 | private IDGenerator idGen; |
47 | private FileManager fileManager; |
48 | private long factoryID; |
49 | |
50 | /** Constructor for a FileDAOFactory with automatically determined ID |
51 | * @param rootDirectory The directory in which to store the data |
52 | */ |
53 | public FileDAOFactory(String rootDirectory) { |
54 | this(IDAOFactory.ID_NOT_SET,rootDirectory); |
55 | } |
56 | |
57 | /** Constructor for a FileDAOFactory with given ID. Used by Sensorframework startup code to reinitialise the |
58 | * SensorframworkDataSet |
59 | * @param rootDirectory The directory in which to store the data |
60 | */ |
61 | public FileDAOFactory(long id, String rootDirectory) { |
62 | this.factoryID = id; |
63 | fileManager = new FileManager(rootDirectory, this); |
64 | idGen = createIdGenerator(); |
65 | } |
66 | |
67 | /** Create or load the ID generator class |
68 | * @return ID generator used to generate IDs of the elements |
69 | */ |
70 | private IDGenerator createIdGenerator() { |
71 | IDGenerator result = (IDGenerator) fileManager.deserializeFromFile(FileDAOFactory.IDGEN_FILE_NAME_PREFIX); |
72 | if (result == null){ |
73 | result = new IDGenerator(); |
74 | } |
75 | return result; |
76 | } |
77 | |
78 | public String getRootDirectory() { |
79 | return fileManager.getRootDirectory(); |
80 | } |
81 | |
82 | /* (non-Javadoc) |
83 | * @see de.uka.ipd.sdq.sensorfactory.entities.dao.IDAOFactory#createExperimentDAO() |
84 | */ |
85 | public IExperimentDAO createExperimentDAO() { |
86 | if (this.experimentDAO == null) |
87 | this.experimentDAO = new FileExperimentDAO(this, idGen); |
88 | return this.experimentDAO; |
89 | } |
90 | |
91 | /* (non-Javadoc) |
92 | * @see de.uka.ipd.sdq.sensorfactory.entities.dao.IDAOFactory#createExperimentRunDAO() |
93 | */ |
94 | public IExperimentRunDAO createExperimentRunDAO() { |
95 | if (this.experimentRunDAO == null) |
96 | this.experimentRunDAO = new FileExperimentRunDAO(this, idGen); |
97 | return this.experimentRunDAO; |
98 | } |
99 | |
100 | /* (non-Javadoc) |
101 | * @see de.uka.ipd.sdq.sensorfactory.entities.dao.IDAOFactory#createMeasurementDAO() |
102 | */ |
103 | public IMeasurementDAO createMeasurementDAO() { |
104 | throw new UnsupportedOperationException(); |
105 | } |
106 | |
107 | /* (non-Javadoc) |
108 | * @see de.uka.ipd.sdq.sensorfactory.entities.dao.IDAOFactory#createSensorDAO() |
109 | */ |
110 | public ISensorDAO createSensorDAO() { |
111 | if (this.sensorDAO == null) |
112 | this.sensorDAO = new FileSensorDAO(this, idGen); |
113 | return this.sensorDAO; |
114 | } |
115 | |
116 | /* (non-Javadoc) |
117 | * @see de.uka.ipd.sdq.sensorfactory.entities.dao.IDAOFactory#createStateDAO() |
118 | */ |
119 | public IStateDAO createStateDAO() { |
120 | if (this.stateDAO == null) |
121 | this.stateDAO = new FileStateDAO(this, idGen); |
122 | return this.stateDAO; |
123 | } |
124 | |
125 | public void finalizeAndClose() { |
126 | fileManager.closeAllLists(); |
127 | fileManager.serializeToFile(FileDAOFactory.IDGEN_FILE_NAME_PREFIX,idGen); |
128 | |
129 | if (this.experimentDAO != null) |
130 | ((FileExperimentDAO)this.experimentDAO).dispose(); |
131 | if (this.sensorDAO != null) |
132 | ((FileSensorDAO)this.sensorDAO).dispose(); |
133 | if (this.stateDAO != null) |
134 | ((FileStateDAO)this.stateDAO).dispose(); |
135 | if (this.experimentRunDAO != null) |
136 | ((FileExperimentRunDAO)this.experimentRunDAO).dispose(); |
137 | } |
138 | |
139 | public FileManager getFileManager() { |
140 | return fileManager; |
141 | } |
142 | |
143 | public String getDescription() { |
144 | return fileManager.getRootDirectory(); |
145 | } |
146 | |
147 | public long getID() { |
148 | return factoryID; |
149 | } |
150 | |
151 | public String getName() { |
152 | return "File Datasource"; |
153 | } |
154 | |
155 | public String getPersistendInfo() { |
156 | return fileManager.getRootDirectory(); |
157 | } |
158 | |
159 | public void setID(long i) { |
160 | factoryID = i; |
161 | } |
162 | |
163 | // This code is only a temporary solution to the reload problem. It |
164 | // can cause problems on concurrent access. |
165 | public void reload() { |
166 | String oldFilename = ""; |
167 | boolean failed = false; |
168 | |
169 | try { |
170 | oldFilename = fileManager.getRootDirectory(); |
171 | fileManager.closeAllLists(); |
172 | } |
173 | catch (Exception ex) { |
174 | SensorFrameworkPluginActivator.log(IStatus.ERROR, "Closing the open File Provider failed", ex); |
175 | failed = true; |
176 | } |
177 | |
178 | /* Reset all DAOs */ |
179 | experimentDAO = null; |
180 | experimentRunDAO = null; |
181 | sensorDAO = null; |
182 | stateDAO = null; |
183 | |
184 | try { |
185 | // StB: This is not safe for concurrent access, but an initial simple implementation |
186 | fileManager = new FileManager(oldFilename, this); |
187 | idGen = createIdGenerator(); |
188 | } catch (Exception ex) { |
189 | SensorFrameworkPluginActivator.log(IStatus.ERROR, "Closing the open File Provider failed", ex); |
190 | failed = true; |
191 | } |
192 | if (failed) |
193 | throw new RuntimeException("Reloading the file provider with ID "+this.getID()+" failed. Consult the Error Log for Details."); |
194 | } |
195 | |
196 | public void store() { |
197 | fileManager.serializeToFile(FileDAOFactory.IDGEN_FILE_NAME_PREFIX,idGen); |
198 | if (this.experimentDAO != null) |
199 | ((FileExperimentDAO)this.experimentDAO).storeAll(); |
200 | if (this.sensorDAO != null) |
201 | ((FileSensorDAO)this.sensorDAO).storeAll(); |
202 | if (this.stateDAO != null) |
203 | ((FileStateDAO)this.stateDAO).storeAll(); |
204 | if (this.experimentRunDAO != null) |
205 | ((FileExperimentRunDAO)this.experimentRunDAO).storeAll(); |
206 | |
207 | fileManager.flush(); |
208 | } |
209 | |
210 | } |