1
15
16 package gate.persist;
17
18 import java.io.*;
19 import java.net.URL;
20 import java.sql.*;
21 import java.util.*;
22
23 import junit.framework.Assert;
24 import oracle.jdbc.driver.OracleCallableStatement;
25 import oracle.sql.*;
26
27 import gate.*;
28 import gate.corpora.DatabaseCorpusImpl;
29 import gate.corpora.DatabaseDocumentImpl;
30 import gate.security.SecurityException;
31 import gate.security.SecurityInfo;
32 import gate.util.*;
33
34 public class OracleDataStore extends JDBCDataStore {
35
36
37 private static final String DS_COMMENT = "GATE Oracle datastore";
38
39
40 private static final String DS_ICON_NAME = "ora_ds.gif";
41
42
43 private static final boolean DEBUG = false;
44
45
46 private static final int ORACLE_TRUE = 1;
47
48 private static final int ORACLE_FALSE = 0;
49
50
51 private static final int VARRAY_SIZE = 10;
52
53
59 private static final int ORACLE_VARCHAR_LIMIT_BYTES = 4000;
60
61
62 private static final int UTF_BYTES_PER_CHAR_MAX = 3;
63
64
67 private static final int ORACLE_VARCHAR_MAX_SYMBOLS =
68 ORACLE_VARCHAR_LIMIT_BYTES/UTF_BYTES_PER_CHAR_MAX;
69
70
71 private static final int INTERNAL_BUFFER_SIZE = 16*1024;
72
73
76 public OracleDataStore() {
77
78 super();
79
80 this.datastoreComment = DS_COMMENT;
81 this.iconName = DS_ICON_NAME;
82 }
83
84
85
86
87 public void setStorageUrl(String storageUrl) throws PersistenceException {
88
89 super.setStorageUrl(storageUrl);
90
91 }
92
93
94
95
96 public String getStorageUrl() {
97
98 return super.getStorageUrl();
99 }
100
101
102
103
108 public void create()
109 throws PersistenceException, UnsupportedOperationException {
110
111 super.create();
112 }
113
114
115
116
117 public void open() throws PersistenceException {
118
119 super.open();
120
121
128 }
129
130
131
132
133 public void close() throws PersistenceException {
134
135 super.close();
136 }
137
138
139
140
145
240
241
242
246 protected void deleteDocument(Long lrId)
247 throws PersistenceException {
248
249 Assert.assertNotNull(lrId);
251
252 CallableStatement stmt = null;
253
254 try {
256 stmt = this.jdbcConn.prepareCall(
257 "{ call "+Gate.DB_OWNER+".persist.delete_document(?) }");
258 stmt.setLong(1,lrId.longValue());
259 stmt.execute();
260 }
261 catch(SQLException sqle) {
262 throw new PersistenceException("can't delete LR from DB: ["+ sqle.getMessage()+"]");
263 }
264 finally {
265 DBHelper.cleanup(stmt);
266 }
267 }
268
269
270
271
275 protected void deleteCorpus(Long lrId)
276 throws PersistenceException {
277
278 Long ID = (Long)lrId;
279
280 CallableStatement stmt = null;
281
282 try {
283 stmt = this.jdbcConn.prepareCall(
284 "{ call "+Gate.DB_OWNER+".persist.delete_corpus(?) }");
285 stmt.setLong(1,ID.longValue());
286 stmt.execute();
287 }
288 catch(SQLException sqle) {
289 throw new PersistenceException("can't delete LR from DB: ["+ sqle.getMessage()+"]");
290 }
291 finally {
292 DBHelper.cleanup(stmt);
293 }
294 }
295
296
297
298
299
300
305 public void setAutoSaving(boolean autoSaving)
306 throws UnsupportedOperationException,PersistenceException {
307
308 super.setAutoSaving(autoSaving);
309 }
310
311
312
313
314 public boolean isAutoSaving() {
315 throw new MethodNotImplementedException();
316 }
317
318
319
323 protected Long createLR(String lrType,
324 String lrName,
325 SecurityInfo si,
326 Long lrParentID)
327 throws PersistenceException,SecurityException {
328
329 Assert.assertNotNull(lrName);
331
332
337 CallableStatement stmt = null;
339
340 try {
341 stmt = this.jdbcConn.prepareCall(
342 "{ call "+Gate.DB_OWNER+".persist.create_lr(?,?,?,?,?,?,?) }");
343 stmt.setLong(1,si.getUser().getID().longValue());
344 stmt.setLong(2,si.getGroup().getID().longValue());
345 stmt.setString(3,lrType);
346 stmt.setString(4,lrName);
347 stmt.setInt(5,si.getAccessMode());
348 if (null == lrParentID) {
349 stmt.setNull(6,java.sql.Types.BIGINT);
350 }
351 else {
352 stmt.setLong(6,lrParentID.longValue());
353 }
354 stmt.registerOutParameter(7,java.sql.Types.BIGINT);
356 stmt.execute();
357
358 Long result = new Long(stmt.getLong(7));
359 return result;
360 }
361 catch(SQLException sqle) {
362
363 switch(sqle.getErrorCode()) {
364 case DBHelper.X_ORACLE_INVALID_LR_TYPE:
365 throw new PersistenceException("can't create LR [step 3] in DB, invalid LR Type");
366 default:
367 throw new PersistenceException(
368 "can't create LR [step 3] in DB : ["+ sqle.getMessage()+"]");
369 }
370 }
371 finally {
372 DBHelper.cleanup(stmt);
373 }
374 }
375
376
377
378
382 protected void updateDocumentContent(Long docID,DocumentContent content)
384 throws PersistenceException {
385
386 PreparedStatement pstmt = null;
388 ResultSet rs = null;
389 CallableStatement cstmt = null;
390 try {
391 String sql = "select dc.dc_id, "+
392 " dc.dc_content_type, " +
393 " dc.dc_character_content, " +
394 " dc.dc_binary_content " +
395 "from "+gate.Gate.DB_OWNER+".t_doc_content dc , " +
396 gate.Gate.DB_OWNER+".t_document doc " +
397 "where dc.dc_id = doc.doc_content_id " +
398 " and doc.doc_id = ? " +
400 "for update ";
401 pstmt = this.jdbcConn.prepareStatement(sql);
402 pstmt.setLong(1,docID.longValue());
403 rs = pstmt.executeQuery();
404
405
407 rs.next();
408 Long contentID = new Long(rs.getLong("dc_id"));
411 long contentType = rs.getLong("DC_CONTENT_TYPE");
412 Clob clob = (Clob)rs.getClob("dc_character_content");
413 Blob blob = (Blob)rs.getBlob("dc_binary_content");
414
415 Assert.assertTrue(contentType == DBHelper.CHARACTER_CONTENT ||
416 contentType == DBHelper.BINARY_CONTENT ||
417 contentType == DBHelper.EMPTY_CONTENT);
418
419
420 writeCLOB(content.toString(),clob);
423 long newContentType = DBHelper.CHARACTER_CONTENT;
424
425 cstmt = this.jdbcConn.prepareCall("{ call "+Gate.DB_OWNER+".persist.change_content_type(?,?) }");
427 cstmt.setLong(1,contentID.longValue());
428 cstmt.setLong(2,newContentType);
429 cstmt.execute();
430 }
431 catch(IOException ioe) {
432 throw new PersistenceException("can't update document content in DB : ["+
433 ioe.getMessage()+"]");
434 }
435 catch(SQLException sqle) {
436 throw new PersistenceException("can't update document content in DB : ["+
437 sqle.getMessage()+"]");
438 }
439 finally {
440 DBHelper.cleanup(rs);
441 DBHelper.cleanup(pstmt);
442 DBHelper.cleanup(cstmt);
443 }
444
445 }
446
447
448
449
453
460
461
465 protected Long createDoc(Long _lrID,
466 URL _docURL,
467 String _docEncoding,
468 Long _docStartOffset,
469 Long _docEndOffset,
470 Boolean _docIsMarkupAware,
471 Long _corpusID)
472 throws PersistenceException {
473
474 CallableStatement cstmt = null;
475 Long docID = null;
476
477 try {
478 cstmt = this.jdbcConn.prepareCall(
479 "{ call "+Gate.DB_OWNER+".persist.create_document(?,?,?,?,?,?,?,?) }");
480 cstmt.setLong(1,_lrID.longValue());
481 if (_docURL == null) {
482 cstmt.setNull(2,java.sql.Types.VARCHAR);
483 }else{
484 cstmt.setString(2,_docURL.toString());
485 }
486 if (null == _docEncoding) {
488 cstmt.setNull(3,java.sql.Types.VARCHAR);
489 }
490 else {
491 cstmt.setString(3,_docEncoding);
492 }
493 if (null==_docStartOffset) {
495 cstmt.setNull(4,java.sql.Types.NUMERIC);
496 }
497 else {
498 cstmt.setLong(4,_docStartOffset.longValue());
499 }
500 if (null==_docEndOffset) {
502 cstmt.setNull(5,java.sql.Types.NUMERIC);
503 }
504 else {
505 cstmt.setLong(5,_docEndOffset.longValue());
506 }
507
508 cstmt.setBoolean(6,_docIsMarkupAware.booleanValue());
509
510 if (null == _corpusID) {
512 cstmt.setNull(7,java.sql.Types.BIGINT);
513 }
514 else {
515 cstmt.setLong(7,_corpusID.longValue());
516 }
517
518 cstmt.registerOutParameter(8,java.sql.Types.BIGINT);
520
521 cstmt.execute();
522 docID = new Long(cstmt.getLong(8));
523 return docID;
524
525 }
526 catch(SQLException sqle) {
527 throw new PersistenceException("can't create document [step 4] in DB: ["+ sqle.getMessage()+"]");
528 }
529 finally {
530 DBHelper.cleanup(cstmt);
531 }
532
533 }
534
535
536
537
538 protected void createAnnotationSet(Long lrID, AnnotationSet aset)
539 throws PersistenceException {
540
541 String asetName = aset.getName();
543 Long asetID = null;
544
545 CallableStatement stmt = null;
547 try {
548 stmt = this.jdbcConn.prepareCall(
549 "{ call "+Gate.DB_OWNER+".persist.create_annotation_set(?,?,?) }");
550 stmt.setLong(1,lrID.longValue());
551
552 if (null == asetName) {
553 stmt.setNull(2,java.sql.Types.VARCHAR);
554 }
555 else {
556 stmt.setString(2,asetName);
557 }
558 stmt.registerOutParameter(3,java.sql.Types.BIGINT);
559 stmt.execute();
560
561 asetID = new Long(stmt.getLong(3));
562 }
563 catch(SQLException sqle) {
564 throw new PersistenceException("can't create a-set [step 1] in DB: ["+ sqle.getMessage()+"]");
565 }
566 finally {
567 DBHelper.cleanup(stmt);
568 }
569
570
571
575 try {
576 stmt = this.jdbcConn.prepareCall(
577 "{ call "+Gate.DB_OWNER+".persist.create_annotation(?,?,?,?,?,?,?,?,?) }");
578
579 Iterator itAnnotations = aset.iterator();
580
581 while (itAnnotations.hasNext()) {
582 Annotation ann = (Annotation)itAnnotations.next();
583 Node start = (Node)ann.getStartNode();
584 Node end = (Node)ann.getEndNode();
585 String type = ann.getType();
586
587 Long annGlobalID = null;
589 stmt.setLong(1,lrID.longValue());
590 stmt.setLong(2,ann.getId().longValue());
591 stmt.setLong(3,asetID.longValue());
592 stmt.setLong(4,start.getId().longValue());
593 stmt.setLong(5,start.getOffset().longValue());
594 stmt.setLong(6,end.getId().longValue());
595 stmt.setLong(7,end.getOffset().longValue());
596 stmt.setString(8,type);
597 stmt.registerOutParameter(9,java.sql.Types.BIGINT);
598
599 stmt.execute();
600
601 annGlobalID = new Long(stmt.getLong(9));
602
603 FeatureMap features = ann.getFeatures();
605 Assert.assertNotNull(features);
606 createFeaturesBulk(annGlobalID,DBHelper.FEATURE_OWNER_ANNOTATION,features);
608 } } catch(SQLException sqle) {
611
612 switch(sqle.getErrorCode()) {
613
614 case DBHelper.X_ORACLE_INVALID_ANNOTATION_TYPE:
615 throw new PersistenceException(
616 "can't create annotation in DB, [invalid annotation type]");
617 default:
618 throw new PersistenceException(
619 "can't create annotation in DB: ["+ sqle.getMessage()+"]");
620 } } finally {
623 DBHelper.cleanup(stmt);
624 }
625 }
627
628
629
630
754
755
760
811
812
817 public Long timestamp()
818 throws PersistenceException{
819
820 CallableStatement stmt = null;
821
822 try {
823 stmt = this.jdbcConn.prepareCall(
824 "{ call "+Gate.DB_OWNER+".persist.get_timestamp(?)} ");
825 stmt.registerOutParameter(1,java.sql.Types.BIGINT);
827 stmt.execute();
828 long result = stmt.getLong(1);
829
830 return new Long(result);
831 }
832 catch(SQLException sqle) {
833 throw new PersistenceException("can't get a timestamp from DB: ["+ sqle.getMessage()+"]");
834 }
835 finally {
836 DBHelper.cleanup(stmt);
837 }
838 }
839
840
841
845 protected boolean canAccessLR(Long lrID,int mode)
846 throws PersistenceException, SecurityException{
847
848 Assert.assertTrue(DBHelper.READ_ACCESS == mode || DBHelper.WRITE_ACCESS == mode);
850
851 if (null == this.session) {
853 throw new SecurityException("user session not set");
854 }
855
856 if (this.ac.isValidSession(this.session) == false) {
858 throw new SecurityException("invalid session supplied");
859 }
860
861 CallableStatement stmt = null;
862
863 try {
864 stmt = this.jdbcConn.prepareCall(
865 "{ call "+Gate.DB_OWNER+".security.has_access_to_lr(?,?,?,?,?)} ");
866 stmt.setLong(1,lrID.longValue());
867 stmt.setLong(2,this.session.getUser().getID().longValue());
868 stmt.setLong(3,this.session.getGroup().getID().longValue());
869 stmt.setLong(4,mode);
870
871 stmt.registerOutParameter(5,java.sql.Types.NUMERIC);
872 stmt.execute();
873 int result = stmt.getInt(5);
874
875 return (ORACLE_TRUE == result);
876 }
877 catch(SQLException sqle) {
878 throw new PersistenceException("can't check permissions in DB: ["+ sqle.getMessage()+"]");
879 }
880 finally {
881 DBHelper.cleanup(stmt);
882 }
883 }
884
885
886
887
888 public static void readCLOB(java.sql.Clob src, StringBuffer dest)
889 throws SQLException, IOException {
890
891 int readLength = 0;
892
893 dest.delete(0,dest.length());
895
896 CLOB clo = (CLOB)src;
898
899 int buffSize = Math.max(INTERNAL_BUFFER_SIZE,clo.getBufferSize());
901 char[] readBuffer = new char[buffSize];
902
903 Reader input = clo.getCharacterStream();
905
906 BufferedReader buffInput = new BufferedReader(input,INTERNAL_BUFFER_SIZE);
908
909 while ((readLength = buffInput.read(readBuffer, 0, INTERNAL_BUFFER_SIZE)) != -1) {
910 dest.append(readBuffer, 0, readLength);
911 }
912
913 buffInput.close();
915 input.close();
916
917 }
918
919
920
921
922 public static void writeCLOB(String src,java.sql.Clob dest)
923 throws SQLException, IOException {
924
925 Assert.assertNotNull(src);
927
928 CLOB clo = (CLOB)dest;
930
931 Writer output = clo.getCharacterOutputStream();
933
934 BufferedWriter buffOutput = new BufferedWriter(output,INTERNAL_BUFFER_SIZE);
936 buffOutput.write(src.toString());
937
938 buffOutput.flush();
941 output.flush();
942
943 buffOutput.close();
945 output.close();
946 }
947
948
949
950
951 public static void writeCLOB(StringBuffer src,java.sql.Clob dest)
952 throws SQLException, IOException {
953
954 writeCLOB(src.toString(),dest);
956 }
957
958
959
960
966 public static Object readBLOB(java.sql.Blob src)
967 throws SQLException, IOException,ClassNotFoundException {
968
969 int readLength = 0;
970 Object result = null;
971
972 Assert.assertNotNull(src);
974
975 BLOB blo = (BLOB)src;
977
978 InputStream input = blo.getBinaryStream();
980 Assert.assertNotNull(input);
981
982 ObjectInputStream ois = new ObjectInputStream(input);
984 result = ois.readObject();
985
986 ois.close();
988 input.close();
989
990 return result;
991 }
992
993
994
995
999 public static void writeBLOB(Object src,java.sql.Blob dest)
1000 throws SQLException, IOException {
1001
1002 Assert.assertNotNull(src);
1004
1005 BLOB blo = (BLOB)dest;
1007
1008 OutputStream output = blo.getBinaryOutputStream();
1010
1011 ObjectOutputStream oos = new ObjectOutputStream(output);
1013 oos.writeObject(src);
1014
1015 oos.flush();
1018 output.flush();
1019
1020 oos.close();
1022 output.close();
1023 }
1024
1025
1026
1027
1032 private Long _createFeature(Long entityID,
1033 int entityType,
1034 String key,
1035 Object value,
1036 int valueType,
1037 CallableStatement stmt)
1038 throws PersistenceException {
1039
1040 Long featID = null;
1042
1044 try {
1045
1048 stmt.setLong(1,entityID.longValue());
1050 stmt.setLong(2,entityType);
1051 stmt.setString(3,key);
1052 stmt.setNull(4,java.sql.Types.NUMERIC);
1053 stmt.setNull(5,java.sql.Types.VARCHAR);
1054 stmt.setLong(6,valueType);
1055 stmt.registerOutParameter(7,java.sql.Types.BIGINT);
1056
1057 switch(valueType) {
1059
1060 case DBHelper.VALUE_TYPE_NULL:
1061 break;
1062
1063 case DBHelper.VALUE_TYPE_BOOLEAN:
1064
1065 boolean b = ((Boolean)value).booleanValue();
1066 stmt.setLong(4, b ? OracleDataStore.ORACLE_TRUE : OracleDataStore.ORACLE_FALSE);
1067 break;
1068
1069 case DBHelper.VALUE_TYPE_INTEGER:
1070
1071 stmt.setLong(4,((Integer)value).intValue());
1072 break;
1073
1074 case DBHelper.VALUE_TYPE_LONG:
1075
1076 stmt.setLong(4,((Long)value).longValue());
1077 break;
1078
1079 case DBHelper.VALUE_TYPE_FLOAT:
1080
1081 Double d = (Double)value;
1082 stmt.setDouble(4,d.doubleValue());
1083 break;
1084
1085 case DBHelper.VALUE_TYPE_BINARY:
1086 break;
1089
1090 case DBHelper.VALUE_TYPE_STRING:
1091
1092 String s = (String)value;
1093 if (fitsInVarchar2(s)) {
1095 stmt.setString(5,s);
1096 }
1097 break;
1098
1099 default:
1100 throw new IllegalArgumentException("unsuppoeted feature type");
1101 }
1102
1103 stmt.execute();
1104 featID = new Long(stmt.getLong(7));
1105 }
1106 catch(SQLException sqle) {
1107
1108 switch(sqle.getErrorCode()) {
1109 case DBHelper.X_ORACLE_INVALID_FEATURE_TYPE:
1110 throw new PersistenceException("can't create feature [step 1],"+
1111 "[invalid feature type] in DB: ["+ sqle.getMessage()+"]");
1112 default:
1113 throw new PersistenceException("can't create feature [step 1] in DB: ["+
1114 sqle.getMessage()+"]");
1115 }
1116 }
1117 finally {
1118 }
1120
1121 return featID;
1122 }
1123
1124
1125
1130 private void _createFeatureBulk(Vector features,
1131 CallableStatement stmt,
1132 ArrayDescriptor adNumber,
1133 ArrayDescriptor adString)
1134 throws PersistenceException {
1135
1136 String[] stringValues = new String[VARRAY_SIZE];
1137 long[] numberValues = new long[VARRAY_SIZE];
1138 double[] floatValues = new double[VARRAY_SIZE];
1139 long[] entityIDs = new long[VARRAY_SIZE];
1140 long[] entityTypes = new long[VARRAY_SIZE];
1141 String[] keys = new String[VARRAY_SIZE];
1142 long[] valueTypes = new long[VARRAY_SIZE];
1143
1144 try {
1147
1148 int ftInd = 0;
1149 int arrInd = 0;
1150 Iterator it = features.iterator();
1151
1152 while (it.hasNext()) {
1153
1154 Feature currFeature = (Feature)it.next();
1155 entityIDs[arrInd] = currFeature.entityID.longValue();
1156 entityTypes[arrInd] = currFeature.entityType;
1157 keys[arrInd] = currFeature.key;
1158 valueTypes[arrInd] = currFeature.valueType;
1159 Assert.assertTrue(currFeature.valueType == DBHelper.VALUE_TYPE_BOOLEAN ||
1162 currFeature.valueType == DBHelper.VALUE_TYPE_FLOAT ||
1163 currFeature.valueType == DBHelper.VALUE_TYPE_INTEGER ||
1164 currFeature.valueType == DBHelper.VALUE_TYPE_LONG ||
1165 currFeature.valueType == DBHelper.VALUE_TYPE_NULL ||
1166 currFeature.valueType == DBHelper.VALUE_TYPE_STRING
1167 );
1168
1169
1170 Object value = currFeature.value;
1171
1172 switch(currFeature.valueType) {
1173
1174 case DBHelper.VALUE_TYPE_NULL:
1175 numberValues[arrInd] = 0;
1176 floatValues[arrInd] = 0;
1177 stringValues[arrInd] = "";
1178 break;
1179
1180 case DBHelper.VALUE_TYPE_BOOLEAN:
1181 boolean b = ((Boolean)value).booleanValue();
1182 numberValues[arrInd] = b ? OracleDataStore.ORACLE_TRUE : OracleDataStore.ORACLE_FALSE;
1183 floatValues[arrInd] = 0;
1184 stringValues[arrInd] = "";
1185 break;
1186
1187 case DBHelper.VALUE_TYPE_INTEGER:
1188 numberValues[arrInd] = ((Integer)value).intValue();
1189 floatValues[arrInd] = 0;
1190 stringValues[arrInd] = "";
1191 break;
1192
1193 case DBHelper.VALUE_TYPE_LONG:
1194 numberValues[arrInd] = ((Long)value).longValue();
1195 floatValues[arrInd] = 0;
1196 stringValues[arrInd] = "";
1197 break;
1198
1199 case DBHelper.VALUE_TYPE_FLOAT:
1200 floatValues[arrInd] = ((Double)value).doubleValue();
1201 numberValues[arrInd] = 0;
1202 stringValues[arrInd] = "";
1203 break;
1204
1205 case DBHelper.VALUE_TYPE_BINARY:
1206 Assert.fail();
1207 break;
1208
1209 case DBHelper.VALUE_TYPE_STRING:
1210 String s = (String)value;
1211
1213 if (fitsInVarchar2(s)) {
1214 stringValues[arrInd] = s;
1215 floatValues[arrInd] = 0;
1216 numberValues[arrInd] = 0;
1217 }
1218 else {
1219 Assert.fail();
1220 }
1221 break;
1222
1223 default:
1224 throw new IllegalArgumentException("unsuppoeted feature type");
1225 }
1226
1227 ftInd++;
1229 arrInd++;
1230
1231 if (ftInd == features.size() || arrInd == VARRAY_SIZE) {
1232
1233 if (arrInd == VARRAY_SIZE) {
1234 arrInd = 0;
1235 }
1236 ARRAY arrEntityIDs = new ARRAY(adNumber, this.jdbcConn,entityIDs);
1238 ARRAY arrEntityTypes = new ARRAY(adNumber, this.jdbcConn,entityTypes);
1239 ARRAY arrKeys = new ARRAY(adString, this.jdbcConn,keys);
1240 ARRAY arrValueTypes = new ARRAY(adNumber, this.jdbcConn,valueTypes);
1241 ARRAY arrNumberValues = new ARRAY(adNumber, this.jdbcConn,numberValues);
1242 ARRAY arrFloatValues = new ARRAY(adNumber, this.jdbcConn,floatValues);
1243 ARRAY arrStringValues = new ARRAY(adString, this.jdbcConn,stringValues);
1244
1245 OracleCallableStatement ostmt = (OracleCallableStatement)stmt;
1246 ostmt.setARRAY(1,arrEntityIDs);
1247 ostmt.setARRAY(2,arrEntityTypes);
1248 ostmt.setARRAY(3,arrKeys);
1249 ostmt.setARRAY(4,arrNumberValues);
1250 ostmt.setARRAY(5,arrFloatValues);
1251 ostmt.setARRAY(6,arrStringValues);
1252 ostmt.setARRAY(7,arrValueTypes);
1253 ostmt.setInt(8, arrInd == 0 ? VARRAY_SIZE : arrInd);
1254
1255 ostmt.execute();
1256 }
1257 }
1258 }
1259 catch(SQLException sqle) {
1260
1261 switch(sqle.getErrorCode()) {
1262
1263 case DBHelper.X_ORACLE_INVALID_FEATURE_TYPE:
1264 throw new PersistenceException("can't create feature [step 1],"+
1265 "[invalid feature type] in DB: ["+ sqle.getMessage()+"]");
1266 default:
1267 throw new PersistenceException("can't create feature [step 1] in DB: ["+
1268 sqle.getMessage()+"]");
1269 }
1270 }
1271 }
1272
1273
1277 private void _updateFeatureLOB(Long featID,Object value, int valueType)
1278 throws PersistenceException {
1279
1280
1283 Assert.assertTrue(valueType == DBHelper.VALUE_TYPE_BINARY ||
1285 valueType == DBHelper.VALUE_TYPE_STRING);
1286
1287
1288 PreparedStatement stmtA = null;
1290 ResultSet rsA = null;
1291 Clob clobValue = null;
1292 Blob blobValue = null;
1293
1294 try {
1295 String sql = " select ft_long_character_value, " +
1296 " ft_binary_value " +
1297 " from "+Gate.DB_OWNER+".t_feature " +
1298 " where ft_id = ? ";
1299
1300 stmtA = this.jdbcConn.prepareStatement(sql);
1301 stmtA.setLong(1,featID.longValue());
1302 stmtA.execute();
1303 rsA = stmtA.getResultSet();
1304
1305 if (false == rsA.next()) {
1306 throw new PersistenceException("Incorrect feature ID supplied ["+featID+"]");
1307 }
1308
1309 clobValue = rsA.getClob(1);
1314 blobValue = rsA.getBlob(2);
1315
1316 if (valueType == DBHelper.VALUE_TYPE_BINARY) {
1318 writeBLOB(value,blobValue);
1320 }
1321 else if (valueType == DBHelper.VALUE_TYPE_STRING) {
1322 String s = (String)value;
1324 writeCLOB(s,clobValue);
1325 }
1326 else {
1327 Assert.fail();
1328 }
1329 }
1330 catch(SQLException sqle) {
1331 throw new PersistenceException("can't create feature [step 2] in DB: ["+ sqle.getMessage()+"]");
1332 }
1333 catch(IOException ioe) {
1334 throw new PersistenceException("can't create feature [step 2] in DB: ["+ ioe.getMessage()+"]");
1335 }
1336 finally {
1337 DBHelper.cleanup(rsA);
1338 DBHelper.cleanup(stmtA);
1339 }
1340
1341 }
1342
1343
1344
1345
1362 private void createFeature(Long entityID, int entityType,String key, Object value, CallableStatement stmt)
1363 throws PersistenceException {
1364
1365 int valueType = findFeatureType(value);
1368
1369 Vector elementsToStore = new Vector();
1371
1372 switch(valueType) {
1373 case DBHelper.VALUE_TYPE_NULL:
1374 case DBHelper.VALUE_TYPE_BINARY:
1375 case DBHelper.VALUE_TYPE_BOOLEAN:
1376 case DBHelper.VALUE_TYPE_FLOAT:
1377 case DBHelper.VALUE_TYPE_INTEGER:
1378 case DBHelper.VALUE_TYPE_LONG:
1379 case DBHelper.VALUE_TYPE_STRING:
1380 elementsToStore.add(value);
1381 break;
1382
1383 default:
1384 List arr = (List)value;
1386 Iterator itValues = arr.iterator();
1387
1388 while (itValues.hasNext()) {
1389 elementsToStore.add(itValues.next());
1390 }
1391
1392 if (valueType == DBHelper.VALUE_TYPE_BINARY_ARR)
1394 valueType = DBHelper.VALUE_TYPE_BINARY;
1395 else if (valueType == DBHelper.VALUE_TYPE_BOOLEAN_ARR)
1396 valueType = DBHelper.VALUE_TYPE_BOOLEAN;
1397 else if (valueType == DBHelper.VALUE_TYPE_FLOAT_ARR)
1398 valueType = DBHelper.VALUE_TYPE_FLOAT;
1399 else if (valueType == DBHelper.VALUE_TYPE_INTEGER_ARR)
1400 valueType = DBHelper.VALUE_TYPE_INTEGER;
1401 else if (valueType == DBHelper.VALUE_TYPE_LONG_ARR)
1402 valueType = DBHelper.VALUE_TYPE_LONG;
1403 else if (valueType == DBHelper.VALUE_TYPE_STRING_ARR)
1404 valueType = DBHelper.VALUE_TYPE_STRING;
1405 }
1406
1407 for (int i=0; i< elementsToStore.size(); i++) {
1409
1410 Object currValue = elementsToStore.elementAt(i);
1411
1412 Long featID = _createFeature(entityID,entityType,key,currValue,valueType,stmt);
1414
1415 if (valueType == DBHelper.VALUE_TYPE_STRING) {
1417 String s = (String)currValue;
1419 if (false == this.fitsInVarchar2(s)) {
1420 _updateFeatureLOB(featID,value,valueType);
1423 }
1424 }
1425 else if (valueType == DBHelper.VALUE_TYPE_BINARY) {
1426 _updateFeatureLOB(featID,value,valueType);
1428 }
1429 }
1430
1431
1432 }
1433
1434
1435
1444 private Vector normalizeFeature(Long entityID, int entityType,String key, Object value)
1445 throws PersistenceException {
1446
1447 int valueType = findFeatureType(value);
1449
1450 Vector elementsToStore = new Vector();
1452 Vector features = new Vector();
1453
1454 switch(valueType) {
1455 case DBHelper.VALUE_TYPE_NULL:
1456 case DBHelper.VALUE_TYPE_BINARY:
1457 case DBHelper.VALUE_TYPE_BOOLEAN:
1458 case DBHelper.VALUE_TYPE_FLOAT:
1459 case DBHelper.VALUE_TYPE_INTEGER:
1460 case DBHelper.VALUE_TYPE_LONG:
1461 case DBHelper.VALUE_TYPE_STRING:
1462 elementsToStore.add(value);
1463 break;
1464
1465 default:
1466 List arr = (List)value;
1468 Iterator itValues = arr.iterator();
1469
1470 while (itValues.hasNext()) {
1471 elementsToStore.add(itValues.next());
1472 }
1473
1474 if (valueType == DBHelper.VALUE_TYPE_BINARY_ARR)
1476 valueType = DBHelper.VALUE_TYPE_BINARY;
1477 else if (valueType == DBHelper.VALUE_TYPE_BOOLEAN_ARR)
1478 valueType = DBHelper.VALUE_TYPE_BOOLEAN;
1479 else if (valueType == DBHelper.VALUE_TYPE_FLOAT_ARR)
1480 valueType = DBHelper.VALUE_TYPE_FLOAT;
1481 else if (valueType == DBHelper.VALUE_TYPE_INTEGER_ARR)
1482 valueType = DBHelper.VALUE_TYPE_INTEGER;
1483 else if (valueType == DBHelper.VALUE_TYPE_LONG_ARR)
1484 valueType = DBHelper.VALUE_TYPE_LONG;
1485 else if (valueType == DBHelper.VALUE_TYPE_STRING_ARR)
1486 valueType = DBHelper.VALUE_TYPE_STRING;
1487 }
1488
1489 for (int i=0; i< elementsToStore.size(); i++) {
1490
1491 Object currValue = elementsToStore.elementAt(i);
1492 Feature currFeature = new Feature(entityID,entityType,key,currValue,valueType);
1493 features.add(currFeature);
1494 }
1495
1496 return features;
1497 }
1498
1499
1500
1510 private boolean fitsInVarchar2(String s) {
1511
1512 return s.getBytes().length < OracleDataStore.ORACLE_VARCHAR_LIMIT_BYTES;
1513 }
1514
1515
1516
1517
1521 protected void createFeatures(Long entityID, int entityType, FeatureMap features)
1522 throws PersistenceException {
1523
1524 CallableStatement stmt = null;
1526 CallableStatement stmtBulk = null;
1527 ArrayDescriptor adNumber = null;
1528 ArrayDescriptor adString = null;
1529
1530 try {
1531 stmt = this.jdbcConn.prepareCall(
1532 "{ call "+Gate.DB_OWNER+".persist.create_feature(?,?,?,?,?,?,?)} ");
1533
1534 stmtBulk = this.jdbcConn.prepareCall(
1535 "{ call "+Gate.DB_OWNER+".persist.create_feature_bulk(?,?,?,?,?,?,?,?)} ");
1536
1537 adNumber = ArrayDescriptor.createDescriptor("GATEADMIN.PERSIST.INTARRAY", this.jdbcConn);
1538 adString = ArrayDescriptor.createDescriptor("GATEADMIN.PERSIST.CHARARRAY", this.jdbcConn);
1539 }
1540 catch (SQLException sqle) {
1541 throw new PersistenceException(sqle);
1542 }
1543
1544
1545 Set entries = features.entrySet();
1546 Iterator itFeatures = entries.iterator();
1547 while (itFeatures.hasNext()) {
1548 Map.Entry entry = (Map.Entry)itFeatures.next();
1549 String key = (String)entry.getKey();
1550 Object value = entry.getValue();
1551 createFeature(entityID,entityType,key,value,stmt);
1552 }
1553
1554 DBHelper.cleanup(stmt);
1556 }
1557
1558
1559
1572 protected void createFeaturesBulk(Long entityID, int entityType, FeatureMap features)
1573 throws PersistenceException {
1574
1575 CallableStatement stmt = null;
1577 CallableStatement stmtBulk = null;
1578 ArrayDescriptor adNumber = null;
1579 ArrayDescriptor adString = null;
1580
1581 try {
1582 stmt = this.jdbcConn.prepareCall(
1583 "{ call "+Gate.DB_OWNER+".persist.create_feature(?,?,?,?,?,?,?)} ");
1584
1585 stmtBulk = this.jdbcConn.prepareCall(
1586 "{ call "+Gate.DB_OWNER+".persist.create_feature_bulk(?,?,?,?,?,?,?,?)} ");
1587
1588 adString = ArrayDescriptor.createDescriptor(Gate.DB_OWNER.toUpperCase()+".STRING_ARRAY", this.jdbcConn);
1592 adNumber = ArrayDescriptor.createDescriptor(Gate.DB_OWNER.toUpperCase()+".INT_ARRAY", this.jdbcConn);
1593 }
1594 catch (SQLException sqle) {
1595 throw new PersistenceException(sqle);
1596 }
1597
1598
1599 Vector entityFeatures = new Vector();
1600
1601 Set entries = features.entrySet();
1602 Iterator itFeatures = entries.iterator();
1603 while (itFeatures.hasNext()) {
1604 Map.Entry entry = (Map.Entry)itFeatures.next();
1605 String key = (String)entry.getKey();
1606 Object value = entry.getValue();
1607 Vector normalizedFeatures = normalizeFeature(entityID,entityType,key,value);
1608 entityFeatures.addAll(normalizedFeatures);
1609 }
1610
1611 Iterator itEntityFeatures = entityFeatures.iterator();
1613
1614 while (itEntityFeatures.hasNext()) {
1615
1616 Feature currFeature = (Feature)itEntityFeatures.next();
1617
1618 if (currFeature.valueType == DBHelper.VALUE_TYPE_STRING) {
1619 String s = (String)currFeature.value;
1621 if (false == this.fitsInVarchar2(s)) {
1622 Long featID = _createFeature(currFeature.entityID,
1625 currFeature.entityType,
1626 currFeature.key,
1627 currFeature.value,
1628 currFeature.valueType,
1629 stmt);
1630 _updateFeatureLOB(featID,currFeature.value,currFeature.valueType);
1631 itEntityFeatures.remove();
1632 }
1633 }
1634 else if (currFeature.valueType == DBHelper.VALUE_TYPE_BINARY) {
1635 Long featID = _createFeature(currFeature.entityID,
1637 currFeature.entityType,
1638 currFeature.key,
1639 currFeature.value,
1640 currFeature.valueType,
1641 stmt);
1642 _updateFeatureLOB(featID,currFeature.value,currFeature.valueType);
1643 itEntityFeatures.remove();
1644 }
1645 }
1646
1647 _createFeatureBulk(entityFeatures, stmtBulk, adNumber, adString);
1649
1650 DBHelper.cleanup(stmt);
1652 DBHelper.cleanup(stmtBulk);
1653 }
1654
1655
1656
1657
1658 public void setSecurityInfo(LanguageResource lr,SecurityInfo si)
1659 throws PersistenceException, SecurityException {
1660 throw new MethodNotImplementedException();
1661 }
1662
1663
1664
1665
1668
1775
1776
1777
1958
1959
1960
1964 protected FeatureMap readFeatures(Long entityID, int entityType)
1965 throws PersistenceException {
1966
1967 Assert.assertNotNull(entityID);
1969 Assert.assertTrue(entityType == DBHelper.FEATURE_OWNER_ANNOTATION ||
1970 entityType == DBHelper.FEATURE_OWNER_CORPUS ||
1971 entityType == DBHelper.FEATURE_OWNER_DOCUMENT);
1972
1973
1974 PreparedStatement pstmt = null;
1975 ResultSet rs = null;
1976 FeatureMap fm = new SimpleFeatureMapImpl();
1977
1978 try {
1980 String sql = " select v2.fk_string, " +
1981 " v1.ft_value_type, " +
1982 " v1.ft_number_value, " +
1983 " v1.ft_binary_value, " +
1984 " v1.ft_character_value, " +
1985 " v1.ft_long_character_value " +
1986 " from "+Gate.DB_OWNER+".t_feature v1, " +
1987 " "+Gate.DB_OWNER+".t_feature_key v2 " +
1988 " where v1.ft_entity_id = ? " +
1989 " and v1.ft_entity_type = ? " +
1990 " and v1.ft_key_id = v2.fk_id " +
1991 " order by v2.fk_string,v1.ft_id";
1992
1993 pstmt = this.jdbcConn.prepareStatement(sql);
1994 pstmt.setLong(1,entityID.longValue());
1995 pstmt.setLong(2,entityType);
1996 pstmt.execute();
1997 rs = pstmt.getResultSet();
1998
1999 Vector arrFeatures = new Vector();
2001 String prevKey = null;
2002 String currKey = null;
2003 Object currFeature = null;
2004
2005
2006 while (rs.next()) {
2007 currKey = rs.getString(1);
2011
2012 Long valueType = new Long(rs.getLong(2));
2013
2014 Object numberValue = null;
2017
2018 switch(valueType.intValue()) {
2021
2022 case DBHelper.VALUE_TYPE_BOOLEAN:
2023 numberValue = new Boolean(rs.getBoolean(3));
2024 break;
2025
2026 case DBHelper.VALUE_TYPE_FLOAT:
2027 numberValue = new Double(rs.getDouble(3));
2028 break;
2029
2030 case DBHelper.VALUE_TYPE_INTEGER:
2031 numberValue = new Integer(rs.getInt(3));
2032 break;
2033
2034 case DBHelper.VALUE_TYPE_LONG:
2035 numberValue = new Long(rs.getLong(3));
2036 break;
2037 }
2038
2039 Blob blobValue = rs.getBlob(4);
2041 String stringValue = rs.getString(5);
2042 Clob clobValue = rs.getClob(6);
2043
2044 switch(valueType.intValue()) {
2045
2046 case DBHelper.VALUE_TYPE_NULL:
2047 currFeature = null;
2048 break;
2049
2050 case DBHelper.VALUE_TYPE_BOOLEAN:
2051 case DBHelper.VALUE_TYPE_FLOAT:
2052 case DBHelper.VALUE_TYPE_INTEGER:
2053 case DBHelper.VALUE_TYPE_LONG:
2054 currFeature = numberValue;
2055 break;
2056
2057 case DBHelper.VALUE_TYPE_BINARY:
2058 currFeature = readBLOB(blobValue);
2059 break;
2060
2061 case DBHelper.VALUE_TYPE_STRING:
2062 if (null == stringValue) {
2066 StringBuffer temp = new StringBuffer();
2068 readCLOB(clobValue,temp);
2069 currFeature = temp.toString();
2070 }
2071 else {
2072 currFeature = stringValue;
2073 }
2074 break;
2075
2076 default:
2077 throw new PersistenceException("Invalid feature type found in DB, type is ["+valueType.intValue()+"]");
2078 }
2080 if (currKey.equals(prevKey) && prevKey != null) {
2082 arrFeatures.add(currFeature);
2084 }
2085 else {
2086
2088 if (arrFeatures.size() > 1) {
2090 fm.put(prevKey, new Vector(arrFeatures));
2093 }
2094 else if (arrFeatures.size() == 1) {
2095 fm.put(prevKey,arrFeatures.elementAt(0));
2096 }
2097 else {
2098 ;
2100 }
2102 arrFeatures.clear();
2105
2106 prevKey = currKey;
2107 arrFeatures.add(currFeature);
2108 } }
2111 if (arrFeatures.size() > 1) {
2113 fm.put(currKey,arrFeatures);
2114 }
2115 else if (arrFeatures.size() == 1) {
2116 fm.put(currKey,arrFeatures.elementAt(0));
2117 }
2118 } catch(SQLException sqle) {
2120 throw new PersistenceException("can't read features from DB: ["+ sqle.getMessage()+"]");
2121 }
2122 catch(IOException ioe) {
2123 throw new PersistenceException("can't read features from DB: ["+ ioe.getMessage()+"]");
2124 }
2125 catch(ClassNotFoundException cnfe) {
2126 throw new PersistenceException("can't read features from DB: ["+ cnfe.getMessage()+"]");
2127 }
2128 finally {
2129 DBHelper.cleanup(rs);
2130 DBHelper.cleanup(pstmt);
2131 }
2132
2133 return fm;
2134 }
2135
2136
2137
2138
2144 public boolean equals(Object obj) {
2145
2146 if (false == obj instanceof OracleDataStore) {
2147 return false;
2148 }
2149
2150 OracleDataStore db2 = (OracleDataStore)obj;
2151
2152 if (false == this.getDatabaseID().equals(db2.getDatabaseID())) {
2153 return false;
2154 }
2155
2156 return true;
2157 }
2158
2159
2160
2161
2162
2166 protected void _syncLR(LanguageResource lr)
2167 throws PersistenceException,SecurityException {
2168
2169 Assert.assertTrue(lr instanceof DatabaseDocumentImpl ||
2171 lr instanceof DatabaseCorpusImpl);;
2172 Assert.assertNotNull(lr.getLRPersistenceId());
2173
2174 CallableStatement stmt = null;
2175
2176 try {
2177 stmt = this.jdbcConn.prepareCall("{ call "+Gate.DB_OWNER+".persist.update_lr(?,?,?) }");
2178 stmt.setLong(1,((Long)lr.getLRPersistenceId()).longValue());
2179 stmt.setString(2,lr.getName());
2180 if (lr instanceof Document &&
2182 null != lr.getParent()) {
2183 stmt.setLong(3,((Long)lr.getParent().getLRPersistenceId()).longValue());
2184 }
2185 else {
2186 stmt.setNull(3,java.sql.Types.BIGINT);
2187 }
2188
2189 stmt.execute();
2190 }
2191 catch(SQLException sqle) {
2192
2193 switch(sqle.getErrorCode()) {
2194 case DBHelper.X_ORACLE_INVALID_LR:
2195 throw new PersistenceException("can't set LR name in DB: [invalid LR ID]");
2196 default:
2197 throw new PersistenceException(
2198 "can't set LR name in DB: ["+ sqle.getMessage()+"]");
2199 }
2200
2201 }
2202 finally {
2203 DBHelper.cleanup(stmt);
2204 }
2205 }
2206
2207
2208
2209
2210 protected void _syncDocumentHeader(Document doc)
2211 throws PersistenceException {
2212
2213 Long lrID = (Long)doc.getLRPersistenceId();
2214
2215 CallableStatement stmt = null;
2216
2217 try {
2218 stmt = this.jdbcConn.prepareCall("{ call "+Gate.DB_OWNER+
2219 ".persist.update_document(?,?,?,?,?) }");
2220 stmt.setLong(1,lrID.longValue());
2221 if (null==doc.getSourceUrl()) {
2223 stmt.setNull(2,java.sql.Types.VARCHAR);
2224 }
2225 else {
2226 stmt.setString(2,doc.getSourceUrl().toString());
2227 }
2228 if (null==doc.getSourceUrlStartOffset()) {
2230 stmt.setNull(3,java.sql.Types.NUMERIC);
2231 }
2232 else {
2233 stmt.setLong(3,doc.getSourceUrlStartOffset().longValue());
2234 }
2235 if (null==doc.getSourceUrlEndOffset()) {
2237 stmt.setNull(4,java.sql.Types.NUMERIC);
2238 }
2239 else {
2240 stmt.setLong(4,doc.getSourceUrlEndOffset().longValue());
2241 }
2242
2243 stmt.setLong(5,true == doc.getMarkupAware().booleanValue() ? OracleDataStore.ORACLE_TRUE
2244 : OracleDataStore.ORACLE_FALSE);
2245
2246 stmt.execute();
2247 }
2248 catch(SQLException sqle) {
2249
2250 switch(sqle.getErrorCode()) {
2251 case DBHelper.X_ORACLE_INVALID_LR :
2252 throw new PersistenceException("invalid LR supplied: no such document: ["+
2253 sqle.getMessage()+"]");
2254 default:
2255 throw new PersistenceException("can't change document data: ["+
2256 sqle.getMessage()+"]");
2257 }
2258 }
2259 finally {
2260 DBHelper.cleanup(stmt);
2261 }
2262
2263 }
2264
2265
2266
2267
2268 protected void _syncDocumentContent(Document doc)
2269 throws PersistenceException {
2270
2294 Long docID = (Long)doc.getLRPersistenceId();
2297 updateDocumentContent(docID,doc.getContent());
2298
2299
2310
2311 }
2312
2313
2314
2315
2316
2419
2420
2421
2422
2434
2435
2436 protected void _syncRemovedDocumentsFromCorpus(List docLRIDs, Long corpLRID)
2437 throws PersistenceException {
2438
2439 Assert.assertNotNull(docLRIDs);
2441 Assert.assertNotNull(corpLRID);
2442 Assert.assertTrue(docLRIDs.size() > 0);
2443
2444 CallableStatement cstmt = null;
2445
2446 try {
2447 cstmt = this.jdbcConn.prepareCall("{ call "+Gate.DB_OWNER+
2448 ".persist.remove_document_from_corpus(?,?) }");
2449
2450 Iterator it = docLRIDs.iterator();
2451 while (it.hasNext()) {
2452 Long currLRID = (Long)it.next();
2453 cstmt.setLong(1,currLRID.longValue());
2454 cstmt.setLong(2,corpLRID.longValue());
2455 cstmt.execute();
2456 }
2457 }
2458 catch(SQLException sqle) {
2459
2460 switch(sqle.getErrorCode()) {
2461 case DBHelper.X_ORACLE_INVALID_LR :
2462 throw new PersistenceException("invalid LR supplied: no such document: ["+
2463 sqle.getMessage()+"]");
2464 default:
2465 throw new PersistenceException("can't change document data: ["+
2466 sqle.getMessage()+"]");
2467 }
2468 }
2469 finally {
2470 DBHelper.cleanup(cstmt);
2471 }
2472
2473 }
2474
2475
2476
2477
2559
2560
2561
2562
2612
2613
2614
2665
2666
2667
2668 protected void _syncFeatures(LanguageResource lr)
2669 throws PersistenceException {
2670
2671 Assert.assertNotNull(lr);
2673 Assert.assertNotNull(lr.getLRPersistenceId());
2674 Assert.assertEquals(((DatabaseDataStore)lr.getDataStore()).getDatabaseID(),
2675 this.getDatabaseID());
2676 Assert.assertTrue(lr instanceof Document || lr instanceof Corpus);
2677
2679 Long lrID = (Long)lr.getLRPersistenceId();
2681 int entityType;
2682
2683 CallableStatement stmt = null;
2685 try {
2686 Assert.assertTrue(false == this.jdbcConn.getAutoCommit());
2687 stmt = this.jdbcConn.prepareCall("{ call "+Gate.DB_OWNER+
2688 ".persist.delete_features(?,?) }");
2689 stmt.setLong(1,lrID.longValue());
2690
2691 if (lr instanceof Document) {
2692 entityType = DBHelper.FEATURE_OWNER_DOCUMENT;
2693 }
2694 else if (lr instanceof Corpus) {
2695 entityType = DBHelper.FEATURE_OWNER_CORPUS;
2696 }
2697 else {
2698 throw new IllegalArgumentException();
2699 }
2700
2701 stmt.setInt(2,entityType);
2702 stmt.execute();
2703 }
2704 catch(SQLException sqle) {
2705 throw new PersistenceException("can't delete features in DB: ["+ sqle.getMessage()+"]");
2706 }
2707 finally {
2708 DBHelper.cleanup(stmt);
2709 }
2710
2711 createFeaturesBulk(lrID,entityType, lr.getFeatures());
2714
2715 }
2716
2717
2718
2719
2720
2816
2817
2818
2822 public boolean lockLr(LanguageResource lr)
2823 throws PersistenceException,SecurityException {
2824
2825 Assert.assertNotNull(lr);
2827 Assert.assertTrue(lr instanceof DatabaseDocumentImpl ||
2828 lr instanceof DatabaseCorpusImpl);
2829 Assert.assertNotNull(lr.getLRPersistenceId());
2830 Assert.assertEquals(lr.getDataStore(),this);
2831
2832 return _lockLr((Long)lr.getLRPersistenceId());
2834 }
2835
2836
2837
2838
2842 private boolean _lockLr(Long lrID)
2843 throws PersistenceException,SecurityException {
2844
2845 Assert.assertNotNull(lrID);
2847
2848 if (null == this.session) {
2850 throw new SecurityException("session not set");
2851 }
2852
2853 if (false == this.ac.isValidSession(this.session)) {
2854 throw new SecurityException("invalid session supplied");
2855 }
2856
2857 if (false == canWriteLR(lrID)) {
2859 throw new SecurityException("no write access granted to the user");
2860 }
2861
2862 CallableStatement cstmt = null;
2864 boolean lockSucceeded = false;
2865
2866 try {
2867 cstmt = this.jdbcConn.prepareCall("{ call "+Gate.DB_OWNER+".persist.lock_lr(?,?,?,?) }");
2868 cstmt.setLong(1,lrID.longValue());
2869 cstmt.setLong(2,this.session.getUser().getID().longValue());
2870 cstmt.setLong(3,this.session.getGroup().getID().longValue());
2871 cstmt.registerOutParameter(4,java.sql.Types.NUMERIC);
2872 cstmt.execute();
2873
2874 lockSucceeded = cstmt.getLong(4) == OracleDataStore.ORACLE_TRUE
2875 ? true
2876 : false;
2877 }
2878 catch(SQLException sqle) {
2879
2880 switch(sqle.getErrorCode()) {
2881 case DBHelper.X_ORACLE_INVALID_LR:
2882 throw new PersistenceException("invalid LR ID supplied ["+sqle.getMessage()+"]");
2883 default:
2884 throw new PersistenceException(
2885 "can't lock LR in DB : ["+ sqle.getMessage()+"]");
2886 }
2887 }
2888 finally {
2889 DBHelper.cleanup(cstmt);
2890 }
2891
2892 return lockSucceeded;
2893 }
2894
2895
2896
2897
2900 public void unlockLr(LanguageResource lr)
2901 throws PersistenceException,SecurityException {
2902
2903 Assert.assertNotNull(lr);
2905 Assert.assertTrue(lr instanceof DatabaseDocumentImpl ||
2906 lr instanceof DatabaseCorpusImpl);
2907 Assert.assertNotNull(lr.getLRPersistenceId());
2908 Assert.assertEquals(lr.getDataStore(),this);
2909
2910 if (null == this.session) {
2912 throw new SecurityException("session not set");
2913 }
2914
2915 if (false == this.ac.isValidSession(this.session)) {
2916 throw new SecurityException("invalid session supplied");
2917 }
2918
2919 if (false == canWriteLR(lr.getLRPersistenceId())) {
2921 throw new SecurityException("no write access granted to the user");
2922 }
2923
2924 CallableStatement cstmt = null;
2926 boolean lockSucceeded = false;
2927
2928 try {
2929 cstmt = this.jdbcConn.prepareCall("{ call "+Gate.DB_OWNER+".persist.unlock_lr(?,?) }");
2930 cstmt.setLong(1,((Long)lr.getLRPersistenceId()).longValue());
2931 cstmt.setLong(2,this.session.getUser().getID().longValue());
2932 cstmt.execute();
2933 }
2934 catch(SQLException sqle) {
2935
2936 switch(sqle.getErrorCode()) {
2937 case DBHelper.X_ORACLE_INVALID_LR:
2938 throw new PersistenceException("invalid LR ID supplied ["+sqle.getMessage()+"]");
2939 default:
2940 throw new PersistenceException(
2941 "can't unlock LR in DB : ["+ sqle.getMessage()+"]");
2942 }
2943 }
2944 finally {
2945 DBHelper.cleanup(cstmt);
2946 }
2947 }
2948
2949
2950
2951
2952
2957 protected void addDocumentToCorpus(Long docID,Long corpID)
2958 throws PersistenceException,SecurityException {
2959
2960 Assert.assertNotNull(docID);
2962 Assert.assertNotNull(corpID);
2963
2964 if (null == this.session) {
2966 throw new SecurityException("session not set");
2967 }
2968
2969 if (false == this.ac.isValidSession(this.session)) {
2970 throw new SecurityException("invalid session supplied");
2971 }
2972
2973 if (false == canWriteLR(corpID)) {
2975 throw new SecurityException("no write access granted to the user");
2976 }
2977
2978 if (false == canWriteLR(docID)) {
2979 throw new SecurityException("no write access granted to the user");
2980 }
2981
2982 CallableStatement cstmt = null;
2984
2985 try {
2986 cstmt = this.jdbcConn.prepareCall("{ call "+
2987 Gate.DB_OWNER+".persist.add_document_to_corpus(?,?) }");
2988 cstmt.setLong(1,docID.longValue());
2989 cstmt.setLong(2,corpID.longValue());
2990 cstmt.execute();
2991 }
2992 catch(SQLException sqle) {
2993
2994 switch(sqle.getErrorCode()) {
2995 case DBHelper.X_ORACLE_INVALID_LR:
2996 throw new PersistenceException("invalid LR ID supplied ["+sqle.getMessage()+"]");
2997 default:
2998 throw new PersistenceException(
2999 "can't add document to corpus : ["+ sqle.getMessage()+"]");
3000 }
3001 }
3002 finally {
3003 DBHelper.cleanup(cstmt);
3004 }
3005 }
3006
3007
3008
3009
3012
3033
3034
3038 public List findLrIds(List constraints) throws PersistenceException {
3039 return findLrIds(constraints,null);
3040 }
3041
3042
3049 public List findLrIds(List constraints, String lrType) throws PersistenceException {
3050 return findLrIds(constraints, lrType, null, -1);
3051 }
3052
3053
3062 public List findLrIds(List constraints, String lrType,
3063 List orderByConstraints, int limitcount) throws PersistenceException {
3064 Vector lrsIDs = new Vector();
3065 CallableStatement stmt = null;
3066 ResultSet rs = null;
3067 Connection conn = null;
3068
3069 try {
3070 Vector sqlValues = new Vector();
3071 String sql = getSQLQuery(constraints, lrType, false, orderByConstraints, limitcount, sqlValues);
3072 conn = DBHelper.connect(this.getStorageUrl(), true);
3073 stmt = conn.prepareCall(sql);
3074 for (int i = 0; i<sqlValues.size(); i++){
3075 if (sqlValues.elementAt(i) instanceof String){
3076 stmt.setString(i+1,sqlValues.elementAt(i).toString());
3077 }
3078 else if (sqlValues.elementAt(i) instanceof Long){
3079 stmt.setLong(i+1,((Long) sqlValues.elementAt(i)).longValue());
3080 }
3081 else if (sqlValues.elementAt(i) instanceof Integer){
3082 stmt.setLong(i+1,((Integer) sqlValues.elementAt(i)).intValue());
3083 }
3084 }
3085 stmt.execute();
3086 rs = stmt.getResultSet();
3087
3088 while (rs.next()) {
3089 long lr_ID = rs.getLong(1);
3090 lrsIDs.addElement(new Long(lr_ID));
3091 }
3092 return lrsIDs;
3093 }
3094 catch(SQLException sqle) {
3095 throw new PersistenceException("can't get LRs from DB: ["+ sqle+"]");
3096 }
3097 catch (ClassNotFoundException cnfe){
3098 throw new PersistenceException("can't not find driver: ["+ cnfe +"]");
3099 }
3100 finally {
3101 DBHelper.cleanup(rs);
3102 DBHelper.cleanup(stmt);
3103 DBHelper.disconnect(conn, true);
3104 }
3105 }
3106
3112 public long getLrsCount(List constraints, String lrType) throws PersistenceException {
3113 Vector lrs = new Vector();
3114 CallableStatement stmt = null;
3115 ResultSet rs = null;
3116 Connection conn = null;
3117
3118 try {
3119 Vector sqlValues = new Vector();
3120 String sql = getSQLQuery(constraints,lrType, true, null, -1, sqlValues);
3121 conn = DBHelper.connect(this.getStorageUrl(), true);
3122 stmt = conn.prepareCall(sql);
3123 for (int i = 0; i<sqlValues.size(); i++){
3124 if (sqlValues.elementAt(i) instanceof String){
3125 stmt.setString(i+1,sqlValues.elementAt(i).toString());
3126 }
3127 else if (sqlValues.elementAt(i) instanceof Long){
3128 stmt.setLong(i+1,((Long) sqlValues.elementAt(i)).longValue());
3129 }
3130 else if (sqlValues.elementAt(i) instanceof Integer){
3131 stmt.setLong(i+1,((Integer) sqlValues.elementAt(i)).intValue());
3132 }
3133 }
3134
3135 stmt.execute();
3136 rs = stmt.getResultSet();
3137 rs.next();
3138 return rs.getLong(1);
3139 }
3140 catch(SQLException sqle) {
3141 throw new PersistenceException("can't get LRs Count from DB: ["+ sqle+"]");
3142 }
3143 catch (ClassNotFoundException cnfe){
3144 throw new PersistenceException("can't not find driver: ["+ cnfe +"]");
3145 }
3146 finally {
3147 DBHelper.cleanup(rs);
3148 DBHelper.cleanup(stmt);
3149 DBHelper.disconnect(conn, true);
3150 }
3151 }
3152
3153 private String getSQLQuery(List filter, String lrType, boolean count,
3154 List orderByFilter, int limitcount, Vector sqlValues){
3155 StringBuffer query = new StringBuffer("");
3156 String join = getJoinQuery(filter, orderByFilter, sqlValues);
3157 String select = "lr_id";
3158 if (count){
3159 select = "count(*)";
3160 }
3161
3162 query = query.append(" SELECT " + select + " " +
3163 " FROM "+Gate.DB_OWNER+".t_lang_resource LR " + join);
3164
3165 if (filter != null && filter.size()>0) {
3166 query = query.append(" ( ");
3167 query = query.append(getIntersectionPart(filter, sqlValues));
3168 query = query.append(" ) intersected_feat_restr ");
3169 }
3170
3171 String endPartOfJoin = getEndPartOfJoin(filter,orderByFilter, lrType,sqlValues);
3172 query = query.append(endPartOfJoin);
3173
3174 if (limitcount>0){
3175 query = query.insert(0,"select lr_id from ( ");
3176 query = query.append( ") where rownum<"+(limitcount+1));
3177 }
3178
3179 return query.toString();
3180 }
3181
3182 private String getIntersectionPart(List filter, Vector sqlValues){
3183 StringBuffer query = new StringBuffer(" ");
3184
3185 Collections.sort(filter, new RestrictionComepator());
3186 Vector list_of_filters = new Vector();
3187 for (int i=0; i<filter.size(); i++){
3188 if (i>0){
3189 Restriction rest = (Restriction) filter.get(i);
3190 Restriction prev = (Restriction) filter.get(i-1);
3191 if (rest.getKey().equals(prev.getKey())){
3192 Vector temp = (Vector) list_of_filters.get(list_of_filters.size()-1);
3193 temp.add(rest);
3194 } else {
3195 Vector temp = new Vector();
3196 temp.add(rest);
3197 list_of_filters.add(temp);
3198 }
3199 } else {
3200 Vector temp = new Vector();
3201 temp.add(filter.get(0));
3202 list_of_filters.add(temp);
3203 }
3204 }
3205
3206 if (filter!=null && filter.size()>0){
3207 for (int i=0; i<list_of_filters.size(); i++){
3208 query = query.append(getRestrictionPartOfQuery((List) list_of_filters.get(i),sqlValues));
3209 if (i<list_of_filters.size()-1) {
3210 query = query.append(" intersect ");
3211 }
3212 }
3213 }
3214 return query.toString();
3215 }
3216
3217 private String getRestrictionPartOfQuery(List list, Vector sqlValues){
3218 StringBuffer expresion = new StringBuffer(
3219 " SELECT ft_entity_id "+
3220 " FROM "+Gate.DB_OWNER+".t_feature FEATURE, " +
3221 Gate.DB_OWNER + ".t_feature_key FTK" +
3222 " WHERE FEATURE.ft_entity_type = 2 ");
3223
3224 Restriction restr = (Restriction) list.get(0);
3225
3226 if (restr.getKey() != null){
3227 expresion = expresion.append(" AND FTK.fk_id = FEATURE.ft_key_id ");
3228 expresion = expresion.append(" AND FTK.fk_string = ? ");
3229 sqlValues.addElement(restr.getKey());
3230 }
3231
3232 for (int i =0; i<list.size(); i++) {
3233 restr = (Restriction) list.get(i);
3234 if (restr.getValue() != null){
3235 expresion = expresion.append(" AND ");
3236 switch (this.findFeatureType(restr.getValue())){
3237 case DBHelper.VALUE_TYPE_INTEGER:
3238 expresion = expresion.append(getNumberExpresion(restr, sqlValues));
3239 break;
3240 case DBHelper.VALUE_TYPE_LONG:
3241 expresion = expresion.append(getNumberExpresion(restr, sqlValues));
3242 break;
3243 default:
3244 if (restr.getOperator()==Restriction.OPERATOR_EQUATION){
3245 expresion = expresion.append(" FEATURE.ft_character_value = ? ");
3246 sqlValues.addElement(restr.getStringValue());
3247 }
3248 if (restr.getOperator()==Restriction.OPERATOR_LIKE){
3249 expresion = expresion.append(" upper(FEATURE.ft_character_value) like ? ");
3250 sqlValues.addElement("%"+restr.getStringValue().toUpperCase()+"%");
3251 }
3252 break;
3253 }
3254 }
3255 }
3256
3257 return expresion.toString();
3258 }
3259
3260 private String getNumberExpresion(Restriction restr, Vector sqlValues){
3261 StringBuffer expr = new StringBuffer("FEATURE.ft_number_value ");
3262
3263 switch (restr.getOperator()){
3264 case Restriction.OPERATOR_EQUATION:
3265 expr = expr.append(" = ");
3266 break;
3267 case Restriction.OPERATOR_BIGGER:
3268 expr = expr.append(" > ");
3269 break;
3270 case Restriction.OPERATOR_LESS:
3271 expr = expr.append(" < ");
3272 break;
3273 case Restriction.OPERATOR_EQUATION_OR_BIGGER:
3274 expr = expr.append(" >= ");
3275 break;
3276 case Restriction.OPERATOR_EQUATION_OR_LESS:
3277 expr = expr.append(" <= ");
3278 break;
3279 default:
3280 return " 0 = 0 ";
3281 }
3282
3283 expr.append(" ? ");
3284 sqlValues.addElement(restr.getValue());
3285
3286 return expr.toString();
3287 }
3288
3289 private String getJoinQuery(List filter, List orderByFilter, Vector sqlValues){
3290 StringBuffer join = new StringBuffer("");
3291 if (filter !=null && filter.size()>0) {
3292 join = join.append(" , ");
3293 }
3294 if (orderByFilter!=null){
3295 for (int i = 0; i<orderByFilter.size(); i++){
3296 join = join.append(Gate.DB_OWNER+".t_feature FT"+i);
3297 join = join.append(" , "+Gate.DB_OWNER+".t_feature_key FTK"+i +" , ");
3298 }
3299 }
3300 return join.toString();
3301 }
3302
3303 private String getEndPartOfJoin(List filter, List orderByFilter, String lrType, Vector sqlValues){
3304 StringBuffer endJoin = new StringBuffer("");
3305 endJoin = endJoin.append(" WHERE ");
3306
3307 endJoin = endJoin.append(" LR.lr_type_id = ? ");
3308 if (lrType.equals(DBHelper.CORPUS_CLASS)) {
3309 sqlValues.addElement(new Long(2));
3310 } if (lrType.equals(DBHelper.DOCUMENT_CLASS)) {
3312 sqlValues.addElement(new Long(1));
3313 }
3315 if (filter != null && filter.size()>0){
3316 endJoin = endJoin.append(" and intersected_feat_restr.ft_entity_id = lr.lr_id ");
3317 }
3318
3319 if (orderByFilter!=null && orderByFilter.size()>0){
3320 for (int i=0; i<orderByFilter.size(); i++){
3321 endJoin = endJoin.append(" and lr_id=FT"+i+".ft_entity_id ");
3322 endJoin = endJoin.append(" and FT"+i+".ft_key_id = FTK"+i+".fk_id ");
3323 endJoin = endJoin.append(" and FTK"+i+".fk_string= ? ");
3324 OrderByRestriction restr = (OrderByRestriction) orderByFilter.get(i);
3325 sqlValues.addElement(restr.getKey());
3326 }
3327 endJoin = endJoin.append(" order by ");
3328 for (int i=0; i<orderByFilter.size(); i++){
3329 OrderByRestriction restr = (OrderByRestriction) orderByFilter.get(i);
3330
3331 endJoin = endJoin.append(" FT"+i+".ft_number_value ");
3332 if (restr.getOperator()==OrderByRestriction.OPERATOR_ASCENDING){
3333 endJoin = endJoin.append(" asc ");
3334 } else {
3335 endJoin = endJoin.append(" desc ");
3336 }
3337
3343 if (i<orderByFilter.size()-1){
3344 endJoin = endJoin.append(" , ");
3345 }
3346 }
3347 }
3348 return endJoin.toString();
3349 }
3350
3351 public List findDocIdsByAnn(List constraints, int limitcount) throws PersistenceException {
3352 Vector lrsIDs = new Vector();
3353 CallableStatement stmt = null;
3354 ResultSet rs = null;
3355 Connection conn = null;
3356
3357 try {
3358 Vector sqlValues = new Vector();
3359 String sql = getSQLQueryAnn(constraints, limitcount, sqlValues);
3360 conn = DBHelper.connect(this.getStorageUrl(), true);
3361 stmt = conn.prepareCall(sql);
3362 for (int i = 0; i<sqlValues.size(); i++){
3363 if (sqlValues.elementAt(i) instanceof String){
3364 stmt.setString(i+1,sqlValues.elementAt(i).toString());
3365 }
3366 else if (sqlValues.elementAt(i) instanceof Long){
3367 stmt.setLong(i+1,((Long) sqlValues.elementAt(i)).longValue());
3368 }
3369 else if (sqlValues.elementAt(i) instanceof Integer){
3370 stmt.setLong(i+1,((Integer) sqlValues.elementAt(i)).intValue());
3371 }
3372 }
3373 stmt.execute();
3374 rs = stmt.getResultSet();
3375
3376 while (rs.next()) {
3377 long lr_ID = rs.getLong(1);
3378 lrsIDs.addElement(new Long(lr_ID));
3379 }
3380 return lrsIDs;
3381 }
3382 catch(SQLException sqle) {
3383 throw new PersistenceException("can't get LRs from DB: ["+ sqle+"]");
3384 }
3385 catch (ClassNotFoundException cnfe){
3386 throw new PersistenceException("can't not find driver: ["+ cnfe +"]");
3387 }
3388 finally {
3389 DBHelper.cleanup(rs);
3390 DBHelper.cleanup(stmt);
3391 DBHelper.disconnect(conn, true);
3392 }
3393 }
3394
3395 private String getSQLQueryAnn(List constraints, int limitcount, Vector sqlValues){
3396 StringBuffer sql = new StringBuffer("");
3397 sql.append("SELECT lr_id ");
3398 sql.append(" FROM gateadmin.t_lang_resource LR ");
3399 sql.append(" WHERE LR.lr_type_id = 1 ");
3400
3401 for (int i = 0; i<constraints.size(); i++){
3402 Restriction rest = (Restriction) constraints.get(i);
3403 sql.append(" AND EXISTS( ");
3404 sql.append(" SELECT F.ft_id ");
3405 sql.append(" FROM gateadmin.t_feature F, ");
3406 sql.append(" gateadmin.T_AS_ANNOTATION A, ");
3407 sql.append(" gateadmin.T_ANNOT_SET S, ");
3408 sql.append(" gateadmin.T_DOCUMENT D, ");
3409 sql.append(" gateadmin.t_feature_key FK ");
3410 sql.append(" WHERE F.ft_entity_id = A.asann_ann_id ");
3411 sql.append(" AND A.asann_as_id = S.as_id ");
3412 sql.append(" AND S.as_doc_id = D.doc_id ");
3413 sql.append(" AND D.doc_lr_id = LR.LR_ID ");
3414 sql.append(" AND S.AS_NAME = ? ");
3415 sqlValues.add("NewsCollector");
3416 sql.append(" AND FK.fk_id = F.ft_key_id ");
3417 sql.append(" AND FK.fk_string= ? ");
3418 sqlValues.add(rest.getKey());
3419 sql.append(" AND F.FT_CHARACTER_VALUE = ? ");
3420 sqlValues.add(rest.getStringValue());
3421 sql.append(" ) ");
3422 }
3423 sql.append(" group by lr_id ");
3424 if (limitcount>0){
3425 sql = sql.insert(0,"select lr_id from ( ");
3426 sql = sql.append( ") where rownum<"+(limitcount+1));
3427 }
3428 return sql.toString();
3429 }
3430 private class Feature {
3431
3432 Long entityID;
3433 int entityType;
3434 String key;
3435 Object value;
3436 int valueType;
3437
3438 public Feature(Long eid, int eType, String key, Object value, int vType) {
3439
3440 this.entityID = eid;
3441 this.entityType = eType;
3442 this.key = key;
3443 this.value = value;
3444 this.valueType = vType;
3445 }
3446 }
3447
3448 private class RestrictionComepator implements Comparator{
3449 public int compare(Object o1, Object o2){
3450 Restriction r1 = (Restriction) o1;
3451 Restriction r2 = (Restriction) o2;
3452 return r1.getKey().compareTo(r2.getKey());
3453 }
3454
3455 public boolean equals(Object o){
3456 return false;
3457 }
3458 }
3459
3460
3461}
3462
3463