Revision 47436 trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.file/org.gvsig.fmap.dal.file.dbf/src/main/java/org/gvsig/fmap/dal/store/dbf/DBFStoreProvider.java
DBFStoreProvider.java | ||
---|---|---|
27 | 27 |
import java.math.BigDecimal; |
28 | 28 |
import java.nio.charset.Charset; |
29 | 29 |
import java.util.ArrayList; |
30 |
import java.util.Date; |
|
30 | 31 |
import java.util.Iterator; |
31 | 32 |
import java.util.List; |
32 |
import java.util.logging.Level; |
|
33 |
|
|
33 |
import java.util.Locale; |
|
34 | 34 |
import org.apache.commons.io.FileUtils; |
35 |
import org.apache.commons.lang3.StringUtils; |
|
36 |
|
|
35 |
import org.apache.commons.lang3.mutable.MutableInt; |
|
37 | 36 |
import org.gvsig.fmap.dal.DALLocator; |
38 | 37 |
import org.gvsig.fmap.dal.DataManager; |
39 | 38 |
import org.gvsig.fmap.dal.DataServerExplorer; |
... | ... | |
49 | 48 |
import org.gvsig.fmap.dal.exception.ReadException; |
50 | 49 |
import org.gvsig.fmap.dal.exception.UnsupportedVersionException; |
51 | 50 |
import org.gvsig.fmap.dal.exception.ValidateDataParametersException; |
51 |
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor; |
|
52 | 52 |
import org.gvsig.fmap.dal.feature.EditableFeatureType; |
53 | 53 |
import org.gvsig.fmap.dal.feature.Feature; |
54 | 54 |
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
... | ... | |
82 | 82 |
import org.gvsig.metadata.MetadataLocator; |
83 | 83 |
import org.gvsig.metadata.MetadataManager; |
84 | 84 |
import org.gvsig.metadata.exceptions.MetadataException; |
85 |
import org.gvsig.tools.dataTypes.CoercionContext; |
|
86 |
import org.gvsig.tools.dataTypes.CoercionContextDecimal; |
|
85 | 87 |
import org.gvsig.tools.dataTypes.CoercionException; |
86 | 88 |
import org.gvsig.tools.dispose.DisposableIterator; |
87 | 89 |
import org.gvsig.tools.dynobject.DynObject; |
88 | 90 |
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException; |
89 | 91 |
import org.gvsig.tools.exception.BaseException; |
90 | 92 |
import org.gvsig.tools.logger.FilteredLogger; |
91 |
|
|
93 |
import org.gvsig.tools.math.BigDecimalUtils; |
|
92 | 94 |
import org.slf4j.Logger; |
93 | 95 |
import org.slf4j.LoggerFactory; |
96 |
import sun.security.ec.point.ProjectivePoint; |
|
94 | 97 |
|
95 | 98 |
public class DBFStoreProvider extends AbstractFeatureStoreProvider implements |
96 | 99 |
ResourceConsumer { |
... | ... | |
170 | 173 |
|
171 | 174 |
} |
172 | 175 |
|
176 |
@Override |
|
173 | 177 |
public Object getDynValue(String name) throws DynFieldNotFoundException { |
174 | 178 |
try { |
175 | 179 |
this.open(); |
... | ... | |
201 | 205 |
dbfResource.addConsumer(this); |
202 | 206 |
} |
203 | 207 |
|
208 |
@Override |
|
204 | 209 |
public String getProviderName() { |
205 | 210 |
return NAME; |
206 | 211 |
} |
... | ... | |
209 | 214 |
return (DBFStoreParameters) super.getParameters(); |
210 | 215 |
} |
211 | 216 |
|
217 |
@Override |
|
212 | 218 |
public DataServerExplorer getExplorer() throws ReadException { |
213 | 219 |
DataManager manager = DALLocator.getDataManager(); |
214 | 220 |
FilesystemServerExplorerParameters params; |
... | ... | |
222 | 228 |
} |
223 | 229 |
} |
224 | 230 |
|
231 |
@Override |
|
225 | 232 |
protected FeatureProvider internalGetFeatureProviderByReference( |
226 | 233 |
FeatureReferenceProviderServices reference, FeatureType featureType) |
227 | 234 |
throws DataException { |
228 | 235 |
return this.getFeatureProviderByIndex( |
229 |
((Number) reference.getOID()).longValue(), featureType); |
|
236 |
((Number) reference.getOID()).longValue(), featureType, null);
|
|
230 | 237 |
} |
231 | 238 |
|
239 |
@Override |
|
232 | 240 |
public void performChanges(Iterator deleteds, Iterator inserteds, |
233 | 241 |
Iterator updateds, Iterator originalFeatureTypesUpdated) |
234 | 242 |
throws PerformEditingException { |
... | ... | |
358 | 366 |
} |
359 | 367 |
} |
360 | 368 |
|
361 |
public FeatureProvider createFeatureProvider(FeatureType type) throws DataException { |
|
362 |
return new DBFFeatureProvider(this, type); |
|
369 |
@Override |
|
370 |
public FeatureProvider createFeatureProvider(FeatureType providerFeatureType) throws DataException { |
|
371 |
return new DBFFeatureProvider(this, providerFeatureType, null); |
|
363 | 372 |
} |
364 | 373 |
|
374 |
public FeatureProvider createFeatureProvider(FeatureType providerFeatureType, FeatureType storeFeatureType) throws DataException { |
|
375 |
return new DBFFeatureProvider(this, providerFeatureType, storeFeatureType); |
|
376 |
} |
|
377 |
|
|
365 | 378 |
protected void initFeatureType() throws InitializeException { |
366 | 379 |
this.featureType = this.getTheFeatureType(); |
367 | 380 |
FeatureType defaultType = this.featureType.getNotEditableCopy(); |
... | ... | |
398 | 411 |
} |
399 | 412 |
|
400 | 413 |
|
401 |
protected void loadValue(FeatureProvider featureProvider, long rowIndex, |
|
414 |
protected void loadValue(DBFFeatureProvider featureProvider, long rowIndex,
|
|
402 | 415 |
FeatureAttributeDescriptor descriptor) throws ReadException { |
403 | 416 |
|
404 | 417 |
if (descriptor.getEvaluator() != null) { |
... | ... | |
437 | 450 |
break; |
438 | 451 |
|
439 | 452 |
case DataTypes.DECIMAL: |
440 |
featureProvider.set(index, |
|
441 |
formatter.parseDecimal( |
|
442 |
value, |
|
443 |
descriptor.getMathContext(), |
|
444 |
descriptor.getScale(), |
|
445 |
(BigDecimal) defaultValue |
|
446 |
) |
|
453 |
BigDecimal d = formatter.parseDecimal( |
|
454 |
value, |
|
455 |
descriptor.getMathContext(), |
|
456 |
descriptor.getScale(), |
|
457 |
(BigDecimal) defaultValue |
|
447 | 458 |
); |
459 |
if (!BigDecimalUtils.isValid(d, descriptor.getScale(), descriptor.getPrecision())) { |
|
460 |
DBFStoreParameters params = this.getDBFParameters(); |
|
461 |
if(params.allowInconsistenciesInDecimals() ) { |
|
462 |
MutableInt scale = new MutableInt(descriptor.getScale()); |
|
463 |
MutableInt precision = new MutableInt(descriptor.getPrecision()); |
|
464 |
d = BigDecimalUtils.fixIfCan(d, scale, precision); |
|
465 |
updateStoreScaleAndPrecision(featureProvider, descriptor, scale.intValue(), precision.intValue()); |
|
466 |
} else { |
|
467 |
FeatureType storeFeatureType = featureProvider.getStoreFeatureType(); |
|
468 |
if(storeFeatureType != null){ |
|
469 |
FeatureAttributeDescriptor storeDescriptor = storeFeatureType.getAttributeDescriptor(descriptor.getName()); |
|
470 |
if (storeDescriptor instanceof EditableFeatureAttributeDescriptor && BigDecimalUtils.isValid(d, storeDescriptor.getScale(), storeDescriptor.getPrecision())) { |
|
471 |
((EditableFeatureAttributeDescriptor)descriptor).setScale(storeDescriptor.getScale()); |
|
472 |
((EditableFeatureAttributeDescriptor)descriptor).setPrecision(storeDescriptor.getPrecision()); |
|
473 |
} |
|
474 |
} |
|
475 |
} |
|
476 |
} |
|
477 |
featureProvider.set(index,d); |
|
448 | 478 |
break; |
449 | 479 |
|
450 | 480 |
case DataTypes.DOUBLE: |
... | ... | |
499 | 529 |
protected FeatureProvider getFeatureProviderByIndex(long index) throws DataException { |
500 | 530 |
return this |
501 | 531 |
.getFeatureProviderByIndex(index, this.getStoreServices() |
502 |
.getDefaultFeatureType()); |
|
532 |
.getDefaultFeatureType(), null);
|
|
503 | 533 |
} |
504 | 534 |
|
535 |
@Override |
|
505 | 536 |
public long getFeatureCount() throws ReadException, OpenException, |
506 | 537 |
ResourceNotifyChangesException { |
507 | 538 |
this.open(); |
508 |
return (long) getResource().execute(new ResourceAction() { |
|
509 |
public Object run() throws Exception { |
|
510 |
return (long) dbfFile.getRecordCount(); |
|
511 |
} |
|
512 |
}); |
|
539 |
return (long) getResource().execute(() -> (long) dbfFile.getRecordCount()); |
|
513 | 540 |
} |
514 | 541 |
|
542 |
@Override |
|
515 | 543 |
public FeatureSetProvider createSet(FeatureQuery query, FeatureType featureType) |
516 | 544 |
throws DataException { |
517 |
return new DBFSetProvider(this, query, featureType); |
|
545 |
return new DBFSetProvider(this, query, featureType, null);
|
|
518 | 546 |
} |
519 | 547 |
|
548 |
public FeatureSetProvider createSet(FeatureQuery query, FeatureType providerFeatureType, FeatureType storeFeatureType) |
|
549 |
throws DataException { |
|
550 |
return new DBFSetProvider(this, query, providerFeatureType, storeFeatureType); |
|
551 |
} |
|
552 |
|
|
520 | 553 |
public boolean canCreate() { |
521 | 554 |
return true; |
522 | 555 |
} |
... | ... | |
600 | 633 |
} |
601 | 634 |
|
602 | 635 |
public boolean allowWrite() { |
603 |
if(allowDuplicatedFieldNames){ |
|
636 |
if(allowDuplicatedFieldNames || this.getDBFParameters().allowInconsistenciesInDecimals()){
|
|
604 | 637 |
return false; |
605 | 638 |
} |
606 | 639 |
return this.dbfFile.isWritable(); |
... | ... | |
621 | 654 |
} |
622 | 655 |
|
623 | 656 |
protected FeatureProvider getFeatureProviderByIndex(long index, |
624 |
FeatureType featureType) throws DataException {
|
|
625 |
FeatureProvider featureProvider = this.createFeatureProvider(featureType);
|
|
657 |
FeatureType providerFeatureType, FeatureType storeFeatureType) throws DataException {
|
|
658 |
FeatureProvider featureProvider = this.createFeatureProvider(providerFeatureType, storeFeatureType);
|
|
626 | 659 |
featureProvider.setOID(index); |
627 | 660 |
return featureProvider; |
628 | 661 |
} |
... | ... | |
649 | 682 |
throw rex; |
650 | 683 |
} |
651 | 684 |
|
685 |
// long t1 = System.nanoTime(); |
|
686 |
((DBFFeatureProvider)featureProvider).setBroken(false); |
|
652 | 687 |
for (FeatureAttributeDescriptor desc : featureProvider.getType()) { |
653 |
this.loadValue(featureProvider, index, desc); |
|
688 |
try { |
|
689 |
this.loadValue((DBFFeatureProvider)featureProvider, index, desc); |
|
690 |
} catch (Throwable th) { |
|
691 |
this.logger.warn("Can't load value for attribute '"+desc.getName()+"'", th); |
|
692 |
((DBFFeatureProvider)featureProvider).setBroken(true); |
|
693 |
featureProvider.set(desc.getIndex(), null); |
|
694 |
} |
|
654 | 695 |
} |
696 |
// long t2 = System.nanoTime(); |
|
697 |
// LOG.info("load "+index+" in :"+(t2-t1)); |
|
655 | 698 |
} |
656 | 699 |
|
700 |
@Override |
|
657 | 701 |
public int getOIDType() { |
658 | 702 |
return DataTypes.LONG; |
659 | 703 |
} |
660 | 704 |
|
705 |
@Override |
|
661 | 706 |
public Object createNewOID() { |
662 | 707 |
if (this.counterNewsOIDs < 0) { |
663 | 708 |
try { |
... | ... | |
672 | 717 |
return counterNewsOIDs; |
673 | 718 |
} |
674 | 719 |
|
720 |
@Override |
|
675 | 721 |
public boolean supportsAppendMode() { |
676 | 722 |
return true; |
677 | 723 |
} |
678 | 724 |
|
725 |
@Override |
|
679 | 726 |
public void append(final FeatureProvider featureProvider) |
680 | 727 |
throws DataException { |
681 |
getResource().execute(new ResourceAction() { |
|
682 |
public Object run() throws Exception { |
|
683 |
writer.append(getStoreServices().createFeature(featureProvider)); |
|
684 |
return null; |
|
685 |
} |
|
728 |
getResource().execute(() -> { |
|
729 |
writer.append(getStoreServices().createFeature(featureProvider)); |
|
730 |
return null; |
|
686 | 731 |
}); |
687 | 732 |
} |
688 | 733 |
|
734 |
@Override |
|
689 | 735 |
public void beginAppend() throws DataException { |
690 | 736 |
this.close(); |
691 |
getResource().execute(new ResourceAction() { |
|
692 |
public Object run() throws Exception { |
|
693 |
writer.begin(getDBFParameters(), |
|
694 |
getStoreServices().getDefaultFeatureType(), |
|
695 |
getStoreServices().getFeatureStore().getFeatureCount()); |
|
696 |
return null; |
|
697 |
} |
|
737 |
getResource().execute(() -> { |
|
738 |
writer.begin(getDBFParameters(), |
|
739 |
getStoreServices().getDefaultFeatureType(), |
|
740 |
getStoreServices().getFeatureStore().getFeatureCount()); |
|
741 |
return null; |
|
698 | 742 |
}); |
699 | 743 |
} |
700 | 744 |
|
... | ... | |
774 | 818 |
} |
775 | 819 |
} |
776 | 820 |
|
821 |
private void updateStoreScaleAndPrecision(DBFFeatureProvider featureProvider, FeatureAttributeDescriptor descriptor, int scale, int precision) { |
|
822 |
if(descriptor.getType() == DataTypes.DECIMAL){ |
|
823 |
if(descriptor.getScale() == scale && descriptor.getPrecision() == precision) { |
|
824 |
return; |
|
825 |
} |
|
826 |
FeatureType ft = this.getFeatureStore().getDefaultFeatureTypeQuietly(); |
|
827 |
FeatureAttributeDescriptor d = ft.getAttributeDescriptor(descriptor.getName()); |
|
828 |
if(d.getScale() == scale && d.getPrecision() == precision) { |
|
829 |
((DBFFeatureProvider)featureProvider).setProviderFeatureType(ft); |
|
830 |
return; |
|
831 |
} |
|
832 |
EditableFeatureType eft = ft.getEditable(); |
|
833 |
EditableFeatureAttributeDescriptor ed = (EditableFeatureAttributeDescriptor) eft.getAttributeDescriptor(descriptor.getName()); |
|
834 |
ed.setScale(scale); |
|
835 |
ed.setPrecision(precision); |
|
836 |
ft = eft.getNotEditableCopy(); |
|
837 |
((DBFFeatureProvider)featureProvider).setProviderFeatureType(ft); |
|
838 |
this.setStoreFeatureType(ft); |
|
839 |
} |
|
840 |
} |
|
841 |
|
|
777 | 842 |
} |
Also available in: Unified diff