Project

General

Profile

Download (9.06 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9

    
10
package eu.etaxonomy.cdm.io.common;
11

    
12
import java.lang.reflect.Method;
13
import java.sql.ResultSet;
14
import java.sql.ResultSetMetaData;
15
import java.sql.SQLException;
16
import java.util.HashMap;
17
import java.util.List;
18
import java.util.Map;
19
import java.util.Set;
20
import java.util.UUID;
21

    
22
import org.apache.commons.lang.StringUtils;
23
import org.apache.log4j.Logger;
24

    
25
import eu.etaxonomy.cdm.common.CdmUtils;
26
import eu.etaxonomy.cdm.model.common.AnnotatableEntity;
27
import eu.etaxonomy.cdm.model.common.Annotation;
28
import eu.etaxonomy.cdm.model.common.Language;
29
import eu.etaxonomy.cdm.model.permission.User;
30
import eu.etaxonomy.cdm.model.reference.ISourceable;
31
import eu.etaxonomy.cdm.persistence.query.MatchMode;
32

    
33
/**
34
 * @author a.mueller
35
 * @since 20.03.2008
36
 */
37
public abstract class DbImportBase<STATE extends DbImportStateBase<CONFIG, STATE>, CONFIG extends DbImportConfiguratorBase<STATE>>
38
            extends CdmImportBase<CONFIG, STATE>
39
            implements ICdmIO<STATE>, IPartitionedIO<STATE> {
40

    
41
    private static final long serialVersionUID = 5539446566014467398L;
42
    private static final Logger logger = Logger.getLogger(DbImportBase.class);
43

    
44
	private String dbTableName ;
45
	private String pluralString;
46

    
47
	public DbImportBase(String tableName, String pluralString) {
48
		super();
49
		this.dbTableName = tableName;
50
		this.pluralString = pluralString;
51
	}
52

    
53
	@Override
54
    protected void doInvoke(STATE state){
55
			//	String strTeamStore = ICdmIO.TEAM_STORE;
56
			CONFIG config = state.getConfig();
57
			Source source = config.getSource();
58
			boolean success = true ;
59

    
60
			logger.info("start make " + getPluralString() + " ...");
61

    
62
			String strIdQuery = getIdQuery(state);
63
			String strRecordQuery = getRecordQuery(config);
64

    
65
			int recordsPerTransaction = config.getRecordsPerTransaction();
66
			try{
67
				ResultSetPartitioner<STATE> partitioner = ResultSetPartitioner.NewInstance(source, strIdQuery, strRecordQuery, recordsPerTransaction);
68
				while (partitioner.nextPartition()){
69
					try {
70
						partitioner.doPartition(this, state);
71
					} catch (Exception e) {
72
						e.printStackTrace();
73
						success = false;
74
					}
75
				}
76
			} catch (SQLException e) {
77
				logger.error("SQLException:" +  e);
78
				state.setUnsuccessfull();
79
			}
80

    
81
			logger.info("end make " + getPluralString() + " ... " + getSuccessString(success));
82
			if (success == false){
83
				state.setUnsuccessfull();
84
			}
85
			return;
86
	}
87

    
88

    
89
	/**
90
	 * @return
91
	 */
92
	protected abstract String getRecordQuery(CONFIG config);
93

    
94
	/**
95
	 * @return
96
	 */
97
	protected abstract String getIdQuery(STATE state);
98

    
99

    
100
	/**
101
	 * @return
102
	 */
103
	protected String getTableName() {
104
		return dbTableName;
105
	}
106

    
107

    
108
	@Override
109
    public String getPluralString() {
110
		return pluralString;
111
	}
112

    
113

    
114
	/**
115
	 * @param state
116
	 * @param sourceable
117
	 * @param id
118
	 * @param namespace
119
	 * @return
120
	 */
121
	protected boolean doId(STATE state, ISourceable sourceable, long id, String namespace) {
122
		return ImportHelper.setOriginalSource(sourceable, state.getTransactionalSourceReference(), id, namespace);
123
	}
124

    
125
	/**
126
	 * @param state
127
	 * @param sourceable
128
	 * @param id
129
	 * @param namespace
130
	 * @return
131
	 */
132
	protected boolean doId(STATE state, ISourceable sourceable, String id, String namespace) {
133
		return ImportHelper.setOriginalSource(sourceable, state.getTransactionalSourceReference(), id, namespace);
134
	}
135

    
136

    
137

    
138
	/**
139
	 * Adds a note to the annotatable entity.
140
	 * Nothing happens if annotatableEntity is <code>null</code> or notes is empty or <code>null</code>.
141
	 * @param annotatableEntity
142
	 * @param notes
143
	 */
144
	protected Annotation doNotes(AnnotatableEntity annotatableEntity, String notes) {
145
		if (isNotBlank(notes) && annotatableEntity != null ){
146
			String notesString = String.valueOf(notes);
147
			if (notesString.length() > 65530 ){
148
				notesString = notesString.substring(0, 65530) + "...";
149
				logger.warn("Notes string is longer than 65530 and was truncated: " + annotatableEntity);
150
			}
151
			Annotation notesAnnotation = Annotation.NewInstance(notesString, Language.DEFAULT());
152
			//notesAnnotation.setAnnotationType(AnnotationType.EDITORIAL());
153
			//notes.setCommentator(bmiConfig.getCommentator());
154
			annotatableEntity.addAnnotation(notesAnnotation);
155
			return notesAnnotation;
156
		}
157
		return null;
158
	}
159

    
160

    
161
	protected User getUser(STATE state, String userString){
162
		if (StringUtils.isBlank(userString)){
163
			return null;
164
		}
165
		userString = userString.trim();
166

    
167
		User user = state.getUser(userString);
168
		if (user == null){
169
			user = getTransformedUser(userString,state);
170
		}
171
		if (user == null){
172
		    user = getExistingUser(state, userString, user);
173
		}
174
		if (user == null){
175
			user = makeNewUser(userString, state);
176
		}
177
		if (user == null){
178
			throw new RuntimeException ("User must not be null");
179
		}
180
		return user;
181
	}
182

    
183
    /**
184
     * @param state
185
     * @param userString
186
     * @param user
187
     * @return
188
     */
189
    protected User getExistingUser(STATE state, String userString, User user) {
190
        List<User> list = getUserService().listByUsername(userString, MatchMode.EXACT, null, null, null, null, null);
191
        if (!list.isEmpty()){
192
            if (list.size()>1){
193
                logger.warn("More than 1 user with name " + userString + " exists");
194
            }
195
            user = list.get(0);
196
            state.putUser(userString, user);
197
        }
198
        return user;
199
    }
200

    
201
	private User getTransformedUser(String userString, STATE state){
202
		Method method = state.getConfig().getUserTransformationMethod();
203
		if (method == null){
204
			return null;
205
		}
206
		try {
207
			userString = (String)state.getConfig().getUserTransformationMethod().invoke(null, userString);
208
		} catch (Exception e) {
209
			logger.warn("Error when trying to transform userString " +  userString + ". No transformation done.");
210
		}
211
		User user = state.getUser(userString);
212
		return user;
213
	}
214

    
215
	private User makeNewUser(String userString, STATE state){
216
		String pwd = getRandomPassword();
217
		User user = User.NewInstance(userString, pwd);
218
		state.putUser(userString, user);
219
		getUserService().save(user);
220
		logger.info("Added new user: " + userString);
221
		return user;
222
	}
223

    
224
	private String getRandomPassword(){
225
		String result = UUID.randomUUID().toString();
226
		return result;
227
	}
228

    
229
	protected boolean resultSetHasColumn(ResultSet rs, String columnName){
230
		try {
231
			ResultSetMetaData metaData = rs.getMetaData();
232
			for (int i = 0; i < metaData.getColumnCount(); i++){
233
				if (metaData.getColumnName(i + 1).equalsIgnoreCase(columnName)){
234
					return true;
235
				}
236
			}
237
			return false;
238
		} catch (SQLException e) {
239
            logger.warn("Exception in resultSetHasColumn");
240
            return false;
241
		}
242
	}
243

    
244

    
245
	protected boolean checkSqlServerColumnExists(Source source, String tableName, String columnName){
246
		String strQuery = "SELECT  Count(t.id) as n " +
247
				" FROM sysobjects AS t " +
248
				" INNER JOIN syscolumns AS c ON t.id = c.id " +
249
				" WHERE (t.xtype = 'U') AND " +
250
				" (t.name = '" + tableName + "') AND " +
251
				" (c.name = '" + columnName + "')";
252
		ResultSet rs = source.getResultSet(strQuery) ;
253
		int n;
254
		try {
255
			rs.next();
256
			n = rs.getInt("n");
257
			return n>0;
258
		} catch (SQLException e) {
259
			e.printStackTrace();
260
			return false;
261
		}
262

    
263
	}
264

    
265

    
266

    
267
	/**
268
	 * Returns a map that holds all values of a ResultSet. This is needed if a value needs to
269
	 * be accessed twice
270
	 * @param rs
271
	 * @return
272
	 * @throws SQLException
273
	 */
274
	protected Map<String, Object> getValueMap(ResultSet rs) throws SQLException{
275
		try{
276
			Map<String, Object> valueMap = new HashMap<String, Object>();
277
			int colCount = rs.getMetaData().getColumnCount();
278
			for (int c = 0; c < colCount ; c++){
279
				Object value = rs.getObject(c+1);
280
				String label = rs.getMetaData().getColumnLabel(c+1).toLowerCase();
281
				if (value != null && ! CdmUtils.Nz(value.toString()).trim().equals("")){
282
					valueMap.put(label, value);
283
				}
284
			}
285
			return valueMap;
286
		}catch(SQLException e){
287
			throw e;
288
		}
289
	}
290

    
291
	/**
292
	 * Reads a foreign key field from the result set and adds its value to the idSet.
293
	 * @param rs
294
	 * @param teamIdSet
295
	 * @throws SQLException
296
	 */
297
	protected void handleForeignKey(ResultSet rs, Set<String> idSet, String attributeName)
298
			throws SQLException {
299
		Object idObj = rs.getObject(attributeName);
300
		if (idObj != null){
301
			String id  = String.valueOf(idObj);
302
			idSet.add(id);
303
		}
304
	}
305

    
306
	/**
307
	 * Returns true if i is a multiple of recordsPerTransaction
308
	 * @param i
309
	 * @param recordsPerTransaction
310
	 * @return
311
	 */
312
	protected boolean loopNeedsHandling(int i, int recordsPerLoop) {
313
		startTransaction();
314
		return (i % recordsPerLoop) == 0;
315
		}
316

    
317
	protected void doLogPerLoop(int count, int recordsPerLog, String pluralString){
318
		if ((count % recordsPerLog ) == 0 && count!= 0 ){ logger.info(pluralString + " handled: " + (count));}
319
	}
320

    
321

    
322

    
323

    
324

    
325

    
326
}
(13-13/65)