View Javadoc

1   /*
2    * #%L
3    * Bitrepository Audit Trail Service
4    * %%
5    * Copyright (C) 2010 - 2012 The State and University Library, The Royal Library and The State Archives, Denmark
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as 
9    * published by the Free Software Foundation, either version 2.1 of the 
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public 
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-2.1.html>.
20   * #L%
21   */
22  package org.bitrepository.alarm.store;
23  
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import org.bitrepository.bitrepositoryelements.Alarm;
28  import org.bitrepository.common.ArgumentValidator;
29  import org.bitrepository.common.utils.CalendarUtils;
30  import org.bitrepository.service.database.DBConnector;
31  import org.bitrepository.service.database.DatabaseUtils;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  import static org.bitrepository.alarm.store.AlarmDatabaseConstants.ALARM_CODE;
36  import static org.bitrepository.alarm.store.AlarmDatabaseConstants.ALARM_COLLECTION_ID;
37  import static org.bitrepository.alarm.store.AlarmDatabaseConstants.ALARM_COMPONENT_GUID;
38  import static org.bitrepository.alarm.store.AlarmDatabaseConstants.ALARM_DATE;
39  import static org.bitrepository.alarm.store.AlarmDatabaseConstants.ALARM_FILE_ID;
40  import static org.bitrepository.alarm.store.AlarmDatabaseConstants.ALARM_TABLE;
41  import static org.bitrepository.alarm.store.AlarmDatabaseConstants.ALARM_TEXT;
42  import static org.bitrepository.alarm.store.AlarmDatabaseConstants.COMPONENT_GUID;
43  import static org.bitrepository.alarm.store.AlarmDatabaseConstants.COMPONENT_ID;
44  import static org.bitrepository.alarm.store.AlarmDatabaseConstants.COMPONENT_TABLE;
45  
46  /**
47   * Handles the ingest of the Alarm messages into the database.
48   * 
49   * Ingested in the following order:
50   * ALARM_COMPONENT_GUID
51   * ALARM_CODE
52   * ALARM_TEXT
53   * ALARM_DATE
54   * ALARM_FILE_ID
55   * ALARM_COLLECTION_ID
56   */
57  public class AlarmDatabaseIngestor {
58      /** The log.*/
59      private Logger log = LoggerFactory.getLogger(getClass());
60      /** The connector to the database, where the alarms should be ingested.*/
61      private final DBConnector dbConnector;
62      
63      /**
64       * @param dbConnector The connector to the database, where the audit trails are to be ingested.
65       */
66      public AlarmDatabaseIngestor(DBConnector dbConnector) {
67          ArgumentValidator.checkNotNull(dbConnector, "DBConnector dbConnector");
68          
69          this.dbConnector = dbConnector;
70      }
71      
72      /**
73       * Ingest the given alarm into the database.
74       * @param alarm The alarm to the ingested into the alarm database.
75       */
76      public void ingestAlarm(Alarm alarm) {
77          ArgumentValidator.checkNotNull(alarm, "Alarm alarm");
78          
79          String sqlInsert = "INSERT INTO " + ALARM_TABLE + " ( " + createIngestElementString(alarm) + " )"
80                  + " VALUES ( " + createIngestArgumentString(alarm) + " )";
81          DatabaseUtils.executeStatement(dbConnector, sqlInsert, extractArgumentsFromEvent(alarm));
82      }
83  
84      /**
85       * @param alarm The alarm to ingest into the database.
86       * @return Creates the set of elements to be ingested into the database.
87       */
88      private String createIngestElementString(Alarm alarm) {
89          StringBuilder res = new StringBuilder();
90          
91          addElement(res, alarm.getAlarmRaiser(), ALARM_COMPONENT_GUID);
92          addElement(res, alarm.getAlarmCode(), ALARM_CODE);
93          addElement(res, alarm.getAlarmText(), ALARM_TEXT);
94          addElement(res, alarm.getOrigDateTime(), ALARM_DATE);
95          addElement(res, alarm.getFileID(), ALARM_FILE_ID);
96          addElement(res, alarm.getCollectionID(), ALARM_COLLECTION_ID);
97          
98          return res.toString();
99      }
100     
101     /**
102      * Adds the field for a given element to the string builder if the element is not null.
103      * @param res The StringBuilder where the restrictions are combined.
104      * @param element The element to be ingested. Is validated whether it is null.
105      * @param name The name of the field in the database corresponding to the element. 
106      */
107     private void addElement(StringBuilder res, Object element, String name) {
108         if(element == null) {
109             return;
110         }
111         
112         if(res.length() == 0) {
113             res.append(" ");
114         } else {
115             res.append(" , ");
116         }
117         
118         res.append(name);
119     }
120     
121     /**
122      * @param alarm The alarm to ingest into the database.
123      * @return The string for the arguments for the elements of the event to be ingested into the database.
124      */
125     private String createIngestArgumentString(Alarm alarm) {
126         StringBuilder res = new StringBuilder();
127         
128         addArgument(res, alarm.getAlarmRaiser());
129         addArgument(res, alarm.getAlarmCode());
130         addArgument(res, alarm.getAlarmText());
131         addArgument(res, alarm.getOrigDateTime());
132         addArgument(res, alarm.getFileID());
133         addArgument(res, alarm.getCollectionID());
134         
135         return res.toString();
136     }
137     
138     /**
139      * Adds a question mark for a given element to the string builder if the element is not null.
140      * @param res The StringBuilder where the restrictions are combined.
141      * @param element The element to be ingested. Is validated whether it is null.
142      */
143     private void addArgument(StringBuilder res, Object element) {
144         if(element == null) {
145             return;
146         }
147         
148         if(res.length() == 0) {
149             res.append(" ? ");
150         } else {
151             res.append(", ? ");
152         }
153     }
154 
155     
156     /**
157      * @return The list of elements in the model which are not null.
158      */
159     private Object[] extractArgumentsFromEvent(Alarm alarm) {
160         List<Object> res = new ArrayList<Object>();
161 
162         if(alarm.getAlarmRaiser() != null) {
163             Long componentGuid = retrieveComponentGuid(alarm.getAlarmRaiser());
164             res.add(componentGuid);
165         }
166         
167         if(alarm.getAlarmCode() != null) {
168             res.add(alarm.getAlarmCode().toString());
169         }
170         
171         if(alarm.getAlarmText() != null) {
172             res.add(alarm.getAlarmText());
173         }
174         
175         if(alarm.getOrigDateTime() != null) {
176             res.add(CalendarUtils.convertFromXMLGregorianCalendar(alarm.getOrigDateTime()));
177         }
178         
179         if(alarm.getFileID() != null) {
180             res.add(alarm.getFileID());
181         }
182         
183         if(alarm.getCollectionID() != null) {
184             res.add(alarm.getCollectionID());
185         }
186         
187         return res.toArray();
188     }
189     
190     /**
191      * Retrieve the guid for a given component. If the component does not exist within the component table, 
192      * then it is created.
193      * 
194      * @param componentId The name of the alarm producing component.
195      * @return The guid of the component with the given name.
196      */
197     private synchronized long retrieveComponentGuid(String componentId) {
198         String sqlRetrieve = "SELECT " + COMPONENT_GUID + " FROM " + COMPONENT_TABLE 
199                 + " WHERE " + COMPONENT_ID + " = ?";
200         
201         Long guid = DatabaseUtils.selectLongValue(dbConnector, sqlRetrieve, componentId);
202         
203         if(guid == null) {
204             log.debug("Inserting component '" + componentId + "' into the component table.");
205             String sqlInsert = "INSERT INTO " + COMPONENT_TABLE + " ( " + COMPONENT_ID + " ) VALUES ( ? )";
206             DatabaseUtils.executeStatement(dbConnector, sqlInsert, componentId);
207             
208             guid = DatabaseUtils.selectLongValue(dbConnector, sqlRetrieve, componentId);
209         }
210         
211         return guid;
212     }
213 }