1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.caleigo.core.service;
20
21
22 import java.sql.*;
23 import java.util.*;
24
25 import org.caleigo.core.*;
26 import org.caleigo.core.meta.*;
27 import org.caleigo.toolkit.log.*;
28 import org.caleigo.toolkit.util.*;
29
30 /***
31 *
32 * @author Mattias Hagstrand
33 * @version $Revision: 1.1 $
34 */
35
36
37
38
39
40
41 public class JDBCMetaProducer implements IMetaProducer
42 {
43
44 public final static int MAX_NBR_OF_OVERVIEW_FIELDS = 3;
45 public final static int MAX_NBR_OF_FIELDS_IN_STATIC = 5;
46
47 private final static int SELECTABLE_SIZE_LIMIT = 20;
48 private final static int LISTABLE_SIZE_LIMIT = 100;
49 private final static int CACHEABLE_SIZE_LIMIT = 1000;
50 private final static int SCANABLE_SIZE_LIMIT = 100000;
51
52
53 private IProgressReceiver mProgressReceiver;
54
55
56
57
58 private String mCatalog;
59 private String mSchema;
60 private String mDataSourceName;
61 private List mEntityRelationCodeNames;
62 private Connection mMetaDataConnection, mDataConnection;
63 private boolean mPerformSizesAnalyzis, mRemoveTablePrefixes, mRemoveColumnPrefixes, mReadDefaultValues, mReadTables, mReadViews;
64
65
66 public JDBCMetaProducer(IProgressReceiver progressReceiver, Connection metaDataConn, String catalog, String schema, String dataSourceName)
67 {
68 this(progressReceiver, metaDataConn, catalog, schema, dataSourceName, null, false, false, false, true, true, true);
69 }
70
71 public JDBCMetaProducer(IProgressReceiver progressReceiver, Connection metaDataConn, String catalog, String schema, String dataSourceName,
72 Connection dataConn, boolean performSizesAnalyzis, boolean removeTablePrefixes, boolean removeColumnPrefixes, boolean readDefaultValues, boolean readTables, boolean readViews)
73 {
74 mProgressReceiver = progressReceiver;
75 mMetaDataConnection = metaDataConn;
76 mDataConnection = dataConn;
77 mCatalog = catalog;
78 mSchema = schema;
79 mDataSourceName = dataSourceName;
80 mPerformSizesAnalyzis = performSizesAnalyzis;
81 mRemoveTablePrefixes = removeTablePrefixes;
82 mRemoveColumnPrefixes = removeColumnPrefixes;
83 mReadDefaultValues = readDefaultValues;
84 mEntityRelationCodeNames = new ArrayList();
85 mReadTables = readTables;
86 mReadViews = readViews;
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 public void produce(IMetaConsumer consumer)
109 {
110 mEntityRelationCodeNames.clear();
111
112 Log.print(this, "Analyzing data source " + mDataSourceName+"...");
113 long startTime = System.currentTimeMillis();
114
115 try
116 {
117
118 DatabaseMetaData dbMetaData = mMetaDataConnection.getMetaData();
119
120 consumer.beginDataSource(mDataSourceName, mDataSourceName, mDataSourceName, "1.0", false);
121
122 Vector tables = new Vector();
123 int nbrOfTables = 0;
124 int nbrOfViews = 0;
125 ResultSet tablesRS = null;
126 if (mReadTables)
127 {
128 tablesRS = dbMetaData.getTables(mCatalog, mSchema, "%", new String[] {"TABLE"});
129 while (tablesRS.next())
130 {
131 String tableName = tablesRS.getString("TABLE_NAME");
132 tables.add(tableName);
133 nbrOfTables++;
134 }
135 tablesRS.close();
136 }
137
138
139
140
141
142 if (mReadViews)
143 {
144 tablesRS = dbMetaData.getTables(mCatalog, mSchema, "%", new String[] {"VIEW"});
145 while (tablesRS.next())
146 {
147 String tableName = tablesRS.getString("TABLE_NAME");
148 tables.add(tableName);
149 nbrOfViews++;
150 nbrOfTables++;
151 }
152 tablesRS.close();
153 }
154 Log.print(this, " Found "+nbrOfTables+" tables in data source.");
155
156 HashMap primaryKeys = new HashMap();
157 HashMap indexes = new HashMap();
158
159 HashMap referenceFields = new HashMap();
160 ArrayList columns = new ArrayList();
161 for (int i = 0; i < tables.size(); i++)
162 {
163 String tableName = (String) tables.get(i);
164 primaryKeys.clear();
165 indexes.clear();
166
167 referenceFields.clear();
168 columns.clear();
169
170 mProgressReceiver.setProgressMessage("Analyzing table " + tableName + "...");
171 Log.print(this, " Analyzing table " + tableName + "...");
172
173
174 ResultSet columnsRS = dbMetaData.getColumns(mCatalog, mSchema, tableName, "%");
175 if (columnsRS != null)
176 {
177 while (columnsRS.next())
178 columns.add(columnsRS.getString("COLUMN_NAME"));
179
180 columnsRS.close();
181 }
182
183
184 try
185 {
186 ResultSet importedKeysRS = dbMetaData.getImportedKeys(mCatalog, mSchema, tableName);
187 if (importedKeysRS != null)
188 {
189 while (importedKeysRS.next())
190 {
191 String pkTableName = importedKeysRS.getString("PKTABLE_NAME");
192 String fkTableName = importedKeysRS.getString("FKTABLE_NAME");
193 String fkColumnName = importedKeysRS.getString("FKCOLUMN_NAME");
194 referenceFields.put(fkColumnName, "");
195 }
196 importedKeysRS.close();
197 }
198 }
199 catch (Exception e)
200 {
201 Log.printWarning(this, "Couldn't get imported keys for table "+tableName, e);
202 }
203
204
205 try
206 {
207 ResultSet primaryKeysRS = dbMetaData.getPrimaryKeys(mCatalog, mSchema, tableName);
208 if (primaryKeysRS != null)
209 {
210 while (primaryKeysRS.next())
211 {
212 String columnName = primaryKeysRS.getString("COLUMN_NAME");
213 Log.print(this, " Found primary key: " + columnName);
214 primaryKeys.put(columnName, "");
215 }
216 primaryKeysRS.close();
217 }
218 else
219 Log.printWarning(this, "getPrimaryKeys returned null");
220 }
221 catch (Exception e)
222 {
223 Log.printWarning(this, "Couldn't get primary keys for table "+tableName, e);
224 }
225
226
227 int entityType = this.getEntityType(columns, primaryKeys, referenceFields);
228 int cacheTime = 300;
229 if(entityType == IEntityDescriptor.STATIC_ENTITY)
230 cacheTime = 72000;
231 int entityFlags = this.getTableSizeType(tableName);
232
233
234 if (i < (nbrOfTables - nbrOfViews))
235 {
236 entityFlags = entityFlags | AbstractEntityDescriptor.CREATABLE | AbstractEntityDescriptor.EDITABLE;
237 if (entityType == IEntityDescriptor.LINK_ENTITY)
238 entityFlags |= AbstractEntityDescriptor.DELETABLE;
239 }
240 else
241 {
242 ResultSet colRS = dbMetaData.getColumns(mCatalog, mSchema, tableName, "%");
243 while (colRS.next())
244 {
245 System.out.println(tableName + ".% -> " + colRS.getString(3) + "." + colRS.getString(4));;
246 }
247 colRS.close();
248 }
249
250
251
252 consumer.beginEntity(this.createCodeName(tableName, false, true, true), tableName, this.createDisplayName(tableName, false, true, true), entityType, entityFlags, cacheTime);
253
254 try
255 {
256 ResultSet importedKeysRS = dbMetaData.getImportedKeys(mCatalog, mSchema, tableName);
257 if (importedKeysRS != null)
258 {
259 boolean previousEntityRelationDone = true;
260 int oldKeySeq = -1;
261 while (importedKeysRS.next())
262 {
263 String pkTableName = importedKeysRS.getString("PKTABLE_NAME");
264 String pkColumnName = importedKeysRS.getString("PKCOLUMN_NAME");
265 String fkTableName = importedKeysRS.getString("FKTABLE_NAME");
266 String fkColumnName = importedKeysRS.getString("FKCOLUMN_NAME");
267 short keySeq = importedKeysRS.getShort("KEY_SEQ");
268
269 if ((keySeq == 0 || (keySeq == 1 && oldKeySeq != 0)) && !previousEntityRelationDone)
270 {
271 consumer.endEntityRelation();
272 previousEntityRelationDone = true;
273 oldKeySeq = -1;
274 }
275
276 oldKeySeq = keySeq;
277
278 Log.print(this, " Found imported key(" + keySeq + "): " + fkTableName + "." + fkColumnName + "->" + pkTableName + "." + pkColumnName);
279 if (previousEntityRelationDone)
280 {
281 consumer.beginEntityRelation(fkTableName,
282 pkTableName,
283 this.createEntityRelationSourceName(this.createCodeName(fkTableName, false, true, true), this.createCodeName(pkTableName, false, true, true)),
284 this.createEntityRelationCodeName(this.createCodeName(fkTableName, false, true, true), this.createCodeName(pkTableName, false, true, true)),
285 this.createDisplayName(fkColumnName, false, true, false),
286 this.createDisplayName(fkTableName, false, false, true));
287 previousEntityRelationDone = false;
288 }
289
290 consumer.addFieldRelation(fkColumnName, pkColumnName);
291
292 }
293 importedKeysRS.close();
294
295 if (!previousEntityRelationDone)
296 consumer.endEntityRelation();
297 }
298 else
299 Log.printWarning(this, "getImportedKeys returned null");
300 }
301 catch (Exception e)
302 {
303 Log.printWarning(this, "Couldn't get imported keys for table "+tableName, e);
304 }
305
306 try
307 {
308 ResultSet indexesRS = dbMetaData.getIndexInfo(mCatalog, mSchema, tableName, false, false);
309 if (indexesRS != null)
310 {
311 while (indexesRS.next())
312 {
313 String columnName = indexesRS.getString("COLUMN_NAME");
314 if (columnName != null)
315 {
316 Log.print(this, " Found index column " + columnName);
317 indexes.put(columnName, "");
318 }
319 }
320 indexesRS.close();
321 }
322 else
323 Log.printWarning(this, "getIndexInfo returned null");
324 }
325 catch (Exception e)
326 {
327 Log.printWarning(this, "Couldn't get index info", e);
328 }
329
330 columnsRS = dbMetaData.getColumns(mCatalog, mSchema, tableName, "%");
331 if (columnsRS != null)
332 {
333 int index = 0;
334 int nbrOfOverviewFields = 0;
335 boolean nameFieldFound = false;
336 while (columnsRS != null && columnsRS.next())
337 {
338 Object columnDef = null;
339 if (mReadDefaultValues)
340 columnDef = columnsRS.getObject("COLUMN_DEF");
341
342 String sourceName = columnsRS.getString("COLUMN_NAME");
343 DataType dataType = this.translateType(columnsRS.getShort("DATA_TYPE"), columnsRS.getString("TYPE_NAME"));
344
345 int flags = 0;
346 if (columnsRS.getString("IS_NULLABLE").trim().compareTo("NO") == 0)
347 flags |= IFieldDescriptor.REQUIRED;
348 if (primaryKeys.containsKey(sourceName))
349 flags |= IFieldDescriptor.IDENTITY_FIELD | IFieldDescriptor.REQUIRED;
350 if (indexes.containsKey(sourceName))
351 flags |= IFieldDescriptor.INDEXED;
352
353
354
355
356 if (sourceName.toUpperCase().indexOf("NAME") != -1 && !nameFieldFound)
357 {
358 flags |= IFieldDescriptor.NAME_FIELD | IFieldDescriptor.OVERVIEW_FIELD;
359 nameFieldFound = true;
360 }
361 if (nbrOfOverviewFields < MAX_NBR_OF_OVERVIEW_FIELDS && this.isOverviewFieldType(dataType))
362 {
363 flags |= IFieldDescriptor.OVERVIEW_FIELD;
364 nbrOfOverviewFields++;
365 }
366
367 Log.print(this, " Found column("+index+") "+sourceName+ " with type "+dataType.getTypeName()+"("+columnsRS.getInt("COLUMN_SIZE")+")");
368 consumer.addField(this.createCodeName(sourceName, primaryKeys.containsKey(sourceName), false, false), sourceName,
369 this.createDisplayName(sourceName, primaryKeys.containsKey(sourceName), false, false), dataType,
370 columnsRS.getInt("COLUMN_SIZE"), flags, this.convertDefaultValue(dataType, columnDef));
371 index++;
372 }
373
374 columnsRS.close();
375 }
376 else
377 Log.printWarning(this, "getColumns returned null");
378
379
380 consumer.endEntity();
381 mProgressReceiver.setProgress((int) (((i + 1) / (nbrOfTables * 1.0)) * 100));
382 }
383
384 consumer.endDataSource();
385 Log.print(this, "Data source analysis completed in " + (System.currentTimeMillis()-startTime) + " ms.");
386 }
387 catch (Exception e)
388 {
389 Log.printError(this, "Error while producing meta data", e);
390 }
391 finally
392 {
393 try
394 {
395 mMetaDataConnection.close();
396 }
397 catch(SQLException sqle)
398 {
399 sqle.printStackTrace();
400 }
401
402 try
403 {
404 if (mDataConnection != null && mDataConnection != mMetaDataConnection)
405 mDataConnection.close();
406 }
407 catch(SQLException sqle)
408 {
409 sqle.printStackTrace();
410 }
411 }
412 }
413
414
415 protected int getEntityType(ArrayList columns, HashMap primaryKeys, HashMap referenceFields)
416 {
417 boolean allColumnsArePrimaryKeys = true;
418 boolean allPrimaryKeysAreForeignKeys = true;
419
420 for (int i = 0; i < columns.size(); i++)
421 {
422 if (!primaryKeys.containsKey(columns.get(i)))
423 allColumnsArePrimaryKeys = false;
424 if (primaryKeys.containsKey(columns.get(i)) && !referenceFields.containsKey(columns.get(i)))
425 allPrimaryKeysAreForeignKeys = false;
426 }
427
428 if (allColumnsArePrimaryKeys && allPrimaryKeysAreForeignKeys)
429 return IEntityDescriptor.LINK_ENTITY;
430 if (allPrimaryKeysAreForeignKeys)
431 return IEntityDescriptor.SLAVE_ENTITY;
432
433 if (columns.size() <= MAX_NBR_OF_FIELDS_IN_STATIC && referenceFields.keySet().size() == 0 &&
434 primaryKeys.keySet().size() == 1)
435 {
436 return IEntityDescriptor.STATIC_ENTITY;
437 }
438
439 return IEntityDescriptor.MASTER_ENTITY;
440 }
441
442 /***
443 * Creates a Correct Code name given the source name from the parsed metadata
444 *
445 * @param sourceName The Source Name for the entity
446 * @param isPrimaryKeyColumn Set to true if the column is part of the Primary Key constraint
447 * @param removePlural Set to true if the method shoul convert pluralis words to singularis
448 * @param isTable true if creating a code name for a table
449 * @return Returns the correct Code Name
450 */
451 protected String createCodeName(String sourceName, boolean isPrimaryKeyColumn, boolean removePlural, boolean isTable)
452 {
453
454 boolean upperCaseOnly = true;
455 for (int i = 0; upperCaseOnly && i < sourceName.length(); i++)
456 if(Character.isLetter(sourceName.charAt(i)))
457 upperCaseOnly = upperCaseOnly && Character.isUpperCase(sourceName.charAt(i));
458
459
460 if (isTable && mRemoveTablePrefixes || !isTable && mRemoveColumnPrefixes)
461 {
462 int underscoreIndex = sourceName.indexOf("_");
463 if (underscoreIndex != -1 && underscoreIndex < sourceName.length() - 2)
464 {
465 sourceName = sourceName.substring(underscoreIndex + 1);
466 }
467 }
468
469
470 StringBuffer codeName = new StringBuffer();
471 boolean lastWasWhiteSpace = true;
472 for(int i = 0; i < sourceName.length(); i++)
473 {
474 if(Character.isWhitespace(sourceName.charAt(i)) || sourceName.charAt(i)=='_')
475 lastWasWhiteSpace = true;
476 else if(Character.isJavaLetterOrDigit(sourceName.charAt(i)))
477 {
478 if(lastWasWhiteSpace)
479 codeName.append(Character.toUpperCase(sourceName.charAt(i)));
480 else if(upperCaseOnly)
481 codeName.append(Character.toLowerCase(sourceName.charAt(i)));
482 else
483 codeName.append(sourceName.charAt(i));
484 lastWasWhiteSpace = false;
485 }
486 }
487
488
489 if(removePlural)
490 this.removePlural(codeName);
491
492 return codeName.toString();
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525 }
526
527 /***
528 * Creates a correct Display Name given the source Name from the parsed metadata
529 *
530 * @param sourceName The source name for the entity
531 * @param isPrimaryKeyColumn Set to true if the column is part of the Primary Key constraint
532 * @param removePlural Set to true if the method shoul convert pluralis words to singularis
533 * @param isTable true if creating a display name for a table
534 * @return Returns the correct Display Name
535 */
536 protected String createDisplayName(String sourceName, boolean isPrimaryKeyColumn, boolean removePlural, boolean isTable)
537 {
538 StringBuffer tempBuffer = new StringBuffer(sourceName);
539
540
541
542 boolean onlyUppserCaseLetters = true;
543 for (int i = 0; onlyUppserCaseLetters && i < tempBuffer.length(); i++)
544 if (Character.isLowerCase(tempBuffer.charAt(i)))
545 onlyUppserCaseLetters = false;
546
547 if (onlyUppserCaseLetters)
548 for (int i = 0; i < tempBuffer.length(); i++)
549 {
550 if (tempBuffer.charAt(i)=='_')
551 {
552 i++;
553 }
554 else
555 {
556 tempBuffer.setCharAt(i, Character.toLowerCase(tempBuffer.charAt(i)));
557 }
558 }
559
560
561 if (removePlural)
562 this.removePlural(tempBuffer);
563
564
565 if (!isPrimaryKeyColumn)
566 this.removeTrailingID(tempBuffer);
567
568 StringBuffer sourceNameBuffer = new StringBuffer(tempBuffer.toString());
569
570
571 if (isTable && mRemoveTablePrefixes || !isTable && mRemoveColumnPrefixes)
572 {
573 int underscoreIndex = sourceNameBuffer.indexOf("_");
574 if (underscoreIndex != -1 && underscoreIndex < sourceNameBuffer.length() - 2)
575 {
576 String newDisplayName = sourceNameBuffer.substring(underscoreIndex + 1);
577 sourceNameBuffer = new StringBuffer(newDisplayName);
578 tempBuffer = new StringBuffer(newDisplayName);
579 }
580 }
581
582
583
584 int nbrOfSpacesInserted = 0;
585 for (int i = 0; i < tempBuffer.length(); i++)
586 if (Character.isUpperCase(sourceNameBuffer.charAt(i + nbrOfSpacesInserted))
587 && i + nbrOfSpacesInserted + 1 < sourceNameBuffer.length()
588 && i > 0
589 && Character.isLowerCase(sourceNameBuffer.charAt(i + nbrOfSpacesInserted + 1))
590 && sourceNameBuffer.charAt(i + nbrOfSpacesInserted - 1) != ' ')
591 {
592 nbrOfSpacesInserted++;
593 sourceNameBuffer.insert(i + nbrOfSpacesInserted - 1, ' ');
594 }
595
596 if (sourceNameBuffer.length() > 0 && Character.isLowerCase(sourceNameBuffer.charAt(0)))
597 sourceNameBuffer.replace(0, 1, String.valueOf(Character.toUpperCase(sourceNameBuffer.charAt(0))));
598
599
600 return sourceNameBuffer.toString().replace('_', ' ');
601 }
602
603 /***
604 * Converts a pluralis word to singularis
605 *
606 * @param stringBuffer The StringBuffer containing the word to process
607 */
608 protected void removePlural(StringBuffer stringBuffer)
609 {
610
611 if(stringBuffer.toString().endsWith("Status"))
612 return;
613
614 if (stringBuffer.length() > 3
615 && Character.toLowerCase(stringBuffer.charAt(stringBuffer.length() - 1)) == 's'
616 && Character.toLowerCase(stringBuffer.charAt(stringBuffer.length() - 2)) == 'e'
617 && Character.toLowerCase(stringBuffer.charAt(stringBuffer.length() - 3)) == 'i')
618 {
619 stringBuffer.replace(stringBuffer.length() - 3, stringBuffer.length(), "y");
620 }
621
622 if (stringBuffer.length() > 1
623 && Character.toLowerCase(stringBuffer.charAt(stringBuffer.length() - 1)) == 's'
624 && Character.toLowerCase(stringBuffer.charAt(stringBuffer.length() - 2)) != 's')
625 {
626 stringBuffer.deleteCharAt(stringBuffer.length() - 1);
627 }
628 }
629
630 protected void removeTrailingID(StringBuffer stringBuffer)
631 {
632 if (stringBuffer.toString().indexOf("ID") != -1)
633 stringBuffer.delete(stringBuffer.toString().indexOf("ID"), stringBuffer.toString().indexOf("ID") + 2);
634 }
635
636 protected DataType translateType(short type, String typeName)
637 {
638 switch (type)
639 {
640 case Types.CHAR:
641 case Types.VARCHAR:
642 case Types.LONGVARCHAR:
643 return DataType.STRING;
644 case Types.TINYINT:
645 return DataType.BYTE;
646 case Types.SMALLINT:
647 return DataType.SHORT;
648 case Types.INTEGER:
649 return DataType.INTEGER;
650 case Types.BIGINT:
651 return DataType.LONG;
652 case Types.REAL:
653 return DataType.FLOAT;
654 case Types.FLOAT:
655 case Types.DOUBLE:
656 return DataType.DOUBLE;
657 case Types.DATE:
658 return DataType.DATE;
659 case Types.BOOLEAN:
660 case Types.BIT:
661 return DataType.BOOLEAN;
662 case Types.TIME:
663 case Types.TIMESTAMP:
664 return DataType.DATE;
665 case Types.NUMERIC:
666 case Types.DECIMAL:
667 return DataType.BIG_DECIMAL;
668
669
670 case Types.ARRAY:
671 case Types.BINARY:
672 case Types.BLOB:
673 case Types.CLOB:
674 case Types.DATALINK:
675 case Types.DISTINCT:
676 case Types.JAVA_OBJECT:
677 case Types.LONGVARBINARY:
678 case Types.NULL:
679 case Types.OTHER:
680 case Types.REF:
681 case Types.STRUCT:
682 case Types.VARBINARY:
683 default:
684 return this.performTypeRecognition(typeName);
685 }
686 }
687
688 protected DataType performTypeRecognition(String typeName)
689 {
690 String typeNameUpperCase = typeName.toUpperCase();
691 if (typeNameUpperCase.indexOf("CHAR") != -1 ||
692 typeNameUpperCase.indexOf("TEXT") != -1)
693 return DataType.STRING;
694
695 if (typeNameUpperCase.indexOf("DATE") != -1 ||
696 typeNameUpperCase.indexOf("TIME") != -1)
697 return DataType.DATE;
698
699 if (typeNameUpperCase.indexOf("IMAGE") != -1)
700 return DataType.IMAGE;
701
702 return DataType.UNKNOWN;
703 }
704
705 protected Object convertDefaultValue(DataType dataType, Object value)
706 {
707 try
708 {
709 if (value==null)
710 {
711 return null;
712 }
713
714 Object result = dataType.convertFrom(value);
715
716 if (result!=null)
717 {
718 return result;
719 }
720
721
722
723
724 if (Number.class.isAssignableFrom(dataType.getDataClass()))
725 {
726 String oldValue = value.toString();
727 StringBuffer newValue = new StringBuffer();
728
729 for (int i=0;i<oldValue.length();i++)
730 {
731 if (Character.isDigit(oldValue.charAt(i)) || oldValue.charAt(i) == ',' || oldValue.charAt(i) == '.')
732 {
733 newValue.append(oldValue.charAt(i));
734 }
735 }
736
737 result = dataType.convertFrom(newValue.toString());
738
739 if (result!=null)
740 {
741 return result;
742 }
743
744 }
745
746 if (java.util.Date.class.isAssignableFrom(dataType.getDataClass()))
747 {
748 StringBuffer newValue = new StringBuffer();
749 String oldValue = value.toString();
750
751 for (int i=0;i<oldValue.length();i++)
752 {
753 if (Character.isDigit(oldValue.charAt(i)) || oldValue.charAt(i) == ' ' || oldValue.charAt(i) == ':' || oldValue.charAt(i) == '-')
754 {
755 newValue.append(oldValue.charAt(i));
756 }
757 }
758
759 result = dataType.convertFrom(newValue.toString());
760
761 if (result!=null)
762 {
763 return result;
764 }
765
766 }
767
768 return null;
769
770 }
771 catch (Throwable t) {}
772
773
774 return null;
775 }
776
777 protected boolean isOverviewFieldType(DataType dataType)
778 {
779 if ((dataType == DataType.IMAGE) ||
780 (dataType == DataType.UNKNOWN))
781 return false;
782
783 return true;
784 }
785
786 protected String createEntityRelationSourceName(String referenceCodeName, String targetCodeName)
787 {
788 return this.createEntityRelationCodeName(referenceCodeName, targetCodeName);
789 }
790
791 protected String createEntityRelationCodeName(String referenceCodeName, String targetCodeName)
792 {
793 String codeName = referenceCodeName + targetCodeName;
794
795 if (mEntityRelationCodeNames.contains(codeName))
796 {
797 int id = 1;
798 while (mEntityRelationCodeNames.contains(codeName + id))
799 id++;
800 codeName += id;
801 }
802
803 mEntityRelationCodeNames.add(codeName);
804
805 return codeName;
806 }
807
808 protected int getTableSizeType(String tableName)
809 {
810 if (mPerformSizesAnalyzis)
811 {
812 try
813 {
814 Statement statement = mDataConnection.createStatement();
815 if (SQLToolKit.isQuotingIdentifiersByDefault())
816 tableName = SQLToolKit.getDefaultQuotingString() + tableName + SQLToolKit.getDefaultQuotingString();
817
818 ResultSet sizeRS = statement.executeQuery("SELECT count(*) FROM " + tableName);
819 sizeRS.next();
820 int tableSize = sizeRS.getInt(1);
821 sizeRS.close();
822
823 if (tableSize < SELECTABLE_SIZE_LIMIT)
824 return AbstractEntityDescriptor.SELECTABLE;
825 if (tableSize < LISTABLE_SIZE_LIMIT)
826 return AbstractEntityDescriptor.LISTABLE;
827 if (tableSize < CACHEABLE_SIZE_LIMIT)
828 return AbstractEntityDescriptor.CACHEABLE;
829 if (tableSize < SCANABLE_SIZE_LIMIT)
830 return AbstractEntityDescriptor.SCANABLE;
831
832 } catch (SQLException e)
833 {
834 Log.printError(this.getClass().getName(), "Error reading table size", e);
835 }
836 }
837
838 return AbstractEntityDescriptor.CACHEABLE;
839 }
840 }